Resetting, checking out & reverting
The git reset, git checkout, and git revert commands are some of the most useful tools in your Git toolbox. They all let you undo some kind of change in your repository, and the first two commands can be used to manipulate either commits or individual files.
이러한 명령은 유사하기 때문에 주어진 개발 시나리오에서 어떤 명령을 사용해야 할지 혼동하기가 매우 쉽습니다. 이 문서에서는 git reset
, git checkout
및 git revert
의 가장 일반적인 구성을 비교해 보겠습니다. 이러한 명령을 사용하여 리포지토리를 탐색할 수 있는 자신감을 가지기 바랍니다.
It helps to think about each command in terms of their effect on the three state management mechanisms of a Git repository: the working directory, the staged snapshot, and the commit history. These components are sometimes known as "The three trees" of Git. We explore the three trees in depth on the git reset page. Keep these mechanisms in mind as you read through this article.
체크아웃은 HEAD
참조 포인터를 지정된 커밋으로 이동하는 작업입니다. 다음 예시를 통해 설명해 보겠습니다.
관련 자료
전체 Git 리포지토리를 이동하는 방법
솔루션 보기
Bitbucket Cloud에서 Git에 대해 알아보기
이 예시는 main
브랜치의 커밋 시퀀스를 보여줍니다. HEAD
참조와 main
브랜치 참조는 현재 커밋 d를 가리킵니다. 이제 git checkout b
를 실행해 보겠습니다
이것은 "커밋 기록" 트리에 대한 업데이트입니다. git checkout
명령은 커밋 또는 파일 수준 범위에서 사용할 수 있습니다. 파일 수준 체크아웃은 파일의 콘텐츠를 특정 커밋의 콘텐츠로 변경합니다.
되돌리기는 지정된 커밋을 받고 지정된 커밋을 반전하는 새 커밋을 만드는 작업입니다. git revert
는 커밋 수준 범위에서만 실행할 수 있으며 파일 수준 기능은 없습니다.
재설정은 지정된 커밋을 받고 지정된 커밋의 리포지토리 상태와 일치하도록 "3개의 트리"를 재설정하는 작업입니다. 3개의 트리에 해당하는 3가지 모드로 재설정을 호출할 수 있습니다.
체크아웃과 재설정은 보통 로컬 또는 비공개로 '실행 취소'하는 데 사용됩니다. 원격 공유 리포지토리로 푸시할 때 충돌을 일으킬 수 있는 리포지토리 기록을 수정합니다. 되돌리기는 원격으로 공유할 수 있는 새로운 기록을 만들고 원격 팀원들이 사용하는 기록을 덮어쓰지 않기 때문에 '공개 실행 취소'를 위한 안전한 작업으로 간주됩니다.
Git reset vs revert vs checkout reference
아래 표에는 이러한 모든 명령의 가장 일반적인 사용 사례가 요약되어 있습니다. Git을 사용하는 동안 일부 내용이 필요한 상황이 생기기 마련이니 잘 보관해 두세요.
명령 | 범위 | 일반적인 사용 사례 |
---|---|---|
| 범위 커밋 수준 | 일반적인 사용 사례 Discard commits in a private branch or throw away uncommitted changes |
| 범위 파일 수준 | 일반적인 사용 사례 파일 스테이징 취소 |
| 범위 커밋 수준 | 일반적인 사용 사례 브랜치 간 전환 또는 이전 스냅샷 검사 |
| 범위 파일 수준 | 일반적인 사용 사례 작업 디렉터리의 변경 사항 버리기 |
| 범위 커밋 수준 | 일반적인 사용 사례 공개 브랜치에서 커밋 실행 취소 |
| 범위 파일 수준 | 일반적인 사용 사례 해당 없음 |
Commit level operations
git reset
및 git check
에 전달하는 매개 변수에 따라 범위가 결정됩니다. 파일 경로를 매개 변수로 포함하지 않으면 전체 커밋에서 작동합니다. 이것이 바로 이 섹션에서 살펴볼 내용입니다. 참고로 git revert
는 파일 수준에 상응하는 사용 사례가 없습니다.
Reset a specific commit
커밋 수준에서 재설정은 브랜치 팁을 다른 커밋으로 이동하는 방법입니다. 현재 브랜치에서 커밋을 제거하는 데 사용할 수 있습니다. 예를 들어, 다음 명령은 hotfix
브랜치를 두 번의 커밋만큼 뒤로 이동시킵니다.
git checkout hotfix git reset HEAD~2
hotfix
끝에 있던 두 커밋은 이제 필요하지 않으며 고립된 커밋에 해당합니다. 따라서 다음에 Git에서 가비지 컬렉션을 수행할 때 삭제됩니다. 즉, 이러한 커밋을 버리고 싶다고 말하는 것과도 같습니다. 이것은 다음과 같이 시각화할 수 있습니다.
이러한 git reset
사용은 다른 팀원과 공유하지 않은 변경 사항을 실행 취소하는 간단한 방법입니다. 기능 작업을 시작하면서 “이런, 내가 뭘 하고 있는 거지? 다시 시작해야겠다”라고 생각하는 순간 꼭 기억해야 할 명령입니다.
현재 브랜치를 이동하는 것 외에도 git reset
을 사용하여 다음 플래그 중 하나를 전달하여 스테이징된 스냅샷 및/또는 작업 디렉터리를 변경할 수 있습니다.
--soft
– 스테이징된 스냅샷과 작업 디렉터리는 어떤 방식으로든 변경되지 않습니다.--mixed
– 스테이징된 스냅샷은 지정된 커밋과 일치하도록 업데이트되지만 작업 디렉터리는 영향을 받지 않습니다. 이 옵션이 기본값입니다.--hard
– 스테이징된 스냅샷과 작업 디렉터리가 모두 지정된 커밋과 일치하도록 업데이트됩니다.
It’s easier to think of these modes as defining the scope of a git reset
operation. For further detailed information visit the git reset page.
이전 커밋 체크아웃
git checkout
명령은 프로젝트 기록의 특정 시점으로 리포지토리 상태를 업데이트하는 데 사용됩니다. 브랜치 이름과 함께 전달하면 브랜치 간에 전환이 가능합니다.
git checkout hotfix
내부적으로 위의 명령은 HEAD
를 다른 브랜치로 이동하고 일치시키기 위해 작업 디렉터리를 업데이트합니다. 이렇게 하면 로컬 변경 사항을 덮어쓸 수 있으므로 Git은 체크아웃 작업 중에 손실될 작업 디렉터리의 변경 사항을 커밋하거나 스태시하도록 합니다. git reset
과 달리 git checkout
은 브랜치를 이동하지 않습니다.
브랜치 대신 커밋 참조를 전달하여 임의의 커밋을 체크아웃할 수도 있습니다. 이 작업은 브랜치를 체크아웃하는 것과 정확히 동일한 작업을 수행합니다. 즉, HEAD
참조를 지정된 커밋으로 이동합니다. 예를 들어, 다음 명령은 현재 커밋의 최상위 커밋을 체크아웃합니다.
git checkout HEAD~2
이는 프로젝트의 이전 버전을 빠르게 검사하는 데 유용합니다. 그러나 현재 HEAD
에 대한 브랜치 참조가 없기 때문에 이렇게 하면 HEAD
가 분리된 상태가 됩니다. 새 커밋을 추가하기 시작하면 다른 브랜치로 전환한 후에 커밋으로 돌아갈 방법이 없기 때문에 위험할 수 있습니다. 따라서 분리된 HEAD
에 커밋을 추가하기 전에는 항상 새 브랜치를 만들어야 합니다.
Undo public commits with revert
되돌리기는 새 커밋을 만들어 커밋을 실행 취소합니다. 커밋 기록을 다시 작성할 기회가 없으므로 변경 사항을 안전하게 실행 취소하는 방법입니다. 예를 들어, 다음 명령은 마지막에서 두 번째 커밋에 포함된 변경 사항을 파악하고, 해당 변경 사항을 실행 취소하는 새 커밋을 만들며, 새 커밋을 기존 프로젝트에 추가합니다.
git checkout hotfix git revert HEAD~2
이것은 다음과 같이 시각화할 수 있습니다.
기존 커밋 기록을 변경
하는 git reset과는 대조적입니다. 따라서 공개 브랜치에서 변경 내용을 실행 취소하려면 git revert
를 사용하고, 비공개 브랜치에서 변경 내용을 실행 취소하려면 git reset
을 실행해야 합니다.
git revert
를 커밋된 변경 사항을 실행 취소하는 도구라고 생각하고, git reset HEAD
를 커밋되지 않은 변경 사항을 실행 취소하는 도구라고 생각할 수 있습니다.
git checkout
과 마찬가지로 git revert
는 작업 디렉터리의 파일을 덮어쓸 가능성이 있으므로 되돌리기 작업 중에 손실될 수 있는 변경 사항을 커밋하거나 스태시하라는 요청을 받게됩니다.
File-level operations
git reset
명령과 git checkout
명령은 선택적 파일 경로도 매개 변수로 받아들입니다. 이것은 명령의 동작을 급격하게 바꿉니다. 이렇게 하면 전체 스냅샷에서 작업하는 대신 단일 파일로 작업을 제한해야 합니다.
Git reset a specific file
파일 경로로 호출하면 git reset
은 스테이징된 스냅샷을 지정된 커밋의 버전과 일치하도록 업데이트합니다. 예를 들어, 이 명령은 마지막에서 두 번째 커밋에서 foo.py
버전을 가져와 다음 커밋을 위해 스테이징합니다.
git reset HEAD~2 foo.py
커밋 수준 버전의 git reset
에서처럼 임의의 커밋보다는 HEAD
와 함께 일반적으로 사용됩니다. git reset HEAD foo.py
를 실행하면 foo.py
스테이징이 취소됩니다. 포함된 변경 사항은 작업 디렉터리에 계속 남아 있게 됩니다.
--soft
, --mixed
및 --hard
플래그는 파일 수준 버전의 git reset
에 영향을 주지 않습니다. 스테이징된 스냅샷은 항상 업데이트되고 작업 디렉터리는 업데이트되지 않기 때문입니다.
Git checkout file
파일 체크아웃은 스테이지 대신 작업 디렉터리
를 업데이트한다는 점을 제외하면 파일 경로로 git reset을 사용하는 것과 비슷합니다. 이 명령의 커밋 수준 버전과는 다르게 HEAD
참조는 이동하지 않으므로 브랜치를 전환하지 않습니다.
예를 들어, 다음 명령은 작업 디렉터리의 foo.py
를 마지막에서 두 번째 커밋의 것과 일치시킵니다.
git checkout HEAD~2 foo.py
git checkout
의 커밋 수준 호출과 마찬가지로, 프로젝트의 이전 버전을 검사하는 데 사용할 수 있지만 범위는 지정된 파일로 제한됩니다.
체크아웃한 파일을 스테이징하고 커밋하면 해당 파일의 이전 버전으로 “되돌리는” 효과가 있습니다. 이렇게 하면 이후의 모든 파일 변경 사항이 제거되는 반면, git revert
명령은 지정된 커밋에서 발생한 변경 사항만 실행 취소합니다.
git reset
과 마찬가지로 이것도 일반적으로 HEAD
와 함께 커밋 참조로 사용됩니다. 예를 들어, git checkout HEAD foo.py
는 foo.py
에 대한 스테이징되지 않은 변경 사항을 버리는 효과가 있습니다. git reset HEAD --hard
와 비슷한 동작이지만 지정된 파일에서만 작동합니다.
요약
You should now have all the tools you could ever need to undo changes in a Git repository. The git reset, git checkout, and git revert commands can be confusing, but when you think about their effects on the working directory, staged snapshot, and commit history, it should be easier to discern which command fits the development task at hand.
이 문서 공유
다음 토픽
여러분께 도움을 드릴 자료를 추천합니다.
이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.