>  기사  >  개발 도구  >  Git 학습: git merge 명령 이해

Git 학습: git merge 명령 이해

青灯夜游
青灯夜游앞으로
2022-03-18 19:48:593478검색

이 기사에서는 Git 브랜치에 대해 설명하고 브랜치 사용을 위한 Git Merge 명령을 소개합니다. 도움이 되길 바랍니다.

Git 학습: git merge 명령 이해

Git에서 병합은 분기된 커밋 기록을 다시 합치는 방법입니다. git merge 명령은 이전에 git Branch 명령을 사용하여 생성한 브랜치와 이 브랜치에서 독립적으로 개발된 콘텐츠를 하나의 브랜치로 통합하는 데 사용됩니다. git merge命令用来将你之前使用git branch命令创建的分支以及在此分支上独立开发的内容整合为一个分支。

请注意下面的所有命令都会是将其他分支合并到当前所在工作分支上。当前工作分支的内容会由于merge操作产生更新,但是目标分支则完全不受影响。再次强调,这意味着git merge通常与其他几个git命令一起使用,包括使用git checkout命令来选择当前工作分支,以及使用git branch -d命令来删除已经合并过的废弃分支。

它是如何运行的

git merge会将多个提交序列合并进一个统一的提交历史。在最常见的使用场景中,git merge被用来合并两个分支。在本文档接下来的部分,我们会专注于这种合并场景。在这种场景中,git merge接受两个commit指针,通常是两个分支的顶部commit,然后向前追溯到这两个分支最近的一个共同提交。一旦找到这个共同提交,Git就会创建一个新的"merge commit",用来合并两个分支上各自的提交序列。

比如说我们有一个功能分支由main分支派生出来,现在我们希望将这个功能分支合并回main分支。

Git 학습: git merge 명령 이해

执行合并命令会将指定分支合并到当前工作分支上,我们假设当前工作分支为main。Git根据两个分支自行决定合并提交的算法(将在下面具体讨论)。

Git 학습: git merge 명령 이해

合并commit与普通commit不一样,因为合并commit会有两个父提交。创建一个合并commit时Git会尝试自动将两个独立的提交历史合并为一个。不过当Git发现某一块数据在两边的提交历史中都含有变更,它将无法自动对其进行合并。这种情况被称为版本冲突,此时Git需要人为介入调整才能继续进行合并。

准备合并

在实际进行合并操作之前,需要进行一些准备步骤,以保证合并过程能够顺利进行。

确认接收合并的分支

执行git status命令查看当前分支的状态,确保HEAD指正指向的是正确的接收合并的分支。如果不是,执行git checkout命令切换到正确的分支。在我们的示例中,执行git checkout main

获取最新的远程提交

确保合并操作涉及的两个分支都更新到远程仓库的最新状态。执行git fetch拉取远程仓库的最新提交。一旦fetch操作完成,为了保证main分支与远程分支同步,还需执行git pull命令。

合并

当上面提及的准备工作都已完备,合并就可以正式开始了。执行git merge <branch></branch>命令,其中为需要合并到当前分支的目标分支名称。

快进合并

当前工作分支到合并目标分支之间的提交历史是线性路径时,可以进行快进合并。在这种情况下,不需要真实的合并两个分支,Git只需要把当前分支的顶端指针移动到目标分支的顶端就可以了(也就是快进的意思)。在这种情况下快进合并成功的将提交历史合并至一处,毕竟目标分支中的提交此时都包含在当前分支的提交历史中了。对于将功能分支快进合并到main

아래의 모든 명령은 다른 분기를 현재 작업 분기로 병합합니다. 현재 작업 브랜치의 내용은 병합 작업으로 인해 업데이트되지만 대상 브랜치는 전혀 영향을 받지 않습니다. 이는 git merge가 일반적으로 git checkout 명령을 사용하여 현재 작업 분기를 선택하고 git를 선택하는 등 여러 다른 git 명령과 함께 사용된다는 것을 의미합니다. Branch -d 명령은 병합된 버려진 브랜치를 삭제합니다.

작동 방식

Git 학습: git merge 명령 이해git merge는 여러 커밋 시퀀스를 통합된 커밋 기록으로 병합합니다. 가장 일반적인 사용 시나리오에서 git merge는 두 개의 분기를 병합하는 데 사용됩니다. 이 문서의 나머지 부분에서는 이 병합 시나리오에 중점을 둘 것입니다. 이 시나리오에서 git merge는 일반적으로 두 분기의 최상위 커밋인 두 개의 커밋 포인터를 수락한 다음 두 분기의 가장 최근 공통 커밋을 추적합니다. 이 공통 커밋이 발견되면 Git은 두 분기의 각 커밋 시퀀스를 병합하는 새로운 "병합 커밋"을 생성합니다.

