diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java
index a41a1727f48f..6e178b9cbc0f 100644
--- a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java
+++ b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java
@@ -228,7 +228,11 @@ public class GitBranchUtil {
String branchName = stdName.substring(slash + 1);
GitRemote remote = findRemoteByName(remoteName, remotes);
if (remote == null) {
- return null;
+ // user may remove the remote section from .git/config, but leave remote refs untouched in .git/refs/remotes
+ LOG.info(String.format("No remote found with the name [%s]. All remotes: %s", remoteName, remotes));
+ GitRemote fakeRemote = new GitRemote(remoteName, ContainerUtil.emptyList(), Collections.emptyList(),
+ Collections.emptyList(), Collections.emptyList());
+ return new GitStandardRemoteBranch(fakeRemote, branchName, hash);
}
return new GitStandardRemoteBranch(remote, branchName, hash);
}
@@ -241,8 +245,6 @@ public class GitBranchUtil {
return remote;
}
}
- // user may remove the remote section from .git/config, but leave remote refs untouched in .git/refs/remotes
- LOG.info(String.format("No remote found with the name [%s]. All remotes: %s", remoteName, remotes));
return null;
}
diff --git a/plugins/git4idea/src/git4idea/repo/GitRemote.java b/plugins/git4idea/src/git4idea/repo/GitRemote.java
index a0695d281bd7..b2e289ce7d40 100644
--- a/plugins/git4idea/src/git4idea/repo/GitRemote.java
+++ b/plugins/git4idea/src/git4idea/repo/GitRemote.java
@@ -39,7 +39,7 @@ import java.util.List;
*
*
* GitRemote instance constructed by {@link GitConfig#read(GitPlatformFacade, File)}} has all these rules applied.
- * Thus, for example, if only one {@code url} and no {@code pushUrls} are defined for the remote,
+ * Thus, for example, if only one {@code url} and no {@code pushUrls} are defined for the remote,
* both {@link #getUrls()} and {@link #getPushUrls()} will return this url.
* This is made to avoid urls transformation logic from the code using GitRemote, leaving it all in GitConfig parsing.
*
@@ -47,14 +47,14 @@ import java.util.List;
* Same applies to fetch and push specs: {@link #getPushRefSpecs()} returns the spec,
* even if there are no separate record in {@code .git/config}
*
- *
+ *
*
* NB: Not all remote preferences (defined in {@code .git/config} are stored in the object.
* If some additional data is needed, add the field, getter, constructor parameter and populate it in {@link GitConfig}.
*
- *
+ *
* Remotes are compared (via equals, hashcode and compareTo) only by names.
- *
+ *
* @author Kirill Likhodedov
*/
public final class GitRemote implements Comparable {
@@ -80,8 +80,8 @@ public final class GitRemote implements Comparable {
@NotNull final List myFetchRefSpecs;
@NotNull private final List myPushRefSpecs;
- GitRemote(@NotNull String name, @NotNull List urls, @NotNull Collection pushUrls,
- @NotNull List fetchRefSpecs, @NotNull List pushRefSpecs) {
+ public GitRemote(@NotNull String name, @NotNull List urls, @NotNull Collection pushUrls,
+ @NotNull List fetchRefSpecs, @NotNull List pushRefSpecs) {
myName = name;
myUrls = urls;
myPushUrls = pushUrls;
diff --git a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.java b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.java
index 89f382806658..9570cbdc06fe 100644
--- a/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.java
+++ b/plugins/git4idea/tests/git4idea/repo/GitRepositoryReaderNewTest.java
@@ -16,10 +16,14 @@
package git4idea.repo;
import com.intellij.dvcs.repo.Repository;
+import com.intellij.openapi.util.Condition;
+import com.intellij.util.containers.ContainerUtil;
import git4idea.GitLocalBranch;
+import git4idea.GitRemoteBranch;
import git4idea.test.GitSingleRepoTest;
import java.io.File;
+import java.util.Collection;
import static git4idea.test.GitExecutor.git;
import static git4idea.test.GitScenarios.commit;
@@ -46,4 +50,24 @@ public class GitRepositoryReaderNewTest extends GitSingleRepoTest {
assertEquals("State value is incorrect", Repository.State.REBASING, state);
}
+ // inspired by IDEA-124052
+ public void test_remote_reference_without_remote() {
+ final String INVALID_REMOTE = "invalid-remote";
+ final String INVALID_REMOTE_BRANCH = "master";
+ git("update-ref refs/remotes/" + INVALID_REMOTE + "/" + INVALID_REMOTE_BRANCH + " HEAD");
+
+ File gitDir = new File(myRepo.getRoot().getPath(), ".git");
+ GitRepositoryReader reader = new GitRepositoryReader(gitDir);
+ GitConfig config = GitConfig.read(myPlatformFacade, new File(gitDir, "config"));
+ Collection remotes = config.parseRemotes();
+
+ Collection remoteBranches = reader.readBranches(remotes).getRemoteBranches();
+ assertTrue("Remote branch not found", ContainerUtil.exists(remoteBranches, new Condition() {
+ @Override
+ public boolean value(GitRemoteBranch branch) {
+ return branch.getNameForLocalOperations().equals(INVALID_REMOTE + "/" + INVALID_REMOTE_BRANCH);
+ }
+ }));
+ }
+
}