PushCommand: determine remote from git config if not given
Add ConfigConstants and expose branch.<name>.pushRemote in the BranchConfig. Use the branch configuration and remote.pushDefault if no remote is given explicitly. If nothing is configured, fall back to "origin". Bug: 578676 Change-Id: I6bb141ff02c8b04980ec34b26ef248b72614c3c9 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
parent
504001228b
commit
855a734875
|
@ -26,6 +26,7 @@
|
|||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.api.errors.TransportException;
|
||||
import org.eclipse.jgit.errors.MissingObjectException;
|
||||
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
|
||||
import org.eclipse.jgit.hooks.PrePushHook;
|
||||
import org.eclipse.jgit.junit.JGitTestUtil;
|
||||
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||
|
@ -633,8 +634,7 @@ public void testPushDefaultSimpleTriangular() throws Exception {
|
|||
|
||||
config = git.getRepository().getConfig();
|
||||
// Don't set remote, it'll default to "origin". Configure a
|
||||
// different
|
||||
// branch name; should be ignored.
|
||||
// different branch name; should be ignored.
|
||||
config.setString("branch", "branchtopush", "merge",
|
||||
"refs/heads/upstreambranch");
|
||||
config.save();
|
||||
|
@ -852,6 +852,176 @@ public void testPushDefaultFromConfigDefault() throws Exception {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that branch.<name>.pushRemote overrides anything else.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testBranchPushRemote() throws Exception {
|
||||
try (Git git = new Git(db);
|
||||
Git git2 = new Git(createBareRepository())) {
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
RemoteConfig remoteConfig = new RemoteConfig(config, "test");
|
||||
URIish uri = new URIish(
|
||||
git2.getRepository().getDirectory().toURI().toURL());
|
||||
remoteConfig.addURI(uri);
|
||||
remoteConfig.addFetchRefSpec(
|
||||
new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
|
||||
remoteConfig.update(config);
|
||||
config.setString("remote", null, "pushDefault", "test");
|
||||
config.save();
|
||||
|
||||
writeTrashFile("f", "content of f");
|
||||
git.add().addFilepattern("f").call();
|
||||
git.commit().setMessage("adding f").call();
|
||||
|
||||
git.checkout().setName("not-pushed").setCreateBranch(true).call();
|
||||
git.checkout().setName("branchtopush").setCreateBranch(true).call();
|
||||
|
||||
config = git.getRepository().getConfig();
|
||||
config.setString("branch", "branchtopush", "remote", "test");
|
||||
config.setString("branch", "branchtopush", "pushremote", "origin");
|
||||
config.setString("branch", "branchtopush", "merge",
|
||||
"refs/heads/branchtopush");
|
||||
config.save();
|
||||
|
||||
assertThrows(InvalidRefNameException.class, () -> git.push()
|
||||
.setPushDefault(PushDefault.UPSTREAM).call());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that remote.pushDefault overrides branch.<name>.remote
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testRemotePushDefault() throws Exception {
|
||||
try (Git git = new Git(db);
|
||||
Git git2 = new Git(createBareRepository())) {
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
RemoteConfig remoteConfig = new RemoteConfig(config, "test");
|
||||
URIish uri = new URIish(
|
||||
git2.getRepository().getDirectory().toURI().toURL());
|
||||
remoteConfig.addURI(uri);
|
||||
remoteConfig.addFetchRefSpec(
|
||||
new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
|
||||
remoteConfig.update(config);
|
||||
config.setString("remote", null, "pushDefault", "origin");
|
||||
config.save();
|
||||
|
||||
writeTrashFile("f", "content of f");
|
||||
git.add().addFilepattern("f").call();
|
||||
git.commit().setMessage("adding f").call();
|
||||
|
||||
git.checkout().setName("not-pushed").setCreateBranch(true).call();
|
||||
git.checkout().setName("branchtopush").setCreateBranch(true).call();
|
||||
|
||||
config = git.getRepository().getConfig();
|
||||
config.setString("branch", "branchtopush", "remote", "test");
|
||||
config.setString("branch", "branchtopush", "merge",
|
||||
"refs/heads/branchtopush");
|
||||
config.save();
|
||||
|
||||
assertThrows(InvalidRefNameException.class, () -> git.push()
|
||||
.setPushDefault(PushDefault.UPSTREAM).call());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that ultimately we fall back to "origin".
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testDefaultRemote() throws Exception {
|
||||
try (Git git = new Git(db);
|
||||
Git git2 = new Git(createBareRepository())) {
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
RemoteConfig remoteConfig = new RemoteConfig(config, "test");
|
||||
URIish uri = new URIish(
|
||||
git2.getRepository().getDirectory().toURI().toURL());
|
||||
remoteConfig.addURI(uri);
|
||||
remoteConfig.addFetchRefSpec(
|
||||
new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
|
||||
remoteConfig.update(config);
|
||||
config.save();
|
||||
|
||||
writeTrashFile("f", "content of f");
|
||||
git.add().addFilepattern("f").call();
|
||||
git.commit().setMessage("adding f").call();
|
||||
|
||||
git.checkout().setName("not-pushed").setCreateBranch(true).call();
|
||||
git.checkout().setName("branchtopush").setCreateBranch(true).call();
|
||||
|
||||
config = git.getRepository().getConfig();
|
||||
config.setString("branch", "branchtopush", "merge",
|
||||
"refs/heads/branchtopush");
|
||||
config.save();
|
||||
|
||||
PushCommand cmd = git.push().setPushDefault(PushDefault.UPSTREAM);
|
||||
TransportException e = assertThrows(TransportException.class,
|
||||
() -> cmd.call());
|
||||
assertEquals(NoRemoteRepositoryException.class,
|
||||
e.getCause().getClass());
|
||||
assertEquals("origin", cmd.getRemote());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a push without specifying a remote or mode or anything can
|
||||
* succeed if the git config is correct.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testDefaultPush() throws Exception {
|
||||
try (Git git = new Git(db);
|
||||
Git git2 = new Git(createBareRepository())) {
|
||||
StoredConfig config = git.getRepository().getConfig();
|
||||
RemoteConfig remoteConfig = new RemoteConfig(config, "test");
|
||||
URIish uri = new URIish(
|
||||
git2.getRepository().getDirectory().toURI().toURL());
|
||||
remoteConfig.addURI(uri);
|
||||
remoteConfig.addFetchRefSpec(
|
||||
new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
|
||||
remoteConfig.update(config);
|
||||
config.save();
|
||||
|
||||
writeTrashFile("f", "content of f");
|
||||
git.add().addFilepattern("f").call();
|
||||
RevCommit commit = git.commit().setMessage("adding f").call();
|
||||
|
||||
git.checkout().setName("not-pushed").setCreateBranch(true).call();
|
||||
git.checkout().setName("branchtopush").setCreateBranch(true).call();
|
||||
|
||||
config = git.getRepository().getConfig();
|
||||
config.setString("branch", "branchtopush", "remote", "test");
|
||||
config.save();
|
||||
|
||||
assertEquals(null,
|
||||
git2.getRepository().resolve("refs/heads/branchtopush"));
|
||||
assertEquals(null,
|
||||
git2.getRepository().resolve("refs/heads/not-pushed"));
|
||||
assertEquals(null,
|
||||
git2.getRepository().resolve("refs/heads/master"));
|
||||
// Should use remote "test", push.default=current
|
||||
PushCommand cmd = git.push();
|
||||
cmd.call();
|
||||
assertEquals("test", cmd.getRemote());
|
||||
assertEquals(PushDefault.CURRENT, cmd.getPushDefault());
|
||||
assertEquals(commit.getId(),
|
||||
git2.getRepository().resolve("refs/heads/branchtopush"));
|
||||
assertEquals(null,
|
||||
git2.getRepository().resolve("refs/heads/not-pushed"));
|
||||
assertEquals(null,
|
||||
git2.getRepository().resolve("refs/heads/master"));
|
||||
assertEquals(commit.getId(), git.getRepository()
|
||||
.resolve("refs/remotes/origin/branchtopush"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that missing refs don't cause errors during push
|
||||
*
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
import org.eclipse.jgit.internal.JGitText;
|
||||
import org.eclipse.jgit.lib.BranchConfig;
|
||||
import org.eclipse.jgit.lib.Config;
|
||||
import org.eclipse.jgit.lib.ConfigConstants;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.NullProgressMonitor;
|
||||
import org.eclipse.jgit.lib.ProgressMonitor;
|
||||
|
@ -58,7 +59,7 @@
|
|||
public class PushCommand extends
|
||||
TransportCommand<PushCommand, Iterable<PushResult>> {
|
||||
|
||||
private String remote = Constants.DEFAULT_REMOTE_NAME;
|
||||
private String remote;
|
||||
|
||||
private final List<RefSpec> refSpecs;
|
||||
|
||||
|
@ -114,6 +115,7 @@ public Iterable<PushResult> call() throws GitAPIException,
|
|||
|
||||
try {
|
||||
Config config = repo.getConfig();
|
||||
remote = determineRemote(config, remote);
|
||||
if (refSpecs.isEmpty()) {
|
||||
RemoteConfig rc = new RemoteConfig(config,
|
||||
getRemote());
|
||||
|
@ -181,6 +183,34 @@ public Iterable<PushResult> call() throws GitAPIException,
|
|||
return pushResults;
|
||||
}
|
||||
|
||||
private String determineRemote(Config config, String remoteName)
|
||||
throws IOException {
|
||||
if (remoteName != null) {
|
||||
return remoteName;
|
||||
}
|
||||
Ref head = repo.exactRef(Constants.HEAD);
|
||||
String effectiveRemote = null;
|
||||
BranchConfig branchCfg = null;
|
||||
if (head != null && head.isSymbolic()) {
|
||||
String currentBranch = head.getLeaf().getName();
|
||||
branchCfg = new BranchConfig(config,
|
||||
Repository.shortenRefName(currentBranch));
|
||||
effectiveRemote = branchCfg.getPushRemote();
|
||||
}
|
||||
if (effectiveRemote == null) {
|
||||
effectiveRemote = config.getString(
|
||||
ConfigConstants.CONFIG_REMOTE_SECTION, null,
|
||||
ConfigConstants.CONFIG_KEY_PUSH_DEFAULT);
|
||||
if (effectiveRemote == null && branchCfg != null) {
|
||||
effectiveRemote = branchCfg.getRemote();
|
||||
}
|
||||
}
|
||||
if (effectiveRemote == null) {
|
||||
effectiveRemote = Constants.DEFAULT_REMOTE_NAME;
|
||||
}
|
||||
return effectiveRemote;
|
||||
}
|
||||
|
||||
private String getCurrentBranch()
|
||||
throws IOException, DetachedHeadException {
|
||||
Ref head = repo.exactRef(Constants.HEAD);
|
||||
|
|
|
@ -137,6 +137,18 @@ public String getRemote() {
|
|||
branchName, ConfigConstants.CONFIG_KEY_REMOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the remote this branch is configured to push to.
|
||||
*
|
||||
* @return the remote this branch is configured to push to, or {@code null}
|
||||
* if not defined
|
||||
* @since 6.1
|
||||
*/
|
||||
public String getPushRemote() {
|
||||
return config.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
|
||||
branchName, ConfigConstants.CONFIG_KEY_PUSH_REMOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the upstream branch as it is called on the remote
|
||||
*
|
||||
|
|
|
@ -329,6 +329,20 @@ public final class ConfigConstants {
|
|||
/** The "remote" key */
|
||||
public static final String CONFIG_KEY_REMOTE = "remote";
|
||||
|
||||
/**
|
||||
* The "pushRemote" key.
|
||||
*
|
||||
* @since 6.1
|
||||
*/
|
||||
public static final String CONFIG_KEY_PUSH_REMOTE = "pushRemote";
|
||||
|
||||
/**
|
||||
* The "pushDefault" key.
|
||||
*
|
||||
* @since 6.1
|
||||
*/
|
||||
public static final String CONFIG_KEY_PUSH_DEFAULT = "pushDefault";
|
||||
|
||||
/** The "merge" key */
|
||||
public static final String CONFIG_KEY_MERGE = "merge";
|
||||
|
||||
|
|
Loading…
Reference in New Issue