如何通过保留双方的所有添加来解决 git 冲突?
How to resolve a git conflict by keeping all additions from both sides?
我一直 运行 解决以下问题,我想知道是否有使用现有 git 命令的简单解决方案,或者我是否需要 write a custom merge driver.
这是一个演示我的问题的例子:假设我的回购的 master
分支有以下文件:
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
我创建了一个名为 mybranch
的新分支并进行了以下更改:
diff --git a/animal.hpp b/animal.hpp
index e27c4bf..3bb691a 100644
--- a/animal.hpp
+++ b/animal.hpp
@@ -5,3 +5,13 @@ class Animal
public:
virtual std::string say() const = 0;
};
+
+class Dog : public Animal
+{
+public:
+ virtual std::string
+ say() const override
+ {
+ return "woof";
+ }
+};
与此同时,其他人添加了以下与 master
非常相似的更改:
diff --git a/animal.hpp b/animal.hpp
index e27c4bf..310d5a7 100644
--- a/animal.hpp
+++ b/animal.hpp
@@ -5,3 +5,13 @@ class Animal
public:
virtual std::string say() const = 0;
};
+
+class Cat : public Animal
+{
+public:
+ virtual std::string
+ say() const override
+ {
+ return "meow";
+ }
+};
现在,当我尝试将 mybranch
与 master
合并(或将 mybranch
变基到 master
时),我遇到了冲突:
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
<<<<<<< HEAD
class Dog : public Animal
=======
class Cat : public Animal
>>>>>>> master
{
public:
virtual std::string
say() const override
{
<<<<<<< HEAD
return "woof";
=======
return "meow";
>>>>>>> master
}
};
此冲突的正确解决方法是:
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
class Dog : public Animal
{
public:
virtual std::string
say() const override
{
return "woof";
}
};
class Cat : public Animal
{
public:
virtual std::string
say() const override
{
return "meow";
}
};
我通过手动编辑文件创建了上述解决方案,复制了两个 类 通用的代码,并删除了冲突标记。但我认为 git 应该能够自动创建此解决方案,因为它只需要添加在一个分支中添加的所有行,然后添加在另一个分支中添加的所有行,而无需重复删除 common线。我怎样才能让 git 为我做这个?
(允许我自定义顺序的解决方案的奖励积分 - 先 Dog
或先 Cat
。)
Git 不能 在典型的工作流程中为您处理这种合并。这就是 为什么 它要求您进行干预。它非常非常努力地尝试不丢失任何一方的更改,但它真的不知道你想如何解决它或你想如何修复它。
您应该研究一个合并工具来帮助您解决这个问题。或者,您可以手动执行此操作并删除 Git 合并冲突行,然后自己处理这两个文件的合并。
那里是一个叫做union merge的东西:
$ printf 'animal.hpp\tmerge=union\n' > .gitattributes
$ git merge --no-commit mybranch
Auto-merging animal.hpp
Automatic merge went well; stopped before committing as requested
在这种特殊情况下,它实际上达到了预期的效果。然而,在许多情况下,它可能会严重失火,并且 永远不会失败 (我的意思是它从不认为自己 已经 失败,即使它产生了一个无意义的结果),所以毕竟在 .gitattributes
中设置它并不是真正明智的(除非你有一个非常罕见的情况)。
相反,最好在事后调用它,使用 git merge-file
:
$ git merge --abort
$ rm .gitattributes
$ git merge mybranch
Auto-merging animal.hpp
CONFLICT (content): Merge conflict in animal.hpp
Automatic merge failed; fix conflicts and then commit the result.
$ git show :1:animal.hpp > animal.hpp.base
$ git show :2:animal.hpp > animal.hpp.ours
$ git show :3:animal.hpp > animal.hpp.theirs
$ mv animal.hpp.ours animal.hpp
$ git merge-file --union animal.hpp animal.hpp.base animal.hpp.theirs
确保结果是你想要的,然后清理一下并添加最终合并版本:
$ rm animal.hpp.base animal.hpp.theirs
$ git add animal.hpp
现在您可以提交结果了。 编辑: 这是我得到的结果(在两种情况下):
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
class Cat : public Animal
{
public:
virtual std::string
say() const override
{
return "meow";
}
};
class Dog : public Animal
{
public:
virtual std::string
say() const override
{
return "woof";
}
};
我一直 运行 解决以下问题,我想知道是否有使用现有 git 命令的简单解决方案,或者我是否需要 write a custom merge driver.
这是一个演示我的问题的例子:假设我的回购的 master
分支有以下文件:
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
我创建了一个名为 mybranch
的新分支并进行了以下更改:
diff --git a/animal.hpp b/animal.hpp
index e27c4bf..3bb691a 100644
--- a/animal.hpp
+++ b/animal.hpp
@@ -5,3 +5,13 @@ class Animal
public:
virtual std::string say() const = 0;
};
+
+class Dog : public Animal
+{
+public:
+ virtual std::string
+ say() const override
+ {
+ return "woof";
+ }
+};
与此同时,其他人添加了以下与 master
非常相似的更改:
diff --git a/animal.hpp b/animal.hpp
index e27c4bf..310d5a7 100644
--- a/animal.hpp
+++ b/animal.hpp
@@ -5,3 +5,13 @@ class Animal
public:
virtual std::string say() const = 0;
};
+
+class Cat : public Animal
+{
+public:
+ virtual std::string
+ say() const override
+ {
+ return "meow";
+ }
+};
现在,当我尝试将 mybranch
与 master
合并(或将 mybranch
变基到 master
时),我遇到了冲突:
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
<<<<<<< HEAD
class Dog : public Animal
=======
class Cat : public Animal
>>>>>>> master
{
public:
virtual std::string
say() const override
{
<<<<<<< HEAD
return "woof";
=======
return "meow";
>>>>>>> master
}
};
此冲突的正确解决方法是:
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
class Dog : public Animal
{
public:
virtual std::string
say() const override
{
return "woof";
}
};
class Cat : public Animal
{
public:
virtual std::string
say() const override
{
return "meow";
}
};
我通过手动编辑文件创建了上述解决方案,复制了两个 类 通用的代码,并删除了冲突标记。但我认为 git 应该能够自动创建此解决方案,因为它只需要添加在一个分支中添加的所有行,然后添加在另一个分支中添加的所有行,而无需重复删除 common线。我怎样才能让 git 为我做这个?
(允许我自定义顺序的解决方案的奖励积分 - 先 Dog
或先 Cat
。)
Git 不能 在典型的工作流程中为您处理这种合并。这就是 为什么 它要求您进行干预。它非常非常努力地尝试不丢失任何一方的更改,但它真的不知道你想如何解决它或你想如何修复它。
您应该研究一个合并工具来帮助您解决这个问题。或者,您可以手动执行此操作并删除 Git 合并冲突行,然后自己处理这两个文件的合并。
那里是一个叫做union merge的东西:
$ printf 'animal.hpp\tmerge=union\n' > .gitattributes
$ git merge --no-commit mybranch
Auto-merging animal.hpp
Automatic merge went well; stopped before committing as requested
在这种特殊情况下,它实际上达到了预期的效果。然而,在许多情况下,它可能会严重失火,并且 永远不会失败 (我的意思是它从不认为自己 已经 失败,即使它产生了一个无意义的结果),所以毕竟在 .gitattributes
中设置它并不是真正明智的(除非你有一个非常罕见的情况)。
相反,最好在事后调用它,使用 git merge-file
:
$ git merge --abort
$ rm .gitattributes
$ git merge mybranch
Auto-merging animal.hpp
CONFLICT (content): Merge conflict in animal.hpp
Automatic merge failed; fix conflicts and then commit the result.
$ git show :1:animal.hpp > animal.hpp.base
$ git show :2:animal.hpp > animal.hpp.ours
$ git show :3:animal.hpp > animal.hpp.theirs
$ mv animal.hpp.ours animal.hpp
$ git merge-file --union animal.hpp animal.hpp.base animal.hpp.theirs
确保结果是你想要的,然后清理一下并添加最终合并版本:
$ rm animal.hpp.base animal.hpp.theirs
$ git add animal.hpp
现在您可以提交结果了。 编辑: 这是我得到的结果(在两种情况下):
$ cat animal.hpp
#include <string>
class Animal
{
public:
virtual std::string say() const = 0;
};
class Cat : public Animal
{
public:
virtual std::string
say() const override
{
return "meow";
}
};
class Dog : public Animal
{
public:
virtual std::string
say() const override
{
return "woof";
}
};