3

我只是在测试 git 以了解我是否可以将它用于我的工作。我遇到了一个看起来很小但可以通过真实代码成为真实问题的问题。我的文件看起来像: text.txt 1 2 3 4 我有一个本地分支“branch1”并在分支和主控中提交了更改。在master中,我将分支中的第一行更改为第二行。所以 master 的差异看起来像这样:

+1 master
 2
 3
 4

对于分支,它是:

 1
-2
+2b1
 3
 4

运行 git merge branch1 解决冲突:

<<<<<<< HEAD
1 master
2
=======
1
2b1
>>>>>>> branch1
3
4

我知道这很容易解决。但无论如何,这怎么会是冲突。git不应该能够合并这个吗?

4

2 回答 2

5

几个评论:

  • 首先,这样一个小例子永远不会被合并:

    警告:无法合并二进制文件:afile.txt(HEAD 与 abranch)
  • 然后,如果您有许多“小”合并冲突,您知道应该独立于上下文解决这些冲突,您可以尝试首先将您的分支重新设置在 之上master,而忽略上下文:

    git rebase -C0 主控

然后将您的分支合并到master.

忽略 rebase 的所有上下文通常不是一个好主意,但如果你确定你的修改(如“修改根本不需要上下文”),它会起作用。

git rebase 手册页

-C<n>

<n>确保每次更改前后至少有几行周围的上下文匹配。
当周围上下文的行数较少时,它们都必须匹配。
默认情况下,不会忽略任何上下文。


您可以很容易地对其进行测试(在 PowerShell 会话中,在 Xp 上使用 Git1.6.5.1)

首先创建一个小蝙蝠实用程序genfile.bat

echo hello, World %1 > afile.txt
echo hello, World %2 >> afile.txt
echo hello, World 3 >> afile.txt
echo hello, World 4 >> afile.txt
echo hello, World 5 >> afile.txt

然后创建一个 repo 并添加一个文件:

PS D:\git\tests\mergeLines> git init m0
PS D:\git\tests\mergeLines> cd m0
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1 2
PS D:\[...]\m0> git add -A
PS D:\[...]\m0> git ci -m "afile to be modified concurrently"

您的文件如下所示:

hello, World 1
hello, World 2
hello, World 3
hello, World 4
hello, World 5

在分支中修改

PS D:\[...]\m0> git co -b abranch
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1 2_modified
PS D:\[...]\m0> git ci -a -m "afile modified in abranch"

你将会有:

hello, World 1
hello, World 2_modified
hello, World 3
hello, World 4
hello, World 5

然后在master中修改

PS D:\[...]\m0> git co master
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1_master 2
PS D:\[...]\m0> git ci -a -m "afile modified in master"

这给了你:

hello, World 1_master
hello, World 2
hello, World 3
hello, World 4
hello, World 5

克隆该回购以进行第一次实验(即:合并abranchinto master

PS D:\[...]\m0> cd ..
PS D:\git\tests\mergeLines> git clone m0 m1
PS D:\git\tests\mergeLines> cd m1
PS D:\[...]\m1> git co -b abranch origin/abranch
PS D:\[...]\m1> git co master
PS D:\[...]\m1> git merge abranch

这给你一个冲突:

Auto-merging afile.txt
CONFLICT (content): Merge conflict in afile.txt
Automatic merge failed; fix conflicts and then commit the result.

PS D:\[...]\m1> type afile.txt
<<<<<<< HEAD
hello, World 1_master 
hello, World 2 
=======
hello, World 1 
hello, World 2_modified 
>>>>>>> abranch
hello, World 3 
hello, World 4 
hello, World 5 

再次克隆第一个 repo,这一次首先abranch在 之上rebase master,没有上下文:

PS D:\[...]\m1> cd ..
PS D:\git\tests\mergeLines> git clone m0 m2
PS D:\git\tests\mergeLines> cd m2
PS D:\[...]\m2> git co -b abranch origin/abranch
PS D:\[...]\m2> git rebase -C0 master

您的文件被静默合并:

hello, World 1_master
hello, World 2_modified
hello, World 3
hello, World 4
hello, World 5

当然,如果您切换回master现在合并abranch,结果将是快进合并。

PS D:\git\tests\mergeLines\m2> git co master
Switched to branch 'master'
PS D:\git\tests\mergeLines\m2> git merge abranch
Updating c8f48b4..8bee1d2
Fast forward
 afile.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
于 2009-11-18T13:04:12.010 回答
4

没有上下文可以隔离这两个更改,因此不清楚正确的解决方案应该是什么。在一行上下文中,更改是:将块“1/2”更改为“1 master/2”并将块“1/2/3”更改为“1/2b1/3”。

尝试将第二个“补丁”应用于第一个补丁的结果会导致错误解决,因为成功应用补丁所需的上下文不匹配。补丁需要“1/2/3”,但有“1 master/2/3”。

足够的上下文在更复杂的场景中很重要,因为没有它,如果本地分支已经移动了足够多的行并且在原始位置检查的最少上下文量足够,合并将很容易将补丁应用到错误的位置而不会发出警告非特定的补丁在不应该应用的时候仍然应用。

于 2009-11-18T10:43:24.387 回答