summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorChristian Halstrick <christian.halstrick@sap.com>2016-06-17 16:41:14 +0200
committerChristian Halstrick <christian.halstrick@sap.com>2016-06-23 09:34:22 +0200
commit5fe44ed3ee025404dc34966ec996641f47f8490b (patch)
tree38cded9b222b7a4c832484d0a7ab3a123a811164 /org.eclipse.jgit
parent2ec3accb3bcc0bd45dfb1333511c72489ab835cb (diff)
downloadjgit-5fe44ed3ee025404dc34966ec996641f47f8490b.tar.gz
jgit-5fe44ed3ee025404dc34966ec996641f47f8490b.zip
Fix DirCacheCheckout to return CheckoutConflictException
Problem occurs when the checkout wants to create a file 'd/f' but the workingtree contains a dirty file 'd'. In order to create d/f the file 'd' would have to be deleted and since the file is dirty that content would be lost. This should lead to a CheckoutConflictException for d/f when failOnConflict was set to true. This fix also changes jgit checkout semantics to be more like native gits checkout semantics. If during a checkout jgit wants to delete a folder but finds that the working tree contains a dirty file at this path then JGit will now throw an exception instead of silently keeping the dirty file. Like in this example: git init touch b git add b git commit -m addB mkdir a touch a/c git add a/c git commit -m addAC rm -fr a touch a git checkout HEAD~ Change-Id: I9089123179e09dd565285d50b0caa308d290cccd Signed-off-by: RĂ¼diger Herrmann <ruediger.herrmann@gmx.de> Also-by: RĂ¼diger Herrmann <ruediger.herrmann@gmx.de>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java32
1 files changed, 28 insertions, 4 deletions
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 12ceb74abb..ab61c59378 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -718,10 +718,23 @@ public class DirCacheCheckout {
return;
}
- // if we have no file at all then there is nothing to do
- if ((ffMask & 0x222) == 0
- && (f == null || FileMode.TREE.equals(f.getEntryFileMode())))
- return;
+ if ((ffMask & 0x222) == 0) {
+ // HEAD, MERGE and index don't contain a file (e.g. all contain a
+ // folder)
+ if (f == null || FileMode.TREE.equals(f.getEntryFileMode())) {
+ // the workingtree entry doesn't exist or also contains a folder
+ // -> no problem
+ return;
+ } else {
+ // the workingtree entry exists and is not a folder
+ if (!idEqual(h, m)) {
+ // Because HEAD and MERGE differ we will try to update the
+ // workingtree with a folder -> return a conflict
+ conflict(name, null, null, null);
+ }
+ return;
+ }
+ }
if ((ffMask == 0x00F) && f != null && FileMode.TREE.equals(f.getEntryFileMode())) {
// File/Directory conflict case #20
@@ -1004,6 +1017,17 @@ public class DirCacheCheckout {
}
}
+ private static boolean idEqual(AbstractTreeIterator a,
+ AbstractTreeIterator b) {
+ if (a == b) {
+ return true;
+ }
+ if (a == null || b == null) {
+ return false;
+ }
+ return a.getEntryObjectId().equals(b.getEntryObjectId());
+ }
+
/**
* A conflict is detected - add the three different stages to the index
* @param path the path of the conflicting entry