-
[git] cherry-pick와 merge 및 rebase를 활용한 commit 내역 관리git 2024. 5. 26. 22:13반응형
1. cherry pick 란?
git docs를 찾아보면 cherry pick에 대해 Apply the changes introduced by some existing commits 라고 한다.
docs description을 보면 무슨 말인지 더 헷갈리는 것 같다..
업무에서 사용해보고 따로 공부해보면서 이해한 바로는 A브랜치로 B브랜치의 commit을 복사해주는 기능이다.
예를 들어 feature/a나 feature/b의 commit 내역을 골라서 develop 브랜치에 적용해야하는 경우 사용한다.
cf. 따로 테스트하면서 유용한 git 명령어 옵션들로는 --continue와 --abort가 있었다.
1-1. cherry pick 사용하기
C:\DEV\git_test>git checkout develop
이 상황에서 feature/b1에 대한 커밋(033623a)을 develop 브랜치에 적용시켜보자.
# git cherry-pick <target commit hash> C:\DEV\git_test>git cherry-pick 033623a
* conflict가 발생할 수도 있다.
Auto-merging main.py
CONFLICT (content): Merge conflict in main.py
error: could not apply 033623a... feauture/b1
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".conflict를 해결하고 아래 명령어들을 실행한다.
C:\DEV\git_test>git add . C:\DEV\git_test>git cherry-pick --continue
그럼 터미널에서 Vim 편집기가 켜진다.
feauture/b1 # Conflicts: # main.py # # It looks like you may be committing a cherry-pick. # If this is not correct, please run # git update-ref -d CHERRY_PICK_HEAD # and try again. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Mon May 27 01:13:33 2024 +0000 # # On branch develop # Your branch is up to date with 'origin/develop'. # # You are currently cherry-picking commit 033623a. # # Changes to be committed: # modified: main.py # ~ ~ ~ .git/COMMIT_EDITMSG [unix] (11:57 27/05/2024) 1,1 All "/c/DEV/git_test/.git/COMMIT_EDITMSG" [unix] 24L, 544B
commit message를 변경하지 않을 거라면, :wq를 입력해서 Vim 편집기를 빠져나온다.
C:\DEV\git_test>git push
2. merge 사용하기
이 상황에서 develop 브랜치에 feature/b 브랜치를 merge한다면 어떻게 될까?
C:\DEV\git_test>git checkout develop
C:\DEV\git_test>git merge feature/b
cf. conflict가 난다면 해결한다.
C:\DEV\git_test>git add . C:\DEV\git_test>git merge --continue
그럼 터미널에서 Vim 편집기가 켜진다.
Merge branch 'feature/b' into develop # Conflicts: # main.py # # It looks like you may be committing a merge. # If this is not correct, please run # git update-ref -d MERGE_HEAD # and try again. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch develop # Your branch is up to date with 'origin/develop'. # # All conflicts fixed but you are still merging. # # Changes to be committed: # modified: main.py # ~ ~ ~ ~ ~ .git/COMMIT_EDITMSG [unix] (12:13 27/05/2024) 1,1 All "/c/DEV/git_test/.git/COMMIT_EDITMSG" [unix] 22L, 510B
commit message를 변경하지 않을 거라면, :wq를 입력해서 Vim 편집기를 빠져나온다.
C:\DEV\git_test>git push
3. rebase 란?
이번 실험을 통해서도 merge 말고 rebase를 써야할 이유를 못 찾았다..
관련 개념적 이해뿐만 아니라 어느 상황에 써야 merge보다 더 좋은지 모르겠으니 해당 개념은 여기를 참고하자.
docs에서 제일 중요한 부분을 가져오자면,
Rebase 의 위험성
Rebase가 장점이 많은 기능이지만 단점이 없는 것은 아니니 조심해야 한다.
그 주의사항은 아래 한 문장으로 표현할 수 있다.
이미 공개 저장소에 Push 한 커밋을 Rebase 하지 마라
이 지침만 지키면 Rebase를 하는 데 문제 될 게 없다.
하지만, 이 주의사항을 지키지 않으면 사람들에게 욕을 먹을 것이다.
Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 같지만 다른 커밋을 새로 만든다.
새 커밋을 서버에 Push 하고 동료 중 누군가가 그 커밋을 Pull 해서 작업을 한다고 하자.
그런데 그 커밋을 git rebase 로 바꿔서 Push 해버리면 동료가 다시 Push 했을 때 동료는 다시 Merge 해야 한다.
그리고 동료가 다시 Merge 한 내용을 Pull 하면 내 코드는 정말 엉망이 된다.위험성에 대해 읽어보면 협업하는 프로젝트에선 rebase보단 merge를 사용하는 게 더 좋을 것 같다..
3-1. rebase 사용하기
feature/b 브랜치를 재활용할 경우 head를 위로 올릴 필요 있다.
이때 rebase를 이용한다.
C:\DEV\git_test>git checkout feature/b
# git rebase <target branch> C:\DEV\git_test>git rebase develop
C:\DEV\git_test>git push
4. feature/a 브랜치 merge? rebase? 실험
해당 브랜치도 위와 같은 방법으로 merge 후 rebase하면 된다.
실험삼아 rebase를 해보려고 했지만 commit내역마다 conflict를 해소해줘야하고 복잡해지는 것 같았다.
이런 경우에는 merge 후 rebase를 통해 HEAD를 끌어 올리는거나 merge로만 해결하는 게 제일 깔끔한 것 같다.
728x90'git' 카테고리의 다른 글
[gitlab, git] git mirror하기 (다른 repo 소스코드 gitlab에 옮기기) (0) 2023.06.12 [git] branch 확인 및 가져오기, 생성 후 Remote Repository에 push하기 (0) 2023.01.15 [git] 원격저장소(Remote Repository)에 이미 push한 commit 삭제하기 (0) 2022.12.22