git reflog

이 페이지에서는 git reflog 명령에 대해 자세히 설명합니다. Git은 참조 로그 또는 "reflog"라는 메커니즘을 사용하여 브랜치 끝에 대한 업데이트를 추적합니다. 대다수의 Git 명령은 커밋에 대한 포인터인 참조나 "ref"를 지정하는 매개 변수를 허용합니다. 일반적인 예시는 다음과 같습니다.

  • Git 체크아웃
  • git reset
  • git merge

reflog는 Git ref가 로컬 리포지토리에 언제 업데이트되었는지 추적합니다. 브랜치 끝 reflog 외에도 Git stash에 대한 특수 reflog가 유지됩니다. Reflog는 로컬 리포지토리의 .git 디렉터리 아래의 디렉터리에 저장됩니다. git reflog 디렉터리는 ..git/logs/refs/heads/., .git/logs/HEAD, 그리고 .git/logs/refs/stash에서 찾을 수 있습니다(리포지토리에서 git stash를 사용한 경우).

기록 다시 작성하기 페이지에서 git reflog에 대해 개략적으로 알아보았습니다. 이 문서에서는 git reflog의 확장된 구성 옵션, git reflog의 일반적인 사용 사례와 위험, git reflog로 변경 사항을 실행 취소하는 방법 등을 다룹니다.

기본 사용 방법

가장 기본적인 reflog 사용 사례는 다음을 호출하는 것입니다.

git reflog

사실상 다음과 같은 지름길에 해당합니다.

git reflog show HEAD

그러면 HEAD reflog가 출력됩니다. 다음과 비슷한 결과가 표시됩니다.

eff544f HEAD@{0}: commit: migrate existing content
bf871fd HEAD@{1}: commit: Add Git Reflog outline
9a4491f HEAD@{2}: checkout: moving from main to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to main
39b159a HEAD@{4}: commit: expand on git context 
9b3aa71 HEAD@{5}: commit: more color clarification
f34388b HEAD@{6}: commit: expand on color support 
9962aed HEAD@{7}: commit: a git editor -> the Git editor

일반적인 reflog 사용의 또 다른 예시를 보려면 기록 다시 작성하기 페이지를 방문하세요.

reflog 참조

기본적으로 git reflogHEAD ref의 reflog를 출력합니다. HEAD는 현재의 활성 브랜치에 대한 상징적인 참조입니다. 다른 ref도 reflog를 사용할 수 있습니다. git ref에 액세스하는 구문은 name@{qualifier}입니다. HEAD ref 외에도 다른 브랜치, 태그, 원격 리포지토리, Git 스태시도 참조할 수 있습니다.

다음을 실행하여 모든 ref의 완전한 reflog를 얻을 수 있습니다.

  git reflog show --all 

특정 브랜치의 reflog를 보려면 브랜치 이름을 git reflog show에 전달합니다

 git reflog show otherbranch 9a4491f otherbranch@{0}: commit: seperate articles into branch PRs 35aee4a otherbranch{1}: commit (initial): initial commit add git-init and setting-up-a-repo docs 

예시를 실행하면 otherbranch 브랜치에 대한 reflog가 표시됩니다. 다음 예시에서는 이전에 git stash 명령을 사용하여 몇 가지 변경 사항을 스태시한 것으로 가정합니다.

 git reflog stash 0d44de3 stash@{0}: WIP on git_reflog: c492574 flesh out intro 

그러면 Git 스태시에 대한 reflog가 출력됩니다. 반환된 ref 포인터를 다른 Git 명령에 전달할 수 있습니다.

 git diff stash@{0} otherbranch@{0} 

이 예시 코드를 실행하면 stash@{0} 변경 사항을 otherbranch@{0} ref와 비교하는 Git diff 출력이 표시됩니다.

시간이 지정된 reflog

모든 reflog 항목에는 타임스탬프가 첨부되어 있습니다. 타임스탬프는 Git ref 포인터 구문의 qualifier 토큰으로 활용할 수 있습니다. 이를 통해 Git reflog를 시간별로 필터링할 수 있습니다. 사용할 수 있는 시간 한정자의 몇 가지 예시는 다음과 같습니다.

  • 1.minute.ago
  • 1.hour.ago
  • 1.day.ago
  • 어제
  • 1.week.ago
  • 1.month.ago
  • 1.year.ago
  • 2011-05-17.09:00:00

시간 한정자는 결합할 수 있으며(예: 1.day.2.hours.ago) 복수형도 허용됩니다(예: 5.minutes.ago).

시간 한정자 ref는 다른 git 명령에 전달할 수 있습니다.

  git diff main@{0} main@{1.day.ago} 

이 예시에서는 현재 main 브랜치를 1일 전의 main과 비교합니다. 일정 기간 내에 발생한 변경 사항을 알고자 할 때 매우 유용합니다.

하위 명령 및 구성 옵션

git reflog는 하위 명령으로 간주되는 몇 가지 추가 인수를 허용합니다.

