ݺߣ

ݺߣShare a Scribd company logo
Advanced
 Git 
A.J
Իᰪ.dz
  
! 
@andrwj
개발자를 위한 고급 Git 활용전략 
- TRACK B, Session 4 
! 
세계의 개발자가 '코드'로 대화하는 환경, 분산버전관리시스템인 
Git 을 멋지게 사용하는 방법을 공유합니다. 실제업무와 개인적 
개발에서도 거침없이 Git 을 사용하는 노하우를 알아봅니다.
Git, Advanced
세션 요점 #1 
 Git 명령의 대부분은 File 보다는 
Commit 객체를 다룬다.
세션 요점 #2 
 Git 명령을 보다 잘 이해하기 위해 
HEAD 와 브랜치는 포인터임을 
기억하자.
미리 알아둘 것 #1 
 Javascript 로 표현되는 Pointer
var HEAD = ‘master’; 
! 
 console.log( HEAD ); 
! 
‘master’ 
HEAD 는 단순 변수
var refs = { 
heads: { 
master: ‘master’, 
develop: ‘develop’ 
} 
}; 
! 
 console.log( refs. heads. master ); 
! 
‘master’ 
refs.heads.master 역시 단순 변수
var refs = { 
heads: { 
master: ‘master’, 
develop: ‘develop’ 
} 
}; 
! 
 HEAD = refs. heads. master; 
! 
 console.log( HEAD ); 
! 
‘master’ HEAD
“master” refs.heads.master 
refs. heads. master 
HEAD 
참조
미리 알아둘 것 #2 
 Javascript 로 알아보는 
HEAD 사용예
var C1 = { 
prev: null, 
value: “ some-value “ 
}; 
! 
! 
! 
C1 
객체 C1을 나타낸다
var C1 = { 
prev: null, 
value: “ some-value “ 
}; 
! 
 var HEAD = C1; 
HEAD 
C1 
HEAD는 C1을 가리킨다 
(pointing)
var C2 = { ... }; 
! 
HEAD 
C1 
같은 종류의 객체 C2를 생성한다. 
C2
var C2 = { ... }; 
! 
 C2.prev = HEAD; 
! 
HEAD 
C1 
HEAD를 이용하여 이전 객체와 연결함을 주의 
C2 
깊게 보자
var C2 = { ... }; 
! 
 C2.prev = HEAD; 
! 
 HEAD = C2; 
C1 
HEAD 
C2 
다시 HEAD를 새로운 C2로 
가리킨다 (pointing)
var C3 = { ... }; 
! 
C1 
같은 종류의 객체 C3를 생성한다. 
HEAD 
C2 C3
var C3 = { ... }; 
! 
 C3.prev = HEAD; 
! 
! 
C1 
역시 HEAD를 이용해 연결한다. 
각 객체는 이전 객체를 알수있다. 
HEAD 
C2 C3
var C3 = { ... }; 
! 
 C3.prev = HEAD; 
! 
 HEAD = C3; 
! 
C1 
다시 HEAD를 새로운 C3로 
가리킨다 (pointing) 
HEAD 
C2 C3
HEAD를 이동시킴으로써 임의의 연결을 자유 
롭게 만들어 갈 수 있음을 보여주는 예
HEAD = C2; 
C1 
HEAD 
HEAD는 C2 객체를 가리킨다. 
C2 C3
HEAD = C2; 
 var C4 = { ... }; 
! 
C1 
HEAD 
C2 C3 
C4 
새로운 객체 C4를 만든다
HEAD = C2; 
 var C4 = { ... }; 
 C4.prev = HEAD; 
C1 
HEAD 
HEAD가 가리키는 객체와 
C2 C3 
C4 
연결 할 수 있다. 
(브랜치가 꺾어지는 모습)
HEAD = C4; 
! 
C1 
객체 C4에 HEAD를 맞춘다 
HEAD 
C2 C3 
C4
var C5 = { ... }; 
 C5.prev = HEAD; 
 HEAD = C5; 
! 
객체 C5역시 같은 방법으로 다른 
객체와 연결할 수 있다 
C1 C2 C3 
HEAD 
C4 C5
HEAD를 이용하여 각 객체는 
연결을 이어갈 수 있다.
C1 C2 C3 
C4 C5 
.prev 
.prev .prev 
.prev
또한, HEAD가 어디를 가리키냐에 따라 
연결 과정이 달라 보일 수 있다. 
! 
(브랜치마다 커밋 로그가 달라보이는 이유)
C1 C2 C3 
HEAD 
C4 C5 
.prev 
.prev 
.prev
HEAD 
C1 C2 C3 
.prev .prev 
C4 C5
Git의 Branch 작동법도 비슷하게 
설명될 수 있다
var C1 = { 
prev: null, 
value: “ some-value “ 
}; 
! 
! 
C1 
C1을 생성하고...
var C1 = { 
prev: null, 
value: “ some-value “ 
}; 
 var master = C1; 
master master 변수에 C1을 설정한다음 ... 
C1
var C1 = { 
prev: null, 
value: “ some-value “ 
}; 
 var master = C1; 
 var HEAD = master; 
! 
HEAD 
master 
C1 
HEAD는 master를 가리킨다
var C2 = { ... }; 
! 
! 
HEAD 
master 
C1 C2 
C2을 생성하고...
var C2 = { ... }; 
! 
 C2.prev = HEAD; 
! 
HEAD 
master 
역시 HEAD를 이용해 연결한다 
C1 C2
var C2 = { ... }; 
! 
 C2.prev = HEAD; 
! 
 master = C2; 
! 
HEAD 
master 
C1 C2 
master를 이동시키면 
HEAD도 따라간다!
var C3 = { ... }; 
! 
 C3.prev = HEAD; 
! 
 master = C3; 
같은 방법으로 객체 C3를 만들어 
이전 객체와 연결시켜줄 수 있다 
HEAD 
master 
C1 C2 C3
이번엔 브랜치 변수를 나타내는 develop을 만들 
어 master와 다른 객체를 가리킨다 
 var develop = C2; 
HEAD 
master 
develop 
C1 C2 C3
var develop = C2; 
 var HEAD = develop; 
master의 위치는 그대로 두고, 
HEAD를 master로 
이동시켜 다음번 객체를 
연결시킬 준비를 한다. 
master 
HEAD 
develop 
C1 C2 C3
var C4 = { .. }; 
! 
master 
HEAD 
develop 
C1 C2 C3 
C4 C4를 만들고..
var C4 = { .. }; 
 C4.prev = HEAD; 
master 
HEAD 
develop 
C1 C2 C3 
C4 
HEAD를 이용해 연결을 이 
어나갈 수 있다
var C5 = { .. }; 
 C5.prev = HEAD; 
 develop = C5; 
master 
C1 C2 C3 
HEAD 
develop 
C4 C5 
계속해서 다른 연결도 
이어갈 수 있다.
이때 HEAD를 변경함으로써 두개의 
‘이름’ 가진 연결을 만들 수 있다. 
! 
( Git Branch 역시 같은 방식이다)
HEAD = master; 
HEAD 
master 
C1 C2 C3 
develop 
C4 C5 
master를 가리킬때는 
C3 - C2 - C1 순으로 연결 (history)
HEAD = develop; 
! 
develop를 가리킬때는 HEAD 
master 
C1 C2 C3 
develop 
C4 C5 
C5 - C4 - C2 - C1 순으로 연결 
(history)
Git의 HEAD는 변수처럼 동작하며 
특정 브랜치를 가리킨다. 
! 
 Git의 Branch는 변수처럼 동작하며 
