Git을 사용하다가, 커밋을 되돌려야 하는 상황이 생길 수 있습니다. Working tree가 꼬여 모든 파일이 제거되는 커밋을 작성했거나, 단순히 변경 사항이 필요없는 경우 등이 있을 수 있습니다. 그러나 이력을 되돌려야 하는 상황 중 대부분은 당황스럽고 급박한 상황인 경우가 많아, 커밋을 되돌리는 방법에 대해 제대로 알지 못하고 있으면 이력을 되돌리는 일조차 제대로 하지 못할 수 있습니다.

Git에서 이력을 되돌리는 방법은 여러가지가 있으나, 대표적으로 resetrevert를 사용할 수 있습니다. reset은 과거로 돌아가고, revert는 되돌릴 커밋의 코드만 복원시킵니다.

Reset

Reset은 과거의 이력으로 돌아간다고 생각하면 됩니다. 돌아가려는 커밋으로 저장소가 재설정되고, 해당 커밋 이후의 이력은 사라집니다.

  • 000004 : Update some.txt
  • 000003 : Update some.txt
  • 000002 : Add some.txt
  • 000001 : 초기화

000001번에 해당하는 첫 커밋부터, 000004번에 해당하는 네 번째 커밋까지 진행되어 있다고 칩시다. some.txt를 만들고 나서 열심히 수정했는데, 이 파일을 포함한 모든 변경 이력이 필요가 없어져서 some.txt를 만들기 전(000001)으로 이력을 되돌리기로 결정했다고 합시다. 다음과 같이 사용할 수 있습니다.

$ git reset 000001

위처럼 커밋 해쉬를 통해서 되돌아가려는 커밋을 직접 지정할 수도 있고, HEAD를 이용할 수도 있습니다. 예를 들어 현재를 기준으로 3개 전의 이력으로 되돌아가려면 아래처럼 사용할 수 있습니다.

$ git reset HEAD~3

옵션은 hard, mixed, soft가 있습니다.

--hard

$ git reset --hard 000001

돌아가려는 이력(여기서는 000001) 이후의 모든 내용을 지웁니다.

--soft

$ git reset --soft 000001

000001번 커밋으로 되돌아 가긴 하지만, 해당 내용은 지워지지 않고 Index(Staging Area)에 그대로 남아 있습니다. 다시 커밋할 수 있는 상태로 남아있는 것입니다.

--mixed

$ git reset --soft 000001

여기서도 000001번으로 이력은 되돌아가지만, 인덱스가 초기화되며 해당 변경 이력에 해당하는 파일들은 Modified 상태가 됩니다.

Revert

Revert는 특정 커밋의 변경 사항을 되돌리는 역할을 합니다. 사실 결과물 자체는 reset과 다를 바 없지만, 이력은 같지 않습니다.

$ git revert 000004

이렇게 되면, 커밋이 사라지지 않고 000004번 커밋을 되돌린 커밋이 새로 생성됩니다.

  • 000005 : Revert "Update some.txt"
  • 000004 : Update some.txt
  • 000003 : Update some.txt
  • 000002 : Add some.txt
  • 000001 : 초기화

되돌릴 커밋을 여러 개 설정할 수도 있습니다.

$ git revert 000004..000002

Reset vs. Revert

Reset은 이력을 단순하게 만들어 줍니다. 그러나 reset은 해당 커밋 이후의 이력을 모두 제거하므로 신중하게 사용해야 하며, 커밋을 되돌린 이력도 한 가지의 이력으로 남겨 두는 것이 좋기 때문에 되도록이면 revert를 사용하는 것이 좋습니다.

'Git 레거시 글' 카테고리의 다른 글

[Git] Cherry-pick  (0) 2018.05.30
[Git] 커밋 히스토리 수정하기  (0) 2018.05.29
[Git] 다시 커밋하기  (0) 2018.05.27
[Git] 파일 상태 Lifecycle 관리하기  (0) 2018.05.26
[Git] 브랜칭 기법  (0) 2018.05.25

커밋에서 파일을 빼먹었거나, 커밋 메시지를 잘못 적었을 때 해당 커밋을 다시 수행해야 합니다. git commit에 --amend 옵션을 사용합니다.

$ git commit --amend

기본적으로 이것도 커밋입니다. 단, --amend 옵션을 지정함으로써 Index에 있는 현재 변경 사항들을 가장 최근 커밋에 덮어쓸 수 있습니다. 따라서, 방금 한 커밋에서 forgotten 파일을 빼먹었다면 아래와 같이 커밋에 파일을 추가할 수 있습니다.

$ git add forgotten
$ git commit --amend

단순히 메시지만을 수정하고 싶다면, Index에 아무 것도 등록하지 않은 채로 --amend 옵션을 지정하고 다시 커밋하면 됩니다.

'Git 레거시 글' 카테고리의 다른 글

[Git] 커밋 히스토리 수정하기  (0) 2018.05.29
[Git] 커밋 되돌리기  (0) 2018.05.28
[Git] 파일 상태 Lifecycle 관리하기  (0) 2018.05.26
[Git] 브랜칭 기법  (0) 2018.05.25
[Git] 브랜치와 Merge  (0) 2018.05.24

Git의 파일에는 Lifecycle이 존재합니다. Unmodified를 Modified로 변경하려면 파일을 수정하면 되고, Modified를 Staged로 변경하려면 git add하면 됩니다. 여기선 그 역방향으로 파일의 Lifecycle을 변경해 보도록 합시다.

Staged 파일을 Modified(Unstaged)로 변경하기

Working tree에서 Staging area(index)로 파일의 상태를 기록(staging)하기 위해 add를 사용했습니다. 현재 작업 트리의 상태를 보여주는 git status를 사용하면, 아래와 같이 출력될 것입니다.

> git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   Will_commit.txt
        modified:   Dont_commit.txt

git reset HEAD <file>...이라는 문장을 볼 수 있습니다. 실제로 이 명령어를 이용해 파일을 Unstaged 상태로 변경할 수 있습니다. Dont_commit.txt 파일을 Unstaged 상태로 변경해 보겠습니다.

$ git reset HEAD Dont_commit.txt
Unstaged changes after reset:
M       Dont_commit.txt
$
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   Will_commit.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   Dont_commit.txt

Modified 파일을 Unmodified로 변경하기

수정된 파일을 수정 전으로 되돌릴 수도 있습니다. 여기서도 git status 명령이 친절하게 알려줍니다.

$ git status
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   Dont_modify.txt

git checkout -- <file>...을 사용하라고 합니다. 알려주는 대로 한 번 해 봅시다.

$ git checkout -- Dont_modify.txt
$ git status
nothing to commit (create/copy files and use "git add" to track)

수정 전으로 돌아갔습니다. 그러나 수정했던 내용은 전부 사라지므로, 조심해서 사용해야 합니다.

'Git 레거시 글' 카테고리의 다른 글

[Git] 커밋 되돌리기  (0) 2018.05.28
[Git] 다시 커밋하기  (0) 2018.05.27
[Git] 브랜칭 기법  (0) 2018.05.25
[Git] 브랜치와 Merge  (0) 2018.05.24
[Git] Pull에서 충돌 해결하기  (1) 2018.05.23

+ Recent posts