]> source.dussan.org Git - jgit.git/commitdiff
Implement --force option in FetchCommand and CLI fetch command 85/119285/1
authorMatthias Sohn <matthias.sohn@sap.com>
Tue, 13 Mar 2018 01:20:29 +0000 (02:20 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Tue, 13 Mar 2018 01:20:29 +0000 (02:20 +0100)
Change-Id: I42cdb57b8fb54ce466d1958391f12f911045327f
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/FetchTest.java
org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java

index 9685d4517a61b113290b6b44946ab452410145e4..dde1a332db81cbd24d64870c062e67de1813921b 100644 (file)
@@ -91,6 +91,19 @@ public class FetchTest extends CLIRepositoryTestCase {
                assertEquals(" * [new tag]         tag        -> tag", result[2]);
        }
 
+       @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");
index cb0ea1bc48c53c621bfd7abde211a846e5b63b17..e9370930d1eb8db9df2f0d161a43108275ac0c9c 100644 (file)
@@ -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]
index bc763728620a657f27ceef9d3e3524aa3c40f4d8..61fd521b8084b73a3c009cb794b933a2ebccda4a 100644 (file)
@@ -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()
index 83a0564c774370274d92de89eff64890ea58095a..cf1afceae6df7a5918c56461b6192f83863e1644 100644 (file)
@@ -101,6 +101,25 @@ public class FetchCommandTest extends RepositoryTestCase {
                                db.resolve(tagRef.getObjectId().getName()));
        }
 
+       @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();
index 5d178bc13c93a90b034fd8c59d3ceffe6a3c9912..73e93a1c942278a92c1d6fee05a620bbae2effb5 100644 (file)
@@ -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;
+       }
 }