gpt4 book ai didi

git - 如何通过保留双方的所有添加来解决 git 冲突?

转载 作者:太空狗 更新时间:2023-10-29 13:33:12 31 4
gpt4 key购买 nike

我一直遇到以下问题,我想知道是否有使用现有 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";
+ }
+};

现在,当我尝试将 mybranchmaster merge (或将 mybranch rebase 到 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 应该能够自动创建此解决方案,因为它只需要添加在一个分支中添加的所有行,然后添加在另一个分支中添加的所有行,而无需删除公共(public)行。我怎样才能让 git 为我做这件事?

(允许我自定义顺序的解决方案的加分 - Dog 优先或 Cat 优先。)

最佳答案

一个叫做 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

确保结果是你想要的,然后清理一下并添加最终的 merge 版本:

$ 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 - 如何通过保留双方的所有添加来解决 git 冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46182123/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com