From 27a64cdd67f14a16c7185012e5be703bc6187f07 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 30 Nov 2017 12:23:50 +0300 Subject: [PATCH] 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) --- .../git4idea/config/GitVersionSpecialty.java | 7 +++ .../src/git4idea/update/GitUpdater.java | 42 ++++++++++++++--- .../git4idea/update/GitUpdateMethodTest.kt | 47 +++++++++++++++++++ 3 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 plugins/git4idea/tests/git4idea/update/GitUpdateMethodTest.kt diff --git a/plugins/git4idea/src/git4idea/config/GitVersionSpecialty.java b/plugins/git4idea/src/git4idea/config/GitVersionSpecialty.java index c1280cfe214a..a844fe005ad1 100644 --- a/plugins/git4idea/src/git4idea/config/GitVersionSpecialty.java +++ b/plugins/git4idea/src/git4idea/config/GitVersionSpecialty.java @@ -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}
* Before this version {@code --no-walk} didn't take any parameters. diff --git a/plugins/git4idea/src/git4idea/update/GitUpdater.java b/plugins/git4idea/src/git4idea/update/GitUpdater.java index c6bef4510631..81e13098a364 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdater.java @@ -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 diff --git a/plugins/git4idea/tests/git4idea/update/GitUpdateMethodTest.kt b/plugins/git4idea/tests/git4idea/update/GitUpdateMethodTest.kt new file mode 100644 index 000000000000..0639bcb9a281 --- /dev/null +++ b/plugins/git4idea/tests/git4idea/update/GitUpdateMethodTest.kt @@ -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)) + } +} \ No newline at end of file