고급 Git 로그
모든 버전 제어 시스템의 목적은 코드의 변경 사항을 기록하는 것입니다. 이를 통해 프로젝트 기록으로 돌아가 누가 무엇을 기여했는지 확인하고, 버그가 어디서 발생했는지 파악하며, 문제가 있는 변경 사항을 되돌릴 수 있습니다. 하지만 이 모든 기록을 사용할 수 있다고 해도 탐색 방법을 모르면 아무 소용이 없습니다. 바로 이러한 경우에 git log 명령이 필요합니다.
이제 커밋을 표시하는 기본적인 git log 명령은 이미 알고 있을 것입니다. 하지만 git log에 다양한 매개 변수를 전달하여 이 출력을 변경할 수 있습니다.
git log의 고급 기능은 각 커밋이 표시되는 방식에 형식을 지정하는 것과 출력에 포함되는 커밋을 필터링하는 것, 두 가지 범주로 나눌 수 있습니다. 이 두 가지 기술을 함께 사용하면 프로젝트로 돌아가서 필요한 모든 정보를 찾을 수 있습니다.
로그 출력 형식 지정
먼저, 이 문서에서는 git log
출력에 형식을 지정할 수 있는 여러 가지 방법을 살펴보겠습니다. 이 방법의 대부분은 git log
에서 정보를 더 많이 또는 더 적게 요청할 수 있게 하는 플래그 형태입니다.
기본 git log
형식이 마음에 들지 않으면 git config
의 별칭 기능을 사용하여 아래에 설명된 모든 형식 지정 옵션에 대한 바로 가기를 만들 수 있습니다. 별칭을 설정하는 방법은 git config 명령을 참조하세요.
Oneline
--oneline
플래그는 각 커밋을 한 줄로 압축합니다. 기본적으로 커밋 ID 및 커밋 메시지의 첫 번째 줄만 표시합니다. 일반적인 git log --online
출력은 다음과 비슷하게 표시될 것입니다.
0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base
이것은 프로젝트의 간략한 개요를 보는 데 매우 유용합니다.
관련 자료
전체 Git 리포지토리를 이동하는 방법
솔루션 보기
Bitbucket Cloud에서 Git에 대해 알아보기
Decorating
각 커밋이 어떤 브랜치 또는 태그와 관련되어 있는지 알면 유용할 때가 많습니다. --decorate
플래그는 git log
가 각 커밋을 가리키는 모든 참조(예: 브랜치, 태그 등)를 표시하도록 합니다.
다른 구성 옵션과 조합하여 함께 사용할 수 있습니다. 예를 들어, git log --oneline --decorate
를 실행하면 커밋 기록이 다음과 같이 형식 지정됩니다.
0e25143 (HEAD, main) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad (tag: v0.9) Add the initial code base
이렇게 하면 최상위 커밋도 체크아웃되고(HEAD
로 표시) main
브랜치의 팁이기도 하다는 것을 알 수 있습니다. 두 번째 커밋에는 feature
라고 하는 또 다른 브랜치가 있으며 마지막으로 네 번째 커밋에는 v0.9
라는 태그가 지정됩니다.
브랜치, 태그, HEAD
및 커밋 기록은 Git 리포지토리에 포함된 거의 모든 정보이므로 리포지토리의 논리적 구조에 대한 전체적인 보기를 제공합니다.
Diffs
git log
명령에는 커밋할 때마다 diff를 표시하기 위한 많은 옵션이 포함되어 있습니다. 가장 일반적인 2가지 옵션은 --stat
및 -p
입니다.
--stat
옵션은 각 커밋에서 변경된 각 파일의 삽입 및 삭제 횟수를 표시합니다(줄 수정은 삽입 1회 및 삭제 1회로 표시됨). 각 커밋에서 생성된 변경 사항을 간략하게 요약하고 싶을 때 유용합니다. 예를 들어, 다음 커밋은 hello.py
파일에 67줄을 추가하고 38줄을 제거했습니다.
commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date: Fri Jun 25 17:30:28 2014 -0500
Add a new feature
hello.py | 105 ++++++++++++++++++++++++-----------------
1 file changed, 67 insertion(+), 38 deletions(-)
파일 이름 옆에 있는 +
및 -
기호 수는 커밋에서 변경된 각 파일의 상대적인 변경 횟수를 나타냅니다. 이를 통해 각 커밋의 변경 사항을 어디에서 찾을 수 있는지 알 수 있습니다.
각 커밋에서 발생한 실제 변경 사항을 보려면 -p
옵션을 git log
로 전달하면 됩니다. 이렇게 하면 해당 커밋을 나타내는 전체 패치가 출력됩니다.
commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date: Fri Jun 25 17:31:57 2014 -0500
Fix a bug in the feature
diff --git a/hello.py b/hello.py
index 18ca709..c673b40 100644
--- a/hello.py
+++ b/hello.py
@@ -13,14 +13,14 @@ B
-print("Hello, World!")
+print("Hello, Git!")
변경 사항이 많은 커밋의 경우 결과 출력이 상당히 길고 다루기 어려워질 수 있습니다. 대체로 전체 패치를 표시하는 경우에는 특정한 변경 사항을 찾고 있을 확률이 높습니다. 이러한 경우에는 곡괭이 옵션을 사용하는 것이 좋을 수 있습니다.
Shortlog
git shortlog
명령은 릴리스 공지를 만들기 위한 git log
의 특별한 버전입니다. 이 명령은 각 커밋을 작성자별로 그룹화하고 각 커밋 메시지의 첫 번째 줄을 표시합니다. 누가 어떤 작업을 했는지 쉽게 확인할 수 있는 방법입니다.
예를 들어, 두 개발자가 한 프로젝트에 5개의 커밋을 기여했다면 git shortlog
출력은 다음과 비슷하게 표시될 것입니다.
Mary (2):
Fix a bug in the feature
Fix a serious security hole in our framework
John (3):
Add the initial code base
Add a new feature
Merge branch 'feature'
기본적으로 git shortlog
는 작성자 이름을 기준으로 출력을 정렬하지만 -n
옵션을 전달하여 작성자당 커밋 수를 기준으로 정렬할 수도 있습니다.
그래프
--graph
옵션은 커밋 기록의 브랜치 구조를 나타내는 ASCII 그래프를 그립니다. 어떤 커밋이 어떤 브랜치에 속하는지 더 쉽게 확인하기 위해 보통 --oneline
및 --decorate
명령과 함께 사용됩니다.
git log --graph --oneline --decorate
브랜치가 2개밖에 없는 간단한 리포지토리의 경우, 다음이 생성됩니다.
* 0e25143 (HEAD, main) Merge branch 'feature'
|\
| * 16b36c6 Fix a bug in the new feature
| * 23ad9ad Start a new feature
* | ad8621a Fix a critical security issue
|/
* 400e4b7 Fix typos in the documentation
* 160e224 Add the initial code base
별표는 커밋이 어느 브랜치에 있었는지 보여주므로 위 그래프는 23ad9ad
및 16b36c6
커밋이 토픽 브랜치에 있고 나머지는 main
브랜치에 있다는 것을 알려줍니다.
간단한 리포지토리에는 좋은 옵션이지만, 브랜치가 많은 프로젝트의 경우에는 gitk
또는 Sourcetree와 같이 더 완전한 기능을 갖춘 시각화 도구를 사용하는 것이 좋습니다.
사용자 지정 형식
다른 모든 git log
형식 지정 요구 사항에 대해 --pretty=format:"
옵션을 사용할 수 있습니다. 이렇게 하면 printf
형식의 자리 표시자를 사용하여 각 커밋을 원하는 방식으로 표시할 수 있습니다.
예를 들어, 다음 명령에서 %cn
, %h
및 %cd
문자는 각각 커밋한 사용자의 이름, 커밋 해시 약칭, 커밋한 날짜로 대체됩니다.
git log --pretty=format:"%cn committed %h on %cd"
그 결과 각 커밋에 대해 다음 형식이 지정됩니다.
John committed 400e4b7 on Fri Jun 24 12:30:04 2014 -0500 John committed 89ab2cf on Thu Jun 23 17:09:42 2014 -0500 Mary committed 180e223 on Wed Jun 22 17:21:19 2014 -0500 John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500
자리 표시자의 전체 목록은 git log 매뉴얼 페이지의 근사한 형식
섹션에서 찾을 수 있습니다.
--pretty=format:"
옵션은 관심 있는 정보만 볼 수 있다는 점 외에도 git log
출력을 다른 명령으로 파이프하려고 할 때 특히 유용합니다.
커밋 기록 필터링
각 커밋이 표시되는 형식을 지정하는 것은 git log
를 학습하는 과정의 절반에 불과합니다. 나머지 절반은 커밋 기록을 탐색하는 방법을 이해하는 것입니다. 이 문서의 나머지 부분에서는 git log
를 사용하여 프로젝트 기록에서 특정 커밋을 선택하는 몇 가지 고급 방법을 소개하겠습니다. 이 모든 것을 위에서 설명한 모든 형식 지정 옵션과 함께 사용할 수 있습니다.
수량별
git log
의 가장 기본적인 필터링 옵션은 표시되는 커밋의 수를 제한하는 것입니다. 마지막 몇 개의 커밋에만 관심이 있는 경우 이렇게 하면 한 페이지에서 모든 커밋을 보는 수고를 덜 수 있습니다.
-
옵션을 포함하여 git log
의 출력을 제한할 수 있습니다. 예를 들어, 다음 명령은 가장 최근 커밋 3개만 표시합니다.
git log -3
날짜별
특정 기간의 커밋을 찾는 경우 --after
또는 --before
플래그를 사용하여 커밋을 날짜별로 필터링할 수 있습니다. 둘 다 다양한 날짜 형식을 매개 변수로 허용합니다. 예를 들어, 다음 명령은 2014년 7월 1일(포함) 이후에 만들어진 커밋만 표시합니다.
git log --after="2014-7-1"
"1 week ago(1주일 전)"
및 "yesterday(어제)"
와 같이 상대 참조를 전달할 수도 있습니다.
git log --after="yesterday"
두 날짜 사이에 만들어진 커밋을 검색하려면 --before
및 --after
날짜를 둘 다 입력하면 됩니다. 예를 들어, 2014년 7월 1일과 2014년 7월 4일 사이에 추가된 커밋을 모두 표시하려면 다음을 사용합니다.
git log --after="2014-7-1" --before="2014-7-4"
변경 사항이 많은 커밋의 경우 결과 출력이 상당히 길고 다루기 어려워질 수 있습니다. 대체로 전체 패치를 표시하는 경우에는 특정한 변경 사항을 찾고 있을 확률이 높습니다. 이러한 경우에는 곡괭이 옵션을 사용하는 것이 좋을 수 있습니다.
작성자별
특정 사용자가 만든 커밋만 찾는 경우 --author
플래그를 사용합니다. 이 플래그는 정규식을 허용하며 작성자가 해당 패턴과 일치하는 커밋을 모두 반환합니다. 찾고 있는 작성자를 정확히 알고 있다면 정규식 대신 이전의 일반 문자열을 사용할 수 있습니다.
git log --author="John"
이렇게 하면 작성자에 John이라는 이름이 포함된 커밋이 모두 표시됩니다. 작성자 이름이 정확히 일치할 필요는 없으며 지정된 문구를 포함하기만 하면 됩니다.
더 복잡한 검색에도 정규식을 사용할 수 있습니다. 예를 들어, 다음 명령은 Mary 또는 John의 커밋을 검색합니다.
git log --author="John\|Mary"
작성자의 이메일도 작성자 이름에 포함되므로 이 옵션을 사용하여 이메일로 검색할 수도 있습니다.
워크플로가 커밋한 사용자와 작성자와 구분하는 경우 --committer
플래그도 같은 방식으로 작동합니다.
메시지별
커밋 메시지별로 커밋을 필터링하려면 --grep
플래그를 사용합니다. 위에서 설명한 --author
플래그처럼 작동하지만 작성자 대신 커밋 메시지와 일치하는 결과를 표시합니다.
예를 들어, 팀이 각 커밋 메시지에 관련 이슈 번호를 포함하는 경우 다음과 같은 명령을 사용하여 해당 이슈와 관련된 모든 커밋을 가져올 수 있습니다.
git log --grep="JRA-224:"
-i
매개 변수를 git log
에 전달하여 패턴은 일치하되 대소문자 차이를 무시하도록 할 수도 있습니다.
파일별
특정 파일에 발생한 변경 사항에만 관심이 있는 경우가 많습니다. 파일과 관련된 기록을 표시하려면 파일 경로를 전달하기만 하면 됩니다. 예를 들어, 다음은 foo.py
또는 bar.py
파일에 영향을 준 모든 커밋을 반환합니다.
git log -- foo.py bar.py
--
매개 변수는 git log
에 후속 인수가 브랜치 이름이 아니라 파일 경로라는 것을 알리는 데 사용됩니다. 브랜치와 혼용할 가능성이 없다면 --
를 생략할 수 있습니다.
콘텐츠별
특정 소스 코드 줄을 삽입하거나 삭제하는 커밋을 검색하는 것도 가능합니다. 이것을 곡괭이라고 하는데 -S"
형식을 취합니다. 예를 들어, Hello, World!라는 문자열이 프로젝트의 파일에 추가된 시점을 알고 싶다면 다음 명령을 사용하면 됩니다.
git log -S"Hello, World!"
문자열 대신 정규식을 사용하여 검색하려면 -G"
플래그를 대신 사용할 수 있습니다.
이것은 특정 코드 줄에 영향을 미치는 모든 커밋을 찾을 수 있게 해주는 아주 강력한 디버깅 도구입니다. 줄이 복사되거나 다른 파일로 이동한 시기까지도 보여줄 수 있습니다.
범위별
커밋 범위를 git log
에 전달하여 해당 범위에 포함된 커밋만 표시할 수 있습니다. 범위는 다음 형식으로 지정되어 있으며 여기서
및
은 커밋 참조입니다.
git log ..
이 명령은 브랜치 참조를 매개 변수로 사용할 때 특히 유용합니다. 두 브랜치 간의 차이점을 보여주는 간단한 방법입니다. 다음 명령을 살펴봅시다.
git log main..feature
main..feature
범위는 feature
브랜치에 있지만 main
브랜치에는 없는 모든 커밋을 포함합니다. 즉, main
에서 포크한 이후로 feature
이 얼마나 진행되었는지 보여줍니다. 이것은 다음과 같이 시각화할 수 있습니다.
범위(feature..main
)의 순서를 바꾸면 feature
이 아닌 main
에 있는 모든 커밋을 가져오게 됩니다. git log
가 두 버전 모두에 대한 커밋을 출력하는 경우 기록이 분기되었다는 뜻입니다.
병합 커밋 필터링
기본적으로 git log
는 출력에 병합 커밋을 포함합니다. 하지만 팀에 항상 병합해야 한다는 정책이 있는 경우(즉, 토픽 브랜치를 업스트림 브랜치로 다시 지정(rebase)하는 대신 업스트림 변경 사항을 토픽 브랜치에 병합) 프로젝트 기록에 관련 없는 병합 커밋이 많이 있을 수 있습니다.
--no-merges
플래그를 전달하면 git log
가 이러한 병합 커밋을 표시하지 않도록 할 수 있습니다.
git log --no-merges
반면 오직 병합 커밋에만 관심이 있다면 --merges
플래그를 사용하면 됩니다.
git log --merges
이것은 상위 항목이 두 개 이상인 모든 커밋을 반환합니다.
요약
이제 git log
의 고급 매개 변수를 사용하여 출력 형식을 지정하고 표시할 커밋을 선택하는 것이 상당히 익숙하게 느껴질 것입니다. 이렇게 하면 프로젝트 기록에서 필요한 내용을 정확히 가져올 수 있습니다.
이러한 새로운 기술은 Git 도구 키트의 중요한 부분이지만 git log
는 다른 Git 명령과 함께 사용되는 경우가 많습니다. 원하는 커밋을 찾고 나면 보통 git checkout
, git revert
또는 커밋 기록을 조작하기 위한 다른 도구에 전달합니다. 따라서 Git의 고급 기능에 대해 계속 학습해야 합니다.
이 문서 공유
다음 토픽
여러분께 도움을 드릴 자료를 추천합니다.
이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.