팀원들과 각자 작업을 하던 것을 github에서 원격으로 merge하는 과정에서 잦은 충돌이 일어나고 있다.
처음부터 각자의 작업물을 합한 것이 아닌, 개별끼리 만들고 중간에 합치는 과정이라
어느 정도 충돌은 예상되기는 했지만, merge하는 과정에서 문제가 되는 것은 다음과 같다.
문제 상황 )
다른 branch로 merge하려고 할 때 발생하는 issue 모음
- merge 할 때, 더하고 빼는 과정에서 merge할 대상 브랜치의 작업자와
일일이 확인해야 하는 번거로움이 필요. - 중복된 메서드 정의와 서로 다른 변수 명명 규칙으로 인해 충돌이 발
그 외의 다른 것도 있지만 위 두 개를 github의 인터페이스 상으로는 확인하는 것이 어려웠다.
그래서 이를 확인하기 위해서. IDE의 힘을 빌리고자 한다.
해결 방법 )
우선 develop branch에 feature branch를 merge하려고 한다고 가정하자.
merge 하고자 하는 target branch는 develop가 된다.
step 1. merge하고자 하는 branch의 최신 정보를 pull을 통해 업데이트
git pull origin develop
step 2. 주입하고자 하는 branch로 main을 오히려 역으로 merge
git checkout feature // feature branch로 checkout
git merge main // feature <- main 으로 merge하는 셈
step 3. conflict 난 부분에서 필요한 메서드, 변수들과 파일의 흐름을 확인해가면서 merge 과정을 진행
Intellij의 경우, 아래의 그림처럼 한 가지 파일에 대해
target branch, 현재 file(merge 후 완성될 파일), 대상 branch 이 셋을 비교해가면서 보여주고,
동시에 현재 파일에서 merge 후 빠트린 파일이 있다면 이 또한 확인해준다.
IDE를 사용한다면 이전, 현재, 타겟 브랜치의 변경 사항을 각기 다른 색상으로 표시하여 비교하기 쉽게 도와준다.
또한, import가 되지 않거나 변수 정의가 빠진 부분이 있어 complie 상에서 문제가 되는 catched exception을 표시해주기에
human error를 최소화 할 수 있다.
conflict가 난 파일들을 모두 resolve 한 뒤에 다음 step을 진행한다.
step 4. 변경 사항들을 모두 추가 한 후 임시로 merge를 진행한다.
git add . // 변경 사항이 있는 파일 모두 추가
git commit -m "Temp: 변경 사항 저장을 위한 임시 commit"
혹은 한번에 다음과 같이 해도 된다.
git commit -am "Temp: 변경 사항 저장을 위한 임시 commit"
step 5. merge commit 만을 reset해서 취소한다.
git reset --soft HEAD~1
위 명령은 방금 업데이트 한 commit의 파일의 변경 사항은 유지하면서
commit만을 취소하는 reset을 적용하는 명령이다.
reset의 옵션을 이해하기 위한 약간의 git 관련 지식
git의 파일 구조를 다시 한 번 떠올려보자. (이전 글을 참고하길 바란다.)
git은 blob, tree, commit 이 세 가지 자료로 구성되어 있고,
git reset은 blob, tree, commit 이 세 가지를 이전의 HEAD, 즉, 이전 commit의 상태로 돌리는 것은 --hard 옵션이다.
반면 --soft 옵션은 commit만을 없애서 blob, tree는 유지한다. 다시 말해 변경 사항을 유지하는 것이다.
Q) 왜 commit을 한 다음에 일부러 merge의 commit만을 취소하는가?
그냥 git add . 을 통해서 변경 사항만을 추가 하고 git merge --abort를 통해서 merge만을 취소하면?
➡️ 좋은 의견이지만 그렇게 되지가 않는다.
git merge를 진행할 경우, 해당하는 merge라는 작업은 feature|merge 라는 임시 merge 단계를 형성한다.
git add . 을 통해서 변경 사항을 추가했을 때, abort를 통해서 merge 과정을 중지한다면 이것이 사라진다.
더해진 변경 사항 또한 merge과정을 진행하는 (feature|merge)라는 임시 단계에서 진행된 변경사항이기 때문에
이를 취소할 경우, 이 임시 단계에서 형성된 과정 또한 feature branch에 적용이 되지 않는 것이다.
Q) abort를 사용할 때, IDE의 힘을 빌린다면 Local History와 같이 파일이 변경된 이력을 tracking해서 롤백하는 방법도 가능하지 않을까? merge를 통한 변경 사항이 생성 된 다음에 abort 했다면 이 또한 파일 변경 이력으로 history에 남아 있을 텐데?
➡️ 이 방법은 실제로 가능하다. 그런데 의외로 이 방식을 통해 완벽하게 변경 사항이 적용된 파일로 롤백하는게 쉽지않다.
Intellij에서 git merge --abort 옵션을 통해 변경사항이 취소될 경우, 해당 변경사항은 Intellij의 외부 변화,
즉 External Change로 기록이 되는데,
이 외부 변화는 여러 번 발생하여, 각 변화의 원인을 구분하고 원하는 최종 결과물로 롤백하기가 쉽지 않다
이렇게 하면 조금 더 효과적으로 merge할 때 생기는 conflict에 대한 대처가 가능하다.
다만 이래도 여전히 사소한 변화에서 conflict가 나는 것들이 있다.
그렇지만 이전에 github에서 제공하는 인터페이스와 코드 편집으로 진행하는 것보다는
변경사항도 훨씬 적어지고, 간편하다.
'Trouble Shooting > episode 2. Git' 카테고리의 다른 글
Git (2). VScode에서 "변경 내용 취소"로 삭제된 파일 복구 (2) | 2024.09.25 |
---|---|
Git (1). main branch의 설정을 각 개발자의 feature branch에 적용 (1) | 2024.09.20 |