본문 바로가기

책/프로 Git

Git 도구-1 - 리비전 조회하기

리비전 조회하기

리비전 하나 가리키기

짧은 SHA-1

다음 명령은 모두 같은 명령이다.

$ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
$ git show 1c002dd4b536e7479f
$ git show 1c002d

 

git log 명령어에 --abbrev-commit 옵션을 추가하면 기본 7자의 해시를 보여주고 중복되면 더 긴 해시값을 보여준다.

$ git log --abbrev-commit --pretty=oneline
ca82a6d changed the version number
085bb3b removed unnecessary test code
a11bef0 first commit

 

보통은 8 ~ 10자 로도 충분하다. 리눅스 커널도 해시값 12자만 사용한다.

브랜치로 가리키기 

topic1 브랜치가 ca82a6d를 가리킨다명 두 명령의 결과는 같다. 

$ git show ca82a6dff817ec66f44342007202690a93763949
$ git show topic1

 

topic1 의 해시값을 확인해보는 명령어이다. (Plumbling 명령어임)

$ git rev-parse topic1
ca82a6dff817ec66f44342007202690a93763949

RefLog로 가리키기

Git은 자동으로 브랜치와 HEAD가 지난 몇 달 동아네 가리켰었던 커밋을 모두 기록하는데 이 로그를 Reflog라고 부른다.

 

git reflog를 실행하면 다음과 같이 refLog를 볼수 있다.

$ git reflog
734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970 HEAD@{1}: merge phedders/rdocs: Merge made by the 'recursive' strategy.
1c002dd HEAD@{2}: commit: added some blame and merge stuff
1c36188 HEAD@{3}: rebase -i (squash): updating HEAD
95df984 HEAD@{4}: commit: # This is a combination of two commits.
1c36188 HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD

 

Git 은 브랜치가 가리키는 것이 변경될 때마다 그 정보를 임시 영역에 저장한다. 그래서 예전에 뭘 가리켰었는지 확인할 수 있다.

  • refLog에 남아있는 것만 조회할 수 있기 때문에 너무 오래된 커밋은 조회할 수 없다.
  • refLog의 일은 모두 로컬의 일이기 때문에 내 reflog가 동료의 저장소에는 있을 수 없다.
  • 이제 막 Clone 한 저장소에도 아무것도 한게 없어서 reflog가 하나도 없다.  

 

HEAD가 5번 전에 가리켰던 것

$ git show HEAD@{5}

 

어제 날짜의 master 브랜치

$ git show master@{yesterday}

 

git log -g 명령 : git reflog 결과를 git log 명령과 같은 형태로 보여준다.

$ git log -g master
commit 734713bc047d87bf7eac9674765ae793478c50d3
Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
Reflog message: commit: fixed refs handling, added gc auto, updated
Author: Scott Chacon <schacon@gmail.com>
Date:   Fri Jan 2 18:32:33 2009 -0800

    fixed refs handling, added gc auto, updated tests

commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
Reflog message: merge phedders/rdocs: Merge made by recursive.
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 15:08:43 2008 -0800

    Merge commit 'phedders/rdocs'

 

계통 관계로 가리키기 

이름 끝에 ^를 붙이면 Git은 해당 커밋의 부모를 찾는다. 

 

프로젝트 히스토리가 다음과 같을때

$ git log --pretty=format:'%h %s' --graph
* 734713b fixed refs handling, added gc auto, updated tests
*   d921970 Merge commit 'phedders/rdocs'
|\
| * 35cfb2b Some rdoc changes
* | 1c002dd added some blame and merge stuff
|/
* 1c36188 ignore *.gem
* 9b29157 add open3_detach to gemspec file list

 

HEAD^는 바로 'HEAD의 부모' 를 의미하므로 바로 이전 커밋을 보여준다.

  • 734713b의 부모 d921970
$ git show HEAD^
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Merge: 1c002dd... 35cfb2b...
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 15:08:43 2008 -0800

    Merge commit 'phedders/rdocs'

 

^의 뒤에 숫자도 사용할 수 있다. 

  • d921970^2 는 'd921970의 두 번째 부모' 
    • 첫 번째 부모는 Merge할때 Checkout했던 브랜치 ( 1c002dd )
    • 두 번째 부모는 Merge한 대상 브랜치 ( 35cfb2b )
$ git show d921970^
commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 14:58:32 2008 -0800

    added some blame and merge stuff

$ git show d921970^2
commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
Author: Paul Hedderly <paul+git@mjr.org>
Date:   Wed Dec 10 22:22:03 2008 +0000

    Some rdoc changes

 

계통을 표현하는 방법으로 ~라는 것도 있다.

  • HEAD~ : HEAD^는 똑같이 첫번째 부모를 가리킨다.
  • HEAD~2 : 명령을 실행할 시점의 '첫번째 부모의 첫번째 부모' 즉 '조부모'를 가리킨다

HEAD~3의 예는 다음과 같다. 

  • 첫 번째 부모의 첫 번째 부모의 첫 번째 부모를 가리킨다.
  • HEAD^^^ 와 같은 표현이다.
$ git show HEAD~3
commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
Author: Tom Preston-Werner <tom@mojombo.com>
Date:   Fri Nov 7 13:47:59 2008 -0500

    ignore *.gem

 

HEAD~3^2 : 증조부모(첫 번째 부모의 첫 번째 부모의 첫 번째 부모) Merge 커밋의 두 번째 부모

범위로 커밋 가리키기

Double Dot

범위를 표현하는 문법으로 (..) 을 많이 쓴다. 다음과 같은 커밋 히스토리가 있다

 

master에는 없지만 expeirment 에는 있는 커밋을 찾을 때 명령어이다.

$ git log master..experiment
D
C

 

experiments에는 없고 master에만 잇는 커밋을 찾을때 명령어이다

  • experiments브랜치를 Merge하기 전에 무엇이 변경됐는지 궁금할 때 유용하다.
$ git log experiment..master
F
E

 

아래 명령어는 origin 저장소의 master 브랜치에는 없고 현재 Checkout 중인 브랜치에만 있는 커밋을 보여준다.

  • Checkout한 브랜치가 orgin/master를 추적하는 브랜치라면 아래 명령어는 커밋이 Push하면 서버에 전송될 커밋이다.
$ git log origin/master..HEAD

# 한쪽의 레퍼런스를 생략하믄 Git은 HEAD라고 가정한다. 
# 아래 명령은 위와 같은 명령어이다.
$ git log origin/master..

세 개 이상의 레퍼런스

Double dot(..)은 두 개 이상의 브랜치에는 사용할 수 없다.

 

현재 작업 중인 브랜치에는 있지만 다른 여러 브랜치에는 없는 커밋

  • .. 으로는 확인할 수 없다.
  • ^과 --not 옵션 뒤에 브랜치를 넣으면 가능하다.

'refB에는 있지만 refA에는 없는 커밋' 의 동일한 명령어

$ git log refA..refB
$ git log ^refA refB
$ git log refB --not refA

 

'refA나 refB에는 있지만 refC에는 없는 커밋' 의 동일한 명령어

$ git log refA refB ^refC
$ git log refA refB --not refC

Triple Dot

두 레퍼런스 사이에 공통으로 가지는 것을 제외하고 서로 다른 커밋만 보여준다.

 

master와 experiment의 공통부분은 빼고 다른 커밋만 보는 명령어

$ git log master...experiment
F
E
D
C

 

--left-right 옵션 : 각 커밋이 어느 브랜치에 속하는지 보여준다.

$ git log --left-right master...experiment
< F
< E
> D
> C