>  기사  >  개발 도구  >  Git에서 병합이란 무엇입니까?

Git에서 병합이란 무엇입니까?

青灯夜游
青灯夜游원래의
2021-12-29 17:41:3619052검색

git에서 merge는 "병합"을 의미합니다. 이 명령은 두 개 이상의 개발 기록을 함께 병합하는 데 사용됩니다. git-pull에서 병합 명령을 사용하면 브랜치의 다른 코드 변경 사항을 통합할 수도 있습니다. 한 지점에서 다른 지점으로 병합.

Git에서 병합이란 무엇입니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, Git 버전 2.30.0, Dell G3 컴퓨터.

git-merge에 대한 종합 분석

Git의 git-merge는 Git에서 자주 사용되는 명령입니다. 많은 사람들이 git merge를 주의하지 않으면 코드를 잃어버리는 문제에 직면하게 된다고 생각합니다. 따라서 git에서 낙담합니다. 이 문서에서는 Git 2.8.2를 기반으로 하는 git-merge 명령에 대한 완전하고 자세한 소개를 제공합니다. 특히 교차 병합으로 인해 발생하는 코드 손실 문제와 관련하여 git 사용자에게 도움이 되기를 바라며 문서 마지막 부분에 제안 사항을 제공합니다. . 이 글에 소개된 내용은 Git 2.8.2

git-merge 명령은 둘 이상의 개발 기록을 병합하는 데 사용되는 작업이며 일반적으로 git merge로 작성할 수도 있습니다.

1.git-merge 관련 옵션 매개변수

1.1 요약

git-merge 명령에는 다음 세 가지 매개변수가 있습니다.

  • git merge [-n] [--stat] [- - no-commit] [--squash] [--[no-]edit] [-s ] [-X ] [-S[]] [-- [ no-]rerere-autoupdate] [-m <msg>] [<commit>...]</commit></msg>
  • git merge [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]</commit></msg></keyid></strategy-option></strategy>
  • git merge <msg> HEAD <commit>...</commit></msg>
  • git merge --abort

1.2git-merge简介

git-merge命令是用于从指定的commit(s)合并到当前分支的操作。

注:这里的指定commit(s)是指从这些历史commit节点开始,一直到当前分开的时候。

git-merge命令有以下两种用途:

  1. 用于git-pull中,来整合另一代码仓库中的变化(即:git pull = git fetch + git merge)
  2. 用于从一个分支到另一个分支的合并

假设下面的历史节点存在,并且当前所在的分支为“master”:

Git에서 병합이란 무엇입니까?

那么git merge topic命令将会把在master分支上二者共同的节点(E节点)之后分离的节点(即topic分支的A B C节点)重现在master分支上,直到topic分支当前的commit节点(C节点),并位于master分支的顶部。并且沿着master分支和topic分支创建一个记录合并结果的新节点,该节点带有用户描述合并变化的信息。

即下图中的H节点,C节点和G节点都是H节点的父节点。

Git에서 병합이란 무엇입니까?

1.3git merge <msg> HEAD <commit>...</commit></msg>命令

该命令的存在是由于历史原因,在新版本中不应该使用它,应该使用git merge -m <msg> <commit>....</commit></msg>进行替代

1.4git merge --abort命令

该命令仅仅在合并后导致冲突时才使用。git merge --abort将会抛弃合并过程并且尝试重建合并前的状态。但是,当合并开始时如果存在未commit的文件,git merge --abort在某些情况下将无法重现合并前的状态。(特别是这些未commit的文件在合并的过程中将会被修改时)

警告:运行git-merge时含有大量的未commit文件很容易让你陷入困境,这将使你在冲突中难以回退。因此非常不鼓励在使用git-merge时存在未commit的文件,建议使用git-stash命令将这些未commit文件暂存起来,并在解决冲突以后使用git stash pop把这些未commit文件还原出来。

2.参数

本部分用于介绍git-merge命令中使用的参数

2.1--commit--no-commit

--commit参数使得合并后产生一个合并结果的commit节点。该参数可以覆盖--no-commit
--no-commit参数使得合并后,为了防止合并失败并不自动提交,能够给使用者一个机会在提交前审视和修改合并结果。

2.2--edit-e以及--no-edit

--edit-e用于在成功合并、提交前调用编辑器来进一步编辑自动生成的合并信息。因此使用者能够进一步解释和判断合并的结果。
--no-editgit merge <msg> HEAD <commit>.. . </commit></msg>

git merge --abort🎜1.2 git-merge 소개🎜🎜git-merge 명령은 지정된 커밋을 제거하는 데 사용됩니다. ( s) 현재 분기에 병합하는 작업입니다. 🎜🎜🎜참고: 여기에 지정된 커밋은 이러한 과거 커밋 노드에서 시작하여 현재 분리까지를 의미합니다. 🎜🎜🎜git-merge 명령에는 다음 두 가지 용도가 있습니다. 🎜
    🎜 git-pull에서 다른 코드 저장소의 변경 사항을 통합하는 데 사용됩니다(예: git pull = git fetch + git merge) 🎜사용됨 한 브랜치에서 다른 브랜치로 병합
