[git] IDEA-124052 Support remote refs w/o a correspondent remote + test

This commit is contained in:
Kirill Likhodedov
2014-05-06 15:23:39 +04:00
parent 172a3f9675
commit 899e7e3434
3 changed files with 35 additions and 9 deletions
@@ -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.<String>emptyList(), Collections.<String>emptyList(),
Collections.<String>emptyList(), Collections.<String>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;
}
@@ -39,7 +39,7 @@ import java.util.List;
* </p>
* <p>
* 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. <br/>
* This is made to avoid urls transformation logic from the code using GitRemote, leaving it all in GitConfig parsing.
* </p>
@@ -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}
* </p>
*
*
* <p>
* 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}.
* </p>
*
*
* <p>Remotes are compared (via equals, hashcode and compareTo) only by names.</p>
*
*
* @author Kirill Likhodedov
*/
public final class GitRemote implements Comparable<GitRemote> {
@@ -80,8 +80,8 @@ public final class GitRemote implements Comparable<GitRemote> {
@NotNull final List<String> myFetchRefSpecs;
@NotNull private final List<String> myPushRefSpecs;
GitRemote(@NotNull String name, @NotNull List<String> urls, @NotNull Collection<String> pushUrls,
@NotNull List<String> fetchRefSpecs, @NotNull List<String> pushRefSpecs) {
public GitRemote(@NotNull String name, @NotNull List<String> urls, @NotNull Collection<String> pushUrls,
@NotNull List<String> fetchRefSpecs, @NotNull List<String> pushRefSpecs) {
myName = name;
myUrls = urls;
myPushUrls = pushUrls;
@@ -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<GitRemote> remotes = config.parseRemotes();
Collection<GitRemoteBranch> remoteBranches = reader.readBranches(remotes).getRemoteBranches();
assertTrue("Remote branch not found", ContainerUtil.exists(remoteBranches, new Condition<GitRemoteBranch>() {
@Override
public boolean value(GitRemoteBranch branch) {
return branch.getNameForLocalOperations().equals(INVALID_REMOTE + "/" + INVALID_REMOTE_BRANCH);
}
}));
}
}