팀 개발을 위한 Git, GitHub 시작하기 - 8, 9

CHAPTER 8 : Git 내부 동작 원리

🖊01. git add 명령의 동작 원리

git-test 폴더 생성 후 로컬저장소 생성

$ pwd     # 현재폴더
$ mkdir git-test    # 빈 폴더 생성
$ cd git-test 
$ git init    # Git 로컬저장소 생성
$ ls -al     # .git 폴더 생성 확인
$ ls -al .git/     # .git 폴더 내부 확인 
-rw-r--r-1 cat-hanbit 197121 23 6월 3 01:00 HEAD 
명령어 의미
-rw-r–r-1 첫번째 칸은 파일의 권한과 상태, 크게 중요하지 X. '-'로 시작하면 일반파일, 'd’로 시작하면 폴더
cat-hanbit 파일 소유자의 아이디
23 파일의 크기, 바이트로 표시, 폴더는 0
6월3 01:0 파일 생성 시간
HEAD 파일 이름, 폴더의 경우 / 가 붙음

git add 와 git status 다시 보는 실습을 위한 저수준의 명령어

명령어 의미
git hash-object <파일명> 일반 파일의 체크섬을 확인할때 사용
git show <체크섬> 해당 체크섬을 가진 객체의 내용 표시
git ls-files --stage 스테이지 파일의 내용 표시, 스테이지 파일은 git add 명령어를 통해 생성되는데, .git/index 파일이 스테이지 파일임

파일 생성 및 워킹트리 상태 확인

$ echo "cat-hanbit" > cat.md     # 파일 생성, 내용을 동일하게 만들것
$ git status 

파일 체크섬 확인

$ git hash-object cat.md     # 파일의 체크섬 확인

스테이지에 파일 추가

$ git add cat.md    # 스테이지에 파일 추가
$ git status     # 파일 상태 확인
$ ls -a .git     # .git  폴더 확인, index 가 생성되었다.
$ file .git/index     # .git/index 파일의 정체 확인
$ git ls-files --stage    # 스테이지 파일의 내용 확인  

.git 폴더를 이용하여 객체 내용을 확인

$ ls -a .git/objects/     # .git/objects/ 폴더 확인
$ ls -a .git/objects/ff     # .git/objects/ff/ 폴더 확인
$ git show ff5bda     # ff5bda 의 내용을 본다 

-.git/objects/ 밑에 ff 폴더가 생긴것을 확인할 수 있는데, 그 폴더 아래는 아까 확인했던 체크섬과 일치하는 파일명이 존재한다.

$ git cat-file -t ff5bda     # 체크섬으로 객체의 종류 알아보기 
$ git cat-file blob ff5bda     # 해당 객체의 내용 들여다 보기 

git add 명령이 워킹트리에 존재하는 파일을 status 에 추가하는데, 해당 파일의 체크섬 값과 동일한 이름을 가지는 blob 객체가 생성되고 이 객체는 .git/objects 파일에 저장된다. 그리고 스테이지의 내용은 .git/index에 기록된다!!!

🖊02. git commit 명령의 동작 원리

커밋상태 확인

$ git commit
$ git log
$ git status      # clean 한 상태인것을 알 수 있다
$ ls -a .git/objects     # .git/objects/ 변화 확인
$ ls -a .git/objects/42     # 42b5fe 오브젝트 존재 확인
$ git show 42b5fe     # 42b5fe 오브젝트의 정채는 ? 

스테이지확인

$ git ls-files --stage     # 스테이지가 비어있지 않다!!
$ git status 

수상한 객체 확인

$ ls -a .git/objects
$ ls -a .git/objects/76/      # object 폴더 내용확인
$ git show 76f6787     # 76f6787 객체는 무엇인가?
$ git ls-tree 76f6787     # 트리 객체의 내용은?
$ git ls-files --stage     # 스테이지도 확인
$ git log --oneline -n1     # 커밋 체크섬 확인
$ git cat-file -t 42b5fed     # 커밋 객체 타입 확인
$ git cat-file commit 42b5fed     # 커밋 객체 내용 확인 

책에서는 모두가 7a 일거라고 했는데 나는 76 이었다…

  • $ git show 명령어를 통해 tree 임을 확인. tree 객체 내용을 확인해 봤을 때 내용이 스테이지와 동일.
  • 커밋 객체의 체크섬을 이용해 타입을 확인해 보면 commit 임을 알 수 있다
  • 이 커밋객체의 내용에는 커밋메세지와 트리 객체로 구성 되어 있음을 알 수 있고, 트리 객체의 체크섬은 위에 $ ls -a .git/objects/76/ 에서 확인한 내용과 같다.