🎜다음과 같은 과거 노드가 존재하고 현재 브랜치가 "마스터"라고 가정합니다:
🎜

Git에서 병합이란 무엇입니까?🎜🎜 그런 다음 git merge topic 명령은 마스터 브랜치(즉, 토픽 브랜치의 A B C 노드)의 공통 노드(E 노드) 이후에 분리된 노드를 마스터 브랜치에서 현재 토픽 브랜치까지 커밋 노드(C 노드)이며 마스터 분기의 상단에 위치합니다. 그리고 마스터 브랜치와 토픽 브랜치를 따라 새 노드를 생성하여 병합 결과를 기록합니다. 이 노드는 병합 변경 사항을 설명하는 사용자 정보를 전달합니다. 🎜🎜🎜즉, 아래 그림의 H 노드, C 노드, G 노드는 모두 H 노드의 부모 노드입니다. 🎜🎜

Git에서 병합이란 무엇입니까?🎜🎜1.3git merge <msg> HEAD <commit>...</commit></msg> command🎜🎜이 명령은 역사적인 이유로 존재하며 새 버전에서는 사용해서는 안 됩니다. git merge -m <msg> <commit>....</commit></msg>🎜🎜1.4git merge --abort command🎜🎜로 대체됩니다. 병합 후 충돌이 발생하는 경우. git merge --abort는 병합 프로세스를 중단하고 병합 전 상태를 다시 작성하려고 시도합니다. 그러나 병합이 시작될 때 커밋되지 않은 파일이 있으면 git merge --abort가 병합 전 상태를 재현하지 못하는 경우가 있습니다. (특히 이러한 커밋되지 않은 파일이 병합 프로세스 중에 수정되는 경우) 🎜🎜🎜경고: 많은 수의 커밋되지 않은 파일을 사용하여 git-merge를 실행할 때 문제가 발생하기 쉽습니다. 갈등에서 물러나기가 어렵습니다. 따라서 git-merge를 사용할 때 커밋되지 않은 파일을 두지 않는 것이 좋습니다. 커밋되지 않은 파일을 임시로 저장하고 충돌을 해결하려면 git-stash 명령을 사용하는 것이 좋습니다. . 커밋되지 않은 파일을 복원하려면 git stash pop을 사용하세요. 🎜🎜🎜2. 매개변수🎜🎜이 섹션은 git-merge 명령🎜🎜2.1--commit--no에 사용되는 매개변수를 소개하는 데 사용됩니다. -commit 🎜🎜--commit이 매개변수는 병합 후 병합된 결과의 커밋 노드가 생성되도록 합니다. 이 매개변수는 --no-commit을 재정의할 수 있습니다.
--no-commit 매개변수는 병합 실패를 방지하기 위해 병합이 자동으로 제출되지 않도록 하여 사용자가 제출 전에 병합 결과를 검토하고 수정할 수 있는 기회를 제공합니다. 🎜🎜2.2 --edit-e--no-edit🎜🎜--edit 및 -e는 성공적인 병합 및 제출 전에 자동으로 생성된 병합 정보를 추가로 편집하기 위해 편집기를 호출하는 데 사용됩니다. 따라서 사용자는 합병 결과를 더 자세히 해석하고 판단할 수 있습니다.
--no-edit 매개변수를 사용하여 자동으로 병합된 정보를 허용할 수 있습니다(일반적으로 권장되지 않음). 🎜

병합 시 -m 매개변수를 지정한 경우(아래 설명 참조) --edit(또는 -e)를 사용하는 것이 여전히 유용합니다. , 그러면 편집기의 -m에 포함된 콘텐츠가 추가로 편집됩니다. -m参数(下文介绍),使用 --edit(或-e)依然是有用的,这将在编辑器中进一步编辑-m所含的内容。

旧版本的节点可能并不允许用户去编辑合并日志信息。

2.3--ff命令

--ff是指fast-forward命令。当使用fast-forward模式进行合并时,将不会创造一个新的commit节点。默认情况下,git-merge采用fast-forward模式。
关于fast-forward模式的详细解释,请看我的另一篇文章:一个成功的Git分支模型的“关于fast forward”一节。

2.4--no-ff命令

即使可以使用fast-forward模式,也要创建一个新的合并节点。这是当git merge在合并一个tag时的默认行为。

2.5--ff-only命令

除非当前HEAD节点已经up-to-date(更新指向到最新节点)或者能够使用fast-forward模式进行合并,否则的话将拒绝合并,并返回一个失败状态。

