본문 바로가기

잡다/git

[Git 04] commit

 commit에는 '~을 적어두다' 는 뜻이 있다. Git에서 사용되는 commit은 파일의 수정 내역을 .git Repository에 기록하는 것으로, 원 단어의 뜻과 의미가 통한다.

 

 Git에서는 파일들의 기록을 커밋이라는 스냅샷 단위로 저장한다. 이때 이전 버전에 비해 수정된 내역만이 저장되므로, 파일시스템을 통해 버전관리를 할때 발생하는 코드의 중복이 발생하지 않는다.

 

깃 폴더 생성

git init

 

깃 파일 상태 확인

git status

 

 

파일 등록

untracked 파일을 tracked로 등록할 때, unstaged 파일을 staged 상태로 전환할 때 모두 add 명령어 사용

git add <file/folderName>
git add . // 모든 파일 등록

 

 

파일 등록 취소

//01. tracked 상태 파일을 untracked 상태로 변환
git rm --cached <filename> // 파일을 삭제하지는 않음

//02. staged 상태 파일을 unstaged 상태로 변환
git restore --staged <filename>

 

커밋 되돌리기

git reset --soft HEAD^ //파일을 삭제하지 않고, 이전 단계로 돌아감

 

reset 이전

 

reset 이후

 

파일의 이름 바꾸기

파일의 이름을 파일 탐색기 상에서 바꾸면, 해당 파일이 삭제되었다가, 추가 된 것으로 받아들인다. 이런 의도가 아니라면, mv 명령어를 이용해야 한다.

 

git mv <filename> <newname>

//progit에 따르면, 다음 코드와 동일

mv <filename> <newname>
git rm <filename>
git add <newname>
// 정말로 순서대로 실행하면 renamed 표시가 뜬다

 

단순히 이름을 변경한 경우. test.rs 파일이 삭제되고, test2.rs가 추가된 것으로 간주.

 

git mv 명령어로 이름을 변경한 경우. renamed가 붙는다. 3줄의 대응 코드 실행해도 동일.

 

 

HEAD 포인터

 

HEAD는 커밋을 가리키는 참조 포인터이며, 최종적인 커밋 작업의 위치를 가리킨다. 이때 새로운 커밋은 부모 커밋을 기반으로 생성되는데, 이때 새로운 커밋이 HEAD 포인터가 가리키는 커밋이다. 첫 커밋 이전에는 HEAD 포인터는 존재하지 않으며, 1번 이상의 커밋 이후에 생성된다. 커밋을 수행하면 새로운 커밋의 위치로 1단계 이동한다.

 

스냅샷

 커밋은 파일의 변화를 .git Repository 에 기록하는데, 파일 전체를 복사하는 것이 아니라, 각 버전간의 차이(diff) 만을 기록해둔다. 이렇듯 수정된 부분만 저장하는 방식이 마치 변화한 부분만 사진으로 찍어둔 것 같다는 의미로 스냅샷 방식이라고 한다.

 

 Git의 스냅샷은 HEAD가 가리키는 커밋을 기반으로 하여 사진을 찍고, 이를 스테이지 영역과 비교하여 새로운 커밋으로 기록한다. 이 덕분에 버전의 차이를 빠르게 알 수 있고, 용량도 적게 차지할 수 있다.

 

커밋

 커밋은 staged 영역을 기준으로 스냅샷을 수행하여 이전 파일과 현재 수정된 파일의 "차이"를 기록한다. 이때 수정된 파일을 검사하는 기준은 해당 파일이 staged 상태에 있는지 여부이다. 이전 버전에 대해 변경된 부분이 있는 tracked 상태의 파일들은 unstaged 상태가 되며, 이 상태에서는 스냅샷이 작동하지 않는다. 이를 해결하기 위해서는 해당 파일을 위에서 언급한 명령어 add을 이용하여 unstaged 에서 staged 상태로 변경해줘야 한다.

 

 파일이 unstaged 상태에 들어가는 전제 조건은 해당 파일이 수정되었는지 여부에 달려있다. 따라서, 커밋은 원칙적으로는 1. 어떤 파일이 수정되어(modifieded) unstaged 상태에 존재할 때, 2. 해당 파일을 add 명령어로 staged 상태로 변경하여 스냅샷이 작동할 때 가능하다.

 

git commit -m "some message" //메시지와 함께 커밋
git commit -a -m "some message" //modified 상태의 파일을 전부 stage 상태로 바꾼 후 커밋

 

