기록 다시 쓰기
Git commit --amend 및 기록을 다시 작성하는 다른 방법
소개
이 튜토리얼은 Git 기록을 다시 작성하고 변경하는 다양한 방법을 다룹니다. Git는 몇 가지 다른 방법을 사용하여 변경 사항을 기록합니다. 몇 가지 방법에 대한 장단점을 분석하고 작업 방법에 대한 예가 제공됩니다. 이 튜토리얼은 커밋된 스냅샷을 덮여쓰는 가장 일반적인 원인을 살펴보고 이런 문제를 방지하는 방법을 보여줍니다.
Git의 주요 작업은 커밋된 변경 사항이 손실되지 않도록 하는 것입니다. 또한 개발 워크플로에 걸쳐 전체적인 제어를 제공하도록 설계되었습니다. 여기에는 프로젝트 기록 형태를 정확하기 정의할 수 있는 기능이 포함되지만 커밋이 손실될 가능성도 있습니다. Git는 사용 시 콘텐츠가 손실될 수 있다는 면책 조항 하에서 기록 다시 작성 명령을 제공합니다.
Git에는 기록을 저장하고 변경 사항을 저장하는 몇 가지 메커니즘이 있습니다. 이러한 메커니즘에는 Commit --amend
, git rebase
및 git reflog
가 포함되어 있습니다. 이러한 옵션은 강력한 워크플로 커스터마이제이션 옵션을 제공합니다. 이 튜토리얼을 마치면 Git 커밋을 다시 구축할 수 있는 명령에 익숙해지고, 기록을 다시 작성할 때 일반적으로 발생되는 문제를 피할 수 있습니다.
관련 자료
Git 치트 시트
솔루션 보기
Bitbucket Cloud에서 Git에 대해 알아보기
마지막 커밋 변경: git commit --amend
git commit --amend
명령은 가장 최근 커밋을 수정하는 편리한 방법입니다. 새 커밋을 전체적으로 생성하지 않아도 기존 커밋으로 단계적인 변화를 결합시킬 수 있습니다. 스냅샷을 변경하지 않아도 이전 커밋 메시지를 간단하게 편집하는 데 사용할 수도 있습니다. 하지만 개정은 가장 최근 커밋을 변경하는 것이 아니라 완전히 대체하며, 이는 개정된 커밋이 자체 참조가 있는 새로운 개체가 되었음을 의미합니다. Git에게는 새로운 커밋처럼 보이고, 이 커밋은 아래 다이어그램에서 별표(*)로 시각화됩니다. git commit --amend
를 사용하는 몇 가지 일반적인 시나리오가 있습니다. 다음 섹션에서 사용 예를 살펴보겠습니다.
가장 최근 Git 커밋 메시지 변경
git commit --amend
방금 커밋했는데 커밋 로그 메시지에서 실수했다고 가정해 보겠습니다. 준비된 항목이 없을 때 이 명령을 실행하면 스냅샷을 변경하지 않고 이전 커밋 메시지를 편집할 수 있습니다.
조기 커밋은 일상의 개발 과정에서 항상 일어납니다. 파일이나 커밋 메시지 형식을 잘못된 방법으로 지정하기 쉽습니다. --amend
플래그는 이런 사소한 실수를 해결할 수 있는 편리한 방법입니다.
git commit --amend -m "an updated commit message"
-m
옵션을 추가하면 편집기를 열지 않아도 명령줄에서 새 메시지를 전달할 수 있습니다.
커밋된 파일 변경
다음 예는 Git 기반 개발에서 일반적인 시나리오를 보여줍니다. 단일 스냅샷에서 커밋하려는 파일을 편집했지만 처음에 파일 중 하나를 추가하는 것을 잊었다고 가정해 보겠습니다. 오류 수정은 단순히 다른 파일을 준비하고 --amend
플래그를 커밋하는 것입니다.
# Edit hello.py and main.py
git add hello.py
git commit
# Realize you forgot to add the changes from main.py
git add main.py
git commit --amend --no-edit
--no-edit
플래그를 사용하면 커밋 메시지를 변경하지 않아도 커밋을 개정할 수 있습니다. 결과 커밋이 불완전한 커밋을 대체하고 단일 스냅샷에서 변경 사항을 hello.py
및 main.py
로 커밋한 것처럼 보입니다.
공용 커밋 개정 금지
개정된 커밋은 실제로 완전하게 새로운 커밋이며 이전 커밋은 현재 브랜치에 더 이상 존재하지 않습니다. 공용 스냅샷을 다시 설정하는 것과 동일한 결과가 발생합니다. 다른 개발자가 작업 기반으로 삼고 있는 커밋은 개정하지 마세요. 이로 인해 개발자에게 혼란스러운 상황이 발생할 수 있으며, 복구하는 것도 복잡한 일입니다.
정리
검토하면 git commit --amend
로 가장 최근 커밋을 가져와 새롭게 준비된 변경 사항을 추가할 수 있습니다. Git 준비 영역에서 변경 사항을 추가하거나 제거해 --amend
커밋으로 적용할 수 있습니다. 준비된 변경 사항이 없어도 --amend
는 최근 커밋 메시지 로그를 수정하라는 메시지를 표시합니다. 다른 팀원과 공유한 커밋에서 --amend
를 사용할 떄는 주의하십시오. 다른 사용자와 공유한 커밋을 개정하면 혼란스러울 가능성이 있고 긴 병합 충돌을 해결해야 합니다.
이전 또는 여러 개의 커밋 변경
이전 또는 여러 개의 커밋을 수정하기 위해 git rebase
를 사용하여 커밋 시퀀스를 새로운 기본 커밋에 결합시킬 수 있습니다. 표준 모드에서 git rebase
를 사용하여 문자 그대로 기록을 다시 작성할 수 있습니다. 즉, 현재 작업 브랜치에서 커밋을 전달된 브랜치 헤드로 자동으로 적용할 수 있습니다. 새 커밋이 이전 커밋을 대체하므로 공개적으로 푸시된 커밋에는 git rebase
를 사용하지 않아야 합니다. 그렇지 않으면 프로젝트 기록이 사라진 것처럼 보입니다.
프로젝트 기록을 정리된 상태로 유지해야 하는 인스턴스 또는 이와 유사한 인스턴스에서 -i
옵션을 git rebase
에 추가하면 rebase interactive
를 실행할 수 있습니다. 이렇게 하면 모든 커밋을 이동시키지 않아도 프로세스에서 개별 커밋을 변경할 수 있습니다. 대화형 기준 재지정 및 추가 기준 재지정 명령에 대한 자세한 내용은 git rebase 페이지를 참조하세요.
커밋된 파일 변경
rebase 도중 편집 또는 e
명령이 해당 커밋에서 rebase 재생을 일시 중지하고 git commit --amend
를 사용하여 추가로 변경할 수 있도록 합니다. Git는 재생을 중단하고 다음과 같은 메시지를 표시합니다.
Stopped at 5d025d1... formatting
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
여러 메시지
각 일반 Git 커밋에는 커밋에서 발생할 일을 설명하는 로그 메시지가 있습니다. 이러한 메시지는 프로젝트 기록에 대한 가치 있는 통찰력을 제공합니다. rebase 도중 커밋에서 몇 가지 명령을 실행하여 커밋 메시지를 수정할 수 있습니다.
기록 정리를 위해 커밋 스쿼시
s
"스쿼시" 명령은 실제 rebase 유틸리티에서 보게 되는 명령입니다. 스쿼시를 사용하여 이전 커밋으로 병합할 커밋을 지정할 수 있습니다. 이를 통해 "정리된 기록"이 가능합니다. rebase 재생 도중 Git는 각 커밋에 대해 지정된 rebase 명령을 실행합니다. 커밋 스쿼시의 경우 Git가 구성된 편집기를 열어 지정된 커밋 메시지를 결합하라는 메시지를 표시합니다. 이 전체 프로세스는 다음과 같이 시각화할 수 있습니다.
참고로 rebase 명령으로 수정된 커밋에는 원래 커밋과는 다른 ID가 지정됩니다. 선택하도록 표시된 커밋에서 이전 커밋을 다시 작성한 경우 새 ID가 부여됩니다.
이제 Bitbucket과 같은 최신 Git 호스팅 솔루션은 병합 시 새로운 기능인 "자동 스쿼싱"을 제공합니다. 이 기능은 호스팅된 솔루션 UI를 활용할 때 자동으로 기준 재지정을 수행하고 브랜치의 커밋을 스쿼싱합니다. 자세한 내용은 "Git 브랜치를 Bitbucket과 병합할 때 커밋 스쿼싱"을 참조하.
정리
Git rebase를 사용해 기록을 수정할 수 있으며, 대화형 rebase는 "지저분한" 흔적을 남기지 않고 해당 작업을 수행할 수 있습니다. 이를 통해 깔끔하고 선형 구조의 프로젝트 기록을 유지하는 동안 오류를 자유롭게 수정하고 작업을 다시 정의할 수 있습니다.
안전망: git reflog
참조 로그 또는 "reflog"는 브랜치 팁 또는 기타 커밋 참조에 적용되는 업데이트를 기록하기 위해 Git가 사용하는 메커니즘입니다. 어떠한 브랜치나 태그가 참조하지 않아도 Reflog를 사용해 커밋으로 되돌아갈 수 있습니다. 기록을 다시 작성한 후 reflog는 이전 상태의 브랜치에 대한 정보를 포함하고 필요한 경우 그 상태로 되돌아갈 수 있습니다. 어떠한 이유(분기 전환, 새 변경 사항에서 풀링, 기록 다시 작성 또는 단순히 새 커밋 추가)에서든 브랜치 팁이 업데이트될 때마다 새로운 항목이 reflog에 추가됩니다. 이 섹션에서는 git reflog
명령을 깊이 있게 살펴보고 일반적인 용도에 대해 알아 보겠습니다.
사용
git reflog
이러면 로컬 리포지토리에 대한 reflog를 표시합니다.
git reflog --relative-date
이는 상태 날짜 정보(예: 2주 전)가 포함된 reflog를 표시합니다.
예
예제를 통해 git reflog
를 살펴보겠습니다.
0a2e358 HEAD@{0}: reset: moving to HEAD~2
0254ea7 HEAD@{1}: checkout: moving from 2.2 to main
c10f740 HEAD@{2}: checkout: moving from main to 2.2
위의 reflog는 메인에서 2.2 브랜치까지 이동한 뒤 돌아오는 체크아웃을 보여줍니다. 여기부터 이전 커밋으로 하드 리셋이 있습니다. 최신 활동은 상단에 HEAD@{0}
레이블로 표시됩니다.
실수로 되돌아갔으면 reflog에는 커밋 2개를 실수로 삭제하기 전에 (0254ea7)
을 가리키는 커밋 메인이 포함됩니다.
git reset --hard 0254ea7
Git reset을 사용하면 메인을 이전 커밋으로 다시 되돌릴 수 있습니다. 기록이 실수로 변경된 경우를 대비한 안전망을 제공합니다.
reflog는 변경 사항이 로컬 리포지토리에 커밋되고 리포지토리 브랜치 팁의 이동을 추적하는 경우에만 이런 안전망을 제공합니다. 추가적으로 reflog 항목에는 만료 날짜가 있습니다. reflog 항목의 기본 만료 기간은 90일입니다.
자세한 내용은 git reflog 페이지를 참조하세요.
요약
이 문서에서는 git 기록을 변경하고 git 변경 사항을 취소하는 몇 가지 방법을 살펴보겠습니다. git rebase 프로세스를 깊이 있게 살펴보겠습니다. 주요 시사점:
- git로 기록을 다시 작성하는 방법은 많습니다.
git commit --amend
를 사용하여 최신 로그 메시지를 변경합니다.git commit --amend
를 사용하여 가장 최근 커밋을 수정합니다.git rebase
를 사용하여 커밋을 결합시키고 브랜치 기록을 수정합니다.git rebase -i
를 사용하면 기록 수정 시 표준 git rebase보다 훨씬 정밀한 제어가 가능합니다.
개별 페이지에서 여기에서 다룬 명령에 대해 자세히 알아보세요.
이 문서 공유
다음 토픽
여러분께 도움을 드릴 자료를 추천합니다.
이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.