2.5 --log[=<n>]</n>--no-log

--log[=<n>]</n>将在合并提交时,除了含有分支名以外,还将含有最多n个被合并commit节点的日志信息。
--no-log并不会列出该信息。

2.6 --stat, -n, --no-stat命令

--stat参数将会在合并结果的末端显示文件差异的状态。文件差异的状态也可以在git配置文件中的merge.stat配置。
相反,-n, --no-stat参数将不会显示该信息。

2.7--squash--no-squash

--squash 当一个合并发生时,从当前分支和对方分支的共同祖先节点之后的对方分支节点,一直到对方分支的顶部节点将会压缩在一起,使用者可以经过审视后进行提交,产生一个新的节点。

注意1:该参数和--no-ff冲突

注意2:该参数使用后的结果类似于在当前分支提交一个新节点。在某些情况下这个参数非常有用,例如使用Git Flow时(关于Git Flow,请参考:一个成功的Git分支模型),功能分支在进行一个功能需求的研发时,开发者可能在本地提交了大量且无意义的节点,当需要合并到develop分支时,可能仅仅需要用一个新的节点来表示这一长串节点的修改内容,这时--squash命令将会发挥作用。此外,如果功能分支的多次提交并不是琐碎而都是有意义的,使用--no-ff命令更为合适。
--no-squash的作用正好相反。

2.8 -s <strategy></strategy>--strategy=<strategy></strategy>

-s <strategy></strategy>--strategy=<strategy></strategy>用于指定合并的策略。默认情况如果没有指定该参数,git将按照下列情况采用默认的合并策略:

  1. 合并节点只含有单个父节点时(如采用fast-forward模式时),采用recursive策略(下文介绍)。
  2. 合并节点含有多个父节点时(如采用no-fast-forward模式时),采用octopus策略(下文介绍)。

2.9 -X <option></option>--strategy-option=<option></option>

-s <strategy></strategy>时指定该策略的具体参数(下文介绍)。

2.10 --verify-signatures, --no-verify-signatures

이전 버전의 노드에서는 사용자가 병합 로그 정보를 편집하는 것을 허용하지 않을 수 있습니다.

2.3--ff 명령 🎜--ff는 빨리 감기 명령을 나타냅니다. 빨리 감기 모드를 사용하여 병합하는 경우 새 커밋 노드가 생성되지 않습니다. 기본적으로 git-merge는 빨리 감기 모드를 사용합니다. 🎜빨리 감기 모드에 대한 자세한 설명은 내 다른 기사: 성공적인 Git 분기 모델의 "빨리 감기 정보" 섹션을 참조하세요. 🎜

2.4--no-ff 명령🎜🎜빨리 감기 모드를 사용할 수 있는 경우에도 새 병합 노드를 생성합니다. 이는 git merge가 태그를 병합할 때의 기본 동작입니다. 🎜

2.5--ff-only 명령🎜🎜현재 HEAD 노드가 최신 상태이거나(최신 노드로 업데이트됨) 빨리 감기 모드를 사용하여 병합될 수 없는 경우, 그렇지 않은 경우 병합을 거부하고 실패 상태를 반환합니다. 🎜

2.5 --log[=<n>]</n>--no-log🎜🎜--log[=<n>] </n>병합 및 제출 시 브랜치 이름 외에도 최대 n개의 병합된 커밋 노드에 대한 로그 정보도 포함됩니다. 🎜--no-log는 이 정보를 나열하지 않습니다. 🎜

2.6 --stat, -n, --no-stat 명령 🎜🎜--stat 매개변수는 병합된 결과가 끝나면 파일 차이 상태를 표시합니다. 파일 차이점 상태는 git 구성 파일의 merge.stat에서 구성할 수도 있습니다. 🎜반대로, -n, --no-stat 매개변수는 이 정보를 표시하지 않습니다. 🎜

2.7--squash--no-squash🎜🎜--squash 병합이 발생하면 현재 분기에서 다른 분기의 공통 조상 노드 이후의 다른 분기 노드와 다른 분기의 최상위 노드가 함께 압축되어 사용자가 검토 후 제출하여 새 노드를 생성할 수 있습니다. 🎜🎜🎜참고 1: 이 매개변수는 --no-ff🎜🎜🎜와 충돌합니다. 참고 2: 이 매개변수를 사용한 결과는 현재 분기에 새 노드를 제출하는 것과 유사합니다. 이 매개변수는 Git Flow를 사용할 때와 같은 일부 경우에 매우 유용합니다(Git Flow에 대해서는 성공적인 Git 분기 모델 참조). 그리고 의미 없는 노드를 개발 브랜치에 병합해야 하는 경우 이 긴 노드 목록의 수정 내용을 나타내기 위해 새 노드만 사용하면 됩니다. code> 명령이 실행됩니다. 또한 기능 브랜치의 여러 제출이 사소하지 않고 의미가 있는 경우 --no-ff 명령을 사용하는 것이 더 적절합니다. 🎜--no-squash는 정반대입니다. 🎜

