diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 000000000..73f69e095
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/WebDevCurriculum.iml b/.idea/WebDevCurriculum.iml
new file mode 100644
index 000000000..d6ebd4805
--- /dev/null
+++ b/.idea/WebDevCurriculum.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 000000000..121d4a228
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 000000000..e149238e6
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 000000000..94557208f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 000000000..35eb1ddfb
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PREFACE.md b/PREFACE.md
new file mode 100644
index 000000000..3f69a1421
--- /dev/null
+++ b/PREFACE.md
@@ -0,0 +1,31 @@
+# Knowre 웹개발 커리큘럼 - 4th Edition, 2021 머리말
+
+대 양적완화의 시대입니다. 시중에 돈이 넘쳐나고, 많은 테크기업들이 막대한 투자금으로 좋은 개발자들을 사냥하고 있습니다. 프로 엔지니어를 꿈꾸는 취업준비생들 사이에서는 한국의 IT회사들의 서열을 가리키는 단어도 유행하고 있고, 은근히 그것을 부추기며 그 서열 한켠에 본인의 회사를 끼워넣는 여론을 만들어 내는 사람들도 있습니다.
+
+구인 현장에서 한 해에도 세 자리수의 소프트웨어 엔지니어들을 면접하고 팀을 이끌어가는 입장에서, 창업 이후에 올해처럼 어렵고 치열했던 시기가 없었던 것 같습니다. 이런 시장에서 스타트업은 어떤 식으로 살아남아야 할까요?
+
+옛날 어떤 농구 감독이 했다는, 전설처럼 내려오는 이야기가 있습니다. '너희들은 공격과 수비 딱 두 가지가 안돼'.. 테크 회사의 엔지니어링 조직 역시 저는 마찬가지라고 생각합니다. 좋은 사람을 뽑고, 좋은 팀을 만들면 됩니다. 문제는 그것을 실행하는 방법이겠지요.
+
+좋은 사람을 뽑으려면 무엇보다 좋은 팀이 되어야 합니다. 하지만 좋은 팀이 되려면 좋은 사람들이 필요하죠. 이런 상황을 전산학에서는 데드락Deadlock 이라고 부릅니다. 이러한 데드락을 피하기 위해서는 무언가 다른 전략이 필요할 것입니다.
+
+이 커리큘럼은 그러한 질문에 대한 고민의 결과이기도 합니다. 이런 상황에서 스타트업이 취할 수 있는 전략 중 하나는, 좋은 사람들을 직접 키워내는 것입니다. 인력시장에는 포텐셜이 충만하지만 아직 더 완성될 부분이 남아있는 꿈나무 엔지니어들이 많습니다. 저는 이런 엔지니어들에게 좋은 엔지니어로 성장할 수 있는 계기를 제공하고 싶고, 그것은 본인에게도 팀에게도 아주 유익한 일일 것입니다.
+
+그렇기 때문에 저는 팀이 커지고 회사가 인수된 지금까지도 10년째 쉬지 않고 그러한 작업을 하고 있습니다. 정확히 세어보진 않았으나 40명 내외의 엔지니어가 저와 이 커리큘럼을 진행했습니다. 그 중에는 아직 저의 팀 동료로 남아있는 사람도 있고 다른 회사로 떠난 사람도 있지만 대부분이 훌륭한 엔지니어로 성장했고, 미국의 가장 큰 테크회사에서부터 스타트업의 키 엔지니어에 이르기까지 다양한 곳에서 활약하고 있습니다.
+
+## 이 커리큘럼을 진행하시는 신규 입사자 분들께
+
+- 여러분들도 이 과정을 통해 프로페셔널 커리어를 설계할 수 있다면 더할나위 없이 좋겠습니다. 이 커리큘럼에서 다루는 지식들도 물론 중요하지만, 그 보다 더 중요한 것은 이 커리큘럼이 이야기하는 소프트웨어 엔지니어로서의 덕목Virtue입니다.
+- 이 커리큘럼을 통해 얻은 지식들 중 어떤 것은 자주 쓰지 않아 잊거나 또 언젠가 다시 기억을 되살리게 될 때가 있을 것입니다. 하지만 이 커리큘럼을 통해 얻은 "공부하는 방법"을 잊지 않는다면 틀림없이 몇 년 후에 매력적인 엔지니어로 성장해 있을 것입니다.
+- 현업 프로젝트의 일정에 압박받지 않고 기술의 깊은 부분을 공부할 수 있는 기회는 앞으로도 쉽게 오는 것이 아닐 것입니다. 아무쪼록 이번 과정을 통해 커리어를 바꿀만한 좋은 경험을 할 수 있기를 기원합니다.
+
+## 이 커리큘럼을 접하신 회사 밖의 분들께
+
+- 이 커리큘럼을 통해 스터디를 진행하는 경우도 있고, 회사에서 신입의 온보딩을 돕는 경우도 있는 것으로 알고 있습니다. 어떤 경우에도 피드백은 아주 중요합니다. 피드백이 없다면 얻을 수 있는 부분이 제한적이기 때문입니다.
+- 퀘스트의 결과물에 대한 피드백은 '이 결과물이 정말 최선인지, 더 개선한다면 어떤 부분을 개선할 수 있을지, 퀘스트를 수행하는 동안 의문스럽거나 꺼림칙한 부분이 있지는 않았는지'를 중심으로 진행하면 좋습니다.
+- 체크리스트의 이론적인 부분에 대한 피드백은 여기에 소개된 링크 이외에도 웹의 방대한 자료를 참조하시면 좋으나, 너무 많은 자료가 오히려 갈피를 잡기 어렵게 만들 수도 있을 것입니다. 또한 '어디까지 파고들어야 하나'를 알 수 없어 막막하기도 할 것입니다.
+- 그런 경우에는 너무 고민하기보다는 커리큘럼의 총 수행기간을 정해 놓고 진행하는 것도 한 가지 방법일 수 있습니다. Knowre의 경우 이 커리큘럼의 총 수행기간은 풀타임(주 40시간 할애) 기준 2~3개월 정도로 잡고 있으니, 그 정도의 시간을 들인다고 생각하시면 참고가 될 수 있을 것 같습니다.
+- 정말 막막하신 경우 저에게 [이메일](mailto:kivoloid@gmail.com)을 보내주셔도 좋습니다. 시간이 닿는 범위에서 최대한 자세히 답변드리도록 하겠습니다.
+
+2011년 말, 2012년 초쯤 창업을 했으니 벌써 9~10년이 되었습니다. 그 세월동안 이 커리큘럼 역시 세 번의 변화를 거쳤습니다. 창업하여 첫 팀원을 받으며 초판을 작성한 후로 2015년과 2018년, 그리고 2021년에 크게 리뉴얼을 했으니 책으로 따지면 4판이라고 할 수 있겠습니다. 정확히 3년정도 주기로 리뉴얼을 했는데, 체감상 3년정도면 기술의 트렌드도 많이 바뀌고 중요한 부분도 달라져 기존의 커리큘럼으로 진행해 나가기에는 아쉽게 되는 것 같습니다. 그렇기 때문에 아마 다음 리뉴얼은 2024년쯤이 되지 않을까 싶습니다.
+
+자매품으로 데브옵스 신입 엔지니어를 위한 [DevOps 커리큘럼](https://github.com/Knowre-Dev/DevOpsCurriculum)도 새로 만들었으니 참고하시면 좋을 것 같습니다.
diff --git a/Quest00/sandbox/Quest00CheckiList.md b/Quest00/sandbox/Quest00CheckiList.md
new file mode 100644
index 000000000..8ef419c48
--- /dev/null
+++ b/Quest00/sandbox/Quest00CheckiList.md
@@ -0,0 +1,630 @@
+# Quest00 - CheckList
+
+## 형상관리 시스템은 왜 나오게 되었을까요?
+
+- 형상관리란 개발과정에서의 시작과 끝의 과정중 변경되는 모든 사항을 관리하는 작업.
+
+- 대표적인 형상관리 시스템 git / svn
+
+
+- 단순하게 본다면 변경사항을 체계적으로 관리 하는 것이다.
+
+## 형상관리 구성요소 4가지 :
+
+- 형상 식별 (Configuration Identification)
+ : 시스템의 효율적인 개발관리를 위해 형상항목(SCI)을 정의하고 분류 하는 활동
+
+
+- 형상 통제 (Configuration Control)
+ : 소프트웨어시스템의 각 베이스라인별로 형상을 설정하고 변경하는 일을 체계적인 절차(변경통제위원회 CCB)에 의해 통제하고 관리하여 결정하는 절차
+
+
+- 형상 감사 (Configuration Audit)
+ : 형상 항목이 요구사항에 맞도록 잘 변경되었는지 확인 하는 것 FCA와 PCA가 있다.
+소스코드를 검토하는 FCA는 실제 성능이 기능 기준선 (Functional Basline) 및 할당 기주선 (Allocated Basline)에 명시된 요구조건을 충족하는가를 확인하는 절차
+
+
+- 형상 기록 (Configuration Status Accounting)
+ : 앞의 3가지 호라동을 자료로 수집하고 기록, 결과의 내용을 데이터베이스화 하고 원하는 형태로 다양하게 이용할수 있도록 하는 활동 .
+
+위에 4가지 요소가 이렇다 정도이지, 결국에는 형상관리는 모든 변동 사항을 체크하는 것이고, 이것이 실수를 줄이기 위한 방법 중 완성도가 높다.
+
+
+형상관리 말고도 PMS(프로젝트 관리시스템) 방법론과 돈이나 진척률 등 프로젝트의 전체적인 사항을 관리하는 시스템, ITSM (IT Service Management) ITIL(IT Infrastructure Library) 프레임워크를 토대로 서비스를 계획, 제공, 운영, 제어 하는 전체적인 활동 시스템, ALM(apllication LifeCycle Management)개발의 요구사항 분석에서부터 아키텍쳐, 변경 관리 등 끝까지 모든 과정을 관리 등 다른 것도 존재하는데 , 주제가 다를 뿐 본질적으론 비슷하다.
+
+
+
+
+## 형상 관리의 장점
+- 소스코드의 변경이력을 관리 할 수 있어서 추적성이 좋다.
+
+- 배포가 편리하다.
+
+- 여러사람이 동일한 소스코드를 공유해 개발할 수 있으며,공유시에 발생하는 버전간의 충돌 문제등을 해결할 수 있다.
+
+- 장애 혹은 기능상 필요할 때 이전 버젼의 BaseLine으로 소프트웨어를 되돌릴 수 있다.
+
+## 형상 관리 사용 이유 요약
+- 가시성의 결핍 : 소프트 웨어는 무형물.
+
+
+- 통제의 어려움 : 가시성이 결핍된 상품의 제작은 통제가 어려움.
+
+
+- 추적의 어려움 : 프로젝트의 중간 목표들을 연결 시키고 개발 과정을 추적하기 어려움.
+
+
+- 감시의 미비 : 가시성과 추적성의 결핍은 프로젝트의 진행을 감시하기 어렵게 함.
+
+
+- 무절제한 변경 : 통제되지 않고 관리 되지 않는 소프트웨어의 무절제한 변경이 발생
+
+
+## Git은 어떤 형상관리 시스템이고 어떤 특징을 가지고 있을까요? 분산형 형상관리 시스템이란 무엇일까요?
+
+ - 깃은 소프트웨어를 개발하는 기업의 핵심 자산인 소스코드를 효과적으로 관리할 수 있게 도와주는 무료 공개 소프트웨어.
+
+
+ - SVN 보다 여러 장점이 있어 SVN을 쓰던 개발 조직들은 하나둘씩 git으로 변경중.
+
+
+ - Git이 SVN과 다른 점은 분산형 관리 시스템이다.
+
+
+ - SVN : 중앙 서버에 소스코드와 히스토리를 저장함.
+
+
+ - Git : 소스코드를 여러 개발 PC와 저장소에 분산해서 저장.
+ 그래서 중앙 서버에 장애가 발생해도 로컬 저장소에 커밋을 할 수 있으며, 로컬 저장소들을 이용하여 중앙 저장소의 복원도 가능하다.
+
+
+ - 사본을 로컬에서 관리하기 때문에 Git이 Svn에 비해 훨씬 빠르다.
+( SVN 의 경우 변경 로그 하나를 보는 것도 인터넷을 경유해야한다고 한다.)
+
+
+ - 깃의 장점
+
+ 1. 소스코드를 주고 받을 필요 없이, 같은 파일을 여러명이서 동시에 작업하는 병렬 개발이 가능하다.
+
+
+ 2. 즉 브랜치를 통해 개발한 뒤, 본 프로그램에 합치는 방식으로 개발 진행이 가능하다.
+
+
+ 3. 분산 관리이기 때문에 인터넷 연결이 되지않아도 개발을 진행할 수 있다. 중앙 저장소에 문제가 생겨도 원상복구가 가능하다.
+
+
+ 4. 팀 프로젝트가 아닌, 개인 프로젝트일지라도 GIT을 통해 버젼 관리를하면 체계적인 개발이 가능해지고 프로그램이나 패치를 배포하는 과정도 간단해집니다. (pull 을 통한 업데이트, patch 파일 배포)
+
+
+## Git 공식문서에서 말하는 깃의 특징
+
+### Distributed development
+
+- 전체 개발 이력을 각 개발자의 로컬로 복사본을 제공 하고 변경된 이력을 다시 하나의 저장소로 복사한다.
+
+- 이러한 변경은 추가개발지점을 가져와, 로컬 개발 지점과 동일하게 병합 할 수 있다. 저장소는 Git protocol 및 Http로 쉽고 효율적 (특별한 웹서버 구성없이) 으로 접근 할 수 있다.
+
+### Strong support for non-linear development
+- 신속하고 편리한 Branch 및 merge 지원, 비선형 개발 이력을 시각화하고 탐색할 수 잇는 강력한 도구를 제공.
+
+### Efficient handling of large projects
+
+- Git은 매우 빠르고, 대형 프로젝트나 이력이 많은 작업에 매우 합리적이다. Git은 대ㅜ분의 다른 버젼 관리 시스템보다 빠르게 요청한다. 그리고 일부 작업에서는 더 빠르게 진행한다.
+- 또한, 최근의 정상급 오픈소스 버젼관리 시스템보다 장기간의 수정내역을 매우 효율적인 압축방법을 사용한다.
+
+### Cryptograhpic authentication of history
+- Git의 이력은 성공한 개발 이력의 commit에 의해 개정명으로 저장된다. 일단 그것이 배포되면, 그것을 모르고 예전 버젼으로 변경하는 것은 불가능하다. 그리고 그것들을 암호화 할 수 있다.
+
+### Toolkit Design
+- Unix의 전통에 따라, Git은 C로 작성된 많은 소규모 도구 모음이다. 그리고 많은 스크립트들이 기능 보강을 제공한다.
+Git 은 새로운 기발한 작업을 위한 손쉬운 사용과 쉬운 스크립팅을 위한 도구를 제공한다.
+
+### Git GUI
+
+ - 너무 많은 git 명령어를 자유자재로 외울 자신이 없을 땐 GUI를 사용할 수도 있다.
+
+
git은 어떻게 개발되게 되었을까요? git이 분산형 시스템을 채택한 이유는 무엇일까요?
+
Git과 GitHub은 어떻게 다를까요?
+- Git은 형상 관리 도구(버전 관리 시스템)
+
+
+- GitHub는 형상 관리 도구 (버전 관리) 웹호스팅 서비스
+
+
+- Git :
+ - 프로젝트를 진행하면서 소스코드나 USB나 메일로 주고 받는건 엄청난 낭비임과 동시에 보안성 위험이 있다.
+ - 그렇기 때문에 프로젝트를 진행 함에 있어 형상관리 도구를 사용한다.
+
+ - 형상관리 도구를 사용하면 변경을 쉽게 되돌릴 수 있다.
+ - 소스코드를 과거의 특정 시점으로 되돌리거나, 특정시점의 변경 사항을 취소하거나, 두 버젼의 소스 코드를 비교하는 등의 일이 가능하다.
+
+
+- GitHub :
+ - 협업하고 있는 코드를 저장할 서버가 필요하다.
+ - 버전 관리 시스템을 지원하는 웹호스팅 서비스의 기능을 통해, push ,pull Request같은 이벤트에 반응하여 자동으로 작업(배포 등)을 실행 할수 있다.
+
+### Git의 `clone`/`add`/`commit`/`push`/`pull`/`branch`/`stash` 명령은 무엇이며 어떨 때 이용하나요?
+그리고 어떻게 사용하나요?
+- clone : 원격 Git 저장소 복제 / 로컬로 복제
+
+
+- 원격 Git 저장소의 주소 Https 혹은 SSH코드를 확인하고, `git clone [Repo_URL OR SSH] [DIR]`로 사용 가능하다.
+`Dir` 을 생략하면 현재 위치로 복제할 위치를 지정한다. (이후 `git remote-v`로 현재 리모트 확인 가능함.)
+
+### add` : 작업 디렉토리 상의 변경 내용을 스테이징 영역에 추가하기 위해 사용한다.
+
+- 위에서 말한것처럼commit 이전에 변경분을 모아두기 위한 명령어이고, commit 이 되기전에는 변경이력에 영향을 주지않는다.
+
+### git add
+
+- `<파일/디렉토리 경로>`로 사용하면 작업 디렉토리의 변경 내용의 일부만 스테이징 영역에 넘기고 싶을때는 수정한 파일이나 디렉토리의 경로를 인자로 넘긴다.
+
+
+- `git add .` 으로 사용하면 현재 디렉토리의 모든 변경 내용을 스테이징 영역으로 넘기고 싶을때는 `.` 을 인자로 준다.
+
+
+- `git add -A `
+ - 작업 디렉토리 내의 모든 변경 사항을 몽땅 스테이징 영역으로 넘기게 된다.
+
+
+ - 작업 디렉토리 상에 어디에 위치하든 동일하게 모든 내용을 스테이징으로 넘긴다.
+ (`git add . ` 의 경우에는 실행된 디렉토리 이하에서만 내용을 포함하게 되며 해당 디렉토리 기준으로 상위 디렉토리의 변경은 포함하지 않는다.
+만약에 `git add .` 를 프로젝트 최상위 디렉토리에서 실행한다고 하면 `git add -A`와 동일한 효과를 내게 된다.)
+
+### `git add -p`
+
+- 각 변경 사항을 터미널에서 직접 눈으로 하나씩 확인하면서 스테이징 영역으로 넘기거나 제외시킬수가 있다. 변경내용이 많을 때에 변경 기록으로 나누어서 남기고 싶을 때 유용하게 사용할 수 있다.
+
+### commit
+
+- 파일 및 폴더의 추가/ 변경 사항들에 대한 기록을 한다.
+
+
+- `add` 로 스테이징 영역(인덱싱되어있는) 에 들어있던 내용들을 시간 순으로 저장하며 최근 커밋부터 거슬러 올라가면 과거 변경 이력과 내용을 확인 할 수 있다. `commit` 을 하게 되면 해당 기록에 대한 이름으로 `영문/숫자40자리` 로 이루어진 이름이 부여되어 이것을 `id값` 으로 구분할 수 있다.
+ - git commit 옵션으로는 -m -am 등이 있다.
+
+ - `git commit -m 'message' ` 를 사용하면 `commit`에서 `vim`을 들어가 `msg`를 작성하는 작업을 skip하고 명령창에서 `msg`를 바로 작성할수 있다.
+
+ - `git commit am 'message'` 는 커밋이 된 이후에 다시 새버젼을 만들 경우 `'add', 'vim' `에서 `msg`작성하는 작업을 명령창에서 바로 할 수 있다.
+
+### push
+- `Push`는 `origin` 즉, 원격 저장소의 브랜치에 밀어올린다, 기록한다. 따라서 `push`를 할때에는 원하는 브랜치를 명시하고, 올리면 해당 브랜치에 기록할 수 있다.
+`git branch -M main`
+`git push origin main`
+
+
+- 기본적으로는 `git push <저장소명> <브랜치명>` 으로 사용한다.
+ex ) `git push origin my-feature `
+`git clone`을 통해 저장소를 복제했다면 일반적으로 `origin`이며
+`git remote` 명령어를 통해서 정확한 저장소명을 알아낼 수도 있다.
+
+`git remote origin`
+
+또한` git push`를 날릴때마다 매번 저장소명과 브랜치명을 명시하는게 귀찮다면` -u `옵션을 사용하여서 최초 저장소명과 브랜치명만 입력하여 이후에 모든 추가 입력사항을 생략할 수 있다고 한다.
+
+예를 들어, 다음과 같이 저장소명과 브랜치명을 남기면서 `-u옵션`과 함께 `git push` 명령어를 날리게 되면
+ex)
+`git push -u origin my-feature`
+그 이후에 커밋한 코드 변경분을 원격 저장소에 올릴 때는 인자없이 `git push`만 입력해주면 된다.
+
+혹은 여러 브랜치를 변경하면서 작업을 하는 경우라면, 최초에 한번 인자를 넘기는 것도 힘들게 느껴질 수 있는데, 대부분의 경우에는 로컬저장소와 원격 저장소에서 동일한 브랜치 이름을 사용하기 때문에 항상현재 브랜치를 기준으로 `git push` 명령어가 작동한다면 매우 편리하다고한다.
+
+이를 위해서는 약간의 설정이 필요하다.
+
+` push.default` 설정을 `current`로 설정해준다.
+ `git cofing --global push.default current `
+이렇게 설정을 해두면 어느 브랜치에서 작업을 하든 `git push` 만 날리면 원격 저장소에 동일한 브랜치로 코드 변경분이 업로드된다.
+
+`git pull`을 사용하면 원격저장소의 변경된 데이터를 가져올 수 있다.
+`pull`한 데이터가 어떻게 반영되는지는 아래 간단하게 확인 해보자면
+
+`A -> B -> X-> Y(origin/master)`
+
+`A -> B(master)`인 상황에서 원격 저장소의 커밋Y 를 로컬로 가져오는 경우를 본다.
+이 상황은 단순히 'fatst-forward 병합' 이 이루어진다.
+이 내부의 `master`는 로컬 저장소의 `master` 브랜치, `origin/master`는 원격 저장소 `origin`의 `master` 브랜치를 나타낸다.
+
+`A-> B-> X-> Y(origin/master master)`
+그러나 로컬 저장서의 'master 브랜치에서도 변경 사항이 생긴 경우, 양쪽의 변경을 통합할 필요가 있다.
+
+`A->B->X->Y (origin /master) `
+`A->B->C->D (master) `
+이때 `pull`을 실행하여 소스를 병합할수 있다.
+충돌하는 변경사항이 없을 경우 자동적으로 병합 커밋이 만들어지지만, 충돌이 있을 경우에는 충돌난 부분을 수동으로 해결한 다음 직접 `commit을` 해야한다.
+
+`branch`의 명령어의 경우
+`git branch` 현재는 `master` 브랜치만 존재한다. (`master` : 최초 레포지토리 생성 후 커밋하면 자동으로 생기는 브랜치)
+*가 붙어있는 브랜치가 현재활성화된 브랜치이다.
+
+- `git branch -v` 를 사용하면 브랜치의 마지막 커밋 메세지를 확인 할 수 있다.
+- `git branch <브랜치명>` 을 사용해서 브랜치를 생성할 수 있다.
+- `git checkout <브랜치명>`으로 브랜치를 이동 할 수 있다.
+- `git checkout -b <브랜치명>` 은 브랜치를 생성하고 바로 이동할 수 있다.
+- `git branch -d <브랜치명>`로 브랜치를 삭제할 수 있다.
+
+
+`stash` 는 임시저장과 비슷한 맥락이다.
+예를 들어서 내가 어떤 작업을 하고 있다가 다른 요청이 들어와 잠시 작업을 멈추고 브랜치를 변경해야한다고 하는 상황에서 내가 마무리하지 않은 작업에 대해서 `commit` 하는 것이 껄끄러운 경우가 충분히 있을 수 있다.
+```
+ Stashed Changes
+
+ |
+
+ Workign Directory - stage-> Staged Snapshot - commit -> committed SnapShots
+```
+아직 마무리되지 않은 작업을 잠시 스택에 저장할 수 있도록 하는 명령어이다.
+이를 `commit` 하지 않고 나중에 다시 꺼내와서 마무리할 수 있도록 해준다.`
+
+- `git stash` 명령을 사용하면 워킹 디렉토리에서 수정한 파일들만 저장한다.
+- `stash` 란 아래에 해당하는 파일들을 보관해두는 장소이다.
+ 1. `modified` 이면서 `Tracked` 상태인 파일
+ - `Tracked` 상태인 파일을 수정한 경우
+ - `Tracked` : 과거에 이미 `commit` 하여 스냅샨에 넣어진 관리 대상의 파일
+ 2. `Staging Area` 에 있는 파일 (`Staged` 상태의 파일)
+ - `git add` 명령을 실행한 경우
+ - `Staged` 상태로 만들려면 git `add` 명령을 실행해야 한다.
+`git Stash` 명령어를 통해 `stash`를 스택에 만들어 하던 작업을 임시로 저장한다.
+ - 예를 들어서 파일2개를 수정하고 그 중하나는 `Staging Area`에 추가한다. 아직 작업 중인 2개의 파일은 `commit` 할게 아니기 때문에 모두 `stash` 에 넣는다.
+ 1. `index.html`: `Staging Area`에 있는 파일 (`Staged` 상태의 파일)
+ 2. `lib/simplegit.rb` : `Modifed` 이면서 `Tracked` 상태인 파일
+
+
+Ex) // working directory에 있는 파일의 상태 확인
+```
+$ git status
+Changes to be committed:
+(use "git reset HEAD ..." to unstage)
+modified: index.html
+Changes not staged for commit:
+(use "git add ..." to update what will be committed)
+(use "git checkout -- ..." to discard changes in working directory)
+modified: lib/simplegit.rb
+```
+
+`git Stash / git Stash save` 명령어로 스택에 새로운 `stash가` 만들어진다.
+이 과정을 통해서 Working directory는 깨끗해진다.
+
+`git stash list`를 통해서 `stash에` 넣은 목록을 확인 할 수 있다.
+`git stash apply` 를 통해서 작업을 다시 가져올 수 있다.
+ex) //가장 최근의 `stash를` 가져와 적용시킨다.
+`git stash apply`
+// `stash` 이름 (ex. `stash@{2}`)에 해당 하는 `stash를` 적용한다.
+`git stash apply [stash 이름]`
+ 위 명령어로는 `Staged` 상태였던 파일을 자동으로 다시 `Staged` 상태로 만들어주지 않는다.
+-`index` 옵션을 주어야 `Staged` 상태까지 복원한다. 이를 통해 원래 작업하던 파일의 상태로 돌아올 수 있다.
+//`Staged` 상태까지 저장
+`git stash appyl --index`
+
+`stash` 제거하기
+`git stash drop`
+apply 옵션은 단순히 `stash를` 적용하는 것으로, 해당 `stash는` 스택에 여전히 남아있다.
+스탹에 남아 있는 `stash` 는 위의 명령어를 사용하여 제거할 수 있다.
+```markdown
+//가장 최근의 `stash를` 제거한다.
+`git stash drop`
+//`stash` 이름(ex. `stash@{2}`)에 해당하는 `stash를` 제거한다.
+`git stash drop [stash 이름]`
+```
+만약 저장되어 있던 `stash` 를 가져와 적용과 동시에 해당 `stash` 를 제거하고 싶으면
+`git stash pop` 명령을 사용하면 된다.
+`// apply + drop`의 형태
+`git stash pop`
+
+실수로 잘못 `stash` 를 가져와 적용했다면
+`git stash show -p | git apply -R`을 사용한다.
+가장 최근의 `stash`를 사용하여 패치를 만들고 그것을 거꾸로 적용한다.
+`git stash show -p | git apply -R`
+//`stash 이름 (ex. stash@{2})` 에 해당하는 `stash` 를 이용하여 거꾸로 적용한다.
+`git stash show -p [stash 이름] | git apply -R`
+
+`Alias` 를 사용할 수도 있다.
+`stash-unapply` 명령어로 간단하게 사용할 수 있다.
+`git config --global alias.stash-unapply '! git stash show -p | git apply -R'`
+`git stash apply`
+`#... work work work`
+// alias로 등록한 stash 되돌리기 명령어
+`git stash upapply`
+
+
+### git의 `Object`, `Commit`, `Head`, `Branch`, `Tag`는 어떤 개념일까요? git 시스템은 프로젝트의 히스토리를 어떻게 저장할까요?
+- git의 개체는 크게 4가지` commit`, `Tree`, `Blob`, `Tag`로 나뉜다.
+git은 내부적으로 이 4가지 `오브젝트 타입`을 관리한다.
+
+오브젝트들은 `.git/objects`에 개별적인 파일들로 존재한다.
+하나의 `commit`, 하나의 `tree`, 하나의 `blob` 그리고 하나의 `tag는` 각각 하나의 파일이다.
+
+두개의 `commit` 은 당연히 두개의 파일이다.
+
+오브젝트가 담긴 파일의 이름은 git 이 오브젝트 컨텐츠의 내용을 참고하여 생성하는 `40자리 문자열`이다.
+예로 git 에 `hello.txt`라는 파일을 하나 추가하면,
+`hello.txt`라는 이름의 `오브젝트`를 생성하는 것이 아니라
+`hello.txt`의 내용 전부를 `해시테이블`에 넣어
+`40자리의 해시값`을 뽑아내어 `오브젝트 파일` 이름으로 사용한다.
+
+그렇다면 `hello.txt`라는 이름은 어디에 저장되는 것일까?
+`hello.txt`를 위한 오브젝트인 `blob` 에는 파일이름인 `hello.txt`라는 문자열로 저장되지 않는다.
+
+대신 디렉토리 구조를 나타내는 `tree` 오브젝트에서 `hello.txt`라는 문자열을 찾을 수 있습니다.
+
+(이는 리눅스 파일 시스템에서 흔히 사용하는 `inode - dentry`의 관계와 동일합니다.)
+
+오브젝트 들은 하나의 파일로 `.git/objects`에 차곡차곡 쌓이게 되는데
+한 디렉토리에 너무 많은 파일이 있으면 파일 시스템의 성능이 저하 될 수 있기때문에
+`오브젝트`의 _**파일 이름 중 앞 2글자는 디렉토리 이름**_ 으로 사용 ,
+나머지 ***38글자는 파일이름으로 사용***하게 된다.
+
+### `blob`(binary large object)
+- 타입 : `blob` 타입
+- 사이즈 : 컨텐츠의 용량을 `bytes`로 표시
+- 컨텐츠 : `blob의` 컨텐츠에는 텍스트, 이미지, 음악 혹은 단순 이진 파일철머 다양한 형식의 파일이 저장될 수 있다.
+파일이름이나 파일 형식은 `blob`에 저장되지 않는다.
+파일의 메타정보를 제외한 파일의 내용 전체를 품는다.
+
+### tree
+- 타입 : `tree` 타입
+- 사이즈 : `트리 오브젝트`의 용량을 `bytes` 로 표시
+- `tree 객체 `: ***하위 디렉토리의 트리 객체를 재귀적으로 참조***할 수 있다.
+- `blob 객체` : 한 디렉토리에 있는 모든 `blob`을 담고 있다.
+객체에 대한 접근권한, 파일이름은 여기서 관리한다.
+
+### commit
+- 작성자
+- 커밋 실행자
+- 커밋 날짜
+- 로그메시지
+- `tree 객체` : 해당 커밋에서의 `dir/file`의 상태를 알 수 있다.
+
+### tag
+- 객체 종류
+- 태그 이름
+- tagger
+- 태그메시지
+- PGP 서명정보
+
+git은 이러한 오브젝트의 상태정보를 확인 할 수 있는 명령어가 노출되어 있다.
+`git cat-file`을 오브젝트에 사용하여 오브젝트가 품고 있는 정보를 자세히 알아보려 합니다.
+
+ex)`git cat-file -p 44cac0afe16f0819bba6cc2332b9418ba3c1ce8b`
+
+git 에서 `HEAD` 란 현재 `체크아웃된 커밋`을 가리킨다.
+즉 현재 작업중인 커밋이다.
+`HEAD` 는 항상 작업트리의 갖아 최근 커밋을 가리킨다.
+작업 트리에 변화를 주는 git 명령어들은 대부분 `HEAD` 를 변경하는 것으로 시작합니다.
+일반적으로 `HEAD` 는 브랜치의 이름을 가리킵니다.
+
+`HEAD` 를 분리한다는 것은 `HEAD` 를 브랜치 대신 커밋에 붙이는 것을 의미한다.
+(`git checkout` 커밋이름 으로 커밋으로변경할수 있다.)
+
+깃에서 태그란
+커밋을 참조하기 쉽도록 알기 쉬운 이름을 붙이는 것을 말한다고 한다.
+한번 붙인 태그는 브랜치 처럼 위치가 이동하지 않고 고정된다.
+Git 에서는 일반적으로 이름 정보만을 갖는 태그 `Lightweight tag`와 보다 상세한 정보를 포함하는 주석태그 이 두가지 태그를 사용할 수 있습니다.
+
+- 일반태그 (`Lightweight tag`)
+ : 이름만 붙일 수 있어요.
+- 주석태그(`Annotated tag`)
+ : 이름을 붙일 수 있어요.
+ : 태그에 대한 설명도 포함할 수 있어요.
+ : 서명도 넣을 수 있어요.
+ : 이 태그를 만든 사람의 이름, 이메일과 태그를 만든 날짜 정보도 포함시킬 수 있어요.
+
+보통 '릴리스 브랜치 (`Release branch`)에서는 주석 태그를 사용하여 설명이나 서명을 넣은 보다 상세한 정보를 포함하는 태그를 사용하고 로컬에서는 일시적으로 사용하는 ' `토픽 브랜치`' 에서만 이름만 만들어 붙이는 태그를 사용한다고 한다.
+또한 태그 이름을 지정하여 `checkout` 하거나 `reset`(아직 안 배웠어요!) 함으로써, 간단하게 과거의 특정 상태로 되돌릴 수 있답니다!
+
+Git에서의 브랜치는 독립적으로 어떤 작업을 진행하기 위한 개념이다. 필요에 의해 만들어지는 각각의 브랜치는 다른 브랜치의 영향을 받지 않기 때문에 여러 작업을 동시에 진행할 수 있다.
+
+또한 이렇게 만들어진 브랜치는 다른 브랜치와 병합(`MERGE`)함으로써 작업한 내용을 다시 하나의 브랜치로 모을 수 있습니다.
+브랜치를 사용하여 동시에 여러 작업을 진행할 때 작업의 흐름을 하눈에 파악 할 수 있습니다.
+
+여러명이서 동시제 작업을 할때에 다른 사람의 작업에 영향을 주거나 받지 않도록, 먼저 멩니 브랜치에서 자신의 작업 전용 브랜치를 만듭니다.
+
+그리고 각자 작업을 진행한 후, 작업이 끝난 사람은 메인 브랜치에 자신의 브랜치의 변경 사항을 적용합니다.
+
+이렇게 함으로써 다른 사람의 작업에 영향을 받지 않고 독립적으로 특정 작업을 수행하고 그 결과를 하나로 모아 나가게 됩니다.
+
+이러한 방식으로 작업할 경우 '작업 단위' 즉 브랜치로 그 작업의 기록을 중간중간에 남기게 되므로 문제가 발생했을 경우에는 원인이 되는 작업을 찾아내거나 그에 따른 대책을 세우기 쉬워진다.
+
+
+### 깃의 내부구조
+- git의 내부는 일종의 단순한 `key-value` 데이터베이스이다.
+
+- git 프로젝트의 `.git` 디렉토리 안에는 git 버전관리에 필요한 데이터들이 저장된다.
+
+### Content-addressable Key-Value Storage
+ git은 버젼 관리에 필요한 데이터를 key-value 형태의 오브젝트로 변환한다.
+ 이때 `ket`는 데이터를 `SHA-1` 알고리즘을 이용한 `체크섬`이 되고 `Value`는 데이터를` zlib`으로 압축한 값이 된다.
+
+`SHA-1` 해시를 사용하여 `체크섬`을 생성하면 `체크섬`은 ***160비트***가 되고 ***16진수로 표현하면 40자리의 문자열***이된다.
+git 은 ***이 40자리 문자열 중 앞의 2자리는 디렉토리 명으로 나머지 38자리는 파일명으로 사용***한다.
+즉, git은 원본 데이터의 `체크섬`을 파일명으로 원본 데이터를 `zlib` 압축한 값을 파일데이터로 저장하고 이를 `object`라고 합니다.
+
+git 은 타입을 나타내는 헤더와 내용을 합쳐 `SHA-1 체크섬`을 계산합니다.
+
+`Object`의 내용을 보면 `zlib`으로 압축되어 있기 때문에 내요을 바로 확인할 수 없습니다.
+`git cat-file` 명령어를 사용하면 `오브젝트의 타입`과 내용을 확인할 수 있습니다.
+