diff --git a/plugins/git4idea/src/git4idea/push/GitPushSpecParser.java b/plugins/git4idea/src/git4idea/push/GitPushSpecParser.java index 81231145ab21..6031dde21edb 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushSpecParser.java +++ b/plugins/git4idea/src/git4idea/push/GitPushSpecParser.java @@ -3,6 +3,7 @@ package git4idea.push; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; +import git4idea.GitBranch; import git4idea.GitUtil; import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRepository; @@ -33,23 +34,29 @@ final class GitPushSpecParser { if (parts.length != 2) { return null; } - String source = parts[0].trim(); - String target = parts[1].trim(); - source = StringUtil.trimStart(source, "+"); + String specSource = parts[0].trim(); + String specTarget = parts[1].trim(); + specSource = StringUtil.trimStart(specSource, "+"); - if (!isStarPositionValid(source, target)) { + if (!isStarPositionValid(specSource, specTarget)) { return null; } - source = GitBranchUtil.stripRefsPrefix(source); - sourceBranch = GitBranchUtil.stripRefsPrefix(sourceBranch); - if (source.equals(GitUtil.HEAD) || source.equals(sourceBranch)) return target; + String strippedSpecSource = GitBranchUtil.stripRefsPrefix(specSource); + String strippedSourceBranch = GitBranchUtil.stripRefsPrefix(sourceBranch); + sourceBranch = GitBranch.REFS_HEADS_PREFIX + strippedSourceBranch; - if (source.endsWith("*")) { - String sourceWoStar = source.substring(0, source.length() - 1); + if (strippedSpecSource.equals(GitUtil.HEAD) || + specSource.equals(sourceBranch) || + specSource.equals(strippedSourceBranch)) { + return specTarget; + } + + if (specSource.endsWith("*")) { + String sourceWoStar = specSource.substring(0, specSource.length() - 1); if (sourceBranch.startsWith(sourceWoStar)) { String starMeaning = sourceBranch.substring(sourceWoStar.length()); - return target.replace("*", starMeaning); + return specTarget.replace("*", starMeaning); } } return null; diff --git a/plugins/git4idea/src/git4idea/push/GitPushTarget.java b/plugins/git4idea/src/git4idea/push/GitPushTarget.java index 7548a4a6ace9..434a3f4c80e9 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushTarget.java +++ b/plugins/git4idea/src/git4idea/push/GitPushTarget.java @@ -20,6 +20,7 @@ import java.text.ParseException; import java.util.Collection; import java.util.List; +import static git4idea.GitBranch.REFS_HEADS_PREFIX; import static git4idea.GitBranch.REFS_REMOTES_PREFIX; import static git4idea.GitUtil.findRemoteBranch; import static git4idea.GitUtil.getDefaultOrFirstRemote; @@ -105,6 +106,12 @@ public class GitPushTarget implements PushTarget { if (targetRef == null) return null; String remotePrefix = REFS_REMOTES_PREFIX + remote.getName() + "/"; + if (targetRef.startsWith(REFS_HEADS_PREFIX)) { + targetRef = targetRef.substring(REFS_HEADS_PREFIX.length()); + GitRemoteBranch remoteBranch = GitUtil.findOrCreateRemoteBranch(repository, remote, targetRef); + boolean existingBranch = repository.getBranches().getRemoteBranches().contains(remoteBranch); + return new GitPushTarget(remoteBranch, !existingBranch, false); + } if (targetRef.startsWith(remotePrefix)) { targetRef = targetRef.substring(remotePrefix.length()); GitRemoteBranch remoteBranch = GitUtil.findOrCreateRemoteBranch(repository, remote, targetRef); diff --git a/plugins/git4idea/tests/git4idea/push/GitPushSpecParserTest.java b/plugins/git4idea/tests/git4idea/push/GitPushSpecParserTest.java index fe23954bad9b..46f6f0a08579 100644 --- a/plugins/git4idea/tests/git4idea/push/GitPushSpecParserTest.java +++ b/plugins/git4idea/tests/git4idea/push/GitPushSpecParserTest.java @@ -62,6 +62,24 @@ public class GitPushSpecParserTest { assertNull(getTargetRef("feature", specs)); } + @Test + public void test_tag_specs_ignored() { + List specs = Arrays.asList("+refs/heads/master:refs/remotes/origin/master", + "refs/tags/*:refs/tags/*"); + assertNull(getTargetRef("qa/ticket1", specs)); + assertEquals("refs/remotes/origin/master", getTargetRef("master", specs)); + assertNull(getTargetRef("feature", specs)); + } + + @Test + public void test_refs_heads_matches() { + List specs = Arrays.asList("refs/heads/master:refs/heads/qa/master", + "refs/tags/*:refs/tags/*", + "refs/heads/*:refs/heads/pr/*"); + assertEquals("refs/heads/pr/qa/ticket1", getTargetRef("qa/ticket1", specs)); + assertEquals("refs/heads/qa/master", getTargetRef("master", specs)); + } + @Nullable private static String getTargetRef(@NotNull String sourceBranch, @NotNull List specs) { GitRepository myRepo = Mockito.mock(GitRepository.class);