git: read pull.rebase config value for default update method IDEA-152689

Note that '*.rebase' configs can have the following values:
  true, interactive, preserve
  yes (not specified in man)
  false, no (both not specified in man)
This commit is contained in:
Kirill Likhodedov
2017-11-30 18:35:35 +03:00
parent 8ce22dab61
commit 27a64cdd67
3 changed files with 90 additions and 6 deletions
@@ -107,6 +107,13 @@ public enum GitVersionSpecialty {
}
},
KNOWS_PULL_REBASE {
@Override
public boolean existsIn(@NotNull GitVersion version) {
return version.isLaterOrEqual(new GitVersion(1, 7, 9, 0));
}
},
/**
* {@code --no-walk=unsorted} <br/>
* Before this version {@code --no-walk} didn't take any parameters.
@@ -28,6 +28,7 @@ import git4idea.commands.Git;
import git4idea.commands.GitCommand;
import git4idea.commands.GitLineHandler;
import git4idea.config.GitConfigUtil;
import git4idea.config.GitVersionSpecialty;
import git4idea.config.UpdateMethod;
import git4idea.merge.MergeChangeCollector;
import git4idea.repo.GitRepository;
@@ -37,6 +38,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import static git4idea.GitUtil.HEAD;
import static git4idea.config.UpdateMethod.MERGE;
import static git4idea.config.UpdateMethod.REBASE;
/**
* Updates a single repository via merge or rebase.
@@ -99,19 +102,46 @@ public abstract class GitUpdater {
@NotNull
public static UpdateMethod resolveUpdateMethod(@NotNull GitRepository repository) {
Project project = repository.getProject();
GitLocalBranch branch = repository.getCurrentBranch();
boolean rebase = false;
if (branch != null) {
String branchName = branch.getName();
try {
String rebaseValue = GitConfigUtil.getValue(repository.getProject(), repository.getRoot(),
"branch." + branch.getName() + ".rebase");
rebase = rebaseValue != null && rebaseValue.equalsIgnoreCase("true");
String rebaseValue = GitConfigUtil.getValue(project, repository.getRoot(), "branch." + branchName + ".rebase");
if (rebaseValue != null) {
if (isRebaseValue(rebaseValue)) {
return REBASE;
}
if (rebaseValue.equalsIgnoreCase("false") || rebaseValue.equalsIgnoreCase("no")) {
// explicit override of a more generic pull.rebase config value
return MERGE;
}
LOG.warn("Unknown value for branch." + branchName + ".rebase: " + rebaseValue);
}
}
catch (VcsException e) {
LOG.warn("Couldn't get git config branch." + branch.getName() + ".rebase", e);
LOG.warn("Couldn't get git config branch." + branchName + ".rebase");
}
}
return rebase ? UpdateMethod.REBASE : UpdateMethod.MERGE;
if (GitVersionSpecialty.KNOWS_PULL_REBASE.existsIn(GitVcs.getInstance(project).getVersion())) {
try {
String pullRebaseValue = GitConfigUtil.getValue(project, repository.getRoot(), "pull.rebase");
if (pullRebaseValue != null && isRebaseValue(pullRebaseValue)) return REBASE;
}
catch (VcsException e) {
LOG.warn("Couldn't get git config pull.rebase");
}
}
return MERGE;
}
private static boolean isRebaseValue(@NotNull String configValue) {
return configValue.equalsIgnoreCase("true") ||
configValue.equalsIgnoreCase("interactive") ||
configValue.equalsIgnoreCase("preserve") ||
configValue.equalsIgnoreCase("yes"); // 'yes' is not specified in the man, but actually works
}
@NotNull
@@ -0,0 +1,47 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package git4idea.update
import git4idea.config.UpdateMethod
import git4idea.test.GitSingleRepoTest
class GitUpdateMethodTest: GitSingleRepoTest() {
fun `test merge is default if no config`() {
assertDefaultUpdateMethod(UpdateMethod.MERGE)
}
fun `test rebase is default if branch-master-rebase is set to interactive`() {
git("config branch.master.rebase interactive")
assertDefaultUpdateMethod(UpdateMethod.REBASE)
}
fun `test rebase is default if branch-master-rebase is set to preserve`() {
git("config branch.master.rebase preserve")
assertDefaultUpdateMethod(UpdateMethod.REBASE)
}
fun `test rebase is default if pull-rebase is set to true`() {
git("config pull.rebase true")
assertDefaultUpdateMethod(UpdateMethod.REBASE)
}
fun `test rebase is default if pull-rebase is set to interactive`() {
git("config pull.rebase interactive")
assertDefaultUpdateMethod(UpdateMethod.REBASE)
}
fun `test rebase is default if pull-rebase is set to preserve`() {
git("config pull.rebase preserve")
assertDefaultUpdateMethod(UpdateMethod.REBASE)
}
fun `test branch config overrides pull-rebase`() {
git("config pull.rebase true")
git("config branch.master.rebase false")
assertDefaultUpdateMethod(UpdateMethod.MERGE)
}
private fun assertDefaultUpdateMethod(expectedMethod: UpdateMethod) {
assertEquals("Default update method is incorrect", expectedMethod, GitUpdater.resolveUpdateMethod(repo))
}
}