]> source.dussan.org Git - jgit.git/commitdiff
A folder does not constitute a dirty work tree 61/10461/2
authorRobin Rosenberg <robin.rosenberg@dewire.com>
Mon, 18 Feb 2013 22:59:20 +0000 (23:59 +0100)
committerRobin Rosenberg <robin.rosenberg@dewire.com>
Sun, 10 Mar 2013 15:53:23 +0000 (16:53 +0100)
This fixes two cases:
- A folder without tracked content exist both in the workdir and merged
commit, as long as there names within that folder does not conflict.
- An empty folder structure exists with the same name as a file in the
merged commit.

Bug: 402834
Change-Id: I4c5b9f11313dd1665fcbdae2d0755fdb64deb3ef

org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java

index d8ef2dd6bace3ca25885d3356d38be3f399f9773..72762437d6eaec5fd9c4ff5039a69d87a423afcd 100644 (file)
@@ -188,6 +188,83 @@ public class ResolveMergerTest extends RepositoryTestCase {
                                indexState(CONTENT));
        }
 
+       /**
+        * An existing directory without tracked content should not prevent merging
+        * a tree where that directory exists.
+        *
+        * @param strategy
+        * @throws Exception
+        */
+       @Theory
+       public void checkUntrackedFolderIsNotAConflict(
+                       MergeStrategy strategy) throws Exception {
+               Git git = Git.wrap(db);
+
+               writeTrashFile("d/1", "1");
+               git.add().addFilepattern("d/1").call();
+               RevCommit first = git.commit().setMessage("added d/1").call();
+
+               writeTrashFile("e/1", "4");
+               git.add().addFilepattern("e/1").call();
+               RevCommit masterCommit = git.commit().setMessage("added e/1").call();
+
+               git.checkout().setCreateBranch(true).setStartPoint(first)
+                               .setName("side").call();
+               writeTrashFile("f/1", "5");
+               git.add().addFilepattern("f/1").call();
+               git.commit().setAll(true).setMessage("added f/1")
+                               .call();
+
+               // Untracked directory e shall not conflict with merged e/1
+               writeTrashFile("e/2", "d two");
+
+               MergeResult mergeRes = git.merge().setStrategy(strategy)
+                               .include(masterCommit).call();
+               assertEquals(MergeStatus.MERGED, mergeRes.getMergeStatus());
+               assertEquals(
+                               "[d/1, mode:100644, content:1][e/1, mode:100644, content:4][f/1, mode:100644, content:5]",
+                               indexState(CONTENT));
+       }
+
+       /**
+        * An existing directory without tracked content should not prevent merging
+        * a file with that name.
+        *
+        * @param strategy
+        * @throws Exception
+        */
+       @Theory
+       public void checkUntrackedEmpytFolderIsNotAConflictWithFile(
+                       MergeStrategy strategy)
+                       throws Exception {
+               Git git = Git.wrap(db);
+
+               writeTrashFile("d/1", "1");
+               git.add().addFilepattern("d/1").call();
+               RevCommit first = git.commit().setMessage("added d/1").call();
+
+               writeTrashFile("e", "4");
+               git.add().addFilepattern("e").call();
+               RevCommit masterCommit = git.commit().setMessage("added e").call();
+
+               git.checkout().setCreateBranch(true).setStartPoint(first)
+                               .setName("side").call();
+               writeTrashFile("f/1", "5");
+               git.add().addFilepattern("f/1").call();
+               git.commit().setAll(true).setMessage("added f/1").call();
+
+               // Untracked empty directory hierarcy e/1 shall not conflict with merged
+               // e/1
+               FileUtils.mkdirs(new File(trash, "e/1"), true);
+
+               MergeResult mergeRes = git.merge().setStrategy(strategy)
+                               .include(masterCommit).call();
+               assertEquals(MergeStatus.MERGED, mergeRes.getMergeStatus());
+               assertEquals(
+                               "[d/1, mode:100644, content:1][e, mode:100644, content:4][f/1, mode:100644, content:5]",
+                               indexState(CONTENT));
+       }
+
        /**
         * Merging two equal subtrees when the index does not contain any file in
         * that subtree should lead to a merged state.
index 292206e539b2255d83a546a7560ec606c5057175..dd9023fc7743f0b6940880a43618d1db74b5181a 100644 (file)
@@ -1129,7 +1129,8 @@ public class DirCacheCheckout {
                if (!tmpFile.renameTo(f)) {
                        // tried to rename which failed. Let' delete the target file and try
                        // again
-                       FileUtils.delete(f);
+                       FileUtils.delete(f, FileUtils.EMPTY_DIRECTORIES_ONLY
+                                       | FileUtils.RECURSIVE);
                        if (!tmpFile.renameTo(f)) {
                                throw new IOException(MessageFormat.format(
                                                JGitText.get().couldNotWriteFile, tmpFile.getPath(),
index bea21193331ac744f0675b056580266e0932f70e..213a1d4daa31391cac9f0936af20c4b309405d3c 100644 (file)
@@ -621,7 +621,10 @@ public class ResolveMerger extends ThreeWayMerger {
                boolean isDirty = work.isModeDifferent(modeO);
                if (!isDirty && nonTree(modeF))
                        isDirty = !tw.idEqual(T_FILE, T_OURS);
-
+               // Ignore existing empty directories
+               if (isDirty && modeF == FileMode.TYPE_TREE
+                               && modeO == FileMode.TYPE_MISSING)
+                       isDirty = false;
                if (isDirty)
                        failingPaths.put(tw.getPathString(),
                                        MergeFailureReason.DIRTY_WORKTREE);