Show - git reflog show

show는 기본적으로 암시적으로 전달됩니다. 예를 들어, 명령은 다음과 같습니다.

 git reflog main@{0} 

이 명령은 다음 명령과 같습니다.

 git reflog show main@{0} 

또한 git reflog showgit log -g --abbrev-commit --pretty=oneline의 별칭입니다. git reflog show 실행 를 실행하면 전달된 의 로그가 표시됩니다.

Expire - git reflog expire

expire 하위 명령은 오래되었거나 연결할 수 없는 reflog 항목을 정리합니다. expire 하위 명령은 데이터 손실의 가능성이 있습니다. 이 하위 명령은 보통 최종 사용자가 아니라 git에서 내부적으로 사용합니다. -n 또는 --dry-run 옵션을 git reflog expire에 전달하면 정리할 것으로 표시된 reflog 항목이 출력되는 "시험 실행"을 수행하지만 실제로 정리하지는 않습니다.

기본적으로 reflog 만료 날짜는 90일로 설정됩니다. 만료 시간은 명령줄 인수 --expire=timegit reflog expire에 전달하거나 git 구성 이름을 gc.reflogExpire로 설정하여 지정할 수 있습니다.

Delete - git reflog delete

delete 하위 명령은 말 그대로 삭제 명령이며 전달된 reflog 항목을 삭제합니다. expire와 마찬가지로 delete는 데이터 손실의 가능성이 있어 일반적으로 최종 사용자가 호출하지 않습니다.

손실된 커밋 복구

Git은 rebase 또는 커밋 수정과 같은 기록 다시 쓰기 작업을 수행하는 경우에도 아무것도 잃어버리지 않습니다. 다음 예시에서는 리포지토리에 몇 가지 새로운 변경 사항을 적용했다고 가정해 보겠습니다. git log --pretty=oneline은 다음과 같습니다.

 338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content 1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content c49257493a95185997c87e0bc3a9481715270086 flesh out intro eff544f986d270d7f97c77618314a06f024c7916 migrate existing content bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs 

그런 다음 변경 사항을 커밋하고 다음을 실행합니다.

 #HEAD에 변경 사항 적용 git commit -am "some WIP changes" 

새 커밋을 추가하면 다음과 같은 로그가 표시됩니다.

 37656e19d4e4f1a9b419f57850c8f1974f871b07 some WIP changes 338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content 1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content c49257493a95185997c87e0bc3a9481715270086 flesh out intro eff544f986d270d7f97c77618314a06f024c7916 migrate existing content bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs 

이 시점에서 다음을 실행하여 main 브랜치에 대한 대화형 rebase를 수행합니다.

 git rebase -i origin/main 

rebase 중에 스쿼시할 커밋을 s rebase 하위 명령으로 표시합니다. rebase하는 동안 가장 최근의 "일부 WIP 변경 사항" 커밋에 몇 개의 커밋을 스쿼시합니다.

커밋을 스쿼시했으므로 이제 git log 출력이 다음과 같이 표시됩니다.

 40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs some WIP changes 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs 

여기서 git log를 살펴보면 스쿼싱하도록 표시된 커밋이 더 이상 없는 것으로 보입니다. 만약 기록에서 변경 사항을 제거하기 위해 스쿼시된 커밋 중 하나에서 작업하고 싶으면 어떻게 해야 할까요? reflog를 활용할 수 있는 좋은 기회입니다.

 git reflog 37656e1 HEAD@{0}: rebase -i (finish): returning to refs/heads/git_reflog 37656e1 HEAD@{1}: rebase -i (start): checkout origin/main 37656e1 HEAD@{2}: commit: some WIP changes 

rebase의 시작과 끝에 reflog 항목이 있으며 그 전에 "일부 WIP 변경 사항" 커밋이 있는 것을 볼 수 있습니다. reflog ref를 git reset에 전달하고 rebase 이전의 커밋으로 재설정할 수 있습니다.

 git reset HEAD@{2} 

재설정 명령을 실행하면 HEAD가 "일부 WIP 변경 사항"이 추가된 커밋으로 이동하여 다른 스쿼시된 커밋도 복원합니다.

요약

이 자습서에서는 git reflog 명령에 대해 살펴봤습니다. 여기서 다룬 몇 가지 핵심 사항은 다음과 같습니다.

  • 특정 브랜치의 reflog를 확인하는 방법
  • reflog를 사용하여 git rebase를 실행 취소하는 방법
  • 시간 기반의 reflog 항목을 지정하고 확인하는 방법

git refloggit checkout, git reset, git merge와 같은 기타 Git 명령과 함께 사용할 수 있다는 것을 간단하게 설명했습니다. 해당 명령 페이지에서 자세히 알아보세요. ref 및 reflog에 대한 추가적인 설명은 여기에서 자세히 알아보세요.

Git을 배울 준비가 되었습니까?

이 대화형 자습서를 사용해 보세요.

지금 시작하기