[hello world]git internal

71
GIT INTERNAL 부제: Git 만드는 12년 8월 23일 목요일

Upload: naver-d2

Post on 21-Jun-2015

8.230 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: [Hello world]git internal

GIT INTERNAL부제: Git 만드는 법

12년 8월 23일 목요일

Page 2: [Hello world]git internal

기본 - GIT 저장소 읽고 쓰기커밋하고 커밋한 것 읽기

12년 8월 23일 목요일

Page 3: [Hello world]git internal

GIT STORAGE

• Git 저장소 = Git Object 저장소

• Git Object = Key-Value pair

• Value = Blob(파일), Tree(디렉토리), Commit, Tag

• Key = Value에 대한 160bit SHA-1 hash값 (이하 sha1sum)

12년 8월 23일 목요일

Page 4: [Hello world]git internal

GIT STORAGE 만드는 법

• mkdir -p .git/objects

• mkdir -p .git/refs

• echo 'ref: refs/heads/master' > .git/HEAD

12년 8월 23일 목요일

Page 5: [Hello world]git internal

GIT OBJECTS

• Blob (파일)

• Tree (디렉토리)

• Commit (저자정보, 날짜, 커미터 정보, 커밋 메시지 등)

• Tag

12년 8월 23일 목요일

Page 6: [Hello world]git internal

BLOB

“blob” <SP> content-length <NUL> content

12년 8월 23일 목요일

Page 7: [Hello world]git internal

BLOB의 예

blob����������� ������������������  17welcome����������� ������������������  to����������� ������������������  n4wiki

12년 8월 23일 목요일

Page 8: [Hello world]git internal

TREE

"tree" <SP> content-length <NUL>

1*(("100644"|”40000”) <SP> name <NUL> sha1sum-bin)

12년 8월 23일 목요일

Page 9: [Hello world]git internal

TREE의 예

100644����������� ������������������  blob����������� ������������������  8e8d68219f81ce69ecb502e43539754770ff0176����������� ������������������   DeveloperGuide.md040000����������� ������������������  tree����������� ������������������  78ee1e687641a9d3aa6afaf6c82fb86fab744a4d����������� ������������������   api100644����������� ������������������  blob����������� ������������������  34b3f62387daf615948ecaf62d3cdee263df6a20����������� ������������������   i18n.md040000����������� ������������������  tree����������� ������������������  dbad3d4da10843b1d666feffa58b0319a8a346b3����������� ������������������   spec040000����������� ������������������  tree����������� ������������������  17bbf90ac4d32f861227f93eed9dea7c48c279ad����������� ������������������   zz.emberjs

12년 8월 23일 목요일

Page 10: [Hello world]git internal

TREE의 예

tree����������� ������������������  178100644����������� ������������������  DeveloperGuide.md??h!???i??59uGp?v40000����������� ������������������  apix?hvA?Ӫj???/?o?tJM100644����������� ������������������  i18n.md4??#???????-<??c?j����������� ������������������  40000����������� ������������������  spec듣=MC??f??????F?40000����������� ������������������  zz.emberjs????/?'?>??|H?y?

12년 8월 23일 목요일

Page 11: [Hello world]git internal

COMMIT"commit" <SP> content-length <NUL>

tree <SP> sha-1 <NEWLINE>

parent <SP> sha-1 <NEWLINE>

author <SP> name <SP> "<" mail ">" <SP> unixtime <SP> timezone-offset <NEWLINE>

committer <SP> name <SP> "<" mail ">" <SP> unixtime <SP> timezone-offset <NEWLINE>

<NEWLINE> message12년 8월 23일 목요일

Page 12: [Hello world]git internal

COMMIT의 예

commit����������� ������������������  252tree����������� ������������������  1d0a84f977f13ae6f1b398e0224d40f181725233parent����������� ������������������  a71a8e9cb41ada4ced77c35ec8f2eaa45c64f729author����������� ������������������  Yi����������� ������������������  EungJun����������� ������������������  <[email protected]>����������� ������������������  1345526494����������� ������������������  +0900committer����������� ������������������  Yi����������� ������������������  EungJun����������� ������������������  <[email protected]>����������� ������������������  1345526494����������� ������������������  +0900

test:����������� ������������������  Fix����������� ������������������  the����������� ������������������  test����������� ������������������  for����������� ������������������  getTreeHead().

