Skip to content

Commit

Permalink
[FIXED JENKINS-18988]
Browse files Browse the repository at this point in the history
CGit's checkout --force is behaving differently from JGit's checkout --force, so handle the difference by ourselves
  • Loading branch information
kohsuke committed Sep 21, 2013
1 parent 5fd1fe7 commit 7001a2e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
28 changes: 24 additions & 4 deletions src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java
Expand Up @@ -12,17 +12,21 @@
import hudson.plugins.git.Revision;
import hudson.util.IOUtils;
import org.eclipse.jgit.api.AddNoteCommand;
import org.eclipse.jgit.api.CheckoutResult;
import org.eclipse.jgit.api.CheckoutResult.Status;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.ResetCommand;
import org.eclipse.jgit.api.ShowNoteCommand;
import org.eclipse.jgit.api.errors.CheckoutConflictException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.diff.RenameDetector;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.errors.TransportException;
Expand Down Expand Up @@ -178,10 +182,26 @@ public void init() throws GitException {
}

public void checkout(String ref) throws GitException {
try {
git().checkout().setName(ref).setForce(true).call();
} catch (GitAPIException e) {
throw new GitException("Could not checkout " + ref, e);
boolean retried = false;
while (true) {
try {
git().checkout().setName(ref).setForce(true).call();
return;
} catch (CheckoutConflictException e) {
// "git checkout -f" seems to overwrite local untracked files but git CheckoutCommand doesn't.
// see the test case GitAPITestCase.test_localCheckoutConflict. so in this case we manually
// clean up the conflicts and try it again

if (retried)
throw new GitException("Could not checkout " + ref, e);
retried = true;
for (String path : e.getConflictingPaths()) {
File conflict = new File(db().getWorkTree(), path);
conflict.delete();
}
} catch (GitAPIException e) {
throw new GitException("Could not checkout " + ref, e);
}
}
}

Expand Down
26 changes: 26 additions & 0 deletions src/test/java/org/jenkinsci/plugins/gitclient/GitAPITestCase.java
Expand Up @@ -121,6 +121,10 @@ File touch(String path, String content) throws IOException {
return f;
}

public void rm(String path) {
file(path).delete();
}

public String contentOf(String path) throws IOException {
return FileUtils.readFileToString(file(path));
}
Expand Down Expand Up @@ -808,4 +812,26 @@ private String formatBranches(List<Branch> branches) {
}
return Util.join(names,",");
}

@Bug(18988)
public void test_localCheckoutConflict() throws Exception {
w.init();
w.touch("foo","old");
w.add("foo");
w.commit("c1");
w.tag("t1");

// delete the file from git
w.cmd("git rm foo");
w.commit("c2");
assertFalse(w.file("foo").exists());

// now create an untracked local file
w.touch("foo","new");

// this should overwrite foo
w.git.checkout("t1");

assertEquals("old",FileUtils.readFileToString(w.file("foo")));
}
}

0 comments on commit 7001a2e

Please sign in to comment.