2.2git diff
서로 다른 커밋 간 차이를 비교해주는 git diff
TL;DR
작업을 하다가 뭔가 잘못되었다는 것을 깨달았다. 스타일링이 깨져있는데, 한두 커밋 전에도 깨져있고 꽤 오래 전 코드를 보니 제대로 되어 있었다. 이 코드와 지금 작업을 비교할 수 있을까?
1. 과거 커밋 찾기
우선 문제가 발생하기 전, 잘 되던 때의 커밋을 찾는다. git log 명령어 또는 Git Graph 익스텐션을 사용해 원하는 커밋의 해시(앞 7자리면 충분하다)를 따로 복사해둔다.
bashgit log # 좀 더 간결하게 볼 수 있다 git log --oneline
가끔은 코드만 봐도 원하는 상태인지 알 수 있지만, 가장 확실한 것은 직접 그 시점의 프로젝트 상태를 열어 테스트하는 방법이다. 이를 위해선 git stash로 현재 작업중인 내역을 저장하고 예전 커밋으로 돌아가거나, detached HEAD 상태로 돌아가기 위해 switch -d와 같이 -d 옵션을 붙여 돌아갔다 올 수 있다.
bashgit switch -d <커밋해시> # 돌아올 때 git switch -
2. git diff로 비교하기
이후, git diff 명령어를 통해 과거 커밋과 현재 작업트리(커밋이 되지 않은 수정 부분 포함)를 비교할 수 있다.
bashgit diff <커밋해시>
다만 이렇게 하면 한참 전 코드와 비교시 모든 변경 사항이 나오기 때문에, 파일을 지정하면 도움이 된다. 나의 경우 css module이었기 때문에 아주 편했다.
bashgit diff <커밋해시> -- <파일경로>
3. 변경 내용 적용하기
변경하고자 하는 내용이 어느 정도 규모인지에 따라 방식이 다르다.
3-1. 특정 파일 전체 되돌리기(restore)
만약 파일 전체를 되돌리려면 해당 커밋 버전으로 파일을 덮어쓰는 restore를 쓸 수 있다.
bashgit restore --source=<커밋해시> -- <파일경로>
3-2. 일부 코드만 가져오기(git checkout -p)
약간 복잡하긴 하지만 특정 라인 일부를 되살리고 싶다면 patch mode를 의미하는 -p 옵션을 써서 checkout할 수 있다.
bashgit checkout -p <커밋해시> -- <파일경로>
명령어를 입력하면 해당 파일의 변경점이 나오며 아래와 같이 물어본다.(숫자와 옵션의 수는 차이가 있을 수 있다.)
bash(1/11) Apply this hunk to index and worktree [y,n,q,a,d,j,J,g,/,s,e,?]?
hunk란 변경 블록, 즉 연속된 변경 내용이다. 맨 앞의 숫자는 현재 hunk가 전체 hunk 중 몇번째인지를 알려준다.
뒤에 나오는 [y, n, q, a, ...]는 해당 hunk를 어떻게 처리할지에 대한 선택 단축키 목록이다. 다 외울 필요는 없는게, ?를 입력하면 어차피 설명이 나온다.
각각 아래와 같은 의미다:
| 키 | 의미 | 설명 | 
|---|---|---|
| y | yes | 변경 적용 | 
| n | no | 적용 X | 
| q | quit | 즉시 종료(나머지는 아무것도 적용 X) | 
| a | all | 이후 나오는 모든 hunk를 한꺼번에 적용 | 
| d | done | 지금까지 선택한것만 적용하고 종료 | 
| j | next | 이번 hunk는 보류, 다음 hunk로 넘어감 | 
| J | skip | 현재 파일의 남은 hunk를 모두 건너뛴다 | 
| g | go | 특정 hunk 번호로 이동 | 
| / | search | 변경 내용 안에서 문자열 검색 | 
| s | split | 한 hunk를 더 작은 부분으로 나눈다. 자주 쓰는 기능이다. | 
| e | edit | 수동 편집 모드. | 
| ? | help | 옵션 설명을 보여준다. |