2.8 -s <strategy></strategy>--strategy=<strategy></strategy>🎜🎜-s --strategy=<strategy></strategy>는 병합 전략을 지정하는 데 사용됩니다. 기본적으로 이 매개변수를 지정하지 않으면 git은 다음 조건에 따라 기본 병합 전략을 사용합니다. 🎜
  1. 병합 노드에 단일 상위 노드만 포함된 경우(예: 빨리 감기 모드를 사용하는 경우) , 재귀 전략(아래 설명)).
  2. 병합된 노드에 여러 상위 노드가 포함된 경우(예: 빨리 감기 없음 모드를 사용하는 경우) 문어 전략(아래 설명)이 사용됩니다.

2.9 -X <option></option>--strategy-option=<option></option>🎜🎜 in - 전략의 특정 매개변수를 지정할 때 <strategy></strategy>입니다(아래 설명 참조). 🎜

2.10 --verify-signatures, --no-verify-signatures🎜🎜 병합된 노드에 GPG 서명이 있는지 확인하고 이를 병합하는 데 사용됩니다. 노드 무시 GPG 서명 확인 기능이 없습니다. 🎜(다음 인용문은 재인쇄된 기사에서 따온 것입니다. 원저자를 찾지 못해 원저자 정보와 원문 링크를 제공할 수 없습니다. 침해된 내용이 있는 경우 비공개 메시지나 댓글로 알려주시고, 다음 인용문은 삭제하겠습니다.)🎜

GPG는 암호화 소프트웨어입니다. GPG에서 생성된 공개 키를 사용하여 파일과 코드를 인터넷에 안전하게 퍼뜨릴 수 있습니다.
왜 안전하다고 하시나요? Google에서 개발한 저장소를 예로 들면, 저장소는 GPG 검증을 사용합니다. 각 마일스톤 태그에는 GPG 암호화 검증이 있습니다. 마일스톤 v1.12.3에서 변경하려면 수정 후 태그를 삭제하면 됩니다. 수정 지점을 가리키도록 동일한 이름의 태그를 생성합니다. 그러나 수정된 ​​프로젝트를 다시 복제하면 이 마일스톤 태그에 대한 변경 사항이 인식되지 않고 확인에 실패하여 여기에서 수정 사항이 정상적으로 구현되지 않는 것을 확인할 수 있습니다. 이는 프로젝트 작성자(개인 키 보유자)가 설정한 마일스톤을 다른 사람이 수정할 수 없도록 보장하는 GPG 검증의 역할입니다. 그러면 작성자의 코드가 안전하게 유포되었다고 할 수 있다.
왜 그런 것이 필요한가요? 프로젝트의 개발부터 릴리스, 이후 업데이트 반복까지 확실히 안정적인 버전과 개발 버전이 많이 있을 것입니다(불안정한 요소가 있음). 프로젝트 개시자 및 보유자로서 그들은 자신이 인식하는 안정 버전을 정의할 권리가 있습니다. 이 안정 버전은 다른 개발자가 변경하는 것을 허용하지 않습니다. Google의 repo 프로젝트를 예로 들어보겠습니다. 프로젝트 소유자는 프로젝트 개발 프로세스에서 포인트 A를 안정 버전 v1.12.3으로 정의합니다. 그런 다음 사용자는 v1.12.3 버전을 다운로드한 후 포인트 A에서 생성된 프로젝트와 제품을 확실히 사용하게 됩니다. 다른 개발자가 v1.12.3을 로컬에서 다시 지정하여 자신의 수정된 지점 B에 지정할 수 있다고 하더라도 최종적으로 사용자가 수정된 버전을 사용하게 되면 GPG 서명 검증이 실패하는 문제, 즉 수정 사항은 적용되지 않습니다.

2.11 —요약, --no-summary—summary,--no-summary

--stat--no-stat相似,并将在未来版本移除。

2.12 -q--quiet

静默操作,不显示合并进度信息。

2.13 -v--verbose

显示详细的合并结果信息。

2.14 --progress--no-progress

切换是否显示合并的进度信息。如果二者都没有指定,那么在标准错误发生时,将在连接的终端显示信息。请注意,并不是所有的合并策略都支持进度报告。

2.15-S[<keyid>]</keyid>--gpg-sign[=<keyid>]</keyid>

GPG签名。

2.16-m <msg></msg>

设置用于创建合并节点时的提交信息。
如果指定了--log参数,那么commit节点的短日志将会附加在提交信息里。

2.17--[no-]rerere-autoupdate