commit 명령어를 수행하면 깃은 HEAD와의 차이를 비교하여 새로운 객체를 생성하고, 이를 깃 저장소에 기록한다.

 

-m 옵션을 통해 커밋을 수행할 때 메시지를 추가할 수 있다. 기본적으로 Git은 동일 파일에 대해 여러개의 스냅샷을 찍고, 각각을 버전으로 관리한다. 이때 파일 자체의 이름은 동일하므로, 파일의 이름만으로는 버전을 구분할 수 없다. 따라서 사람이 이런 버전들을 구분하기 위해서는 다른 방식이 필요한데, 이를 커밋 메시지가 담당한다. 커밋 메시지는 각 커밋 객체에 대해 존재해야 하며, 후에 해당 커밋 메시지를 보고 프로그래머는 버전을 어느정도 구분할 수 있게 된다. 커밋 메시지를 작성하지 않으면 해당 커밋 시도는 취소되므로, 커밋을 수행하고 싶다면 메시지를 작성해야 한다.

 

git config --global core.editor "code -w" // vscode을 기본 에디터로 사용한다

 

git commit 명령어 작성 시 나타나는 화면. 아래에 메시지를 덧붙인다.

 

 하지만, 모든 커밋이 원칙을 따를 필요는 없다. 프로그래머의 필요에 의해 커밋 메시지가 없거나, 변경 내역이 없는 커밋을 수행할 수 있다. 각각 --allow-empty-message, --allow-empty 옵션을 통해 가능하다.

 

git commit --allow-empty -m "some message" // empty 커밋 수행
git commit --allow-empty-message //메시지 없는 커밋 수행

 

--allow-empty 커밋을 git log -p 옵션으로 보았을 때, diff가 존재하지 않는다.

 

가장 최근 커밋이 --allow-empty-message 옵션을 이용하여 커밋메시지가 없는 모습.

 

커밋 로그 기록 : log

 이전에 수행한 커밋 기록은 log 명령을 통해 볼 수 있다.

 

git log // 가장 단순한 형태. 단순한 로그를 보여줌

git log -p -2 //커밋 내역을 diff와 함께(-p) 최근 2개만 보여줌

git log --oneline //커밋 내역'만' 보여주고, 다른 정보는 안보여줌.

git log --graph // 커밋을 그래프 형태로 나타냄

git log --pretty=format:"%h %s" --graph //특정 포맷을 기준으로 그래프 형태로 나타냄

git log -S println // 수정 내역 중, println이 있는 커밋만 선택

 

format에 들어갈 수 있는 옵션들

 

대표적인 옵션

 

커밋의 제약 조건

 

수정내역 되돌리기

파일을 수정하다가, 그냥 다시 복귀시키고 싶은 경우 checkout 명령어를 이용할 수 있다.

checkout 명령어 자체는 매우 많은 기능을 할 수 있지만, 여기서는 파일 복구 기능만 언급한다.

git checkout -- <filename> // 이전 커밋 당시 파일 상태로 복구

 

커밋 아이디

 

각 커밋에는 아이디가 존재한다.

 

커밋을 수행하면 각 커밋을 지칭하는 일련의 아이디가 부여되는데, 이 것이 커밋 아이디다. 커밋 아이디는 특정 커밋을 지칭하는 절대적 이름이며, 이를 통해 해당 커밋을 참조할 수 있다.

 

커밋 아이디는 SHA1 해시 알고리즘을 이용하여 생성되어 각 커밋을 구분될 수 있게 한다. 이때 checkout 명령어 및 커밋 아이디(7자리 이상)을 이용하여 특정 커밋으로 이동도 가능하다.

 

git checkout <commit_id> // 특정 커밋으로 이동한다.

 

diff : 차이를 출력

 

unstaged / staged 상태에 있는 파일들의 차이 출력

git diff --staged // staged 상태의 차이

git diff // unstaged 상태의 차이

 

커밋간 차이 출력

git diff <commit_id> // 해당 커밋과 현재 커밋 사이의 차이

 

커밋시 diff 내용 메시지에 추가

git commit -v // 메시지에 diff 내용 추가

'잡다 > git' 카테고리의 다른 글

[Git 06] Alias  (0) 2021.10.31
[Git 05] remote  (0) 2021.10.30
[Git 03] .gitignore 파일  (0) 2021.10.29
[Git 02] 깃 저장소와 파일의 상태  (0) 2021.10.29
[Git 01] 버전관리 시스템  (0) 2021.10.29