1. Git Merge

Git Merge는 현재 위치한 버전에 다른 버전을 병합하는 작업이다.

  • Branch를 병합할때 사용한다.
  • Push, Pull 할때 병합이 일어난다.
git merge <branch_name>

1.1 Main Branch에서 Dev Branch를 Merge

git merge dev

Merge Commit 결과

Main branch에서 dev branch로 merge하는 경우는 다음과 같다.

  • dev branch에 대해서 작업을 하다가 작업 결과가 잘 나와서 main과 merge를 하고 dev branch 작업을 종료하는 경우. 이때 해당 branch를 삭제하는 경우가 있다.

1.2 Dev Branch에서 Main Branch를 Merge

git checkout dev
git merge main

Merge Commit 결과

dev branch에서 main branch로 merge하는 경우는 다음과 같다.

  • 내가 C2 시점에서 branch에 대해서 작업을 하고 있었는데 main에서 계속 갱신되는 부분들에 대해서 계속 공유를 받아야할 경우. 개발 중 개발 싱크를 맞춰야할 때 해당한다.

1.3 Main Branch 변경 사항이 없을 때 Dev Branch를 Merge

git merge dev

이 경우는 main은 갱신이 없고 dev만 갱신을 한 상태로 dev만 버전이 하나 더 증가를 한 상태이다.

Merge Commit 결과

C2에서 C4로 갱신된 버전이 합쳐도 C4 그대로이기 때문에 main이 C4를 가리키는 동작으로만 종료가 된다. 새로운 merge 버전은 생기지 않는다.

1.4 Dev Branch 변경 사항이 없을 때 Main Branch를 Merge

이 경우는 C2에서 dev branch를 생성하고 dev는 버전을 갱신한 상태이고 dev에서 main을 땡겨오겠다는 말이다. 따라서 HEAD를 dev로 옮겨야한다.

git checkout dev
git merge main

Merge Commit 결과

Main과 dev를 merge하면 버전 차이가 없어서 아무일도 일어나지 않는다.

2. Conflict

Conflict는 두 branch에서 같은 버전의 같은 부분을 수정하는 경우, Auto Merge가 불가능한 상황에서 발생한다.

따라서 merge 중 conflict가 발생하면 개발자가 직접 해결해야 한다.

Auto Merge가 불가능한 상황은 다음과 같다.

  • 같은 버전에서 두 개발자가 같은 파일의 같은 부분을 수정할 시 누가 만든지 판단할 수 있는 기준이 없다. 따라서 개발자들끼리 서로 협의를 하여 좀 더 나은 코드가 뭔지를 결정하여 적용해야하는 문제이지 논리로 판단할 수 있는 문제가 아니다. 따라서 판단 기준이 없는 상황에서는 git은 auto merge를 하지않고 conflict를 발생시킨다.

2.1 Conflict가 발생한 파일

<<<<<<<< HEAD
print("Hello, Irene!")
=======
print("Hello, Yeji!")
>>>>>>>> HEAD
  • Conflict message와 git status로 파악할 수 있다.
  • Merge 과정에서 충돌 발생시 가운데 =======를 기준으로 위/아래로 충돌 부분을 보여주는데 이를 기준으로 코드 수정이 필요하다.

2.2 Conflict 해결

Conflict가 발생한 부분이 여러군데일 수 있다.

1) 파일 수정

print("Hello, Irene!")

2) Git Add

git add <conflict_file_name>

3) Git Commit

git commit -m <merge_message>
  • Git commit까지 완려되면 conflict 상태가 해지되어 merge가 가능하다.
  • 참고로, git commit이 실패하는 경우 'git commit -i'로 강제 commit 할 수 있다.
  • Merge도 완료된다.

2.3 Push/Pull 중 Conflict 발생

Push 동작 중 conflict 상황이 발생하면,

  • Push가 실패한다.
  • Pull을 해서 conflict 에러를 확일 할 수 있다.
    remote 서버꺼를 local 서버로 pull 해서 local 서버에서 conflict를 해결한 다음에 다시 push를 하면 가능해진다.

Pull 동작 중 conflict 상황이 발생하면,

  • Fetch만 되고 merge가 실패한 conflict 상태가 된다.
  • Conflict를 해결하면 merge commit이 완료된다.

TIP

따라서 해당 conflict 발생을 줄이려면 remote 서버랑 연동을 할 때 push를 해야되는 상황에서 바로 push를 하지말고 항상 업데이트 된게 있는지 local 서버로 pull 먼저 하고 push하는 습관을 가지면 좋다.

3. Branch를 Merge

3.1 GitHub에서 Remote 저장소 생성

1) GitHub 로그인
2) New 버튼 클릭
3) Repository name 입력
4) Private 선택
5) Add a README file 선택
6) Create repository 버튼 클릭
7) < > Code 클릭
8) HTTPS 주소 복사

https://github.com/yeji4175/merge_project.git

3.2 Local 저장소로 복제 (Git Clone)

1) Terminal 실행
2) Query 입력