rerere即reuse recorded resolution,重复使用已经记录的解决方案。它允许你让 Git 记住解决一个块冲突的方法,这样在下一次看到相同冲突时,Git 可以为你自动地解决它。

2.18--abort

--stat--no-stat code code>도 유사하며 향후 버전에서는 제거될 예정입니다.

2.12 -q--quiet

자동으로 작업하며 병합 진행 정보가 표시되지 않습니다.

2.13 -v--verbose


자세한 병합 결과 정보를 표시합니다.

2.14 --progress--no-progress

병합된 진행 정보 표시 여부를 전환합니다. 둘 다 지정하지 않으면 표준 오류가 발생할 때 연결된 터미널에 메시지가 표시됩니다. 모든 병합 전략이 진행 상황 보고를 지원하는 것은 아닙니다.

2.15-S[<keyid>]</keyid>--gpg-sign[=<keyid>]</keyid>

GPG 서명.

2.16-m <msg></msg>

🎜병합 노드 생성 시 사용되는 커밋 정보를 설정합니다. 🎜--log 매개변수를 지정하면 커밋 노드의 짧은 로그가 커밋 메시지에 추가됩니다. 🎜🎜2.17--[no-]rerere-autoupdate🎜🎜rerere는 기록된 해상도를 재사용하고 기록된 솔루션을 재사용하는 것입니다. Git에게 블록 충돌 해결 방법을 기억하도록 요청하면 다음에 동일한 충돌이 나타날 때 Git이 자동으로 이를 해결할 수 있습니다. 🎜🎜2.18--abort🎜🎜현재 병합 충돌 처리 프로세스를 중단하고 병합 전 상태를 재구성해 보세요. 🎜🎜3. 병합에 대한 다른 개념🎜🎜3.1 병합 전 감지🎜🎜외부 분기를 병합할 때는 자체 분기를 깨끗하게 유지해야 합니다. 그렇지 않으면 병합 충돌이 발생할 때 많은 문제가 발생합니다. 🎜커밋 병합 시 관련 없는 파일이 기록되는 것을 방지하기 위해 인덱스가 가리키는 HEAD 노드에 커밋되지 않은 파일이 등록되어 있으면 git-pull 및 git-merge 명령이 중지됩니다. 🎜🎜3.2fast-forward merge🎜🎜일반적으로 분기 병합은 병합 노드를 생성하지만 일부 특수한 경우에는 예외가 있습니다. 예를 들어 git pull 명령을 호출하여 원격 코드를 업데이트할 때 로컬 브랜치에 커밋이 없으면 병합 노드를 생성할 필요가 없습니다. 이 경우 병합 노드는 생성되지 않으며 HEAD는 업데이트된 상위 코드를 직접 가리킵니다. 이 병합 전략은 빨리 감기 병합입니다. 🎜🎜3.3 병합 세부 정보🎜🎜위에서 언급한 빨리 감기 병합 모드 외에도 병합된 분기는 병합 노드를 통해 현재 분기에 연결됩니다. 병합 노드에는 병합 전 현재 분기의 최상위 노드와 최상위 노드도 있습니다. 다른 분기의 노드를 상위 노드로 함께 사용합니다. 🎜병합 버전은 커밋 노드, HEAD 노드 및 인덱스 포인터를 포함하여 모든 관련 분기의 변경 사항을 일관되게 만들고 노드 트리가 업데이트됩니다. 이러한 노드의 파일이 겹치지 않는 한 이러한 파일에 대한 변경 사항은 노드 트리에서 수정 및 업데이트됩니다. 🎜이러한 변경 사항을 명시적으로 병합할 수 없는 경우 다음과 같은 결과가 발생합니다. 🎜
  1. HEAD 포인터가 가리키는 노드는 그대로 유지됩니다
  2. MERGE_HEAD 포인터가 다른 브랜치 위에 위치합니다MERGE_HEAD指针被置于其他分支的顶部
  3. 已经合并干净的路径在index文件和节点树中同时更新
  4. 对于冲突路径,index文件记录了三个版本:版本1记录了二者共同的祖先节点,版本2记录了当前分支的顶部,即HEAD,版本3记录了MERGE_HEAD。节点树中的文件包含了合并程序运行后的结果。例如三路合并算法会产生冲突。
  5. 其他方面没有任何变化。特别地,你之前进行的本地修改将继续保持原样。
    如果你尝试了一个导致非常复杂冲突的合并,并想重新开始,那么可以使用git merge --abort

关于三路合并算法:
三路合并算法是用于解决冲突的一种方式,当产生冲突时,三路合并算法会获取三个节点:本地冲突的B节点,对方分支的C节点,B,C节点的共同最近祖先节点A。三路合并算法会根据这三个节点进行合并。具体过程是,B,C节点和A节点进行比较,如果B,C节点的某个文件和A节点中的相同,那么不产生冲突;如果B或C只有一个和A节点相比发生变化,那么该文件将会采用该变化了的版本;如果B和C和A相比都发生了变化,且变化不相同,那么则需要手动去合并;如果B,C都发生了变化,且变化相同,那么并不产生冲突,会自动采用该变化的版本。最终合并后会产生D节点,D节点有两个父节点,分别为B和C。

