나는 항상 알고 싶었다. 바로 이런 그럼을
이 그림이 어떤 그림이냐 하면 master에서 2번커밋에서 sub브랜치 생성하고 3번커밋을 진행했는데 3번커밋이 잘못됐다는 것을 깨닫고 sub브랜치에서 4번 커밋을 하고 그 커밋을 master,가 merge하는 5번커밋을 진행하는 것이 가능하냐라는 질문이다.
이것은 로컬에서 진행하냐 원격에서 진행하냐에 따라 다르다 원격이 훨씬 난이도가 높다
로컬에서 진행한다면 명령어를 하나만 알면 된다. 바로 reset --hard이다.
빈 폴더를 만들고
git init
을 명령해보자
이후 내용으로 1을 저장한 txt파일을 만들고 저장한뒤
git add .
git commit -m 1
을 하여 첫 번째 커밋까지 진행하자
이제 2번커밋까지 진행하자 커밋메세지와 txt파일의 내용은 같다고 가정하자
git commit -am 2
이번엔 branch를 따보자
git branch sub
이후 master에서 다시한번 commit이 진행되었다고 해보자
git commit -am 3
그리고 sub브랜치에서 4번 커밋이 진행되었다
git checkout sub
git commit -am 4
그런데 3번 커밋이 잘못되었단건 인지하고 4번커밋을 master의 HEAD로 삼고 싶어졌다.
이때 master에서 sub를 merge한 후 conlict 난 부분을 수정후 다시 커밋해도 되지만
git checkout master
git reset --hard HEAD^
git merge sub
위처럼 마스터에서 head바로 앞 커밋까지 커밋이력을 reset한 다음 sub를 merge해도 된다 다만 커밋이력이 사라지니 이것은 master가 원격 저장소의 공유 브랜치라면 해서는 안되는 일이다. 하지만 local에서는 자신만 헷갈리지 않는다면 아주 좋은 방법이다.
이번엔 원격 저장소의 경우는 어떻게 해야 될까
master는 원격저장소에서 협업하는 브랜치고 sub는 나만 사용하는 branch라고 가정해 보자
이경우 가장 바람직한 방법은 책임자가 revert를 통해 master브랜치를 돌이키는 커밋(reset은 커밋 이력을 없애는 것이고 revert는 돌아가는 커밋을 더하는 것이다)을 하여 conflict가 발생하진 않겠지만 발생한다면 책임지고 해결한뒤, sub브랜치로 이동해서 patch파일을 만들어준다
git format-patch -1
현재 시점에서 1번 째 전 커밋까지의 정보를 담은 patch파일이 만들어진다. 이건 브랜치가 바껴도 파일이 유지된다. 이후 master브랜치로 돌아와
git revert HEAD
를 하여 커밋을 하나 만큼 뒤로 미룬 커밋을 하고
git am 0001-4.patch
이 커밋을 통해 커밋 내용을 복사한 patch파일이 master 브랜치에 적용되도록 한다.
이후 푸시하면 된다.
잠깐 revert와 reset의 차이점을 보자
revert는 ~~를 돌이켜라고 reset은 ~~까지 돌이켜라다
그래서 git revert HEAD라고 하면 현재헤드인 것을 돌이켜 이전 커밋과 같은 결과가 되고
git reset HEAD^ 라고 하면 헤드에서 하나전까지 돌이켜라가 되고 이전커밋과 같은 결과가 된다
정리하자면 다음과 같다.
두번째 5번은 master 브랜치인데 잘못그렸다..
이번에 알게된 git 명령어 git commit -am "메세지", git log --oneline --graph가 있다는 것도 기억하자