예를 들어 main 분기에서 파생된 기능 분기가 있고 이제 이 기능 분기를 main 분기에 다시 병합하려고 합니다.

Git 학습: git merge 명령 이해Git 학습: git merge 명령 이해

실행 merge 명령은 지정된 분기를 현재 작업 분기로 병합합니다. 현재 작업 분기가 main이라고 가정합니다. Git은 두 브랜치를 기반으로 커밋을 병합하기 위한 자체 알고리즘을 결정합니다(자세한 내용은 아래에서 설명). 🎜🎜Git 학습: git merge 명령 이해🎜🎜병합 커밋은 병합 커밋에 두 개의 상위 커밋이 있기 때문에 일반 커밋과 다릅니다. 병합 커밋을 생성하면 Git은 두 개의 개별 커밋 기록을 하나로 자동 병합하려고 시도합니다. 그러나 Git이 특정 데이터 조각에 양측의 커밋 기록에 변경 사항이 포함되어 있음을 발견하면 자동으로 병합할 수 없습니다. 이 상황을 버전 충돌이라고 합니다. 이때 Git에서는 병합을 계속하려면 수동 개입이 필요합니다. 🎜

병합 준비

🎜실제 병합 작업에 앞서 병합 프로세스가 원활하게 진행될 수 있도록 몇 가지 준비 단계를 수행해야 합니다. 🎜

병합된 브랜치 수신 확인

🎜 git status 명령을 실행하여 현재 브랜치의 상태를 확인하고 >HEAD는 병합을 수신할 올바른 분기를 가리키도록 수정합니다. 그렇지 않은 경우 git checkout 명령을 실행하여 올바른 분기로 전환하세요. 이 예에서는 git checkout main을 실행합니다. 🎜

최신 원격 커밋 가져오기

🎜병합 작업에 관련된 두 브랜치가 모두 원격 저장소의 최신 상태로 업데이트되었는지 확인하세요. git fetch를 실행하여 원격 웨어하우스에서 최신 커밋을 가져옵니다. 가져오기 작업이 완료되면 main 브랜치가 원격 브랜치와 동기화되었는지 확인하기 위해 git pull 명령을 실행해야 합니다. 🎜

병합

🎜위의 준비가 완료되면 공식적으로 합병이 시작됩니다. git merge <branch></branch> 명령을 실행합니다. 여기서 는 현재 브랜치에 병합해야 하는 대상 브랜치의 이름입니다. 🎜

Fast-forward 병합

🎜현재 작업 중인 브랜치와 병합 대상 브랜치 간의 제출 내역이 선형 경로인 경우 Fast-forward 병합을 수행할 수 있습니다. 이 경우 실제로 두 브랜치를 병합할 필요는 없으며 Git은 현재 브랜치의 최상위 포인터를 대상 브랜치의 맨 위로 이동하기만 하면 됩니다(즉, 빨리 감기). 이 경우 빨리 감기 병합은 커밋 기록을 한 곳에 성공적으로 병합합니다. 결국 대상 브랜치의 커밋은 이제 현재 브랜치의 커밋 기록에 포함됩니다. Feature 브랜치를 main 브랜치로 fast-forward 병합하는 과정은 아래 그림을 참고하세요: 🎜🎜🎜🎜🎜단, 두 브랜치가 분기된 경우 fast-forward 병합은 허용되지 않습니다. . 현재 브랜치에 대한 대상 브랜치의 커밋 기록이 선형이 아닌 경우 Git은 3방향 병합 알고리즘을 통해 두 브랜치를 병합하는 방법만 결정할 수 있습니다. 3방향 병합 알고리즘에서는 양측의 커밋 기록을 통합하기 위해 전용 커밋을 사용해야 합니다. 이 용어는 Git이 병합 커밋을 생성하려면 세 가지 커밋, 즉 두 브랜치의 최상위 커밋과 공통 조상 커밋을 사용해야 한다는 사실에서 유래되었습니다. 🎜🎜🎜🎜