3.4合并tag

当合并一个tag时,Git总是创建一个合并的提交,即使这时能够使用fast-forward模式。该提交信息的模板预设为该tag的信息。额外地,如果该tag被签名,那么签名的检测信息将会附加在提交信息模板中。

3.5冲突是如何表示的

当产生合并冲突时,该部分会以, <code>=======表示。在=======之前的部分是当前分支这边的情况,在=======之后的部分是对方分支的情况。

3.6如何解决冲突

在看到冲突以后,你可以选择以下两种方式:

  • 决定不合并。这时,唯一要做的就是重置index到HEAD节点。git merge --abort用于这种情况。
  • 解决冲突。Git会标记冲突的地方,解决完冲突的地方后使用git add加入到index中,然后使用git commit产生合并节点。
    你可以用以下工具来解决冲突:
  • 使用合并工具。git mergetool将会调用一个可视化的合并工具来处理冲突合并。
  • 查看差异。git diff将会显示三路差异(三路合并中所采用的三路比较算法)。
  • 查看每个分支的差异。git log --merge -p <path></path>将会显示HEAD版本和MERGE_HEAD版本的差异。
  • 查看合并前的版本。git show :1:文件名显示共同祖先的版本,git show :2:文件名显示当前分支的HEAD版本,git show :3:文件名显示对方分支的MERGE_HEAD版本。

4.合并策略

Git可以通过添加-s参数来指定合并的策略。一些合并策略甚至含有自己的参数选项,通过-X<option></option>

병합된 정리 경로는 인덱스 파일과 노드 트리에서 동시에 업데이트됩니다

충돌하는 경로의 경우 인덱스 파일은 세 가지 버전을 기록합니다. 버전 1은 두 버전의 공통 조상 노드를 기록하고, 버전 2는 현재 분기의 최상위, 즉 HEAD를 기록하고, 버전 3은 MERGE_HEAD를 기록합니다. 노드 트리의 파일에는 병합 프로그램 실행 결과가 포함됩니다. 예를 들어, 3방향 병합 알고리즘은 충돌을 일으킬 수 있습니다.


다른 변경 사항은 없습니다. 특히 이전에 수행한 로컬 수정 사항은 그대로 유지됩니다.

매우 복잡한 충돌을 초래한 병합을 시도했고 다시 시작하고 싶다면 git merge --abort를 사용할 수 있습니다.🎜
🎜3방향 병합 알고리즘 정보 : 🎜Three 경로 병합 알고리즘은 충돌이 발생하면 3방향 병합 알고리즘이 3개의 노드(로컬 충돌의 B 노드, 다른 분기의 C 노드, 가장 가까운 공통 노드)를 획득합니다. B 및 C 노드의 조상 노드 A. 3방향 병합 알고리즘은 이 세 개의 노드를 기반으로 병합됩니다. 구체적인 프로세스는 노드 B와 C를 노드 A와 비교하는 것입니다. 노드 B와 C의 파일이 노드 A의 파일과 동일하면 노드와 비교하여 B 또는 C 중 하나만 변경되면 충돌이 없습니다. A를 선택하면 파일이 변경된 버전을 채택합니다. A와 비교하여 B와 C가 변경되고 변경 사항이 동일하지 않은 경우 B와 C가 변경되었으며 변경 사항이 동일하면 수동으로 병합해야 합니다. 을 선택하면 충돌이 발생하지 않으며 변경된 버전이 자동으로 적용됩니다. 최종 병합 후에는 D 노드가 생성됩니다. D 노드에는 B와 C라는 두 개의 상위 노드가 있습니다. 🎜
🎜3.4 태그 병합🎜🎜태그를 병합할 때 Git은 빨리 감기 모드를 사용할 수 있는 경우에도 항상 병합된 커밋을 생성합니다. 제출 정보의 템플릿은 태그 정보에 미리 설정되어 있습니다. 또한 태그가 서명되면 서명 감지 정보가 커밋 메시지 템플릿에 추가됩니다. 🎜🎜3.5 충돌 표현 방법🎜🎜병합 충돌이 발생하면 이 부분에 <code>====로 표시됩니다. == ==. ======== 앞 부분은 현재 브랜치의 상황이고, <code>======== 뒤 부분은 현재 브랜치의 상황입니다. 상대방의 가지. 🎜🎜3.6 충돌 해결 방법🎜🎜충돌을 확인한 후 다음 두 가지 방법을 선택할 수 있습니다. 🎜
    🎜병합하지 않기로 결정합니다. 이때 해야 할 일은 인덱스를 HEAD 노드로 재설정하는 것 뿐이다. 이 경우 git merge --abort가 사용됩니다. 🎜🎜충돌을 해결하세요. Git은 충돌을 해결한 후 git add를 사용하여 이를 인덱스에 추가하고 git commit를 사용하여 병합 노드를 생성합니다. 🎜다음 도구를 사용하여 충돌을 해결할 수 있습니다. 🎜🎜병합 도구를 사용하세요. git mergetool은 시각적 병합 도구를 호출하여 충돌하는 병합을 처리합니다. 🎜🎜차이점을 확인해보세요. git diff는 3방향 차이점(3방향 병합에 사용되는 3방향 비교 알고리즘)을 표시합니다. 🎜🎜지점별 차이점을 확인해보세요. git log --merge -p <path></path>HEAD 버전과 MERGE_HEAD 버전 간의 차이를 표시합니다. 🎜🎜병합 전 버전을 확인하세요. git show :1:파일 이름은 공통 조상 버전을 표시하고, git show :2:파일 이름은 현재 분기의 HEAD 버전을 표시합니다. git show :3 :파일 이름은 상대방 브랜치의 MERGE_HEAD 버전을 표시합니다. 🎜

