Ps.我不想执行 3 向差异。
计算机编程中有不同的设置。不是每个人的工作都是DevOps,github,敏捷初创公司或一些规范的开源工作流程的一部分,但仍然可以使用编程。 在我们的特定设置中,我们需要独立于 git 以外的其他工具积极参与每个贡献。 也就是说,一旦更改突出显示并可编辑,不受交互式分期等累积过程的影响,就可以使用他们选择的本地工具来解决"冲突"(实际上是"适应更改")。
尽管有些问题听起来与此问题相似,但它们的答案都没有解决一般问题,这不仅对某些上下文中的代码有用,而且对于代码文档或其他类型的版本控制文本尤其重要。
假设我们有两个分支main
(在我的 git 版本中master
)和friend
(或origin
,具体取决于每种特定情况)。我希望能够接受、拒绝或编辑每个传入的更改,因为每个更改都可以是文本的审阅者,并且需要在不更改原始意图的情况下合并更改/建议。另一个例子是主管从学生那里接收代码,或者相反。需要明确的是,这不是在更大的工作流程的上下文中,例如GitHub,拉取请求等。它只是纯粹的git。好吧,对于可能习惯于不同的VCS日常使用的人来说,这种设置的存在就足够了。
例:
mkdir force-conflict
cd force-conflict
git init .
echo -e "anbncn" > file.txt
cat file.txt
# output:
a
b
c
git add .
git commit -m "First message"
模拟朋友的贡献:
git checkout -b friend
# output:
Switched to a new branch 'friend'
echo -e "dn" >> file.txt
cat file.txt
# output:
a
b
c
d
git add .
git commit -m "Contributions from friend"
好的,我的朋友做出了贡献。回到我的代码(主或主)...
git checkout master
# output:
Switched to branch 'master'
。如果我希望传入的更改(例如,添加的最后一行)显示为冲突,那么使用下一个 paraghaph 中给出的解决方案是不够的。合并将自动包含它而不会发出警报。
对其他类似问题(我再也找不到了)的一些答案指出了 git 中的交互模式,但这是一个按顺序迭代所有更改的复杂过程,并且不能移植到其他工具/IDE(例如,Intellij 的合并实用程序或其他 IDE/diff 工具)。 其他解决方案似乎忽略了单个分支上的更改。其他人只是将整个文件标记为冲突,但不在内部使用标记<<<
指定它们。
我们从一个归零的分支(这里称为ether
)重新创建两个分支(friend
和master
),所以每个变化都将是冲突,有效地暂时取消了3-diff算法使用的共同祖先。最后,正如预期的那样,只有外部贡献和我们的更改会出现在历史记录中。
git checkout master
# output:
Switched to branch 'master'
git checkout -b ether
# output:
Switched to a new branch 'ether'
git rm -r .
# output:
rm 'file.txt'
git commit -m "Simulating an empty common ancestor"
git checkout -b master-from-empty
# output:
Switched to a new branch 'master-from-empty'
git checkout master .
git commit -m "Recovering old content as new content"
git checkout ether
git checkout -b friend-from-empty
# output:
Switched to a new branch 'friend-from-empty'
git checkout friend .
git commit -m "Recovering friend's content as ex nihilo"
git checkout master-from-empty
# output:
Switched to branch 'master-from-empty'
master-from-empty
收到来自friend-from-empty
的更改后,合并过程将按预期导致冲突:
git merge friend-from-empty
# output:
Auto-merging file.txt
CONFLICT (add/add): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
cat file.txt
# output:
a
b
c
<<<<<<< HEAD
=======
d
>>>>>>> friend-from-empty
我们可以根据需要编辑冲突...
echo -e "anbncnd reviewed by men" > file.txt
cat file.txt
# output:
a
b
c
d reviewed by me
。提交,然后回到主。
git add .
git commit -m "Accept/edit changes"
git checkout master
# output:
Switched to branch 'master'
我们必须注意保留朋友的提交并在此基础上添加我们的更改。
git merge -X theirs friend # To keep their authorship, before anything else.
git checkout master-from-empty . # Recover my edits.
git commit -m "Edit friend's contribution"
cat file.txt
# output:
a
b
c
d reviewed by me
git log
# output:
commit bbb62c91c72d880d65e330f1812d0685df6ea211 (HEAD -> master)
Author: xxx
Date: Mon Dec 28 11:39:05 2020 -0300
"Edit friend's contribution"
commit 724e67e1dc5befe85ee8e4371cb5ef415c774b5a (friend)
Author: xxx
Date: Mon Dec 28 10:12:31 2020 -0300
"Contributions from friend"
commit d06a87a4319d865ebbf352507021d74355a85d07
Author: xxx
Date: Mon Dec 28 10:05:44 2020 -0300
"First message"
一些清理...
git branch -D ether master-from-empty friend-from-empty
# output:
Deleted branch ether (was 0e892f6).
Deleted branch master-from-empty (was 5677380).
Deleted branch friend-from-empty (was 0c7bc17).
这是否可以安全地放入一般的 bash 脚本中是另外 2 小时工作的主题。