From d056a543846ccf9b8cd0f59cc2f5920427fc4559 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 21 Aug 2018 14:44:28 -0700 Subject: [PATCH] CheckoutCommand: force flag now allows overwrite Before this commit, a force checkout would fail if there were any conflicting files. After this commit, a force checkout will overwrite the conflicting files, as expected. Making this work required fixing a bug in DirCacheCheckout. Before this commit, when DirCacheCheckout had failOnConflict=false, it would delete all conflicting files from the working copy and just leave them missing. After this commit, DirCacheCheckout overwrites conflicting files with the merge tree. This change in DirCacheCheckout causes "reset --hard" and "revert --abort" to behave as expected (previously they would simply delete conflicting files, now they will be overwritten from the merge tree). Change-Id: If7e328ee792ef6511ab7d9c26d8d77c39210ec9f Signed-off-by: Ned Twigg --- .../eclipse/jgit/api/CheckoutCommandTest.java | 4 ++- .../org/eclipse/jgit/api/CheckoutCommand.java | 2 +- .../jgit/dircache/DirCacheCheckout.java | 29 ++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java index 71df59e1ff..498005deda 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java @@ -154,7 +154,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { } @Test - public void testCheckoutWithConflict() { + public void testCheckoutWithConflict() throws Exception { CheckoutCommand co = git.checkout(); try { writeTrashFile("Test.txt", "Another change"); @@ -165,6 +165,8 @@ public class CheckoutCommandTest extends RepositoryTestCase { assertEquals(Status.CONFLICTS, co.getResult().getStatus()); assertTrue(co.getResult().getConflictList().contains("Test.txt")); } + git.checkout().setName("master").setForce(true).call(); + assertThat(read("Test.txt"), is("Hello world")); } @Test diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java index 11edb10894..455a2e665f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java @@ -269,7 +269,7 @@ public class CheckoutCommand extends GitCommand { try { dco = new DirCacheCheckout(repo, headTree, dc, newCommit.getTree()); - dco.setFailOnConflict(true); + dco.setFailOnConflict(!force); dco.setProgressMonitor(monitor); try { dco.checkout(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index ca1e3ab275..db6073f89a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -522,7 +522,7 @@ public class DirCacheCheckout { builder.finish(); // init progress reporting - int numTotal = removed.size() + updated.size(); + int numTotal = removed.size() + updated.size() + conflicts.size(); monitor.beginTask(JGitText.get().checkingOutFiles, numTotal); performingCheckout = true; @@ -597,6 +597,33 @@ public class DirCacheCheckout { } throw ex; } + for (String conflict : conflicts) { + // the conflicts are likely to have multiple entries in the + // dircache, we only want to check out the one for the "theirs" + // tree + int entryIdx = dc.findEntry(conflict); + if (entryIdx >= 0) { + while (entryIdx < dc.getEntryCount()) { + DirCacheEntry entry = dc.getEntry(entryIdx); + if (!entry.getPathString().equals(conflict)) { + break; + } + if (entry.getStage() == DirCacheEntry.STAGE_3) { + checkoutEntry(repo, entry, objectReader, false, + null); + break; + } + ++entryIdx; + } + } + + monitor.update(1); + if (monitor.isCancelled()) { + throw new CanceledException(MessageFormat.format( + JGitText.get().operationCanceled, + JGitText.get().checkingOutFiles)); + } + } monitor.endTask(); // commit the index builder - a new index is persisted -- 2.39.5