실제로 이러한 다양한 병합 전략을 사용할 수 있는 옵션이 있지만 대부분의 개발자는 특히 소규모 기능 개발이나 버그 수정의 경우 빨리 감기 병합을 선호합니다. 반대로 기능 분기의 경우, 3방향 병합을 사용할 가능성이 더 높습니다. 두 번째 시나리오에서는 병합으로 생성된 병합 커밋이 두 분기의 병합 표시로 커밋 기록에 유지됩니다. 다음으로 아래 첫 번째 예를 사용하여 빨리 감기 병합을 수행하는 방법을 보여줍니다. 다음 명령은 먼저 새 분기를 만들고 새 분기에 두 개의 커밋을 만든 다음 빠른 병합을 사용하여 새 분기를 main 분기에 다시 병합합니다.

# Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout main
git merge new-feature
git branch -d new-feature

이 예의 워크플로는 일반적으로 단기 기능 개발에 사용됩니다. 이 개발 프로세스는 상대적으로 독립적인 개발 프로세스로 간주되며 조정 및 관리가 필요한 장기 기능 개발 분기에 해당합니다. main分支。

git merge --no-ff <branch>

这个例子中的工作流程通常用于短期功能的开发,这种开发流程更多地被当做是比较独立的一次开发流程,与之对应的则是需要协调和管理的长期功能开发分支。

另外还需注意到,在此例中Git不会对git branch -d命令发出警告,因为new-feature的内容已经合并到主分支里了。

在某些情况下,虽然目标分支的提交历史相对于当前分支是线性的,可以进行快进合并,但你仍然希望有一个合并commit来标志合并在此commit发生过,那么可以在执行git merge命令时使用--no-ff选项。

Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the main branch
git checkout main
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to main"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature

以上命令将指定分支合并到当前分支,但总会生成一个合并commit(即便这一合并操作可以快进)。当你需要在仓库的提交历史中标记合并事件时这一命令相当有用。

三路合并

接下来的例子与上面比较像,但是因为main分支在feature分支向前发展的过程中,自身也发生的改变,因此在合并时需要进行三路合并。在进行大的功能开发或者有多个开发者同时进行开发时这种场景相当常见。

On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

需注意在这种情况下,由于没有办法直接把main的顶端指针移动到new-feature分支上,因此Git无法执行快进合并。

在大多数实际工作场景中,new-feature应该是一个很大的功能,开发过程持续了相当长的时间,这也就难免同时期在main分支上也有新的提交。如果你的功能分支大小像上面的例子一样小,则完全可以使用rebase将new-feature分支变基到main分支上,然后再执行一次快进合并。这样也会避免在项目提交历史中产生过多的冗余。

解决冲突

如果将要合并的两个分支都修改了同一个而文件的同一个部分内容,Git就无法确定应该使用哪个版本的内容。当这种情况发生时,合并过程会停止在合并commit提交之前,以便给用户留下机会手动修复这些冲突。

在Git的合并过程中,很棒的一点是它使用人们熟知的 编辑 / 暂存 / 提交 这样的工作流程来解决冲突。当碰到合并冲突时,执行git status命令会列出哪些文件含有冲突并需要手动解决。比如说当两个分支都修改了hello.py文件的同一部分,你会看到类似下面这样的信息:

here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch;

冲突是如何显示的

当Git在合并过程中碰到了冲突,它会编辑受影响的文件中的相关内容,并添加视觉标记用以展示冲突中双方在此部分的不同内容。这些视觉标记为:>>>>>>。要找到冲突发生的具体位置,在文件中搜索这些视觉标记会非常便捷地达成目的。

rrreee

通常来说在 ====== 标记之前的内容来自于接收合并的分支,而在这之后的内容来自于要合并的分支。

一旦找到冲突的部分,就可以根据需要来修正冲突。当你完成了冲突的修复并准备好继续进行合并,只需要执行git add命令把已经解决好冲突的文件添加暂存区,告诉Git这些冲突已经解决完毕即可。这之后就像正常提交代码一样执行git commit

또한 이 예에서는 new-feature의 내용이 기본 브랜치에 병합되었기 때문에 Git은 git Branch -d 명령에 대해 경고를 발행하지 않습니다.

어떤 경우에는 대상 브랜치의 커밋 기록이 현재 브랜치에 대해 선형적이지만 빨리 감기 병합을 수행할 수 있지만 여전히 이 커밋에서 병합이 발생했음을 표시하기 위해 병합 커밋을 원할 수 있습니다. 그러면 git merge 명령을 사용할 때 --no-ff 옵션을 사용할 수 있습니다. 🎜rrreee🎜위 명령은 지정된 분기를 현재 분기로 병합하지만 항상 병합 커밋을 생성합니다(이 병합 작업을 빨리 감을 수 있는 경우에도). 이 명령은 저장소의 커밋 기록에 병합 이벤트를 표시해야 할 때 유용합니다. 🎜

3방향 병합

