klo*_*lor 0 git git-merge-conflict
我想接受所有远程(他们的)修改,而不需要任何手动解决冲突.但是我仍然会在没有自动解决方案的情
$ git merge -s recursive -X theirs local/master
CONFLICT (rename/delete): rcS.d/S08kmod deleted in HEAD and renamed in local/master. Version local/master of rcS.d/S08kmod left in tree.
Auto-merging php5/cli/conf.d/20-xdebug.ini
CONFLICT (add/add): Merge conflict in php5/cli/conf.d/20-xdebug.ini
Auto-merging apt/sources.list
CONFLICT (rename/rename): Rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf.conf" in branch "HEAD" rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf" in "local/master"
Run Code Online (Sandbox Code Playgroud)
使用拉:
$ git pull local master
From ssh://192.168.1.101/etc
* branch master -> FETCH_HEAD
warning: Cannot merge binary files: console-setup/cached_UTF-8_del.kmap.gz (HEAD vs. ada82813d27e5bef846ee086d07a87a82cfbb020)
CONFLICT (rename/delete): rcS.d/S08kmod deleted in HEAD and renamed in ada82813d27e5bef846ee086d07a87a82cfbb020. Version ada82813d27e5bef846ee086d07a87a82cfbb020 of rcS.d/S08kmod left in tree.
CONFLICT (add/add): Merge conflict in php5/cli/conf.d/20-xdebug.ini
CONFLICT (rename/rename): Rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf.conf" in branch "HEAD" rename "apache2/sites-available/default-ssl"->"apache2/sites-available/default-ssl.conf" in "ada82813d27e5bef846ee086d07a87a82cfbb020"
Run Code Online (Sandbox Code Playgroud)
我也尝试过:
git merge --allow-unrelated-histories --strategy-option theirs local/master
Run Code Online (Sandbox Code Playgroud)
但同样的冲突.
在第一个例子中使用git v2.8.1.在第二个例子之前升级到GIT v2.9.2.
我的用例: 我使用GIT(更准确地说是使用ETCKEEPER)跟踪/ etc中的Debian升级更改.现在升级完成一些更改后,我想接受Debian所做的所有更改.当然我相信Debian升级所做的更改,所以我想覆盖(合并)所有已完成的更改,而不进行任何交互.
任何想法如何自动解决他们的修改冲突?
你期待的-X theirs比Git能提供的更多.
首先要记住git merge通常的(递归)策略:
这两个差异有一系列差异显示"我们做了什么"和"他们做了什么",Git现在会尝试将它们组合起来,以便我们得到每个变化的一个副本.这意味着如果我们在某个文件的第49行修复了单词的拼写,而他们没有,我们就得到了修复.如果他们修复了拼写,我们没有,我们得到修复.如果我们都做了相同的拼写修复,我们得到修复一次,而不是两次,尽管"修复拼写"的事实表示为:
"首先,删除旧行.然后,插入一个新的不同行."
并且过分天真地应用"采取每次更改"将尝试删除一行两次,和/或插入新行的两个副本.Git(或任何体面的版本控制系统的合并)注意到这两个变化是相同的,只保留一个副本.
但是,如果两个不同差异中的两个差异对同一原始源区域进行了不同的更改,那么Git通常只会声明合并冲突.它继续做任何其他事情,但它记住冲突,并在合并结束时停止,使冲突出现在工作树(熟悉的<<<<<<< ... >>>>>>>形式)和索引中.
也称为"临时区域"或"缓存",索引通常每个工作树文件有一个条目,2但在冲突合并期间,每个此类文件最多有三个条目:一个来自合并基地,一个来自"我们的",一个来自"他们的"."正常"(无冲突)条目进入"暂存槽零",但此时此插槽不用于此文件.相反,该文件的合并基础版本位于暂存插槽1中,而其他两个版本位于插槽2和3中(我们可以使用--ours并--theirs获取它们,而不是记住这些插槽编号,但gitrevisions如果您需要,则会记录它们随时查看它们.我们必须通过编辑工作树中的文件来解决冲突 - 然后告诉Git用正常的单个副本替换索引中"未合并"插槽中的三个副本,"准备进入下一次提交"阶段零槽.
1这假设存在单个合并库提交.如果存在多个合并库,则操作取决于策略.默认的"递归"策略查找所有合并基础,并将它们合并以生成单个"虚拟合并基础"."解决"策略只是在(显然)随机选择一个合并基础."章鱼"策略宣告合并失败.
2更确切地说,每个跟踪文件有一个条目,对于HEAD提交中的文件有一个特殊的白名输入,但由于a而被安排删除git rm.真正未跟踪的文件根本没有索引暂存插槽.
-X ours 和 -X theirs什么-X意思是:不是在宣布这一特定情况下发生冲突(冲突的DIFF帅哥),简单地采取要么我们改变(-X ours)或它们的变化(-X theirs),丢弃其它比较大块.
一个简单的例子是我们在一行上修复第一个单词的拼写,同时修复第五个单词在同一行上的拼写.这-X ours将保留我们的修复并丢弃他们的,-X theirs并将保留他们的修复并丢弃我们的.
在更复杂的情况下,我们可能添加或删除了添加或删除不同行的某些行,因此冲突更难以考虑.例如,有时git diff可能会错误地在空白行或由单个闭括号组成的行上进行同步,从而导致某些人或实际了解要合并的材料的人能够成功合并的冲突.再一次,-X简单地丢弃他们的差异或我们的差异,采取我们告诉它的任何一个.
就目前而言这很好,但它只处理差异差异.您看到的冲突是不兼容的文件更改:
CONFLICT (rename/delete): rcS.d/S08kmod deleted in HEAD and renamed
in local/master. Version local/master of rcS.d/S08kmod left in tree.
Run Code Online (Sandbox Code Playgroud)
在这种情况下,一个git diff(找到"我们的"更改)发现we(HEAD)完全删除 rcS.d/S08kmod,而他们(local/master)重命名该文件.在任何delete-file-vs-rename-file冲突中,Git将文件保存在新名称下,因为我们更容易删除它(git rm newname),而不是让我们弄清楚新名称是什么并检索我们或他们的文件版本.
Auto-merging php5/cli/conf.d/20-xdebug.ini
Run Code Online (Sandbox Code Playgroud)
(这个很顺利,可能-X theirs用来解决差异冲突)
CONFLICT (add/add): Merge conflict in php5/cli/conf.d/20-xdebug.ini
Run Code Online (Sandbox Code Playgroud)
这里,合并库没有名为的文件php5/cli/conf.d/20-xdebug.ini.Git在索引中留下了两个版本; 我们可以使用git checkout --ours我们的工作树,git checkout --theirs并将他们放在工作树中.遗憾的是,我们仍然需要手动合并和解析此文件.我没有检查Git版本2.8在这里做了什么(添加/添加冲突解决方案最近已经完成了一些工作).
Auto-merging apt/sources.list
Run Code Online (Sandbox Code Playgroud)
(另一个自动合并进展顺利,也许再次使用-X)
CONFLICT (rename/rename): Rename "apache2/sites-available/default-ssl"->
"apache2/sites-available/default-ssl.conf.conf" in branch "HEAD"
rename "apache2/sites-available/default-ssl"->
"apache2/sites-available/default-ssl.conf" in "local/master"
Run Code Online (Sandbox Code Playgroud)
在这种情况下,合并基础(在名称下apache2/sites-available/default-ssl.conf.conf)的文件从两个差异中出现,在我们的更改与其更改中的重命名方式不同.我再次不知道是什么,如果有的话,做的Git关于变更内的文件,虽然从逻辑上讲,-X theirs 应该在任何时候申请,并采取"自己的"差异帅哥那里我们和他们发生冲突.但是,Git不知道该文件使用哪个最终名称,因此它声明了冲突.
在声明这些冲突后,Git会停止并让用户像往常一样手动解决剩余的问题.您可以git add或git rm您想要的每个文件的版本,然后git commit是结果.当然,你使用任何时间-X theirs或-X ours,这是明智的测试工作树以某种方式(目测diff文件或运行手动或自动测试,或其他)提交之前.