위의 내용 요약

  1. 커밋을 하면 스테이지의 객체로 트리가 만들어 진다.
  2. 커밋에는 커밋메세지와 트리객체가 포함된다.

🖊03. 수동 커밋하며 살펴보기

파일 내용 수정하고 파일 체크섬 확인

$ cat cat.md
$ git hash-object cat.md     # 체크섬(ff5bda)
$ echo "Hello, cat-hanbit" >> cat.md     # cat.md 파일에 텍스트 추가
$ git hash-object cat.md     # 변경된 체크섬 확인(f3e6fa)
$ git ls-files --stage     # 스테이지의 파일 확인
100644 ff5bda20472c44e0b85e570185bc0769a6adec68 0  cat.md (위에 변경된 체크섬과 다른것을 알 수 있다, 기존 체크섬)
$ git ls-tree HEAD     # 헤드 커밋의 내용 확인 

변경내용 스테이지에 추가

$ git add cat.md
$ git ls-files --stage 

수동으로 트리만들기

$ git write-tree     # 트리 생성 (da5c3)
$ git ls-tree da5c3     # 생성된 트리 객체 확인 
100644 blob f3e6fa5c881ffb692cf2f2353dc2e90ce5a207f8  cat.md 

트리로 커밋하기

$ echo "트리로 커밋하기" | git commit-tree da5c3 -p HEAD     # 트리로 커밋 생성
ddb2751801b9c3d7dc5cee87c54f5ad034cd4f0d
$ git cat-file commit ddb27     # 생성된 커밋 확인
$ git log --oneline    # 커밋 로그 확인 

HEAD 갱신하기

$ ls .git     # .git 폴더 목록 확인
$ cat .git/HEAD     # HEAD 파일의 내용 확인
$ cat .git/refs/heads/master     #  refs/heads/master 내용 확인
$ git update-ref refs/heads/master ddb27     # 직접 커밋한 객체로 업데이트
$ cat .git/refs/heads/master     # 업데이트 확인
$ git log --oneline     # 로그 확인 
ddb2751 (**HEAD ->** **master**) 트리로 커밋하기
42b5fed 커밋 확인용 커밋 

중복파일 관리

$  cp cat.md  cat2.md     # 파일복사
$ echo "cat-hanbit" > cat3.md     # 이전 버전과 같은 내용의 파일 생성
$ git add cat2.md cat3.md     # 전부 스테이지에 추가
$ git ls-files --stage    # 스테이지 내용 확인
100644 f3e6fa5c881ffb692cf2f2353dc2e90ce5a207f8 0  cat.md
100644 f3e6fa5c881ffb692cf2f2353dc2e90ce5a207f8 0  cat2.md
100644 ff5bda20472c44e0b85e570185bc0769a6adec68 0  cat3.md
$ git commit     #  커밋 

git add 명령은 워킹트리의 내용을 스테이지에 반영하는 것이고, git commit 명령은 스테이지의 내용을 가지고 트리객체를 만들고 이 트리객체를 기반으로 기존 HEAD커밋을 부모로 하는 새로운 커밋을 만든다. 마지막으로 생성된 커밋은 다시 HEAD가 된다.

🖊04. 브랜치 작업 살펴보기

브랜치 생성하고 확인해보기

$ git branch test     # 브랜치 생성
$ git log --oneline     # 생성된 브랜치 확인
$ ls .git/refs/heads/    # .git 폴더 내부
master  test
$ cat .git/refs/heads/test     # 실제 파일 내용 확인
7776ba95364d949cd9b9dbd2b3c512083906277b 

아직 이 부분이 잘 이해가 되지 않는다….

브랜치 삭제 및 재생성

$ git branch -d test     # test 브랜치 삭제
$ ls .git/refs/heads/     # 브랜치 폴더 목록 확인
master
$ git branch test2     # test2 브랜치 생성
$ ls .git/refs/heads/     # 브랜치 폴더 목록 확인
master test2
$ git log --oneline -n1     # 로그 확인
$ rm .git/refs/heads/test2     # 브랜치 파일 삭제
$ git log --oneline -n1      # 다시 로그 확인 

브랜치 체크아웃 git checkout 관찰하기