🎜다음 예는 위와 비슷하지만 main 브랜치가 해당 기능을 진행 중이기 때문입니다. 분기 이동 앞으로 자체도 변경되었으므로 병합 중에 3방향 병합이 필요합니다. 이 시나리오는 대규모 기능 개발을 수행하거나 여러 개발자가 동시에 개발할 때 매우 일반적입니다. 🎜rrreee🎜이 경우에는 main의 최상위 포인터를 new-feature 브랜치로 직접 이동할 수 있는 방법이 없기 때문에 Git에서는 다음 작업을 수행할 수 없습니다. 빨리 감기 병합. 🎜🎜대부분의 실제 업무 시나리오에서 new-feature는 매우 큰 기능이어야 하고, 개발 과정도 오랜 시간이 걸리기 때문에 main이 되는 것은 불가피합니다. 동시에 개발되었습니다. 코드> 분기에도 새로운 커밋이 있습니다. 기능 분기의 크기가 위의 예만큼 작은 경우 리베이스를 사용하여 new-feature 분기를 main 분기로 리베이스한 다음 빨리 감기를 수행할 수 있습니다. 다시 병합합니다. 이는 또한 프로젝트의 커밋 기록에 너무 많은 중복이 생성되는 것을 방지합니다. 🎜

충돌 해결

🎜병합할 두 브랜치가 파일의 동일한 부분을 수정한 경우 Git에서는 어떤 버전의 콘텐츠를 사용해야 할지 결정할 수 없습니다. 이런 일이 발생하면 병합 커밋이 커밋되기 전에 병합 프로세스가 중지되어 사용자에게 이러한 충돌을 수동으로 해결할 수 있는 기회가 제공됩니다. 🎜🎜Git 병합 프로세스의 가장 큰 장점은 잘 알려진 편집/스테이징/커밋 워크플로를 사용하여 충돌을 해결한다는 것입니다. 병합 충돌이 발생하면 git status 명령을 실행하면 충돌이 포함되어 수동으로 해결해야 하는 파일이 나열됩니다. 예를 들어 두 분기 모두 hello.py 파일의 동일한 부분을 수정하면 다음과 유사한 메시지가 표시됩니다. 🎜rrreee

충돌 표시 방법

🎜Git은 병합 프로세스 중에 충돌이 발생하면 영향을 받은 파일에서 관련 내용을 편집하고 충돌의 이 부분의 다른 내용을 표시하기 위해 시각적 표시를 추가합니다. 이러한 시각적 마커는 다음과 같습니다. >>>>>. 충돌이 발생한 특정 위치를 찾으려면 파일에서 이러한 시각적 표시를 쉽게 검색할 수 있습니다. 🎜rrreee🎜 일반적으로 ====== 표시 앞의 내용은 병합을 받는 브랜치에서 오고, 뒤의 내용은 병합되는 브랜치에서 옵니다. 🎜🎜충돌되는 부분을 찾으면 필요에 따라 충돌을 수정할 수 있습니다. 충돌 수정을 완료하고 병합을 계속할 준비가 되면 git add 명령을 실행하여 해결된 충돌이 있는 파일을 스테이징 영역에 추가하고 Git에 이러한 충돌이 해결되었음을 알리기만 하면 됩니다. . 이후, 정상적으로 코드를 제출하는 것과 마찬가지로 git commit을 실행하여 병합 커밋을 완료합니다. 이 프로세스는 일반적인 상황에서 코드를 제출하는 것과 정확히 동일합니다. 즉, 일반 개발자에게는 충돌 처리가 매우 쉽습니다. 🎜🎜 또한 병합 충돌은 3방향 병합 중에만 발생할 수 있으며 빨리 감기 병합 중에는 발생하지 않습니다. 🎜

요약

이 문서는 git merge명령에 대한 개요입니다. Git을 사용하는 과정에서 merge는 매우 중요한 작업이다. 이 문서에서는 병합 작업의 메커니즘과 빨리 감기 병합과 3방향 병합 간의 차이점에 대해 설명합니다. 독자들이 기억해야 할 핵심 사항은 다음과 같습니다.

  • Git 병합 프로세스는 다양한 커밋 시퀀스를 통합된 커밋 기록으로 병합하는 것입니다.

  • Git 병합 프로세스에는 두 가지 주요 방법이 있습니다. 3방향 병합

  • 두 커밋 시퀀스 사이에 충돌이 없는 한 Git은 일반적으로 자동으로 커밋을 병합할 수 있습니다

권장 학습: "Git Tutorial"

위 내용은 Git 학습: git merge 명령 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제