summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/FetchTest.java13
-rw-r--r--org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties1
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java6
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java19
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java43
5 files changed, 79 insertions, 3 deletions
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/FetchTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/FetchTest.java
index 9685d4517a..dde1a332db 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/FetchTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/FetchTest.java
@@ -92,6 +92,19 @@ public class FetchTest extends CLIRepositoryTestCase {
}
@Test
+ public void testFetchForceUpdate() throws Exception {
+ String[] result = execute(
+ "git fetch test refs/heads/master:refs/remotes/origin/master");
+ assertEquals(" * [new branch] master -> origin/master",
+ result[1]);
+ assertEquals(" * [new tag] tag -> tag", result[2]);
+ remoteGit.commit().setAmend(true).setMessage("amended").call();
+ result = execute(
+ "git fetch -f test refs/heads/master:refs/remotes/origin/master");
+ assertEquals("", result[0]);
+ }
+
+ @Test
public void testFetchNoTags() throws Exception {
String[] result = execute("git fetch --no-tags test refs/heads/master:refs/remotes/origin/master");
assertEquals(" * [new branch] master -> origin/master",
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index cb0ea1bc48..e9370930d1 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -343,6 +343,7 @@ usage_forEachRefOutput=for-each-ref output
usage_forceCheckout=when switching branches, proceed even if the index or the working tree differs from HEAD
usage_forceClean=required to delete files or directories
usage_forceCreateBranchEvenExists=force create branch even exists
+usage_forcedFetch=force ref update fetch option
usage_forceReplacingAnExistingTag=force replacing an existing tag
usage_getAndSetOptions=Get and set repository or global options
usage_groups=Restrict manifest projects to ones with specified group(s), use "-" for excluding [default|all|G1,G2,G3|G4,-G5,-G6]
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
index bc76372862..61fd521b80 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
@@ -100,6 +100,9 @@ class Fetch extends AbstractFetchCommand implements FetchCommand.Callback {
tags = Boolean.FALSE;
}
+ @Option(name = "--force", usage = "usage_forcedFetch", aliases = { "-f" })
+ private Boolean force;
+
private FetchRecurseSubmodulesMode recurseSubmodules;
@Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules")
@@ -155,6 +158,9 @@ class Fetch extends AbstractFetchCommand implements FetchCommand.Callback {
if (quiet == null || !quiet.booleanValue())
fetch.setProgressMonitor(new TextProgressMonitor(errw));
fetch.setRecurseSubmodules(recurseSubmodules).setCallback(this);
+ if (force != null) {
+ fetch.setForceUpdate(force.booleanValue());
+ }
FetchResult result = fetch.call();
if (result.getTrackingRefUpdates().isEmpty()
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
index 83a0564c77..cf1afceae6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
@@ -102,6 +102,25 @@ public class FetchCommandTest extends RepositoryTestCase {
}
@Test
+ public void testForcedFetch() throws Exception {
+ remoteGit.commit().setMessage("commit").call();
+ remoteGit.commit().setMessage("commit2").call();
+ git.fetch().setRemote("test")
+ .setRefSpecs("refs/heads/master:refs/heads/master").call();
+
+ remoteGit.commit().setAmend(true).setMessage("amended").call();
+ FetchResult res = git.fetch().setRemote("test")
+ .setRefSpecs("refs/heads/master:refs/heads/master").call();
+ assertEquals(RefUpdate.Result.REJECTED,
+ res.getTrackingRefUpdate("refs/heads/master").getResult());
+ res = git.fetch().setRemote("test")
+ .setRefSpecs("refs/heads/master:refs/heads/master")
+ .setForceUpdate(true).call();
+ assertEquals(RefUpdate.Result.FORCED,
+ res.getTrackingRefUpdate("refs/heads/master").getResult());
+ }
+
+ @Test
public void fetchShouldAutoFollowTag() throws Exception {
remoteGit.commit().setMessage("commit").call();
Ref tagRef = remoteGit.tag().setName("foo").call();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
index 5d178bc13c..73e93a1c94 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -105,6 +105,8 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
private Callback callback;
+ private boolean isForceUpdate;
+
/**
* Callback for status of fetch operation.
*
@@ -198,7 +200,8 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
.setTagOpt(tagOption)
.setCheckFetchedObjects(checkFetchedObjects)
.setRemoveDeletedRefs(isRemoveDeletedRefs())
- .setThin(thin).setRefSpecs(refSpecs)
+ .setThin(thin)
+ .setRefSpecs(applyOptions(refSpecs))
.setDryRun(dryRun)
.setRecurseSubmodules(recurseMode);
configure(f);
@@ -237,8 +240,8 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
transport.setTagOpt(tagOption);
transport.setFetchThin(thin);
configure(transport);
-
- FetchResult result = transport.fetch(monitor, refSpecs);
+ FetchResult result = transport.fetch(monitor,
+ applyOptions(refSpecs));
if (!repo.isBare()) {
fetchSubmodules(result);
}
@@ -261,6 +264,17 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
}
+ private List<RefSpec> applyOptions(List<RefSpec> refSpecs2) {
+ if (!isForceUpdate()) {
+ return refSpecs2;
+ }
+ List<RefSpec> updated = new ArrayList<>(3);
+ for (RefSpec refSpec : refSpecs2) {
+ updated.add(refSpec.setForceUpdate(true));
+ }
+ return updated;
+ }
+
/**
* Set the mode to be used for recursing into submodules.
*
@@ -517,4 +531,27 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
this.callback = callback;
return this;
}
+
+ /**
+ * Whether fetch --force option is enabled
+ *
+ * @return whether refs affected by the fetch are updated forcefully
+ * @since 5.0
+ */
+ public boolean isForceUpdate() {
+ return this.isForceUpdate;
+ }
+
+ /**
+ * Set fetch --force option
+ *
+ * @param force
+ * whether to update refs affected by the fetch forcefully
+ * @return this command
+ * @since 5.0
+ */
+ public FetchCommand setForceUpdate(boolean force) {
+ this.isForceUpdate = force;
+ return this;
+ }
}