20250721 - 학습일지

창훈·2025년 7월 22일

Git에서 rebase와 merge는 브랜치를 통합하는 두 가지 주요 방법입니다. merge는 기존 브랜치 히스토리를 유지하면서 두 브랜치를 합치는 반면, rebase는 한 브랜치의 base(시작점)를 다른 브랜치의 최신 커밋으로 이동시켜 히스토리를 재작성합니다. 두 방법 모두 장단점이 있으며, 사용 목적에 따라 적절한 방법을 선택해야 합니다.

1. Merge (병합):

개념:

현재 브랜치와 다른 브랜치를 합쳐 새로운 커밋을 생성합니다. 두 브랜치의 히스토리를 모두 유지하며, 마치 두 선로가 합쳐지는 것처럼 병합된 브랜치의 커밋 기록을 볼 수 있습니다.

예시:

bugFix 브랜치에서 작업하던 내용을 main 브랜치에 합치고 싶을 때, git merge bugFix 명령어를 사용합니다.
main 브랜치에는 bugFix 브랜치의 작업 내용이 추가되고, bugFix 브랜치의 커밋 기록도 함께 유지됩니다.

장점:

히스토리가 명확하게 남습니다. 어떤 커밋이 언제 병합되었는지 쉽게 파악할 수 있습니다.
충돌 발생 시, 병합 과정에서 충돌 해결을 위한 정보를 제공합니다.

단점:

불필요한 커밋들이 많이 생길 수 있다.


picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git init
Reinitialized existing Git repository in C:/workplace/git_example/.git/

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ touch 0 && git add . && git commit -m "C0"
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git checkout bugFix
error: pathspec 'bugFix' did not match any file(s) known to git

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git checkout -b bugFix
Switched to a new branch 'bugFix'

picto@milton-friedman MINGW64 /c/workplace/git_example (bugFix)
$ touch 1 && git add . && git commit -m "C1"
[bugFix 8e5e08c] C1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 1

picto@milton-friedman MINGW64 /c/workplace/git_example (bugFix)
$ touch 2 && git add . && git commit -m "C2"
[bugFix 137146c] C2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 2

picto@milton-friedman MINGW64 /c/workplace/git_example (bugFix)
$ touch 3 && git add . && git commit -m "C3"
[bugFix 4c0b172] C3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 3

picto@milton-friedman MINGW64 /c/workplace/git_example (bugFix)
$ git checkout main
error: pathspec 'main' did not match any file(s) known to git

picto@milton-friedman MINGW64 /c/workplace/git_example (bugFix)
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 5 commits.
  (use "git push" to publish your local commits)

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ touch 4 && git add . && git commit -m "C4"
[master 6571255] C4
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 4

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ touch 5 && git add . && git commit -m "C5"
[master 52801cf] C5
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 5

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ touch 6 && git add . && git commit -m "C6"
[master 9b7db6d] C6
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 6

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git log --oneline --graph
* 9b7db6d (HEAD -> master) C6
* 52801cf C5
* 6571255 C4
* 587cd6d C0
* 72d3277 c1
* d0f9a05 c0
* 2ae1f2d C3
* 4ec1d2c C2
* 40b9ae3 (origin/master, origin/HEAD) C

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git log --oneline --graph --all
* 9b7db6d (HEAD -> master) C6
* 52801cf C5
* 6571255 C4
| * 4c0b172 (bugFix) C3
| * 137146c C2
| * 8e5e08c C1
|/
* 587cd6d C0
* 72d3277 c1
* d0f9a05 c0
* 2ae1f2d C3
* 4ec1d2c C2
* 40b9ae3 (origin/master, origin/HEAD) C

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git rebase bugFix master
Successfully rebased and updated refs/heads/master.

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$ git log --oneline --graph --all
* ebf4a01 (HEAD -> master) C6
* d9d6344 C5
* a51d81e C4
* 4c0b172 (bugFix) C3
* 137146c C2
* 8e5e08c C1
* 587cd6d C0
* 72d3277 c1
* d0f9a05 c0
* 2ae1f2d C3
* 4ec1d2c C2
* 40b9ae3 (origin/master, origin/HEAD) C

picto@milton-friedman MINGW64 /c/workplace/git_example (master)
$

2. Rebase (베이스 이동):

개념:

현재 브랜치의 base를 다른 브랜치의 최신 커밋으로 이동시킵니다. 마치 두 선로가 합쳐지는 대신 한 선로가 다른 선로의 끝에서 다시 시작하는 것처럼, 히스토리가 재작성됩니다.

예시:

bugFix 브랜치에서 작업하던 내용을 main 브랜치에 합치고 싶을 때, git rebase main 명령어를 사용합니다.
bugFix 브랜치의 base가 main 브랜치의 최신 커밋으로 이동하고, bugFix 브랜치의 커밋들은 main 브랜치의 최신 커밋 이후에 추가됩니다.

장점:

히스토리가 깔끔하게 정리됩니다. 병합으로 인해 발생하는 불필요한 커밋을 줄일 수 있습니다.
선형적인 히스토리를 유지할 수 있습니다.
단점:
히스토리가 변경됩니다. 기존 커밋이 변경되기 때문에, 다른 개발자와 공유된 브랜치에서 rebase를 사용하는 것은 위험할 수 있습니다.
충돌 해결이 복잡할 수 있습니다. 특히 여러 커밋에서 충돌이 발생하면 해결하기 어려울 수 있습니다.

주의사항:

Rebase는 이미 공유된 커밋에 대해서는 사용하지 않는 것이 좋습니다. 이미 다른 사람들과 공유된 커밋에 대해 rebase를 사용하면, 다른 사람들의 작업 내용과 충돌이 발생하고 혼란을 야기할 수 있습니다.
Rebase는 로컬에서만 사용하고, 공유 브랜치에는 push하기 전에 다시 한번 신중하게 고려해야 합니다.
Rebase는 merge에 비해 위험하지만, 잘 사용하면 히스토리를 더욱 깔끔하게 관리할 수 있습니다.

결론:

merge는 안전하고 히스토리를 명확하게 유지하는 반면, rebase는 히스토리를 깔끔하게 정리할 수 있지만 공유된 커밋에 사용 시 주의해야 합니다. 각 명령어의 장단점을 이해하고, 프로젝트의 상황에 맞게 적절한 방법을 선택하는 것이 중요합니다.

충돌 해결:

텍스트 편집기를 사용하여 충돌이 발생한 파일을 열고, <<<<<<<, =======, >>>>>>> 기호들을 제거합니다.
두 브랜치의 변경 내용을 비교하고, 원하는 내용으로 수정한 후, 하나의 내용으로 만듭니다.
수정된 파일을 저장합니다.

최종 수정 사항 결정:

각 브랜치의 변경 사항을 검토하여 최종적으로 어떤 내용을 반영할지 결정합니다.
필요한 경우, 두 브랜치의 변경 사항을 모두 반영하거나, 한쪽의 변경 사항만 반영할 수 있습니다.
충돌 부분을 직접 수정하여 원하는 내용을 반영할 수도 있습니다.

충돌 해결 및 커밋:

충돌 부분을 수정한 후, git add <충돌 파일> 명령어를 사용하여 수정 사항을 스테이지에 추가합니다.
git commit 명령어를 사용하여 충돌을 해결한 변경 사항을 커밋합니다.

추가적으로 알아두면 좋은 내용:

git mergetool: 충돌 해결을 위한 GUI 도구를 사용할 수 있습니다.
git checkout --ours <파일>: 현재 브랜치의 변경 사항만 유지합니다.
git checkout --theirs <파일>: 병합하려는 브랜치의 변경 사항만 유지합니다.
git merge --abort: 병합을 취소하고 이전 상태로 되돌립니다.

충돌 해결 후:

git add <파일 이름> 명령어를 사용하여 수정한 파일을 스테이징 영역에 추가합니다.
git commit 명령어를 사용하여 커밋합니다.
필요하다면 git push 명령어를 사용하여 원격 저장소에 변경 사항을 반영합니다.
추가 팁:
git diff 명령어를 사용하여 특정 브랜치와 현재 브랜치 간의 차이점을 확인할 수 있습니다.
git checkout -- <파일 이름> 명령어를 사용하여 특정 파일의 변경 내용을 이전 상태로 되돌릴 수 있습니다.
git merge --abort 명령어를 사용하여 병합을 취소하고 이전 상태로 되돌릴 수 있습니다.

profile
한줄소개불가

0개의 댓글