git_ws % git clone https://https://github.com/yeji4175/merge_project.git

git_ws % cd merge_project
merge_project % ls

3.3 Dev Branch 생성

merge_project % git log --oneline

merge_project % git branch dev
merge_project % git log --oneline

3.4 Main Branch에 파일 추가

merge_project % touch main.py
merge_project % git add main.py
merge_project % git commit -m "add main.py"

merge_project % git log --oneline

3.5 Dev Branch에 파일 추가

merge_project % git checkout dev

merge_project % touch dev.py
merge_project % git add dev.py
merge_project % git commit -m "add dev.py"

merge_project % git log --oneline

3.6 각 Branch에 파일 존재 확인

merge_project % ls

merge_project % git checkout main

merge_project % ls

3.7 Main Branch에서 Dev Branch를 Merge

merge_project % git branch

merge_project % git merge dev #main에 dev를 병합

merge_project % git log --oneline

merge를 하면 빈 VSCode가 열리는데 아무것도 작성을 안하고 닫아버리면 git log --oneline을 썼을 때 자동으로 Merge branch 'dev' 메시지가 작성이 된다.

3.8 각 Branch 상태 확인

merge_project % ls

merge_project % git checkout dev

merge_project % ls

merge_project % git log --oneline

4. Remote Branch를 Merge

4.1 Local 저장소를 Push

merge_project % git checkout main
merge_project % git branch

merge_project % status

merge_project % git push origin main

4.2 GitHub의 Remote 저장소 확인

GitHub의 merge_project를 새로고침하면 원격의 main branch가 local 저장소와 merge가 된걸 확인할 수 있다.

4.3 Dev Branch를 Push

merge_project % git checkout dev
merge_project % git branch

merge_project % git status

merge_project % git push origin dev

4.4 GitHub의 Remote 저장소 다시 확인

GitHub의 merge_project에서 dev branch가 추가가 된걸 확인할 수 있다. 또한 2개의 commits으로 dev의 local과 같은 상태인걸 확인할 수 있다.

4.5 GitHub에서 New Branch 생성

다른 사람이 remote repository에 branch를 생성해서 올렸다라는 상황이다.

1) main의 오른쪽 branch 클릭
2) New branch 클릭
3) Create a branch 팝업창에서 New branch name 입력
4) Source 선택
5) Create new branch 버튼 클릭

4.6 Dev2 Branch에서 파일 추가

dev2가 생긴걸 확인할 수 있다.

main과 똑같이 4개의 commits을 확인할 수 있다.

1) Add file + 버튼에서 Create new file 클릭
2) 파일 이름 입력
3) 파일 내용 편집
4) Commit changes 버튼 클릭
5) Commit message 입력
6) Commit changes 버튼 클릭

위의 새로운 파일을 만드는 동작은 local 서버에서 새로운 파일을 만드는 동작과 똑같은 동작을 remote에서 하는거다.

4.7 Local 저장소에는 Dev2 Branch가 없다

merge_project % git checkout main

merge_project % git branch -a

위의 이미지에서 보면 dev2의 폴더는 찾아볼수가 없다. 그 이유는 remote에서는 버전이 변경이 되었지만 remote꺼를 pull 해오지 않아서 remote 서버와 local 서버가 동기화가 안되어 있어서 local 서버는 dev2가 있는지 모르는 상태이다.

4.8 Git Fetch

Git fetch를 서버의 정보가 다운로드가 되고 merge가 되지는 않는다.

merge_project % git fetch

merge_project % git branch -a

remote 서버에 dev2가 있는거지 local 서버에는 아직 dev 폴더가 없는걸 확인 할 수 있다.

4.9 Main Branch에 Dev2 Branch를 Merge

merge_project % git merge origin/dev2

merge_project % ls

merge_project % git log --oneline

dev2 파일이 추가가 된걸 확인할 수 있다.

5. Conflict 체험

5.1 main.py 수정

merge_project % git branch

merge_project % cat > main.py
print("Hello, world")
merge_project % git commit -a -m "Hello, world"

merge_project % git log --oneline -1

5.2 Dev3 Branch 생성 후 파일 수정

merge_project % git branch dev3
merge_project % git branch

merge_project %  cat > main.py
print("Hello, people")
merge_project % git commit -a -m "Hello, people"

merge_project % git log --oneline -2

5.3 Dev3 Branch 파일 수정

merge_project %  git checkout dev3

merge_project % cat > main.py
print("Hello, everyone")
merge_project % git commit -a -m "Hello, everyone"

merge_project % git log --oneline -2

5.4 Main Branch에서 Merge 시도

merge_project % git checkout main

merge_project % git branch

merge_project % git merge dev3

CONFLICT message를 확인할 수 있다.

5.5 Conflict 파일 수정 및 해결

merge_project % cat main.py

merge_project % cat > main.py
print("Hello, people")
merge_project % git commit -a -m "resoved conflict"

merge_project % git log --oneline -4

profile
거북선통통통통

0개의 댓글