$ git branch test HEAD^     # 현재 HEAD의 부모 커밋으로부터 test3 브랜치를 만든다.
$ git log --oneline -n2     # 로그 확인
$ cat .git/HEAD     # 체크아웃 전 HEAD 파일 확인
refs/heads/master
$ git checkout test3     # 체크아웃
$ cat .git/HEAD     # HEAD 파일 변경사항 확인
refs/heads/test3
$ git stauts      # 워킹트리 확인 

수동 체크아웃

$ echo "ref: refs/heads/master" > .git/HEAD     # HEAD 파일 직접 수정
$ git log --oneline -n1     # 로그 확인
$ git status     # 상태보기
$ git reset --hard     # hard reset 수행
$ git status     #  다시 상태 확인

이번장에서 배운 것들

  1. git add 명령을 수행하면 워킹트리의 내용을 스테이지에 추가한다.
  2. git commit 명령을 수행하면 스테이지의 내용으로 새로운 커밋을 만든다.
  3. 커밋 이후 git status 명령을 내리면 clean 한 상태임을 표시해주는데, 이것은 working tree, stage, HEAD 커밋들이 모두 동일한 내용을 담고있다는 뜻.
  4. 커밋객체는 트리객체와 blob 객체들의 조합을 이루어져 있다.
  5. 커밋객체는 부모커밋에 대한 참조를 가지고 있다.
  6. 브랜치를 생성하면 단순히 브랜치 파일 하나를 추가한다.
  7. 브랜치를 체크아웃하면 HEAD를 해당 브랜치로 변경하고 브랜치가 참조하는 커밋의 내용으로 스테이지와 워킹트리의 내용을 변경한다.

CHAPTER 9 : 인증 기능 살펴보기

🖊01. 인증 관련 기능 사용하기

윈도우

윈도우의 자격증명 관리_credential.helper 변수 값 사용해보기

$ git config crendential.helper
manager
$ git config --local crendential.helper
$ git config --global crendential.helper
$ git config --system crendential.helper
manager 

계정정보가 없는상태에서 git push 실행

$ git push     # GitHub 로그인창이 나타남

맥에서 인증관련 사용자 옵션_mac에서 git 인증관리

$ git config --local credential.helper 
$ git config --global credential.helper
$ git config --system credential.helper
osxkeychain 

리눅스 인증 옵션 확인해보기

$ git config --local credential.helper 
$ git config --global credential.helper
$ git config --system credential.helper 

credential.helper 값을 cache로 지정

$ git config credential.helper "cache --timeout=30"     # 30초간 아이디와 패스워드를 저장
$ git push     # 최초 1회 패스워드와 아이디 입력
$ git push     # 다시 입력해보면 ID가 저장되어 있음
$ gut push     # 30 초 지나서 다시 시도

credential.helper 값을 store로 지정

$ git config credential.helper stroe     # 인증방식 store 로 변경
$ git push      # 처음입력한 id/pw 저장함
$ git push    # 이후로는 id/pw 를 물어보지 않음 

git 인증 초기화

$ git config --unset credential.helper      # 옵션 삭제
$ file ~/.git-credentials     # 인증파일 정보확인
$ rm ~/.git-credentials     # 인증파일 삭제

🖊02. SSH 키 생성 및 사용하기 SSH란?

SSH키 생성하기

$ ssh-keygen     # ssh-keygen 명령어를 사용해서 SSH key 생성
# 엔터키 누름
# 엔터키 두번 누름
$ cd ~/.ssh/     # 키가 저장된 폴더로 이동
$ pwd    
$ ls      # 두개의 키파일 확인
$ cat id_rsa.pub     # 공개키 확인, 내용을 메모장에 붙여놓는다. 

GitHub에 키 등록하기

SSH를 이용해서 저장소 클론하기

HTTPS를 사용하는 원격저장소 주소 : https://github.com/jina95/TIL.git
SSH를 사용하는 원격저장소 주소 : git@github.com:jina95/TIL.git 

SSH로 원격저장소 클론하기 1

$ git clone git@github.com:jina95/TIL.git     # 슬프게도 실패 

근데 나는.. 되었다는게 함정….

ssh 설정파일 만들기

$ echo "Host github.com" >> ~/.ssh/config 

ssh 설정파일 내용

Host github.com
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa 

SSH를 이용해서 clone 및 push해보기

$ git clone git@github.com:jina95/TIL.git
$ cd TIL/
$ git push