4. 병합 전략

🎜Git은 -s 매개변수를 추가하여 병합 전략을 지정할 수 있습니다. 일부 병합 전략에는 -X<option></option>을 통해 설정할 수 있는 자체 매개변수 옵션도 있습니다. (병합은 git merge 및 git pull 명령 모두에서 발생할 수 있으므로 이 병합 전략은 git pull에도 적용됩니다.) 🎜🎜4.1resolve🎜🎜 3방향 병합 알고리즘만 사용하여 두 분기(예: 현재 분기와 끌어온 다른 분기)의 최상위 노드를 병합합니다. 이 병합 전략은 두 분기의 HEAD 노드와 공통 하위 노드가 3방향 병합을 수행하는 3방향 병합 알고리즘을 따릅니다. 🎜물론 우리를 정말 괴롭히는 것은 교차 교차 병합의 경우입니다. 소위 교차 병합은 여러 개의 공통 조상 노드가 있는 상황을 의미합니다. 예를 들어 두 개의 분기가 병합되는 경우 이때 두 개의 공통 조상 노드가 있을 가능성이 매우 높습니다. 3방향 병합 알고리즘에 적용됩니다(공통 조상 노드는 고유하지 않기 때문). 해결 전략이 교차 병합 문제를 처리하는 방법은 여기에서 "Git를 사용한 버전 제어"를 참조하세요.

가능한 병합 기반이 두 개 이상인 교차 병합 상황에서 해결 전략은 다음과 같이 작동합니다. 가능한 병합 기반 중 하나를 선택하고 실제로 최선의 결과가 나오길 바랍니다. 사용자가 코드의 다른 부분을 작업하고 있는 경우가 종종 있습니다. 이 경우 Git은 이미 적용된 일부 변경 사항을 다시 병합하고 중복된 변경 사항을 건너뛰어 충돌을 피합니다. 충돌을 일으키는 충돌은 적어도 개발자가 처리하기 쉬워야 합니다

여기에 간단한 번역이 있습니다: 교차 병합의 경우 병합 참조 지점(공통 조상 노드)이 두 개 이상 있으며 해결 전략은 다음과 같이 작동합니다. 가능한 병합 기준점 중 하나를 선택하고 이것이 최상의 병합 결과가 되기를 바랍니다. 실제로 이것은 들리는 것만큼 나쁘지는 않습니다. 일반적으로 사용자는 코드의 다른 부분을 수정하는데, 이 경우 많은 병합 충돌이 실제로 중복되고 반복됩니다. 병합을 위해 해결을 사용하면 생성된 충돌을 처리하기가 더 쉽고 코드가 실제로 손실되는 경우는 거의 없습니다.

4.2recursive

3방향 병합 알고리즘만 사용하여 두 가지 분기를 병합합니다. 해결과 달리 교차 병합의 경우 이 병합 방법은 공통 조상 노드 이후 두 분기의 서로 다른 노드에서 시작하여 충돌이 발생하면 재귀적으로 호출되어 병합됩니다. 파일 병합은 더 이상 계속되지 않으며 충돌이 직접 발생합니다. 충돌이 없는 다른 파일은 최상위 노드까지 실행됩니다. 또한 이 접근 방식은 파일 이름 수정과 관련된 작업을 감지하고 처리할 수 있습니다. 이는 git 병합 및 코드 가져오기에 대한 기본 병합 작업입니다.
재귀 병합 전략에는 다음 매개변수가 있습니다.

4.2.1 ours

