sungyup's.

dev_toolkits / Git / 2.2 git diff

2.2git diff

서로 다른 커밋 간 차이를 비교해주는 git diff

TL;DR

작업을 하다가 뭔가 잘못되었다는 것을 깨달았다. 스타일링이 깨져있는데, 한두 커밋 전에도 깨져있고 꽤 오래 전 코드를 보니 제대로 되어 있었다. 이 코드와 지금 작업을 비교할 수 있을까?

1. 과거 커밋 찾기

우선 문제가 발생하기 전, 잘 되던 때의 커밋을 찾는다. git log 명령어 또는 Git Graph 익스텐션을 사용해 원하는 커밋의 해시(앞 7자리면 충분하다)를 따로 복사해둔다.

bash
git log # 좀 더 간결하게 볼 수 있다 git log --oneline

가끔은 코드만 봐도 원하는 상태인지 알 수 있지만, 가장 확실한 것은 직접 그 시점의 프로젝트 상태를 열어 테스트하는 방법이다. 이를 위해선 git stash로 현재 작업중인 내역을 저장하고 예전 커밋으로 돌아가거나, detached HEAD 상태로 돌아가기 위해 switch -d와 같이 -d 옵션을 붙여 돌아갔다 올 수 있다.

bash
git switch -d <커밋해시> # 돌아올 때 git switch -

2. git diff로 비교하기

이후, git diff 명령어를 통해 과거 커밋과 현재 작업트리(커밋이 되지 않은 수정 부분 포함)를 비교할 수 있다.

bash
git diff <커밋해시>

다만 이렇게 하면 한참 전 코드와 비교시 모든 변경 사항이 나오기 때문에, 파일을 지정하면 도움이 된다. 나의 경우 css module이었기 때문에 아주 편했다.

bash
git diff <커밋해시> -- <파일경로>

3. 변경 내용 적용하기

변경하고자 하는 내용이 어느 정도 규모인지에 따라 방식이 다르다.

3-1. 특정 파일 전체 되돌리기(restore)

만약 파일 전체를 되돌리려면 해당 커밋 버전으로 파일을 덮어쓰는 restore를 쓸 수 있다.

bash
git restore --source=<커밋해시> -- <파일경로>

3-2. 일부 코드만 가져오기(git checkout -p)

약간 복잡하긴 하지만 특정 라인 일부를 되살리고 싶다면 patch mode를 의미하는 -p 옵션을 써서 checkout할 수 있다.

bash
git 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를 어떻게 처리할지에 대한 선택 단축키 목록이다. 다 외울 필요는 없는게, ?를 입력하면 어차피 설명이 나온다.

각각 아래와 같은 의미다:

의미설명
yyes변경 적용
nno적용 X
qquit즉시 종료(나머지는 아무것도 적용 X)
aall이후 나오는 모든 hunk를 한꺼번에 적용
ddone지금까지 선택한것만 적용하고 종료
jnext이번 hunk는 보류, 다음 hunk로 넘어감
Jskip현재 파일의 남은 hunk를 모두 건너뛴다
ggo특정 hunk 번호로 이동
/search변경 내용 안에서 문자열 검색
ssplit한 hunk를 더 작은 부분으로 나눈다. 자주 쓰는 기능이다.
eedit수동 편집 모드.
?help옵션 설명을 보여준다.