git冲突解决文件并不总是代表源文件中的每一行吗?

Do git conflict resolution files not always represent every line in the source files?

本文关键字:一行 源文件 文件 解决 冲突 git      更新时间:2023-10-16

我在一个有三个分支的repo中工作:master, stage和dev.我已经在dev上工作了一段时间,我已经准备好推送我的更改,并且已经将我的本地提交压缩成一个单独的提交用于发布。我想用团队成员推送到远程"阶段"分支的任何工作来更新我的本地repo。我想:

  1. 当我在开发
  2. 时,将任何更改推到阶段
  3. 将代表我的工作的'dev'上的单个提交重置为'stage'
  4. 其他与出版相关的内容

(没有其他人引用我的本地开发分支,所以我很乐意重新定位)

我做

:

git checkout stage
git pull
git checkout dev

情况如下:

foo.cpp on branch dev (out of date)

...
if (conditional)
{
    Datastructure data = someValue;
    cout << "Some text" << endl;
    cout << "More text" << endl;
}
return 0; // rest of function NYI
if (someOtherConditional) {
    Bob bob = makeBob();
    Fred fred = makeFred();
    ...
}
...

foo.cpp on branch stage (more recent)

...
if (conditional)
{
    Datastructure data = someValue;
    cout << "Some text" << endl;
    cout << "More text" << endl;
    cout << "Even more text" << endl;
    cout << "Lots of text" << endl;
    // todo: fix this hackish code
    if (anotherConditional) {
        myBool = true;
    }
}
if (yetAnotherConditional) {
    Bob bob = makeBob();
    Fred fred = makeFred();
    ...
}
...

最后,我做了:

git rebase stage

我得到一些冲突,包括foo.cpp。我打开foo.cpp,得到:

foo.cpp

...
if (conditional)
{
    Datastructure data = someValue;
    cout << "Some text" << endl;
    cout << "More text" << endl;
<<<<<<<< HEAD
    cout << "Even more text" << endl;
    cout << "Lots of text" << endl;
    // todo: fix this hackish code
    if (anotherConditional) {
        myBool = true;
    }
}
=======
return 0; // rest of function NYI
if (someOtherConditional) {
>>>>>>> mostRecentDevCommit
if (yetAnotherConditional) {
    Bob bob = makeBob();
    Fred fred = makeFred();
    ...
}
...

mostRecentDevCommit中缺少与第一个if (conditional) {匹配的右括号是怎么回事?

为什么if (yetAnotherConditional) {在冲突解决部分之外-分支'dev'上的foo.cpp没有这个!

谢谢-我实际上不需要弄清楚这个来解决冲突,但我想知道Git在这里做什么。

对于这种情况,要做的事情是检查原始版本,看看是什么让这两个替换的大块看起来像一个最小的编辑。

为了将来的参考,您可以要求"diff3"风格的冲突报告,它将在报告中包含原始的块,可以根据特定文件的需要,也可以作为默认值:

git -c merge.conflictstyle=diff3 checkout -m -- paths # just these for now
git config --global merge.conflictstyle diff3 # or as global default

您可以通过检查refflogs来执行任何合并或重新base的一次性重新运行,这里git reflog dev将包含像

这样的一对。
9d7143d dev@{1}: rebase finished: refs/heads/dev onto 0f30b87ba7a2499c2b5d87b17d26ea8d353b8e34
5e58907 dev@{2}: commit: -

有了这些数字,你就可以

git -c merge.conflictstyle=diff3 rebase dev@{2} 0f30b87
# (look at foo.cpp, if the conflict report is still confusing, post it?)
git rebase --abort
git checkout @{-1}     # <-- takes you back to your previous checkout

我能想到的最好的没有,也许它是(也许更多的行删除在两个替换):

    }
    return 0;
}
void func(type parm ...)
{
    if (someOtherConditional) {

三个版本似乎都是正确的