通过交互式rebase在分支中间修改提交需要解决冲突

时间:2016-07-11 15:21:28

标签: git rebase

例如,master分支具有init提交,其内容由:

创建
echo "init" > data

我创建了功能分支:

git checkout -b feature

然后是连续提交的更改:

for newLine in feature1 feature2; do echo "$newLine" >> data; git commit -am "$newLine" ; done

我想更改feature1 commit:

git rebase -i master

制作'编辑' feature1提交,更改数据文件并继续rebase:

sed -i 's/feature1/F/g' data; git add data; git rebase --continue

但是存在冲突:

init
<<<<<<< HEAD
F
=======
feature1
feature2
>>>>>>> f4ac9dc... feature2

是否可以避免这种冲突。我只需要应用差异。结果将是:

init
F
feature2

不合适的解决方案:

git rebase -s recursive -X {ours,theirs} -i master

2 个答案:

答案 0 :(得分:2)

没有;至少,它(不容易)可能避免或忽略这种冲突。编辑距离太近了。

(以下是对git默认行为的描述.Leon的答案显示了通过定义自定义合并工具来解决这些限制的一种方法。)

通过创建表示一个分支中的更改的补丁(与diff -u一样)并将其应用(与patch一样)到另一个分支来合并工作。要应用补丁,上下文必须相同。 (参见How do diff/patch work and how safe are they?)上下文,即diff中实际删除和插入的几行,是告诉补丁工具它正在修补文件的右边部分。

Git不会删除与原始中删除的行完全匹配的行,并且除了与原始行完全匹配的行之外,它不会插入行。所以它不会插入功能2&#39;在&#39; F&#39;之后因为它在补丁中说&#39; feature2&#39;追随&#39; feature1&#39; (而不是在&#39; F&#39;之后)。

合并时,每次冲突附近发生变化时,您都必须解决此冲突。当你显然必须对连续几十次提交进行相同的更正时,这可能会变得乏味,但我不知道周围的好方法。

在某些情况下,您可以使用其他merge strategy来让您的生活更轻松。请注意此功能,因为某些策略不如默认策略保守,并且可能很乐意破坏您的代码。无论如何,我不认为有一个合并策略可以解决示例问题。

答案 1 :(得分:2)

I was able to come-up with a custom mergetool that allows to automatically resolve conflicts for the described scenario under the following assumptions:

  1. The amending change and upstream changes (if any) are limited to changed lines (i.e. no lines are added or removed).

  2. The conflict is solely due to abutment of changes (i.e. the changes must not overlap).

Then, such a conflict can be resolved by converting the later change to an ed script, that is expressed via absolute line numbers, and running that script on the local version of the file.

The dummymerge script below implements that idea.

It must be registered with git as follows:

git config mergetool.dummymerge.cmd 'dummymerge $BASE $LOCAL $REMOTE > $MERGED'
git config mergetool.dummymerge.trustExitCode true

Use it to auto-resolve conflicts of the described type as follows:

git mergetool -t dummymerge

dummymerge

#!/bin/bash

myname=$(basename "$0")

if [ $# -ne 3 ]
then
    echo "Usage: $myname base_rev rev1 rev2"
    exit 1
fi

diff -e "$1" "$3"|patch -e -o - "$2"
相关问题