회사에서 다른 분이 작업했었던 브랜치가 master 에 병합이 되었는데 적용하지 말아야 하는 경우가 생겨서 이미 다른 사람들까지 병합이 된 상황에서 되돌려야 하는 경우가 생겼다.
$ git log --oneline --graph
* f82c9d2 (HEAD -> master, tag: v1.16.7o, origin/master, origin/HEAD) Merge branch 'hotfix/EMTT-350' into 'master'
|\
| * cf2113f (origin/hotfix/EMTT-350, hotfix/EMTT-350) feat: cache key 확인 후 없으면 api 호출하도록 수정
| * adb8f11 refact: 인자 수정
| * e1653bd refact: isset 은 null 확인까지 하므로 키 있는지만 확인하도록 수정
| * eb7cf72 feat: JSON 문자열 파싱 함수 수정
|/
* f030a02 Merge branch 'feature/TOP-14' into 'master'
|\
| * bc363dd 주석 수정
| * 48b82b3 로그아웃 로그 오타 수정
| * d907051 로그인/아웃 로그 추가.
| * 081d7f0 sub account로 로그인 가능 하도록 수정
* | b56d294 (tag: v1.16.4) Merge branch 'hotfix/HH2023-109' into 'master'
|\ \
| |/
|/|
| * f26db3e intmon 상수 주석 추가.
| * cf82a6c org 한글 도메인 길이 체크 오류 수정.
|/
말하자면 위의 그래프에서 bc363dd 부터 081d7f0 까지 병합된 파일을 다시 되돌려서 적용이 되지 않도록 해야 했다. 커밋 이력과 함께 봤을 때 feature/TOP-14 브랜치에서 작업한 내용들만 되돌려야 했다.
위 문제를 해결하기 위해서는 해당 브랜치에서 작업한 파일들 기준으로 되돌리기를 진행해야 한다.
두 가지 방법이 있는데 하나는 커밋 하나하나를 여러 개를 한꺼번에 되돌리는 방법이고, 다른 하나는 브랜치 병합된 시점 기준으로 되돌리는 것이다.
첫 번째 방법은 아래처럼 하면 쉽게 해결할 수 있다. 근데 뭔가 빼먹었을 것 같은 찝찝함이 있을 것도 같다.
$ git revert bc363dd 48b82b3 d907051 081d7f0
두 번째 방법은 브랜치 병합 시점의 커밋 기준으로 해결하는 방법이다.
revert 는 특정 시점까지의 커밋 이력을 전부 되돌리는 것이 아니라 해당 시점에서의 커밋 이력을 되돌리는 것이기 때문에 b56d294 가 아니라 f030a02 를 보아야 한다.
그래서 단순히 해당 커밋을 기준으로 revert 를 하려고 하면 아래처럼 오류가 난다.
$ git revert f030a02
error: commit f030a02 is a merge but no -m option was given.
fatal: revert failed
이유는 트리를 보면 알 수 있는데 브랜치 2개가 하나로 합쳐지므로 어떤 브랜치를 기준으로 커밋 이력을 파악해야 하는지 알 수가 없기 때문이다.
여기서 해당 커밋을 상세히 보면 아래와 같은 정보들이 나타난다.
$ git cat-file -p f030a02
tree e80e557479b5af48245845ebcc76516bdd4cb70d
parent b56d294cc054b14cf43ac4d5f3b44b85805586e3
parent bc363ddd9f0bca685d95e783b4cc7da6727ba804
author {SOMEONE} <{SOMEEMAIL}> 1693989716 +0900
committer {SOMEONE} <{SOMEEMAIL}> 1693989716 +0900
Merge branch 'feature/TOP-14' into 'master'
기본 로그인 동작 로직 수정
See merge request {SOMEGIT}!113
부모가 두 개가 있다.
첫 번째 부모는 b56d294 이고, 두 번째 부모는 bc363dd 이다. 위 그래프에서 보면 알 수 있듯이 왼쪽부터 차례대로 보면 된다.
해당 시점의 커밋에서 변경된 파일들은 b56d294 커밋과 f030a02 커밋을 비교하면 그 차이를 알 수 있으므로 첫 번째 부모를 가지고 revert 를 실행해야 한다.
아래와 같이 -m 또는 --mainline 옵션을 이용하여 revert 를 해주면 된다. 숫자는 방금 위에서 말했던 부모들의 순서다(첫 번째 부모를 가지고 실행해야 하므로 1).
$ git revert -m 1 f030a02 ✔ 10:21:16
[revert aa6325e] Revert "Merge branch 'feature/TOP-14' into 'master'"
7 files changed, 137 insertions(+), 355 deletions(-)
...(변경된 파일들)
revert 명령어를 실행할 때는 브랜치 관리를 위해 브랜치를 따로 만든 다음에 실행하도록 하자.
'프로그래밍 > GIT' 카테고리의 다른 글
[GIT] Upsource 말고 Jetbrains 에서 GitLab 통합 기능으로 코드 리뷰를 해보자 (0) | 2023.10.15 |
---|---|
[GIT] GIT 원격 origin 변경 방법 (0) | 2022.09.21 |
[GitLab] rsync 를 이용한 cicd 자동화 배포 (0) | 2022.06.09 |
[GIT] SVN 에서 GIT 으로 이전하기 (0) | 2022.06.09 |
[GIT] git add * 과 git add . 차이 (0) | 2019.08.29 |