작업중에 최종 commit 을 실행하고 원격저장소로 보내기 위해 push 하기 전 만전을 기하기 위해 한번 더 체크해보니까 뭔가 중요한(혹은 시덥잖은) 오타같은게 발견되었다고 치자.

이럴 경우 기존에 하던 방식대로 진행하자면 오타수정 commit을 한 번 더 해줘야 한다.

이건 별 것도 아닌 일로 저장소의 리비전을 하나 더 늘이는 결과를 가져오게 되며,

내가 오타를 만들었다는 흑역사가 저장소의 히스토리에 영원히 남는 불상사가 일어나게 된다.

(물론 rollback 후에 다시 commit 하는 방법이 있긴 하지만, rollback은 Mercurial 2.7 버전부터 deprecated)


이럴 땐 commit의 옵션중 --amend 를 이용하면 한 번 더 commit 하지 않고 최종 commit된 리비전에 오타수정내용을 추가함으로써,

리비전을 하나 더 늘이지 않고, 나의 병신같은 오타 흑역사가 저장소 히스토리에 영원히 남는 불상사가 일어나지 않도록 할 수 있다.


이를 위해 하나 알아야 할 것이 있는데,

Mercurial의 각 리비전마다 phase 라고 하는, 리비전의 상태값이라고 할 수 있는 것이 존재하는데,

public / draft / secret 의 3가지가 있으며,

public의 경우 remote 상에서 와리가리된 빼도박도 못하는 공식 리비전을 말하고,

draft는 local 상에서 나 혼자 commit 한 리비전을 말한다.

secret의 경우엔 네트워크 상의 다른 저장소에서 이 리비전의 존재여부를 알 수 없는, 좀 더 은폐된 상태라 보면 된다.

자세한 내용은 http://mercurial.selenic.com/wiki/Phases 여길 참고.


다시 commit --amend로 돌아와서, 이 옵션을 사용하려면 하나 확인할 사항이 있는데 수정내용을 추가하려고 하는 리비전이 public 이 아닌 draft 혹은 secret 상태여야 한다는 것이다.

원격 저장소에서 받아온, 너도 나도 모두 알고 있는 공개된(public) 리비전을 --amend로 덮어쓸 수는 없다.


아래는 hg commit --amend 를 하는 예제다.



// 직전 로그를 보자
C:\rep> hg log -b . -l 1 --style compact
11[tip]   ddebbb310126   2014-08-05 23:27 +0900   cdbaek
  push 전 최종 commit 마무으리

// 하지만 코드리뷰 하다가 오타가 발견되었다. 그러나 흑역사를 남기고 싶지 않다.
// hg commit --amend 를 할 수 있는 상황인지 보자.
C:\rep> hg phase -r ddebbb310126
11: draft

// 할렐루야! draft 상태이므로 amend가 가능하다.
// 이제 오타를 수정한 후 흑역사를 감춰보자.
C:\rep> hg commit --amend -m "진짜 마지막"
saved backup bundle to C:\rep\.hg\strip-backup/ddebbb310126-amend-backup.hg

// 이전 커밋은 strip된 백업을 .hg/strip-backup 디렉토리에 남기고 나의 흑역사는 사라졌다.
C:\rep> hg log -b . -l 1 --style compact
11[tip]   4febaf552e0a   2014-08-05 23:27 +0900   cdbaek
  진짜 마지막












Posted by bloodguy
,