Change-Id: I42cdb57b8fb54ce466d1958391f12f911045327f Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v5.0.0.201805151920-m7
@@ -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"); |
@@ -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] |
@@ -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() |
@@ -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(); |
@@ -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; | |||
} | |||
} |