git - Git合并导致不合理的冲突
问题描述
我基本上在几乎所有从 current_iteration 合并到我的分支中的文件上都遇到了冲突。这令人发狂,让许多人惊讶地看着和挠头。
我目前正在使用带有 git version 的 mac 工作2.18.0
。我的同行都在 Windows git 版本上工作2.12.2.windows.2
。
MacBook 配置
macbook-pro:~ chris$ git config -l
credential.helper=osxkeychain
user.email=chris.hinshaw@foo.com
user.name=Chris Hinshaw
user.autocrlf=false
视窗配置
C:> git config -l
core.symlinks=false
core.autocrlf=true
core.fscache=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
help.format=html
rebase.autosquash=true
http.sslcainfo=C:/Users/…
diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.required=true
filter.lfs.process=git-lfs filter-process
credential.helper=manager
merge.tool=kdiff3
mergetool.kdiff3.cmd="C:\\Program Files\\KDiff3\\kdiff3" $BASE $LOCAL $REMOTE -o $MERGED
difftool.kdiff3.path="C:\\Program Files\\KDiff3\\kdiff3"
difftool.kdiff3.keepbackup=false
difftool.kdiff3.trustexitcode=false
alias.lg=!git lg1
alias.lg1=!git lg1-specific --all
alias.lg2=!git lg2-specific --all
alias.lg3=!git lg3-specific --all
alias.lg1-specific=log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'
alias.lg2-specific=log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
alias.lg3-specific=log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'
core.whitespace=cr-at-eol
core.autocrlf=true
credential.helper=manager
http.emptyauth=true
当前迭代分支更改
在这里,我正在检查 current_iteration 并确保它完全是最新的。我表明差异是从类中删除组件注释的单行更改。
macbook-pro:devel chris$ git checkout current_iteration
macbook-pro:devel chris$ git pull origin
commit 81dea298657c882a5c32ee3f30b459643035024e
Author: Them
Date: Wed Aug 1 11:12:12 2018 -0500
commit 0676ffd81a83cfbdf18a3b1fc93f31439d7e3a00
Author: Me
Date: Mon Jul 30 18:01:53 2018 -0500
commit 0d8f7a2dfe35d43ef03af339694479189ff86b79
Author: Me
Date: Wed Jul 25 15:04:44 2018 -0500
将应用于我当前分支的差异
git diff 81dea~1 ./somepath/OjaiLifecycleListener.java
./somepath/OjaiLifecycleListener.javaindex 08c3e66c..f0864c52 100644
--- a/somepath/OjaiLifecycleListener.java
+++ b/somepath/OjaiLifecycleListener.java
@@ -14,7 +14,7 @@ import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
-@Component
+
public class OjaiLifecycleListener implements SmartLifecycle {
private static final Logger logger = LoggerFactory.getLogger(OjaiLifecycleListener.class);
我的分行
macbook-pro:devel chris$ git checkout feature/mapr-autoinit
macbook-pro:devel chris$ git pull origin
git diff feature/feature/mapr-autoinit..current_iteration ./somepath/OjaiLifecycleListener.java diff --git a/somepath/OjaiLifecycleListener.java index 5d29f3eb..f0864c52 100644
--- a/somepath/OjaiLifecycleListener.java
+++ b/somepath/OjaiLifecycleListener.java @@ -14,7 +14,7 @@ import java.util.Collection; import java.util.Map; import java.util.function.Supplier;
-@Component
+ public class OjaiLifecycleListener implements SmartLifecycle {
private static final Logger logger = LoggerFactory.getLogger(OjaiLifecycleListener.class); @@ -52,23 +52,25 @@ public class OjaiLifecycleListener implements SmartLifecycle {
}
private void createIfMissing(Class<? extends OjaiRepository> cls) throws IOException {
- logger.debug("Configuring reopsitory {}", cls.getName());
+ logger.info("configuring reopsitory {}", cls.getName());
// final Table table = cls.getAnnotation(Table.class); // No worky cuz of cglib
final Table table = AnnotationUtils.findAnnotation(cls, Table.class);
if (table != null) {
- logger.debug("Found table annotation for class {} with table id {}", cls.getSimpleName(), table.name());
+ logger.info("Found table annotation for class {} with table id {}", cls.getSimpleName(), table.name());
final String tablePath = tableAdmin.getEnvironmentQualifiedPath(table.name()).toString();
boolean exists = tableAdmin.tableExists(tablePath);
- logger.info("Repository => {}, Path => {}, Exists => {} ", cls.getSimpleName(), tablePath, exists);
+ logger.info("Table for class {} with table path {} exists : {} ", cls.getSimpleName(), tablePath, exists);
+
if (! exists) {
logger.info("Creating table for class {} with table path {}", cls.getSimpleName(), tablePath);
tableAdmin.createTable(tablePath, defaultTablePerms, defaultCFPerms);
}
} else {
- logger.warn("Repository {} is missing @Table annotation", cls);
+ logger.warn("Found table without table annotation {} ", cls);
}
}
+
@Override
public boolean isAutoStartup() {
return true;
对我来说,上面的补丁看起来完全合理,应该可以正常应用。没有重复的公共行被更改。
合并
git merge -s recursive -Xignore-space-at-eol -Xignore-space-change current_iteration
这会导致大量的冲突。但是我们可以查看单个文件
<<<<<<< HEAD
@Component
public class OjaiLifecycleListener implements SmartLifecycle {
=======
>>>>>>> current_iteration
public class OjaiLifecycleListener implements SmartLifecycle {
<<<<<<< HEAD
private final Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier;
private final OjaiTableAdmin tableAdmin;
private final Map<String, String> defaultTablePerms;
private final Map<String, String> defaultCFPerms;
private volatile boolean isStarted = false;
=======
private static final Logger logger = LoggerFactory.getLogger(OjaiLifecycleListener.class);
private final Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier;
private final OjaiTableAdmin tableAdmin;
private final Map<String, String> defaultTablePerms;
private final Map<String, String> defaultCFPerms;
private volatile boolean isStarted = false;
>>>>>>> current_iteration
@Inject
public OjaiLifecycleListener(Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier, OjaiTableAdmin tableAdmin,
@Named("mapr.mapr.ojai.table.perms") Map<String, String> defaultTablePerms,
@Named("mapr.mapr.ojai.cf.perms") Map<String, String> defaultCFPerms) {
this.ojaiRepositorySupplier = ojaiRepositorySupplier;
this.tableAdmin = tableAdmin;
this.defaultTablePerms = defaultTablePerms;
this.defaultCFPerms = defaultCFPerms;
}
@Override
public void start() {
logger.info("Configuring Ojai Tables");
if (isStarted) return;
ojaiRepositorySupplier.get().forEach(c -> {
try {
createIfMissing(c);
} catch (IOException e) {
throw new RuntimeException("Failed to create ojai table: " + c.getName(), e);
}
});
isStarted = true;
}
private void createIfMissing(Class<? extends OjaiRepository> cls) throws IOException {
<<<<<<< HEAD
logger.debug("Configuring reopsitory {}", cls.getName());
// final Table table = cls.getAnnotation(Table.class); // No worky cuz of cglib
final Table table = AnnotationUtils.findAnnotation(cls, Table.class);
if (table != null) {
logger.debug("Found table annotation for class {} with table id {}", cls.getSimpleName(), table.name());
final String tablePath = tableAdmin.getEnvironmentQualifiedPath(table.name()).toString();
boolean exists = tableAdmin.tableExists(tablePath);
logger.info("Repository => {}, Path => {}, Exists => {} ", cls.getSimpleName(), tablePath, exists);
=======
logger.info("configuring reopsitory {}", cls.getName());
// final Table table = cls.getAnnotation(Table.class); // No worky cuz of cglib
final Table table = AnnotationUtils.findAnnotation(cls, Table.class);
if (table != null) {
logger.info("Found table annotation for class {} with table id {}", cls.getSimpleName(), table.name());
final String tablePath = tableAdmin.getEnvironmentQualifiedPath(table.name()).toString();
boolean exists = tableAdmin.tableExists(tablePath);
logger.info("Table for class {} with table path {} exists : {} ", cls.getSimpleName(), tablePath, exists);
>>>>>>> current_iteration
if (! exists) {
logger.info("Creating table for class {} with table path {}", cls.getSimpleName(), tablePath);
tableAdmin.createTable(tablePath, defaultTablePerms, defaultCFPerms);
}
} else {
<<<<<<< HEAD
logger.warn("Repository {} is missing @Table annotation", cls);
=======
logger.warn("Found table without table annotation {} ", cls);
>>>>>>> current_iteration
}
}
我查看了空格问题,并尝试了所有可能的忽略空格组合。我尝试使用他们的配置选项和 kdiff 合并选项。我曾尝试使用 dos2unix 工具重新格式化文件。我唯一能想到的是,这是 autosquash 选项的一个问题,它并不总是在我的本地分支上正确地重放更改。我们正在使用 TFS btw,它是一个 Windows git 存储库,如果这有什么不同的话。
更新 1
抱歉,我正在重命名分支以使其更符合 git 标准。只有两个分支 current_iteration 和 features/mapr-autoinit。
import javax.inject.Named;
import javax.persistence.Table;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.function.Supplier;
<<<<<<< HEAD
@Component
public class OjaiLifecycleListener implements SmartLifecycle {
||||||| merged common ancestors
@Service
public class OjaiLifecycleListener implements Lifecycle {
=======
>>>>>>> current_iteration
public class OjaiLifecycleListener implements SmartLifecycle {
<<<<<<< HEAD
private final Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier;
private final OjaiTableAdmin tableAdmin;
private final Map<String, String> defaultTablePerms;
private final Map<String, String> defaultCFPerms;
||||||| merged common ancestors
=======
private static final Logger logger = LoggerFactory.getLogger(OjaiLifecycleListener.class);
>>>>>>> current_iteration
<<<<<<< HEAD
private volatile boolean isStarted = false;
||||||| merged common ancestors
private final ApplicationContext context;
=======
private final Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier;
private final OjaiTableAdmin tableAdmin;
private final Map<String, String> defaultTablePerms;
private final Map<String, String> defaultCFPerms;
>>>>>>> current_iteration
<<<<<<< HEAD
@Inject
public OjaiLifecycleListener(Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier, OjaiTableAdmin tableAdmin,
@Named("mapr.mapr.ojai.table.perms") Map<String, String> defaultTablePerms,
@Named("mapr.mapr.ojai.cf.perms") Map<String, String> defaultCFPerms) {
this.ojaiRepositorySupplier = ojaiRepositorySupplier;
this.tableAdmin = tableAdmin;
this.defaultTablePerms = defaultTablePerms;
this.defaultCFPerms = defaultCFPerms;
||||||| merged common ancestors
public OjaiLifecycleListener(ApplicationContext context) {
this.context = context;
=======
private volatile boolean isStarted = false;
@Inject
public OjaiLifecycleListener(Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier, OjaiTableAdmin tableAdmin,
@Named("mapr.mapr.ojai.table.perms") Map<String, String> defaultTablePerms,
@Named("mapr.mapr.ojai.cf.perms") Map<String, String> defaultCFPerms) {
this.ojaiRepositorySupplier = ojaiRepositorySupplier;
this.tableAdmin = tableAdmin;
this.defaultTablePerms = defaultTablePerms;
this.defaultCFPerms = defaultCFPerms;
>>>>>>> current_iteration
}
@Override
public void start() {
<<<<<<< HEAD
logger.info("Configuring Ojai Tables");
if (isStarted) return;
||||||| merged common ancestors
logger.info("starting ojai listener");
final Map<String, OjaiRepository> repositories = context.getBeansOfType(OjaiRepository.class);
logger.info("found {} ojai repositories", repositories.size());
repositories.forEach(OjaiLifecycleListener::createIfMissing);
=======
logger.info("Configuring Ojai Tables");
if (isStarted) return;
ojaiRepositorySupplier.get().forEach(c -> {
try {
createIfMissing(c);
} catch (IOException e) {
throw new RuntimeException("Failed to create ojai table: " + c.getName(), e);
}
});
isStarted = true;
}
>>>>>>> current_iteration
<<<<<<< HEAD
ojaiRepositorySupplier.get().forEach(c -> {
try {
createIfMissing(c);
} catch (IOException e) {
throw new RuntimeException("Failed to create ojai table: " + c.getName(), e);
}
});
isStarted = true;
}
private void createIfMissing(Class<? extends OjaiRepository> cls) throws IOException {
logger.debug("Configuring reopsitory {}", cls.getName());
// final Table table = cls.getAnnotation(Table.class); // No worky cuz of cglib
final Table table = AnnotationUtils.findAnnotation(cls, Table.class);
if (table != null) {
logger.debug("Found table annotation for class {} with table id {}", cls.getSimpleName(), table.name());
final String tablePath = tableAdmin.getEnvironmentQualifiedPath(table.name()).toString();
boolean exists = tableAdmin.tableExists(tablePath);
logger.info("Repository => {}, Path => {}, Exists => {} ", cls.getSimpleName(), tablePath, exists);
if (! exists) {
logger.info("Creating table for class {} with table path {}", cls.getSimpleName(), tablePath);
tableAdmin.createTable(tablePath, defaultTablePerms, defaultCFPerms);
}
} else {
logger.warn("Repository {} is missing @Table annotation", cls);
}
||||||| merged common ancestors
=======
private void createIfMissing(Class<? extends OjaiRepository> cls) throws IOException {
logger.info("configuring reopsitory {}", cls.getName());
// final Table table = cls.getAnnotation(Table.class); // No worky cuz of cglib
final Table table = AnnotationUtils.findAnnotation(cls, Table.class);
if (table != null) {
logger.info("Found table annotation for class {} with table id {}", cls.getSimpleName(), table.name());
final String tablePath = tableAdmin.getEnvironmentQualifiedPath(table.name()).toString();
boolean exists = tableAdmin.tableExists(tablePath);
logger.info("Table for class {} with table path {} exists : {} ", cls.getSimpleName(), tablePath, exists);
if (! exists) {
logger.info("Creating table for class {} with table path {}", cls.getSimpleName(), tablePath);
tableAdmin.createTable(tablePath, defaultTablePerms, defaultCFPerms);
}
} else {
logger.warn("Found table without table annotation {} ", cls);
}
>>>>>>> current_iteration
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public void stop(Runnable callback) {
stop();
callback.run();
}
更新 2
@Torek 现在正在帮助我理解这一点。他指出了一个我对 git merge base 不熟悉的命令
macbook-pro:fido-service chris$ git merge-base current_iteration feature/mapr-autoinit
295c022c9f3d6da92e87f2addec1bbd7be30c5d7
根据输出,这将解释冲突。
@@ -1,58 +1,97 @@
package com.apc.its.services.fido.persistence.mapr;
-import com.mapr.fs.tables.MapRAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.Lifecycle;
-import org.springframework.stereotype.Service;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.stereotype.Component;
+import javax.inject.Inject;
+import javax.inject.Named;
import javax.persistence.Table;
+import java.io.IOException;
+import java.util.Collection;
import java.util.Map;
+import java.util.function.Supplier;
-@Service
-public class OjaiLifecycleListener implements Lifecycle {
+@Component
+public class OjaiLifecycleListener implements SmartLifecycle {
private static final Logger logger = LoggerFactory.getLogger(OjaiLifecycleListener.class);
+ private final Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier;
+ private final OjaiTableAdmin tableAdmin;
+ private final Map<String, String> defaultTablePerms;
+ private final Map<String, String> defaultCFPerms;
- private final ApplicationContext context;
+ private volatile boolean isStarted = false;
- public OjaiLifecycleListener(ApplicationContext context) {
-
- this.context = context;
+ @Inject
+ public OjaiLifecycleListener(Supplier<Collection<Class<? extends OjaiRepository>>> ojaiRepositorySupplier, OjaiTableAdmin tableAdmin,
+ @Named("mapr.mapr.ojai.table.perms") Map<String, String> defaultTablePerms,
:
更新 3
我想我可能对导致此问题的原因有所了解。我经常遇到冲突的原因是我的分支正在跟踪另外两个分支。一个是 master,另一个是 master 的一个分支,即 current_iteration。看来我的分支正在破译最好的
git remote show origin
...
Local branches configured for 'git pull':
current_iteration merges with remote current_iteration
feature/mapr-autoinit merges with remote feature/mapr-autoinit
master merges with remote master
这导致合并必须找到一个共同的祖先,这将是最后一次将 current_iteration 合并到 master 中(显然是前一段时间)。
这表明 git merge 正在尝试从几个月前的修订版 1b813c6 合并。这将解释为什么要重新应用更改等。
git checkout feature/mapr-autoinit
Switched to branch 'feature/mapr-autoinit'
Your branch is up to date with 'origin/feature/mapr-autoinit'.
macbook-pro:fido-service rkh477$ git show-branch --merge-base
1b813c6c48f1c11d65862331f6667258d536adf9
macbook-pro:fido-service rkh477$ git log 1b813c6c48f1c11d65862331f6667258d536adf9
commit 1b813c6c48f1c11d65862331f6667258d536adf9
Author: Somebody
Date: Wed Feb 28 16:30:02 2018 -0600
我假设我需要用 master 重新设置 current_iteration 来解决这个问题?任何帮助,将不胜感激。
解决方案
推荐阅读
- input - 单击 ArrowUp 和 ArrowDown 时输入失去焦点
- java - reactor-netty HttpClient 的默认读取和连接超时
- reactjs - 对输入做出反应 onChange 重新呈现整个组件
- unity3d - Unity 输入系统,缺少上下文菜单选项
- jestjs - 如何使用 store 和 propsData 安装 Nuxt 组件以进行 Jest 测试
- javascript - 如何根据我是否得到不同的对象来映射数据?JS 角 2+
- laravel - LogManager::debug() 必须是 laravel 中的数组类型
- reactjs - Ant Design-仅在字段外单击时进行表单验证
- visual-studio-code - 如何创建自定义开发容器?
- image - 如何使用 Elfinder 上传图片