Git Refs

앵우·2025년 7월 31일

Git Refs

해시값으로 개체를 조회하는 것에 불편함을 느껴, 해시값 대신 쉬운 이름으로 파일에 해시값을 저장

.git/refs 디렉터리 아래에 파일은 없고 디렉터리 heads와 tags가 있다.

브랜치

브랜치는 어떤 작업 중 마지막 작업을 가리키는 포인터 또는 Refs이다.

git update-ref 명령어로 .git/refs/heads/main 파일을 수정할 수 있다.

  • 이는 .git/refs/heads 디렉터리 아래에 있는 main 브랜치가 가리키는 커밋 해시값을 저장하는 파일을 수정하는 것이다.
  • 이 때 명령어 인자값으로 주는 해시값은 .git/objects 디렉터리 아래에 있는 해시값이어야 하며 커밋 개체여야 한다.
  • 명령어로 파일을 수정하면 기존에 있었던 커밋 해시값 위에 덮어씌워지므로 이전 파일 내용은 사라진다.

즉 정리하자면 refs/heads/브랜치 파일에 있는 해시값은 해당 브랜치가 가리키는 가장 최신 커밋의 해시값이다. 따라서 git branch <branch> 명령을 수행하면 git은 내부적으로 update-ref 명령을 실행한다.

현 브랜치를 가리키는 간접(symbolic) Refs

  • git checkout <브랜치> 를 수행하면 Git은 HEAD 파일의 내용을 ref: refs/heads/<브랜치>로 바꾼다.
  • git commit을 실행할 때 만들어지는 커밋 개체에서 HEAD가 가리키고 있는 커밋의 SHA-1값이 부모로 사용된다.
  • git symbolic-ref 명령을 사용해 HEAD값을 읽거나 변경할 수 있다.

HEAD값 읽기

$ git symbolic-ref HEAD
refs/heads/master

HEAD값 변경하기

$ git symbolic-ref HEAD refs/heads/test
$ cat .git/HEAD
ref: refs/heads/test

태그

  • 누가, 언제 태그를 달았는지 태그 메시지는 무엇이고 어떤 커밋을 가리키는지에 대한 정보가 포함된다.
  • 브랜치처럼 커밋 개체를 가리키지만 옮길 수는 없다.
  • 2가지 종류: Annotated 태그 & Lightweight 태그

Lightweigth 태그

  • 브랜치랑 비슷하지만 브랜치처럼 옮길 수는 없다.
$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d

Annoated 태그

  • Git은 태그 개체를 만들고 거기에 커밋을 가리키는 Refs를 저장한다.
  • 커밋을 직접 가리키지 않고 태그 개체를 가리킨다.
  • 커밋 개체 말고도 모든 Git 개체에 태그를 달 수 있음
$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'
$ cat .git/refs/tags/v1.1
9585191f37f7b0fb9444f35a9bf50de191beadc2

$ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2
object 1a410efbd13591db07496601ebc7a059dd55cfe9 # 태그가 가리키는 커밋
type commit
tag v1.1
tagger Scott Chacon <schacon@gmail.com> Sat May 23 16:48:58 2009 -0700

test tag

리모트

리모트를 추가하고 Push하면 Git은 각 브랜치마다 Push한 마지막 커밋이 무엇인지 refs/remotes 디렉터리에 저장한다.

# origin이라는 리모트를 추가하고 master 브랜치를 푸시
$ git remote add origin git@github.com:schacon/simplegit-progit.git
$ git push origin master
Counting objects: 11, done.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 716 bytes, done.
Total 7 (delta 2), reused 4 (delta 1)
To git@github.com:schacon/simplegit-progit.git
  a11bef0..ca82a6d  master -> master
  
# origin의 master 브랜치에서 서버와 마지막으로 교환한 커밋이 어떤 것인지 확인
$ cat .git/refs/remotes/origin/master
ca82a6dff817ec66f44342007202690a9376394
  • 리모트 Refs는 읽기 용도로만 쓸 수 있는 브랜치이다.
  • 리모트 Refs는 서버의 브랜치가 가리키는 커밋이 무엇인지 적어둔 일종의 북마크

레퍼런스
https://git-scm.com/book/ko/v2/Git%EC%9D%98-%EB%82%B4%EB%B6%80-Git-Refs

0개의 댓글