이 매개변수는 충돌이 발생할 때 현재 분기의 버전이 자동으로 사용되도록 합니다. 이 병합 방법은 문제를 일으키지 않으며 git도 다른 브랜치 버전에 포함된 충돌 내용을 확인하지 않습니다. 이 방법은 다른 브랜치의 충돌 내용을 삭제합니다.

4.2.2 그들의 것

은 우리의 것과 정확히 반대입니다.
그들의 매개변수와 우리의 매개변수는 모두 바이너리 파일 충돌을 병합하는 데 적합합니다.

4.2.2 인내

이 매개변수를 사용하면 git merge-recursive는 중요하지 않은 줄(예: 함수의 괄호)이 누락되는 것을 방지하기 위해 약간의 추가 시간을 소비합니다. 현재 브랜치와 다른 브랜치의 버전 브랜치 간 간격이 매우 큰 경우 이 병합 방법을 사용하는 것이 좋습니다. git merge-recursive花费一些额外的时间来避免错过合并一些不重要的行(如函数的括号)。如果当前分支和对方分支的版本分支分离非常大时,建议采用这种合并方式。

4.2.3diff-algorithm=[patience|minimal|histogram|myers]

告知git merge-recursive使用不同的比较算法。

4.2.4 ignore-space-change, ignore-all-space, ignore-space-at-eol

根据指定的参数来对待空格冲突。

  • 如果对方的版本仅仅添加了空格的变化,那么冲突合并时采用我们自己的版本
  • 如果我们的版本含有空格,但是对方的版本包含大量的变化,那么冲突合并时采用对方的版本
  • 采用正常的处理过程

4.2.5 no-renames

关闭重命名检测。

4.2.6subtree[=<path>]</path>

4.2.3 diff-algorithm=[patience|minimal|histogram|myers]

git merge-recursive에 다른 비교 알고리즘을 사용하라고 지시합니다.

4.2.4 space-change 무시, all-space 무시, ignore-space-at-eol

에 따르면 공백 충돌을 처리하기 위해 지정된 매개변수입니다.

  • 상대방 버전이 공백에만 변경 사항을 추가하는 경우 충돌 병합 시 우리 버전이 사용됩니다.
  • 우리 버전에는 공백이 포함되어 있지만 상대방 버전에는 많은 숫자가 포함되어 있는 경우 그런 다음 충돌을 병합할 때 상대방의 버전을 사용합니다.
  • 일반적인 처리 절차를 채택합니다.

4.2.5 이름 바꾸기 없음

이름 바꾸기 끄기 발각.

4.2.6subtree[=<path>]</path>

이 옵션은 하위 트리 병합 전략의 고급 형태로, 병합 프로세스 중에 두 노드 트리가 어떻게 이동하는지 추측합니다. 차이점은 지정된 경로가 병합 시작 시 제거되므로 하위 트리를 찾을 때 다른 경로가 일치될 수 있다는 것입니다. (하위 트리 병합 전략에 대한 자세한 내용은 아래를 참조하세요.)

4.3octopus

이 병합 방법은 두 개 이상의 분기에 사용되지만 충돌로 인해 수동 병합이 필요한 경우 병합을 거부합니다. 이 병합 방법은 여러 분기를 함께 묶는 데 더 적합하며 다중 분기 병합을 위한 기본 병합 전략이기도 합니다. 4.4ours

이 방법은 원하는 개수의 분기를 병합할 수 있지만 노드 트리의 병합 결과는 항상 현재 분기의 충돌하는 부분입니다. 이 방법은 이전 버전을 교체할 때 매우 효율적일 수 있습니다. 이 방법은 재귀 전략의 ours 매개변수와 다르다는 점에 유의하세요.

4.5subtree

subtree는 재귀 전략의 수정된 버전입니다. 트리 A와 트리 B를 병합할 때 B가 A의 하위 트리인 경우 B는 동일한 노드를 읽는 대신 먼저 A의 트리 구조와 일치하도록 조정합니다. 🎜🎜4.5 요약🎜🎜3방향 병합 전략(기본 재귀 전략 참조)을 사용할 때 현재 브랜치와 다른 브랜치 모두에서 파일(또는 코드 줄)이 변경되었다가 나중에 하나에서 롤백되는 경우 🎜그러면 이 대체 변경 사항이 결과에 반영됩니다🎜. 이 점은 일부 사람들을 혼란스럽게 할 수 있습니다. 이는 병합 프로세스 중에 git이 두 분기의 모든 노드가 아닌 두 분기의 공통 조상 노드와 HEAD 노드에만 초점을 맞추기 때문입니다. 따라서 병합 알고리즘은 롤백된 부분을 🎜변경되지 않은 부분🎜으로 간주하여 병합된 결과가 다른 브랜치의 변경된 부분이 됩니다. 🎜🎜추천 학습: "🎜Git Tutorial🎜"🎜

위 내용은 Git에서 병합이란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.