12년 8월 23일 목요일

Page 13: [Hello world]git internal

GIT OBJECT 저장하는 법

•내용의 sha1sum을 계산

•내용을 deflate로 압축

• sha1sum을 이름으로 해서 .git/objects/sha1sum앞2자/sha1sum나머지38자 파일로 저장

12년 8월 23일 목요일

Page 14: [Hello world]git internal

LIVE CODINGhttps://github.com/npcode/git-internal-demo

12년 8월 23일 목요일

Page 15: [Hello world]git internal

REFS

• .git/HEAD: 현재 브랜치를 가리킴

• .git/refs/heads/*: 로컬 저장소의 브랜치들

• .git/refs/remotes/*: 원격 저장소의 브랜치들

12년 8월 23일 목요일

Page 16: [Hello world]git internal

커밋하는 법

•커밋할 파일들을 blob으로 저장

•디렉토리를 tree로 저장

•루트 디렉토리의 sha1sum, 저자 정보, 커밋 메시지 등을 담은 commit을 저장

•현재 브랜치 갱신

12년 8월 23일 목요일

Page 17: [Hello world]git internal

12년 8월 23일 목요일

Page 18: [Hello world]git internal

Hello, World!

12년 8월 23일 목요일

Page 19: [Hello world]git internal

8ab68(greet)

12년 8월 23일 목요일

Page 20: [Hello world]git internal

8ab68(greet)

100644 greet 8ab68

12년 8월 23일 목요일

Page 21: [Hello world]git internal

8ab68(greet)

100644 greet 8ab68

12년 8월 23일 목요일

Page 22: [Hello world]git internal

8ab68(greet)

c97aa

12년 8월 23일 목요일

Page 23: [Hello world]git internal

8ab68(greet)

c97aa

tree c97aaauthor Yicommitter Yi

the first commit!

12년 8월 23일 목요일

Page 24: [Hello world]git internal

8ab68(greet)

c97aa

tree c97aaauthor Yicommitter Yi

the first commit!

12년 8월 23일 목요일

Page 25: [Hello world]git internal

8ab68(greet)

c97aa

15c68

12년 8월 23일 목요일

Page 26: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

12년 8월 23일 목요일

Page 27: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

12년 8월 23일 목요일

Page 28: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

Bye, World!

12년 8월 23일 목요일

Page 29: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

02c8f(greet)

12년 8월 23일 목요일

Page 30: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

100644 greet 02c8f

02c8f(greet)

12년 8월 23일 목요일

Page 31: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

100644 greet 02c8f

02c8f(greet)

12년 8월 23일 목요일

Page 32: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

8f7bc

02c8f(greet)

12년 8월 23일 목요일

Page 33: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

8f7bc

tree 8f7bcparent 15c68author Yicommitter Yi

the second commit!

02c8f(greet)

12년 8월 23일 목요일

Page 34: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

8f7bc

tree 8f7bcparent 15c68author Yicommitter Yi

the second commit!

02c8f(greet)

12년 8월 23일 목요일

Page 35: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

8f7bc

59866

02c8f(greet)

12년 8월 23일 목요일

Page 36: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

8f7bc

59866

02c8f(greet)

12년 8월 23일 목요일

Page 37: [Hello world]git internal

8ab68(greet)

c97aa

15c68

HEADrefs/heads/master

8f7bc

59866

02c8f(greet)

12년 8월 23일 목요일

Page 38: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

12년 8월 23일 목요일

Page 39: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

Bye, World!

12년 8월 23일 목요일

Page 40: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

12년 8월 23일 목요일

Page 41: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

100644 bye 02c8f

12년 8월 23일 목요일

Page 42: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

100644 bye 02c8f

12년 8월 23일 목요일

Page 43: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

cab01

12년 8월 23일 목요일

Page 44: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

cab01

tree cab01parent 59866author Yicommitter Yi

the third commit!

12년 8월 23일 목요일

Page 45: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

cab01

tree cab01parent 59866author Yicommitter Yi

the third commit!

12년 8월 23일 목요일

Page 46: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

cab01

95dfd

12년 8월 23일 목요일

Page 47: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

cab01

95dfd

12년 8월 23일 목요일

Page 48: [Hello world]git internal

c97aa

15c68

8f7bc

59866

8ab68(greet)

02c8f(greet)

HEADrefs/heads/master

cab01

95dfd

12년 8월 23일 목요일

Page 49: [Hello world]git internal

커밋된 파일 읽는 법

• .git/HEAD 를 읽어서 현재 브랜치를 알아냄

•현재 브랜치를 읽어서 커밋의 sha1sum을 알아냄

•커밋을 읽어서 루트 tree의 sha1sum을 알아냄

•루트 tree를 읽어서 읽고자 하는 blob(파일)의 sha1sum을 알아냄

• blob(파일)을 읽음

12년 8월 23일 목요일

Page 50: [Hello world]git internal

고급 - PACK 다루기packed object 읽기

12년 8월 23일 목요일

Page 51: [Hello world]git internal

GIT OBJECTS

• Loose object - packfile에 들어있지 않은 object

• Packed object - packfile에 들어있는 object

12년 8월 23일 목요일

Page 52: [Hello world]git internal

PACK

• You must have around 7,000 loose objects or more than 50 packfiles for Git to fire up a real gc command.

• push/pull을 할 때도 packfile을 주고받음

•Documentation/technical/pack-format.txt

• https://github.com/schacon/gitbook

12년 8월 23일 목요일

Page 53: [Hello world]git internal

PACK에서 GIT OBJECT 얻는 법

•찾고자 하는 object가 .git/objects 에 없으면,

• .git/objects/pack/*.idx 를 뒤져서 object가 어느 pack의 어디에 있는지 알아냄

•알아낸 곳을 읽고 해석하여 object를 얻음

12년 8월 23일 목요일

Page 54: [Hello world]git internal

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 55: [Hello world]git internal

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 56: [Hello world]git internal

HEADER“\377tOc” - pack signature

“0002” - pack version

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 57: [Hello world]git internal

FANOUTfanout[i] = sha1sum이 i로 시작하는 object의 갯수

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 58: [Hello world]git internal

SHA LISTINGobject들의 sha1sum을 오름

차순으로 나열

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 59: [Hello world]git internal

CRC CHECKSUM

object들을 검증하기 위한 4바이트 checksum

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 60: [Hello world]git internal

PACKFILE OFFSETS

offset[i] = i번째 object의 packfile 에서의 위치

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 61: [Hello world]git internal

LARGE PACKFILE OFFSETS

4바이트로는 표현이 안되는 큰 offset들

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 62: [Hello world]git internal

TRAILERpackfile과 idxfile의 SHA1

checksumScott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 63: [Hello world]git internal

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 64: [Hello world]git internal

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 65: [Hello world]git internal

Scott Chacon. (2008). The Community Git Book.

12년 8월 23일 목요일

Page 66: [Hello world]git internal

TYPE 별 BODY 해석방법

•OBJ_COMMIT, OBJ_TREE, OBJ_BLOB, OBJ_TAG

• Git Object의 body (deflate로 압축된 상태)

12년 8월 23일 목요일

Page 67: [Hello world]git internal

TYPE 별 BODY 해석방법

•OBJ_REF_DELTA

• body의 첫 20바이트는 base object의 sha1sum

•나머지는 base object에 대한 delta (deflate로 압축되어있음)

12년 8월 23일 목요일

Page 68: [Hello world]git internal

TYPE 별 BODY 해석방법

•OBJ_OFS_DELTA

• header에서 body size를 해석한 것과 같은 방법으로 해석해서 base object에 대한 offset을 얻는다.

• 나머지 부분은 base object에 대한 delta (deflate로 압축되어있음)

12년 8월 23일 목요일

Page 69: [Hello world]git internal

DELTA COMPRESSION

header����������� ������������������  ����������� ������������������  src_size����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1XXXXXXXX����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ...����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  0XXXXXXXX����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  dest_size����������� ������������������  ����������� ������������������  ����������� ������������������  1XXXXXXXX����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ...����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  0XXXXXXXXbody����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  header����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  0XXXXXXXX����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  to_dest����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ...����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  header����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1XXXXXXXX����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  cp_off����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ...����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  cp_size����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  ...

headersrc_size

1.����������� ������������������  첫����������� ������������������  비트가����������� ������������������  0인����������� ������������������  바이트까지����������� ������������������  모두����������� ������������������  읽는다.2.����������� ������������������  읽어들인����������� ������������������  바이트의����������� ������������������  첫����������� ������������������  비트를����������� ������������������  제거한����������� ������������������  뒤����������� ������������������  순서대로����������� ������������������  연결한다.3.����������� ������������������  그����������� ������������������  값을����������� ������������������  src_size로����������� ������������������  삼는다.

dest_size

1.����������� ������������������  위와����������� ������������������  같은����������� ������������������  방법으로����������� ������������������  얻는다.

body1.����������� ������������������  한����������� ������������������  바이트를����������� ������������������  읽어서����������� ������������������  모든����������� ������������������  비트가����������� ������������������  0이면����������� ������������������  에러,

2.����������� ������������������  첫����������� ������������������  비트가����������� ������������������  1����������� ������������������  이라면����������� ������������������  다음의����������� ������������������  규칙에����������� ������������������  따른다.

1ABCDEFG

1.����������� ������������������  DEFG를����������� ������������������  근거로����������� ������������������  cp_off,����������� ������������������  ABC를����������� ������������������  근거로����������� ������������������  cp_size를����������� ������������������  구한다.����������� ������������������  (좀����������� ������������������  특이함)����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1.1.����������� ������������������  G,����������� ������������������  F,����������� ������������������  E,����������� ������������������  D����������� ������������������  순서로����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1.2.����������� ������������������  1이라면����������� ������������������  pos����������� ������������������  위치의����������� ������������������  한����������� ������������������  바이트를����������� ������������������  읽고,����������� ������������������  pos에����������� ������������������  1을����������� ������������������  더한다.����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1.3.����������� ������������������  1인����������� ������������������  비트가����������� ������������������  E라면����������� ������������������  8비트,����������� ������������������  F라면����������� ������������������  16비트,����������� ������������������  G라면����������� ������������������  24비트를����������� ������������������  왼쪽으로����������� ������������������  shift한다.����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1.4.����������� ������������������  위의����������� ������������������  방법으로����������� ������������������  구한����������� ������������������  값을����������� ������������������  cp_off����������� ������������������  에����������� ������������������  더한다.����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1.5.����������� ������������������  만약����������� ������������������  cp_size����������� ������������������  가����������� ������������������  0이라면����������� ������������������  65536으로����������� ������������������  바뀐다.����������� ������������������  (cp_size����������� ������������������  =����������� ������������������  cp_size����������� ������������������  ||����������� ������������������  65536)2.����������� ������������������  src에서����������� ������������������  cp_off����������� ������������������  부터����������� ������������������  cp_size����������� ������������������  크기만큼����������� ������������������  읽어서����������� ������������������  dest에����������� ������������������  더한다.����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  2.1.����������� ������������������  C,����������� ������������������  B,����������� ������������������  A����������� ������������������  순서로����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  1.2.����������� ������������������  1이라면����������� ������������������  pos����������� ������������������  위치의����������� ������������������  한����������� ������������������  바이트를����������� ������������������  읽고,����������� ������������������  pos에����������� ������������������  1을����������� ������������������  더한다.����������� ������������������  ����������� ������������������  ����������� ������������������  ����������� ������������������  2.3.����������� ������������������  1인����������� ������������������  비트가����������� ������������������  E라면����������� ������������������  8비트,����������� ������������������  F라면����������� ������������������  16비트,����������� ������������������  G라면����������� ������������������  24비트를����������� ������������������  왼쪽으로����������� ������������������  shift한다.

3.����������� ������������������  첫����������� ������������������  비트가����������� ������������������  0����������� ������������������  이라면����������� ������������������  다음의����������� ������������������  규칙에����������� ������������������  따른다.

0ABCDEFG

ABCDEFG����������� ������������������  바이트����������� ������������������  만큼����������� ������������������  읽어서����������� ������������������  dest에����������� ������������������  더한다.

4.����������� ������������������  그����������� ������������������  외에는����������� ������������������  에러이다.

12년 8월 23일 목요일

Page 70: [Hello world]git internal

DELTA COMPRESSION

Git 소스코드를 읽는 것이 낫습니다.

patch-delta.c

12년 8월 23일 목요일

Page 71: [Hello world]git internal

LICENSE

•이 문서는 GPLv2 라이선스로 배포됩니다.

• This document is distributed under the GPLv2.

12년 8월 23일 목요일