특정 커밋을 가리킨다.
미리 알아둘 것 #2 
 Git 저장소 해부
. 
./.git 
./.git/branches 
./.git/config 
./.git/description 
./.git/HEAD 
./.git/hooks 
./.git/hooks/applypatch-msg.sample 
./.git/hooks/commit-msg.sample 
./.git/hooks/post-commit.sample 
./.git/hooks/post-receive.sample 
./.git/hooks/post-update.sample 
./.git/hooks/pre-applypatch.sample 
./.git/hooks/pre-commit.sample 
./.git/hooks/pre-rebase.sample 
./.git/hooks/prepare-commit-msg.sample 
./.git/hooks/update.sample 
./.git/info 
./.git/info/exclude 
./.git/objects 
./.git/objects/info 
./.git/objects/pack 
./.git/refs 
./.git/refs/heads 
git init 명령후 생성되는 파일들
. 
./.git 
./.git/branches 
./.git/config 
./.git/description 
./.git/HEAD 
./.git/hooks 
./.git/hooks/applypatch-msg.sample 
./.git/hooks/commit-msg.sample 
./.git/hooks/post-commit.sample 
./.git/hooks/post-receive.sample 
./.git/hooks/post-update.sample 
./.git/hooks/pre-applypatch.sample 
./.git/hooks/pre-commit.sample 
./.git/hooks/pre-rebase.sample 
./.git/hooks/prepare-commit-msg.sample 
./.git/hooks/update.sample 
./.git/info 
./.git/info/exclude 
./.git/objects 
./.git/objects/info 
./.git/objects/pack 
./.git/refs 
./.git/refs/heads 
./.git/refs/tags 
원활한 설명을 위해 무시..
. 
./.git 
./.git/branches 
./.git/config 
./.git/description 
./.git/HEAD 
./.git/info 
./.git/info/exclude 
./.git/objects 
./.git/objects/info 
./.git/objects/pack 
./.git/refs 
./.git/refs/heads 
./.git/refs/tags 
앞서 Javascript 변수로 설명한 
것들이 파일로 존재한다!
git init 명령직후에는 master 파일 내 
용에 아무것도 없다 
$ cat ./git/HEAD 
ref: refs/heads/master 
! 
$ cat .git/refs/heads/master 
cat: .git/refs/heads/master: No such file or directory 
! 
$ git branch 
! 
$ 
! 
브랜치 역시 없는 상태
간단히 README 파일을 생성한다 
$ echo ‘just created’  README 
! 
$ ls -la 
total 0 
drwxr-xr-x 4 andrwj staff 136 11 25 00:18 . 
drwxr-xr-x 3 andrwj staff 102 11 25 00:14 .. 
drwxr-xr-x 14 andrwj staff 476 11 26 17:21 .git 
-rw-r--r-- 1 andrwj staff 0 11 25 00:16 README 
! 
$ cat README 
just created 
! 
$ 
현재 폴더에는 READ와 
.git 폴더 뿐이다
. 
./.git 
./.git/branches 
./.git/COMMIT_EDITMSG 
./.git/config 
./.git/description 
git add README 직후, 
./.git/HEAD 
긴이름의 파일이 생긴다 
./.git/index 
./.git/objects 
./.git/objects/4e 
./.git/objects/4e/8238248ad38d598515adb865b818ec9381f967 
./.git/objects/info 
./.git/objects/pack 
./.git/objects/info 
./.git/objects/pack 
./.git/refs 
./.git/refs/heads 
./.git/refs/heads/master 
./.git/refs/tags 
./README
$ cat .git/HEAD 
! 
ref: refs/heads/master 
!! 
그러나 여전히 master 파일의 내용은 비어있다 
$ cat .git/refs/heads/master 
cat: .git/refs/heads/master: No such file or directory 
!!! 
$ cat .git/object/4e/8238248ad38d598515adb865b818ec9381f967 
! 
x??Q 
B!??????? 
??-?ied?]?? 
?;03K?? 
@???9Cd?9%t?I???Ή?(J+B?%e4?=n??? 
??L?s?^k(?????!???zkͤs3?߂????????/? 
생성된 긴 이름의 파일을 출력해보니 
TEXT 포맷의 파일이 아님을 알수있다
git blob format 
 헤더 정보를 포함하여 zlib로 압축되어 저장된다 
 헤더 형식: “blob 원본파일크기 null”
blob format 
$ cd .git/object/4e/ 
$ python 
 fd = open(“8238248ad38d598515adb865b818ec9381f967”) 
 line = fd.read() 
 import zlib 
 zlib.decompress(line) 
‘blob 13x00just createdn’ 
 
객체 종류는 
‘blob’ 원본 크기는 13 바이트 
null 바이트 
원본 내용
git hash-object README 
$ git hash-object README 
4e8238248ad38d598515adb865b818ec9381f967 
! 
$ git cat-file -p 4e8238 
just created 
파일이름으로 해쉬명을 알 수 있다 
파일이름 몇글자로 
내용을 출력할 수 있다
why hash ? 
 내용에 따라 중복된 이름이 나올 가능성이 극히 드물다 
 육안으로 분별하기 힘든 차이도 쉽게 검출 가능하다 
 번호로된 파일 이름보다 관리 하기 쉽다(?) 
 파일명이 변경되어도 내용이 같으면 동일한 것으로 
인식한다.
README 
! 
‘just created’ 
README 
! 
‘just created ‘ 
$ cat README 
! 
‘just created’ 
!! 
끝부분 공백도 명확히 알 수 있다 
$ git hash-object README 
! 
ec53c2432a2e9c2fadaa9d5982bd3cf31f9b38d2 
! 
$ cat README 
! 
‘just created ’ 
!! 
$ git hash-object README 
! 
a6014d70c71eab934f3ac1248f8bad19ad3d451c 
!
README.1 
! 
‘just created’ 
README.2 
! 
‘just created‘ 
$ cat README.1 
! 
‘just created’ 
!! 
내용이 같으면 파일이름이 달라도 같은 값을 출력한다 
$ git hash-object README.1 
! 
ec53c2432a2e9c2fadaa9d5982bd3cf31f9b38d2 
! 
$ cat README.2 
! 
‘just created’ 
!! 
$ git hash-object README.2 
! 
ec53c2432a2e9c2fadaa9d5982bd3cf31f9b38d2 
!
git use hash !
이제부터 핵심!
four object 
Blob Commit 
Tag 
Tree 
Git에는 4가지 객체가 있다
var blob = “헤더+내용이 zlib 로 압축된 문자열”; 
! 
 var Tree = [ 
blob, 
Tree, 
]; 
! 
 var Commit = { 
Javascript로 표현 ... 
parent: { }, 
tree: [ ], 
author: “string”, 
date: “2011/11/30” 
}; 
! 
 var Tag = “커밋을 가리키는 문자열”
blob object 
Blob 
 header + content 
! 
 zlib로 압축되어 있다 
! 
 .git/objects/ 아래 있다
tree object 
Tree 
 blob + 다른 tree 객체 
! 
 ‘폴더’와 같은 개념 
! 
 .git/objects/ 아래 있다
commit object 
Commit 
 blobs + trees + author 
+ date + message 
! 
 .git/objects/ 아래 있다
tag object 
Tag 
 pointer to commit object 
! 
 .git/refs/tags/ 아래있다
B 
BB 
T 
TBT T 
TBT T 
prev 
author 
date 
message 
BTT TBT 
Tag 
BBB 
prev 
author 
date 
message 
T 
TBT T 
TBT T 
TBT 
BBB 
prev 
author 
date 
message 
T 
TBT T 
TBT T 
TBT 
Tag 
BB 
BT HEAD 
master 
예를 들자면...
중간 정리 
파일은 blob 포맷으로 저장된다. 
폴더는 tree 객체로, 파일은 blob 객체로 표현된다. 
commit, tag 역시 객체로 취급되어 파일형태로 저장된다. 
모든 파일은 SHA 방식의 해쉬로 표현된다. 
Git의 branch와 commit 은 pointer 이다.
three spaces 
- Working area 
! 
- Staging or Index 
! 
- Local Repository
but, these are just 
concept!!
Staging Repo 
! 
- 영구저장 영역 
- .git/object/* 
! 
- 작업 폴더 영역 
- ./ 
! 
Working 
3개의 공간 
! 
- 스테이징 영역 
- .git/index
첫번째 커밋
Repo 
!R 
Working Staging 
EADME 
$ cat ‘just created’  README 
과정1 /11 - 처음으로 커밋할 파일을 생성
Repo 
!R 
Working Staging 
EADME 
$ cat README 
just created 
과정2 /11 - 파일 내용 보기
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
$ git add README 
스과테정이3 징/1 영1역 -에 스 파테일이 징정 보영 역기에록 
파일 정보 기록 
‘README’ 파일은 blob 형식으로 변환되어 
.git/object/ 아래에 저장됨
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
$ git ls-files -s 
100644 4e8238248ad38d598515adb865b818ec9381f967 0 README 
! 
과정4 /11 - 스테이징 영역의 파일 정보 열람 
(.git/index 파일 내용을 참조)
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
$ ls -la .git/object/4e 
drwxr-xr-x 3 andrwj staff 102 11 26 17:37 . 
drwxr-xr-x 7 andrwj staff 238 11 26 18:06 .. 
-r--r--r-- 1 andrwj staff 29 11 26 17:37 8238248ad38d598515adb865b818ec9381f967 
과정5 /11 - ‘commit’ 단계에서 파일이 저장되는 것이 아니라, 
‘add’ 단계에서 이미 저장되어 있는 것이 
subversion 과 다른점!
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
$ cat .git/index 
??~?){???e?쓁?gREADME'mh?$ 
과정6 /11 - .git/index 파일은 TEXT 형식의 파일이 아 
님.
! 
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
$ git commit -m ‘first commit’ 
[master (root-commit) b3d38eb] first commit 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 README 
!R 
C1: b3d38eb 
EADME 
! 
과정7 /11 - 이미 README 저장되어 있으므로 
‘commit’ 단계에선 스테이징 영역의 리스트를 참조 
하여 commit object를 만든다
! 
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
$ git commit -m ‘first commit’ 
[master (root-commit) b3d38eb] first commit 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 README 
!R 
C1: b3d38eb 
EADME 
! 
과정8 /11 - 스테이징 (.git/index) 영역의 정보도 
그대로 남아있다!!
! 
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
!R 
EADME 
! 
$ cat .git/HEAD 
ref: refs/heads/master 
! 
$ cat .git/refs/heads/master 
b3d38eb6591fc4737509a00471e9a64ba4f79c5c 
C1: b3d38eb 
과정9 /11 - 이제 ‘master’ 브랜치는 새로운 커밋을 가리킨다
! 
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
!R 
C1: b3d38eb 
EADME 
! 
$ git cat-file -p b3d38eb6591fc4737509a00471e9a64ba4f79c5c 
tree b529edd1315d7d85716378eb7829ba0772542851 
author AJ andrwj@gmail.com 1322298365 +0900 
committer AJ andrwj@gmail.com 1322298365 +0900 
과정10 /11 - 커밋객체(파일)의 내용을 출력해보면 
tree 객체와 커밋한 사용자와 날짜 및 
커밋 메세지를 볼 수 있다.
! 
! 
Repo 
!R 
Working 
EADME 
!R 
Staging 
EADME 
!R 
C1: b3d38eb 
EADME 
! 
$ file . -name ‘*d38eb6591fc4737509a00471e9a64ba4f79c5c’ 
./.git/objects/b3/d38eb6591fc4737509a00471e9a64ba4f79c5c 
과정11 /11 - 커밋객체(파일) 역시 .git/objects/ 폴더 아래에 있다.
HEAD 
master 
C1 
b3d38eb 
첫번째 커밋후의 상태
when you ‘commit’ 
- you’re making 
a snapshot
두번째 커밋
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
!R 
Staging 
EADME 
$ mkdir doc 
$ echo ‘index file’  ./doc/index.html 
!R 
C1: b3d38eb 
EADME 
! 
과정1 /5 - 폴더(doc/)와 파일(index.html)을 새로 만든다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
!R 
Staging 
EADME 
$ mkdir doc 
$ echo ‘index file’  ./doc/index.html 
!R 
C1: b3d38eb 
EADME 
! 
과정2 /5 - 스테이징 영역의 데이터는 그대로 남아있다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
$ git add doc 
!R 
C1: b3d38eb 
EADME 
! 
과정3 /5 - 스테이징(.git/index) 영역에 파일 정보를 추가한다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
!R 
C1: b3d38eb 
EADME 
! 
$ find .git/object/ 
./.git/objects/4e/8238248ad38d598515adb865b818ec9381f967 
./.git/objects/b3/d38eb6591fc4737509a00471e9a64ba4f79c5c 
./.git/objects/b5/29edd1315d7d85716378eb7829ba0772542851 
./.git/objects/c3/d940db4a30ccfdaa29ffa322dc080b8a193734 
과정4 /5 - 파일은 .git/objects/ 아래에 blob/tree 객체로 만들어진다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
!R 
C2: 250a18f 
EADME 
! 
$ git commit -m ‘second commit’ 
[master 250a18f] second commit 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 doc/index.html 
! 
C1: b3d38eb 
!R 
EADME 
doc/ 
doc/index.html 
과정5 /5 - 새로운 커밋(리스트)파일이 만들어지고 
HEAD는 이 커밋(C2)을 가리킨다
두번째 커밋후의 상태 
C1 
b3d38eb 
HEAD 
master 
C2 
250a18f
세번째 커밋
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
$ echo ‘another index file’ index.html 
$ ls 
README 
doc/ 
index.html 
! 
! 
!R 
C1: b3d38eb 
C2: 250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
과정1 /4 - 작업폴더 최상위에 
파일(index.html)을 새로 만든다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
$ echo ‘another index file’ index.html 
$ ls 
README 
doc/ 
index.html 
! 
! 
!R 
C1: b3d38eb 
C2: 250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
과정2 /4 - 스테이징 영역의 데이터는 직전 
의 커밋 정보와 같다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
$ git add index.html 
! 
!R 
C1: b3d38eb 
C2: 250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
과정3 /4 - 스테이징(.git/index) 영역에 파일 정보를 추가한다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
$ git commit -m ‘third commit’ 
[master cfc19ca] third commit 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 index.html 
!R 
C1: b3d38eb 
C2: 250a18f 
EADME 
! 
!R 
!R 
C3:cfc19ca 
EADME 
doc/ 
doc/index.html 
EADME 
doc/ 
doc/index.html 
index.html 
과정4 /4 - 새로운 커밋(리스트)파일이 만들어지고 
HEAD는 이 커밋(C3)을 가리킨다
C1 
b3d38eb 
세번째 커밋후의 상태 
C2 
HEAD 
master 
250a18f 
C3 
cfc19ca
첫번째 리셋: --soft 옵션
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
EADME 
doc/ 
doc/index.html 
index.html 
$ git reflog 
cfc19ca HEAD@{0}: commit: third commit 
250a18f HEAD@{1}: commit: second commit 
b3d38eb HEAD@{2}: commit (initial): first commit 
! 
과정1 /7 - 지금까지 모두 세개의 커밋을 하였다
Working 
과정 
! 
! 
Repo 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
EADME 
doc/ 
doc/index.html 
index.html 
$ git reflog 
cfc19ca HEAD@{0}: commit: third commit 
250a18f HEAD@{1}: commit: second commit 
b3d38eb HEAD@{2}: commit (initial): first commit 
! 
과과정정2 /7 - 세 영역모두 리스트 정보가 일치한다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
$ git reset --soft HEAD~ 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
EADME 
doc/ 
doc/index.html 
index.html 
과정3 /7 - HEAD를 두번째 커밋(C2)로 옮긴다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
C4:250a18f 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reset --soft HEAD~ 
과정3 /7 - HEAD를 옮겼다는 정보를 담은 
새로운 커밋인 C4가 생성된다. 
하지만, 두번째 커밋의 정보와 같다!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
C4:250a18f 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reflog 
250a18f HEAD@{0}: HEAD~: updating HEAD 
cfc19ca HEAD@{1}: commit: third commit 
250a18f HEAD@{2}: commit: second commit 
b3d38eb HEAD@{3}: commit (initial): first commit 
과정5 /7 - reflog를 통해 확인!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reset --soft HEAD~ 
과정6 /7 - 두번째 커밋의 정보에는 
./index.html 파일에 대한 정보가 없다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
$ git status 
# On branch master 
# Changes to be committed: 
# (use git reset HEAD file... to unstage) 
# 
# new file: index.html 
# 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
과정7 /7 - 따라서 스테이징 영역(.git/index)의 리스트와 
HEAD의 리스트 정보가 다르므로, 커밋 대상으로 인식한다!
첫번째 리셋후의 상태 (--soft 옵션사용) 
C1 
b3d38eb 
HEAD 
C2 
250a18f 
C3 
cfc19ca 
master
git reset --soft 
 Local Repository의 HEAD 정보를 
지정된 위치로 옮긴다. 
 Staging 영역및 Working 영역은 
영향을 받지 않는다.
두번째 리셋: --mixed 옵션
첫번째 리셋과 비교를 위해 
세번째 커밋 (C3)에서 다시 시작한다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
$ git reset --mixed HEAD~ 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
EADME 
doc/ 
doc/index.html 
index.html 
과정1 /9 - HEAD를 두번째 커밋(C2)로 옮긴다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
C4:250a18f 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reset --mixed HEAD~ 
과정2 /9 - HEAD를 옮겼다는 정보를 담은 
새로운 커밋인 C4가 생성된다. 
역시, 두번째 커밋의 정보와 같다!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
EADME 
! 
!R 
C4:250a18f 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reflog 
250a18f HEAD@{0}: HEAD~: updating HEAD 
cfc19ca HEAD@{1}: commit: third commit 
250a18f HEAD@{2}: commit: second commit 
b3d38eb HEAD@{3}: commit (initial): first commit 
과정3 /9 - reflog를 통해 확인!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reset --mixed HEAD~ 
과정4 /9 - Local Repository의 HEAD를 C2로 
옮기면 ./index.html 파일에 대한 정보가 없다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git reset --mixed HEAD~ 
과정5 /9 - --mixed 옵션은 Staging 영역의 정보를 
Local Repository의 HEAD내용으로 갱신한다! 
! 
Staging 정보는 HEAD와 같아진다!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
$ git status 
# On branch master 
# Untracked files: 
# (use git add file... to include in what will be committed) 
# 
# index.html 
nothing added to commit but untracked files present (use git add to track) 
과정6 /9 - 따라서 Working 영역과 스테이징 영역 
(.git/index)의 리스트정보가 다르므로, 추가 대상으로 인식한다!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
$ git add index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
index.html 
과정7 /9 - 만약 여기서 git add 명령을 통해 Staging 영역에 정 
보를 추가하고 ..
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
C5:0815eb5 
EADME 
doc/ 
doc/index.html 
index.html 
EADME 
doc/ 
doc/index.html 
index.html 
$ git commit -m ‘4th commit’ 
[master 0815eb5] 4th commit 
1 files changed, 1 insertions(+), 0 deletions(-) 
create mode 100644 index.html 
과정8 /9 - ‘commit’을 하면 
새로운 커밋객체(C5)가 만들어진다! 
!R 
EADME 
doc/ 
doc/index.html 
! 
index.html
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
! 
! 
Repo 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4:250a18f 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
C5:0815eb5 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
EADME 
doc/ 
doc/index.html 
EADME 
doc/ 
doc/index.html 
index.html 
$ git reflog 
0815eb5 HEAD@{0}: commit: 4th commit 
250a18f HEAD@{1}: HEAD~: updating HEAD 
cfc19ca HEAD@{2}: commit: third commit 
250a18f HEAD@{3}: commit: second commit 
b3d38eb HEAD@{4}: commit (initial): first commit 
과정9 /9 - ‘reflog’ 로 기록을 살펴본다
두번째 리셋후의 상태 (--mixed 옵션사용) 
C1 
b3d38eb 
C2 
HEAD 
250a18f 
C3 
cfc19ca 
master 
C4 
250a18f 
C5 
0815eb5
git reset --mixed 
 Local Repository의 HEAD 정보를 
지정된 위치로 옮긴다. 
 Staging 영역에 HEAD 정보를 복사한다. 
 Working 영역은 영향을 받지 않는다
세번째 리셋: --hard 옵션
다른 리셋과 비교를 위해 
세번째 커밋 (C3)에서 다시 시작한다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C3:cfc19ca 
EADME 
! 
EADME 
doc/ 
doc/index.html 
$ git reset --hard b3d38eb 
HEAD is now at b3d38eb first commit 
C2: 250a18f 
!R 
EADME 
doc/ 
doc/index.html 
index.html 
과정1 /5 - HEAD를 첫번째 커밋(C1)로 옮긴다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4: b3d38eb 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
EADME 
doc/ 
! 
doc/index.html 
index.html 
$ git reset --hard b3d38eb 
HEAD is now at b3d38eb first commit 
과정1 /5 - Local Repository의 HEAD를 
첫번째 커밋(C1)로 옮긴다
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4: b3d38eb 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
EADME 
doc/ 
! 
doc/index.html 
index.html 
$ git reset --hard b3d38eb 
HEAD is now at b3d38eb first commit 
과정1 /5 - LocalStaging 영역의 정보가 HEAD와 같아진다! 
따라서, doc/, doc/index.html 정보는 없어진다.
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4: b3d38eb 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
EADME 
doc/ 
! 
doc/index.html 
index.html 
$ git reset --hard b3d38eb 
HEAD is now at b3d38eb first commit 
과정1 /5 - Staging 영역의 정보에 따라 Working Folder의 
파일을 삭제하거나 생성한다. 
따라서, doc/, doc/index.html 파일은 삭제된다!
! 
! 
Repo 
!R 
Working 
EADME 
doc/ 
doc/index.html 
index.html 
!R 
Staging 
EADME 
doc/ 
doc/index.html 
index.html 
$ ls 
README 
!R 
C1: b3d38eb 
!R 
C2: 250a18f 
C3:cfc19ca 
C4: b3d38eb 
EADME 
! 
!R 
EADME 
doc/ 
doc/index.html 
!R 
EADME 
EADME 
doc/ 
! 
doc/index.html 
index.html 
과정1 /5 - Working Folder의 내용을 확인해보면 
README 파일밖에 없다!
세번째 리셋후의 상태 (--hard 옵션사용) 
C1 
b3d38eb 
C2 
HEAD 
250a18f 
C3 
cfc19ca 
master 
C4 
b3d38eb
git reset --hard 
 Local Repository의 HEAD 정보를 
지정된 위치로 옮긴다. 
 Staging 영역에 HEAD 정보를 복사한다. 
 Staging 영역의 정보에 따라 
Working folder 영역의 파일을 삭제하거나 
새로 만든다.

More Related Content

2011년 KTH H3 컨퍼런스 Track B, 세션4 "Advanced Git" by A.J

  • 5. 개발자를 위한 고급 Git 활용전략 - TRACK B, Session 4 ! 세계의 개발자가 '코드'로 대화하는 환경, 분산버전관리시스템인 Git 을 멋지게 사용하는 방법을 공유합니다. 실제업무와 개인적 개발에서도 거침없이 Git 을 사용하는 노하우를 알아봅니다.
  • 7. 세션 요점 #1 Git 명령의 대부분은 File 보다는 Commit 객체를 다룬다.
  • 8. 세션 요점 #2 Git 명령을 보다 잘 이해하기 위해 HEAD 와 브랜치는 포인터임을 기억하자.
  • 9. 미리 알아둘 것 #1 Javascript 로 표현되는 Pointer
  • 10. var HEAD = ‘master’; ! console.log( HEAD ); ! ‘master’ HEAD 는 단순 변수
  • 11. var refs = { heads: { master: ‘master’, develop: ‘develop’ } }; ! console.log( refs. heads. master ); ! ‘master’ refs.heads.master 역시 단순 변수
  • 12. var refs = { heads: { master: ‘master’, develop: ‘develop’ } }; ! HEAD = refs. heads. master; ! console.log( HEAD ); ! ‘master’ HEAD
  • 13. “master” refs.heads.master refs. heads. master HEAD 참조
  • 14. 미리 알아둘 것 #2 Javascript 로 알아보는 HEAD 사용예
  • 15. var C1 = { prev: null, value: “ some-value “ }; ! ! ! C1 객체 C1을 나타낸다
  • 16. var C1 = { prev: null, value: “ some-value “ }; ! var HEAD = C1; HEAD C1 HEAD는 C1을 가리킨다 (pointing)
  • 17. var C2 = { ... }; ! HEAD C1 같은 종류의 객체 C2를 생성한다. C2
  • 18. var C2 = { ... }; ! C2.prev = HEAD; ! HEAD C1 HEAD를 이용하여 이전 객체와 연결함을 주의 C2 깊게 보자
  • 19. var C2 = { ... }; ! C2.prev = HEAD; ! HEAD = C2; C1 HEAD C2 다시 HEAD를 새로운 C2로 가리킨다 (pointing)
  • 20. var C3 = { ... }; ! C1 같은 종류의 객체 C3를 생성한다. HEAD C2 C3
  • 21. var C3 = { ... }; ! C3.prev = HEAD; ! ! C1 역시 HEAD를 이용해 연결한다. 각 객체는 이전 객체를 알수있다. HEAD C2 C3
  • 22. var C3 = { ... }; ! C3.prev = HEAD; ! HEAD = C3; ! C1 다시 HEAD를 새로운 C3로 가리킨다 (pointing) HEAD C2 C3
  • 23. HEAD를 이동시킴으로써 임의의 연결을 자유 롭게 만들어 갈 수 있음을 보여주는 예
  • 24. HEAD = C2; C1 HEAD HEAD는 C2 객체를 가리킨다. C2 C3
  • 25. HEAD = C2; var C4 = { ... }; ! C1 HEAD C2 C3 C4 새로운 객체 C4를 만든다
  • 26. HEAD = C2; var C4 = { ... }; C4.prev = HEAD; C1 HEAD HEAD가 가리키는 객체와 C2 C3 C4 연결 할 수 있다. (브랜치가 꺾어지는 모습)
  • 27. HEAD = C4; ! C1 객체 C4에 HEAD를 맞춘다 HEAD C2 C3 C4
  • 28. var C5 = { ... }; C5.prev = HEAD; HEAD = C5; ! 객체 C5역시 같은 방법으로 다른 객체와 연결할 수 있다 C1 C2 C3 HEAD C4 C5
  • 29. HEAD를 이용하여 각 객체는 연결을 이어갈 수 있다.
  • 30. C1 C2 C3 C4 C5 .prev .prev .prev .prev
  • 31. 또한, HEAD가 어디를 가리키냐에 따라 연결 과정이 달라 보일 수 있다. ! (브랜치마다 커밋 로그가 달라보이는 이유)
  • 32. C1 C2 C3 HEAD C4 C5 .prev .prev .prev
  • 33. HEAD C1 C2 C3 .prev .prev C4 C5
  • 34. Git의 Branch 작동법도 비슷하게 설명될 수 있다
  • 35. var C1 = { prev: null, value: “ some-value “ }; ! ! C1 C1을 생성하고...
  • 36. var C1 = { prev: null, value: “ some-value “ }; var master = C1; master master 변수에 C1을 설정한다음 ... C1
  • 37. var C1 = { prev: null, value: “ some-value “ }; var master = C1; var HEAD = master; ! HEAD master C1 HEAD는 master를 가리킨다
  • 38. var C2 = { ... }; ! ! HEAD master C1 C2 C2을 생성하고...
  • 39. var C2 = { ... }; ! C2.prev = HEAD; ! HEAD master 역시 HEAD를 이용해 연결한다 C1 C2
  • 40. var C2 = { ... }; ! C2.prev = HEAD; ! master = C2; ! HEAD master C1 C2 master를 이동시키면 HEAD도 따라간다!
  • 41. var C3 = { ... }; ! C3.prev = HEAD; ! master = C3; 같은 방법으로 객체 C3를 만들어 이전 객체와 연결시켜줄 수 있다 HEAD master C1 C2 C3
  • 42. 이번엔 브랜치 변수를 나타내는 develop을 만들 어 master와 다른 객체를 가리킨다 var develop = C2; HEAD master develop C1 C2 C3
  • 43. var develop = C2; var HEAD = develop; master의 위치는 그대로 두고, HEAD를 master로 이동시켜 다음번 객체를 연결시킬 준비를 한다. master HEAD develop C1 C2 C3
  • 44. var C4 = { .. }; ! master HEAD develop C1 C2 C3 C4 C4를 만들고..
  • 45. var C4 = { .. }; C4.prev = HEAD; master HEAD develop C1 C2 C3 C4 HEAD를 이용해 연결을 이 어나갈 수 있다
  • 46. var C5 = { .. }; C5.prev = HEAD; develop = C5; master C1 C2 C3 HEAD develop C4 C5 계속해서 다른 연결도 이어갈 수 있다.
  • 47. 이때 HEAD를 변경함으로써 두개의 ‘이름’ 가진 연결을 만들 수 있다. ! ( Git Branch 역시 같은 방식이다)
  • 48. HEAD = master; HEAD master C1 C2 C3 develop C4 C5 master를 가리킬때는 C3 - C2 - C1 순으로 연결 (history)
  • 49. HEAD = develop; ! develop를 가리킬때는 HEAD master C1 C2 C3 develop C4 C5 C5 - C4 - C2 - C1 순으로 연결 (history)
  • 50. Git의 HEAD는 변수처럼 동작하며 특정 브랜치를 가리킨다. ! Git의 Branch는 변수처럼 동작하며 특정 커밋을 가리킨다.
  • 51. 미리 알아둘 것 #2 Git 저장소 해부
  • 52. . ./.git ./.git/branches ./.git/config ./.git/description ./.git/HEAD ./.git/hooks ./.git/hooks/applypatch-msg.sample ./.git/hooks/commit-msg.sample ./.git/hooks/post-commit.sample ./.git/hooks/post-receive.sample ./.git/hooks/post-update.sample ./.git/hooks/pre-applypatch.sample ./.git/hooks/pre-commit.sample ./.git/hooks/pre-rebase.sample ./.git/hooks/prepare-commit-msg.sample ./.git/hooks/update.sample ./.git/info ./.git/info/exclude ./.git/objects ./.git/objects/info ./.git/objects/pack ./.git/refs ./.git/refs/heads git init 명령후 생성되는 파일들
  • 53. . ./.git ./.git/branches ./.git/config ./.git/description ./.git/HEAD ./.git/hooks ./.git/hooks/applypatch-msg.sample ./.git/hooks/commit-msg.sample ./.git/hooks/post-commit.sample ./.git/hooks/post-receive.sample ./.git/hooks/post-update.sample ./.git/hooks/pre-applypatch.sample ./.git/hooks/pre-commit.sample ./.git/hooks/pre-rebase.sample ./.git/hooks/prepare-commit-msg.sample ./.git/hooks/update.sample ./.git/info ./.git/info/exclude ./.git/objects ./.git/objects/info ./.git/objects/pack ./.git/refs ./.git/refs/heads ./.git/refs/tags 원활한 설명을 위해 무시..
  • 54. . ./.git ./.git/branches ./.git/config ./.git/description ./.git/HEAD ./.git/info ./.git/info/exclude ./.git/objects ./.git/objects/info ./.git/objects/pack ./.git/refs ./.git/refs/heads ./.git/refs/tags 앞서 Javascript 변수로 설명한 것들이 파일로 존재한다!
  • 55. git init 명령직후에는 master 파일 내 용에 아무것도 없다 $ cat ./git/HEAD ref: refs/heads/master ! $ cat .git/refs/heads/master cat: .git/refs/heads/master: No such file or directory ! $ git branch ! $ ! 브랜치 역시 없는 상태
  • 56. 간단히 README 파일을 생성한다 $ echo ‘just created’ README ! $ ls -la total 0 drwxr-xr-x 4 andrwj staff 136 11 25 00:18 . drwxr-xr-x 3 andrwj staff 102 11 25 00:14 .. drwxr-xr-x 14 andrwj staff 476 11 26 17:21 .git -rw-r--r-- 1 andrwj staff 0 11 25 00:16 README ! $ cat README just created ! $ 현재 폴더에는 READ와 .git 폴더 뿐이다
  • 57. . ./.git ./.git/branches ./.git/COMMIT_EDITMSG ./.git/config ./.git/description git add README 직후, ./.git/HEAD 긴이름의 파일이 생긴다 ./.git/index ./.git/objects ./.git/objects/4e ./.git/objects/4e/8238248ad38d598515adb865b818ec9381f967 ./.git/objects/info ./.git/objects/pack ./.git/objects/info ./.git/objects/pack ./.git/refs ./.git/refs/heads ./.git/refs/heads/master ./.git/refs/tags ./README
  • 58. $ cat .git/HEAD ! ref: refs/heads/master !! 그러나 여전히 master 파일의 내용은 비어있다 $ cat .git/refs/heads/master cat: .git/refs/heads/master: No such file or directory !!! $ cat .git/object/4e/8238248ad38d598515adb865b818ec9381f967 ! x??Q B!??????? ??-?ied?]?? ?;03K?? @???9Cd?9%t?I???Ή?(J+B?%e4?=n??? ??L?s?^k(?????!???zkͤs3?߂????????/? 생성된 긴 이름의 파일을 출력해보니 TEXT 포맷의 파일이 아님을 알수있다
  • 59. git blob format 헤더 정보를 포함하여 zlib로 압축되어 저장된다 헤더 형식: “blob 원본파일크기 null”
  • 60. blob format $ cd .git/object/4e/ $ python fd = open(“8238248ad38d598515adb865b818ec9381f967”) line = fd.read() import zlib zlib.decompress(line) ‘blob 13x00just createdn’ 객체 종류는 ‘blob’ 원본 크기는 13 바이트 null 바이트 원본 내용
  • 61. git hash-object README $ git hash-object README 4e8238248ad38d598515adb865b818ec9381f967 ! $ git cat-file -p 4e8238 just created 파일이름으로 해쉬명을 알 수 있다 파일이름 몇글자로 내용을 출력할 수 있다
  • 62. why hash ? 내용에 따라 중복된 이름이 나올 가능성이 극히 드물다 육안으로 분별하기 힘든 차이도 쉽게 검출 가능하다 번호로된 파일 이름보다 관리 하기 쉽다(?) 파일명이 변경되어도 내용이 같으면 동일한 것으로 인식한다.
  • 63. README ! ‘just created’ README ! ‘just created ‘ $ cat README ! ‘just created’ !! 끝부분 공백도 명확히 알 수 있다 $ git hash-object README ! ec53c2432a2e9c2fadaa9d5982bd3cf31f9b38d2 ! $ cat README ! ‘just created ’ !! $ git hash-object README ! a6014d70c71eab934f3ac1248f8bad19ad3d451c !
  • 64. README.1 ! ‘just created’ README.2 ! ‘just created‘ $ cat README.1 ! ‘just created’ !! 내용이 같으면 파일이름이 달라도 같은 값을 출력한다 $ git hash-object README.1 ! ec53c2432a2e9c2fadaa9d5982bd3cf31f9b38d2 ! $ cat README.2 ! ‘just created’ !! $ git hash-object README.2 ! ec53c2432a2e9c2fadaa9d5982bd3cf31f9b38d2 !
  • 67. four object Blob Commit Tag Tree Git에는 4가지 객체가 있다
  • 68. var blob = “헤더+내용이 zlib 로 압축된 문자열”; ! var Tree = [ blob, Tree, ]; ! var Commit = { Javascript로 표현 ... parent: { }, tree: [ ], author: “string”, date: “2011/11/30” }; ! var Tag = “커밋을 가리키는 문자열”
  • 69. blob object Blob header + content ! zlib로 압축되어 있다 ! .git/objects/ 아래 있다
  • 70. tree object Tree blob + 다른 tree 객체 ! ‘폴더’와 같은 개념 ! .git/objects/ 아래 있다
  • 71. commit object Commit blobs + trees + author + date + message ! .git/objects/ 아래 있다
  • 72. tag object Tag pointer to commit object ! .git/refs/tags/ 아래있다
  • 73. B BB T TBT T TBT T prev author date message BTT TBT Tag BBB prev author date message T TBT T TBT T TBT BBB prev author date message T TBT T TBT T TBT Tag BB BT HEAD master 예를 들자면...
  • 74. 중간 정리 파일은 blob 포맷으로 저장된다. 폴더는 tree 객체로, 파일은 blob 객체로 표현된다. commit, tag 역시 객체로 취급되어 파일형태로 저장된다. 모든 파일은 SHA 방식의 해쉬로 표현된다. Git의 branch와 commit 은 pointer 이다.
  • 75. three spaces - Working area ! - Staging or Index ! - Local Repository
  • 76. but, these are just concept!!
  • 77. Staging Repo ! - 영구저장 영역 - .git/object/* ! - 작업 폴더 영역 - ./ ! Working 3개의 공간 ! - 스테이징 영역 - .git/index
  • 79. Repo !R Working Staging EADME $ cat ‘just created’ README 과정1 /11 - 처음으로 커밋할 파일을 생성
  • 80. Repo !R Working Staging EADME $ cat README just created 과정2 /11 - 파일 내용 보기
  • 81. ! Repo !R Working EADME !R Staging EADME $ git add README 스과테정이3 징/1 영1역 -에 스 파테일이 징정 보영 역기에록 파일 정보 기록 ‘README’ 파일은 blob 형식으로 변환되어 .git/object/ 아래에 저장됨
  • 82. ! Repo !R Working EADME !R Staging EADME $ git ls-files -s 100644 4e8238248ad38d598515adb865b818ec9381f967 0 README ! 과정4 /11 - 스테이징 영역의 파일 정보 열람 (.git/index 파일 내용을 참조)
  • 83. ! Repo !R Working EADME !R Staging EADME $ ls -la .git/object/4e drwxr-xr-x 3 andrwj staff 102 11 26 17:37 . drwxr-xr-x 7 andrwj staff 238 11 26 18:06 .. -r--r--r-- 1 andrwj staff 29 11 26 17:37 8238248ad38d598515adb865b818ec9381f967 과정5 /11 - ‘commit’ 단계에서 파일이 저장되는 것이 아니라, ‘add’ 단계에서 이미 저장되어 있는 것이 subversion 과 다른점!
  • 84. ! Repo !R Working EADME !R Staging EADME $ cat .git/index ??~?){???e?쓁?gREADME'mh?$ 과정6 /11 - .git/index 파일은 TEXT 형식의 파일이 아 님.
  • 85. ! ! Repo !R Working EADME !R Staging EADME $ git commit -m ‘first commit’ [master (root-commit) b3d38eb] first commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 README !R C1: b3d38eb EADME ! 과정7 /11 - 이미 README 저장되어 있으므로 ‘commit’ 단계에선 스테이징 영역의 리스트를 참조 하여 commit object를 만든다
  • 86. ! ! Repo !R Working EADME !R Staging EADME $ git commit -m ‘first commit’ [master (root-commit) b3d38eb] first commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 README !R C1: b3d38eb EADME ! 과정8 /11 - 스테이징 (.git/index) 영역의 정보도 그대로 남아있다!!
  • 87. ! ! Repo !R Working EADME !R Staging EADME !R EADME ! $ cat .git/HEAD ref: refs/heads/master ! $ cat .git/refs/heads/master b3d38eb6591fc4737509a00471e9a64ba4f79c5c C1: b3d38eb 과정9 /11 - 이제 ‘master’ 브랜치는 새로운 커밋을 가리킨다
  • 88. ! ! Repo !R Working EADME !R Staging EADME !R C1: b3d38eb EADME ! $ git cat-file -p b3d38eb6591fc4737509a00471e9a64ba4f79c5c tree b529edd1315d7d85716378eb7829ba0772542851 author AJ andrwj@gmail.com 1322298365 +0900 committer AJ andrwj@gmail.com 1322298365 +0900 과정10 /11 - 커밋객체(파일)의 내용을 출력해보면 tree 객체와 커밋한 사용자와 날짜 및 커밋 메세지를 볼 수 있다.
  • 89. ! ! Repo !R Working EADME !R Staging EADME !R C1: b3d38eb EADME ! $ file . -name ‘*d38eb6591fc4737509a00471e9a64ba4f79c5c’ ./.git/objects/b3/d38eb6591fc4737509a00471e9a64ba4f79c5c 과정11 /11 - 커밋객체(파일) 역시 .git/objects/ 폴더 아래에 있다.
  • 90. HEAD master C1 b3d38eb 첫번째 커밋후의 상태
  • 91. when you ‘commit’ - you’re making a snapshot
  • 93. ! ! Repo !R Working EADME doc/ doc/index.html !R Staging EADME $ mkdir doc $ echo ‘index file’ ./doc/index.html !R C1: b3d38eb EADME ! 과정1 /5 - 폴더(doc/)와 파일(index.html)을 새로 만든다
  • 94. ! ! Repo !R Working EADME doc/ doc/index.html !R Staging EADME $ mkdir doc $ echo ‘index file’ ./doc/index.html !R C1: b3d38eb EADME ! 과정2 /5 - 스테이징 영역의 데이터는 그대로 남아있다
  • 95. ! ! Repo !R Working EADME doc/ doc/index.html !R Staging EADME doc/ doc/index.html $ git add doc !R C1: b3d38eb EADME ! 과정3 /5 - 스테이징(.git/index) 영역에 파일 정보를 추가한다
  • 96. ! ! Repo !R Working EADME doc/ doc/index.html !R Staging EADME doc/ doc/index.html !R C1: b3d38eb EADME ! $ find .git/object/ ./.git/objects/4e/8238248ad38d598515adb865b818ec9381f967 ./.git/objects/b3/d38eb6591fc4737509a00471e9a64ba4f79c5c ./.git/objects/b5/29edd1315d7d85716378eb7829ba0772542851 ./.git/objects/c3/d940db4a30ccfdaa29ffa322dc080b8a193734 과정4 /5 - 파일은 .git/objects/ 아래에 blob/tree 객체로 만들어진다
  • 97. ! ! Repo !R Working EADME doc/ doc/index.html !R Staging EADME doc/ doc/index.html !R C2: 250a18f EADME ! $ git commit -m ‘second commit’ [master 250a18f] second commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 doc/index.html ! C1: b3d38eb !R EADME doc/ doc/index.html 과정5 /5 - 새로운 커밋(리스트)파일이 만들어지고 HEAD는 이 커밋(C2)을 가리킨다
  • 98. 두번째 커밋후의 상태 C1 b3d38eb HEAD master C2 250a18f
  • 100. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html $ echo ‘another index file’ index.html $ ls README doc/ index.html ! ! !R C1: b3d38eb C2: 250a18f EADME ! !R EADME doc/ doc/index.html 과정1 /4 - 작업폴더 최상위에 파일(index.html)을 새로 만든다
  • 101. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html $ echo ‘another index file’ index.html $ ls README doc/ index.html ! ! !R C1: b3d38eb C2: 250a18f EADME ! !R EADME doc/ doc/index.html 과정2 /4 - 스테이징 영역의 데이터는 직전 의 커밋 정보와 같다
  • 102. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html $ git add index.html ! !R C1: b3d38eb C2: 250a18f EADME ! !R EADME doc/ doc/index.html 과정3 /4 - 스테이징(.git/index) 영역에 파일 정보를 추가한다
  • 103. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html $ git commit -m ‘third commit’ [master cfc19ca] third commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 index.html !R C1: b3d38eb C2: 250a18f EADME ! !R !R C3:cfc19ca EADME doc/ doc/index.html EADME doc/ doc/index.html index.html 과정4 /4 - 새로운 커밋(리스트)파일이 만들어지고 HEAD는 이 커밋(C3)을 가리킨다
  • 104. C1 b3d38eb 세번째 커밋후의 상태 C2 HEAD master 250a18f C3 cfc19ca
  • 106. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R EADME doc/ doc/index.html EADME doc/ doc/index.html index.html $ git reflog cfc19ca HEAD@{0}: commit: third commit 250a18f HEAD@{1}: commit: second commit b3d38eb HEAD@{2}: commit (initial): first commit ! 과정1 /7 - 지금까지 모두 세개의 커밋을 하였다
  • 107. Working 과정 ! ! Repo !R EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R EADME doc/ doc/index.html EADME doc/ doc/index.html index.html $ git reflog cfc19ca HEAD@{0}: commit: third commit 250a18f HEAD@{1}: commit: second commit b3d38eb HEAD@{2}: commit (initial): first commit ! 과과정정2 /7 - 세 영역모두 리스트 정보가 일치한다
  • 108. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html $ git reset --soft HEAD~ !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R EADME doc/ doc/index.html EADME doc/ doc/index.html index.html 과정3 /7 - HEAD를 두번째 커밋(C2)로 옮긴다
  • 109. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R C4:250a18f EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reset --soft HEAD~ 과정3 /7 - HEAD를 옮겼다는 정보를 담은 새로운 커밋인 C4가 생성된다. 하지만, 두번째 커밋의 정보와 같다!
  • 110. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R C4:250a18f EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reflog 250a18f HEAD@{0}: HEAD~: updating HEAD cfc19ca HEAD@{1}: commit: third commit 250a18f HEAD@{2}: commit: second commit b3d38eb HEAD@{3}: commit (initial): first commit 과정5 /7 - reflog를 통해 확인!
  • 111. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reset --soft HEAD~ 과정6 /7 - 두번째 커밋의 정보에는 ./index.html 파일에 대한 정보가 없다
  • 112. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html $ git status # On branch master # Changes to be committed: # (use git reset HEAD file... to unstage) # # new file: index.html # !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html 과정7 /7 - 따라서 스테이징 영역(.git/index)의 리스트와 HEAD의 리스트 정보가 다르므로, 커밋 대상으로 인식한다!
  • 113. 첫번째 리셋후의 상태 (--soft 옵션사용) C1 b3d38eb HEAD C2 250a18f C3 cfc19ca master
  • 114. git reset --soft Local Repository의 HEAD 정보를 지정된 위치로 옮긴다. Staging 영역및 Working 영역은 영향을 받지 않는다.
  • 116. 첫번째 리셋과 비교를 위해 세번째 커밋 (C3)에서 다시 시작한다
  • 117. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html $ git reset --mixed HEAD~ !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R EADME doc/ doc/index.html EADME doc/ doc/index.html index.html 과정1 /9 - HEAD를 두번째 커밋(C2)로 옮긴다
  • 118. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R C4:250a18f EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reset --mixed HEAD~ 과정2 /9 - HEAD를 옮겼다는 정보를 담은 새로운 커밋인 C4가 생성된다. 역시, 두번째 커밋의 정보와 같다!
  • 119. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca EADME ! !R C4:250a18f EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reflog 250a18f HEAD@{0}: HEAD~: updating HEAD cfc19ca HEAD@{1}: commit: third commit 250a18f HEAD@{2}: commit: second commit b3d38eb HEAD@{3}: commit (initial): first commit 과정3 /9 - reflog를 통해 확인!
  • 120. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reset --mixed HEAD~ 과정4 /9 - Local Repository의 HEAD를 C2로 옮기면 ./index.html 파일에 대한 정보가 없다
  • 121. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git reset --mixed HEAD~ 과정5 /9 - --mixed 옵션은 Staging 영역의 정보를 Local Repository의 HEAD내용으로 갱신한다! ! Staging 정보는 HEAD와 같아진다!
  • 122. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html $ git status # On branch master # Untracked files: # (use git add file... to include in what will be committed) # # index.html nothing added to commit but untracked files present (use git add to track) 과정6 /9 - 따라서 Working 영역과 스테이징 영역 (.git/index)의 리스트정보가 다르므로, 추가 대상으로 인식한다!
  • 123. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html $ git add index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R EADME doc/ doc/index.html index.html EADME doc/ doc/index.html index.html 과정7 /9 - 만약 여기서 git add 명령을 통해 Staging 영역에 정 보를 추가하고 ..
  • 124. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R C5:0815eb5 EADME doc/ doc/index.html index.html EADME doc/ doc/index.html index.html $ git commit -m ‘4th commit’ [master 0815eb5] 4th commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 index.html 과정8 /9 - ‘commit’을 하면 새로운 커밋객체(C5)가 만들어진다! !R EADME doc/ doc/index.html ! index.html
  • 125. !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html ! ! Repo !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4:250a18f EADME ! !R EADME doc/ doc/index.html !R C5:0815eb5 EADME doc/ doc/index.html index.html !R EADME doc/ doc/index.html EADME doc/ doc/index.html index.html $ git reflog 0815eb5 HEAD@{0}: commit: 4th commit 250a18f HEAD@{1}: HEAD~: updating HEAD cfc19ca HEAD@{2}: commit: third commit 250a18f HEAD@{3}: commit: second commit b3d38eb HEAD@{4}: commit (initial): first commit 과정9 /9 - ‘reflog’ 로 기록을 살펴본다
  • 126. 두번째 리셋후의 상태 (--mixed 옵션사용) C1 b3d38eb C2 HEAD 250a18f C3 cfc19ca master C4 250a18f C5 0815eb5
  • 127. git reset --mixed Local Repository의 HEAD 정보를 지정된 위치로 옮긴다. Staging 영역에 HEAD 정보를 복사한다. Working 영역은 영향을 받지 않는다
  • 129. 다른 리셋과 비교를 위해 세번째 커밋 (C3)에서 다시 시작한다
  • 130. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C3:cfc19ca EADME ! EADME doc/ doc/index.html $ git reset --hard b3d38eb HEAD is now at b3d38eb first commit C2: 250a18f !R EADME doc/ doc/index.html index.html 과정1 /5 - HEAD를 첫번째 커밋(C1)로 옮긴다
  • 131. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4: b3d38eb EADME ! !R EADME doc/ doc/index.html !R EADME EADME doc/ ! doc/index.html index.html $ git reset --hard b3d38eb HEAD is now at b3d38eb first commit 과정1 /5 - Local Repository의 HEAD를 첫번째 커밋(C1)로 옮긴다
  • 132. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4: b3d38eb EADME ! !R EADME doc/ doc/index.html !R EADME EADME doc/ ! doc/index.html index.html $ git reset --hard b3d38eb HEAD is now at b3d38eb first commit 과정1 /5 - LocalStaging 영역의 정보가 HEAD와 같아진다! 따라서, doc/, doc/index.html 정보는 없어진다.
  • 133. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4: b3d38eb EADME ! !R EADME doc/ doc/index.html !R EADME EADME doc/ ! doc/index.html index.html $ git reset --hard b3d38eb HEAD is now at b3d38eb first commit 과정1 /5 - Staging 영역의 정보에 따라 Working Folder의 파일을 삭제하거나 생성한다. 따라서, doc/, doc/index.html 파일은 삭제된다!
  • 134. ! ! Repo !R Working EADME doc/ doc/index.html index.html !R Staging EADME doc/ doc/index.html index.html $ ls README !R C1: b3d38eb !R C2: 250a18f C3:cfc19ca C4: b3d38eb EADME ! !R EADME doc/ doc/index.html !R EADME EADME doc/ ! doc/index.html index.html 과정1 /5 - Working Folder의 내용을 확인해보면 README 파일밖에 없다!
  • 135. 세번째 리셋후의 상태 (--hard 옵션사용) C1 b3d38eb C2 HEAD 250a18f C3 cfc19ca master C4 b3d38eb
  • 136. git reset --hard Local Repository의 HEAD 정보를 지정된 위치로 옮긴다. Staging 영역에 HEAD 정보를 복사한다. Staging 영역의 정보에 따라 Working folder 영역의 파일을 삭제하거나 새로 만든다.
  • 137. conclusion Git 명령은 Commit 객체를 조작한다. HEAD와 브랜치는 Pointer 다.
  • 139. composited by A.J @andrwj 2011.12.22 v1.0