Git:将自动合并文件转换为冲突文件



我有一个包含一些代码的github存储库。另一个人分叉了该存储库并克隆了它。他们更改了一些代码。我想用他们的代码替换我的所有代码(接受他们的所有更改)。我跑了

git pull -X theirs https://github.com/epicmanmoo/JavaStudyBuddies.git master

这适用于冲突的文件,它会删除我的代码,留下他们的代码。 问题是它仅适用于包含 ===== 的文件>>>>> <<<<内容(冲突文件)。

问题是未标记为冲突的文件,例如Column.java

专栏.java

package javastudybuddies.discordbots.entities;
public enum Column {
NAME("name", "name", "projects"),
DESCRIPTION("description", "description",  "projects"),
STATUS("status", "status", "projects"),
COMPLETED("completed", "completed", "projects"),
DIFFICULTY("difficulty", "difficulty", "projects"),
TYPE("type", "type", "projects"),
USERNAME("username", "username", "users"), LEVEL("level", "level", "users"),
COUNTRY("country", "country", "users"), TIMEZONE("timezone", "timezone", "users"),
AGE("age", "age", "users"), IDSTRING("id_string", "id", "users"), TAGSTRING("tag_string", "tag", "users"),
GOAL("goal", "goal", "users"), TECH("tech", "tech", "users");
public final String databaseLabel;
public final String userLabel;
public final String table;
...

而在 https://github.com/epicmanmoo/JavaStudyBuddies/blob/master/src/main/java/javastudybuddies/discordbots/entities/Column.java

public enum Column {
NAME("name", "name", "projects"),
DESCRIPTION("description", "description",  "projects"),
STATUS("status", "status", "projects"),
TYPE("type", "type", "projects"),
COMPLETED("completed", "completed", "projects"),
DIFFICULTY("difficulty", "difficulty", "projects"),
USERNAME("username", "username", "users"), LEVEL("level", "level", "users"),
COUNTRY("country", "country", "users"), TIMEZONE("timezone", "timezone", "users"),
AGE("age", "age", "users"), IDSTRING("id_string", "id", "users"), TAGSTRING("tag_string", "tag", "users"),
GOAL("goal", "goal", "users"), TECH("tech", "tech", "users");
public final String databaseLabel;
public final String userLabel;
public final String table;
...

看到区别了吗?在我的版本中,TYPE 是最后一个,在他的版本中,TYPE 在中间,因此甚至不会注册为合并冲突。

为了调试,我运行了通常版本的git pull(没有-X theirs):

git pull https://github.com/epicmanmoo/JavaStudyBuddies.git master

该版本也是这样做的:

public enum Column {
NAME("name", "name", "projects"),
DESCRIPTION("description", "description",  "projects"),
STATUS("status", "status", "projects"),
TYPE("type", "type", "projects"),
COMPLETED("completed", "completed", "projects"),
DIFFICULTY("difficulty", "difficulty", "projects"),
TYPE("type", "type", "projects"),
USERNAME("username", "username", "users"), LEVEL("level", "level", "users"),
COUNTRY("country", "country", "users"), TIMEZONE("timezone", "timezone", "users"),
AGE("age", "age", "users"), IDSTRING("id_string", "id", "users"), TAGSTRING("tag_string", "tag", "users"),
GOAL("goal", "goal", "users"), TECH("tech", "tech", "users");
public final String databaseLabel;
public final String userLabel;
public final String table;

并且不包含该文件

git diff --name-only --diff-filter=U(冲突文件列表)

而另一个文件,例如 ProjectsBot.java 被标记为冲突 当我打开它时,我看到这个

<<<<<<< HEAD
public class ProjectsBot extends ListenerAdapter  {
private enum Command  {
=======
public class ProjectsBot extends ListenerAdapter {
private enum Command {
>>>>>>> b858d8ab9c06ee2645a0dda716d9b5e14a6db11d
CREATE_PROJECT("create project "name", "description", "difficulty""),
JOIN_PROJECT("join project 'name"");
public final String syntax;
<<<<<<< HEAD
Command(String syntax)  {
=======
Command(String syntax) {
>>>>>>> b858d8ab9c06ee2645a0dda716d9b5e14a6db11d
this.syntax = syntax;
}
}

所以,我的问题是,如果不是为了像Column.java这样的文件,

git pull -X theirs https://github.com/epicmanmoo/JavaStudyBuddies.git master

本来是理想的解决方案 - 它会自动接受他们的更改,我可以立即推送它们。有没有办法让它适用于像Column.java这样的文件?让它们在内心看起来有点像这样:

>>>>HEAD
NAME("name", "name", "projects"),
DESCRIPTION("description", "description",  "projects"),
STATUS("status", "status", "projects"),
COMPLETED("completed", "completed", "projects"),
DIFFICULTY("difficulty", "difficulty", "projects"),
TYPE("type", "type", "projects"),
=====
NAME("name", "name", "projects"),
DESCRIPTION("description", "description",  "projects"),
STATUS("status", "status", "projects"),
TYPE("type", "type", "projects"),
COMPLETED("completed", "completed", "projects"),
DIFFICULTY("difficulty", "difficulty", "projects"),
>>>>theircommit

以便-X theirs选项可以用其下方的所有内容替换=====上面的所有内容?

简短的回答是否定的,你不能那样做。

长答案是你可以这样做,但你必须编写自己的合并策略:不仅仅是一个合并驱动程序,也不是像-X theirs这样的策略选项,而是像-s my-new-strategy这样的策略,它将有Git调用git-merge-my-new-strategy,这意味着你必须在$PATH中有一个这样拼写的命令。 编写策略非常困难(一种方法是克隆 Git 的副本,然后将现有的递归策略复制到新的策略中,并在新策略中编写一堆新的 C 代码,使用递归策略作为起点)。

如果涉及的文件不多,我建议改用:

git checkout <branch>
git merge --no-commit <options> <commit-specifier>

然后使用您认为最好的任何技术手动解析每个文件。--no-commit意味着无论 Git 是否认为合并成功(-X theirs它通常会认为合并成功),合并都会停止,就好像存在冲突一样,这使您可以编辑和git add文件。

当你完成所有操作时——现在使用git diff HEADgit diff --cached HEAD将工作树(第一个命令)或索引(第二个命令)中的内容与HEAD提交进行比较很有用,看看最终合并结果会有什么不同——运行:

git merge --continue

提交合并,或:

git commit

如果您的 Git 太旧而无法支持git merge --continue. (git merge --continue命令只是运行git commit,但在运行git commit之前有一个合并要提交,所以它充当检查以确保没有其他错误。 例如,如果您在解决问题时不小心执行了git reset,则可能已删除合并状态。 在这种情况下,最终git commit只会进行普通的非合并提交,而不是进行合并提交。 这也是可以恢复的,但是修复它比一开始就不犯错误更烦人 - 所以git merge --continue是一件好事。

最新更新