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 f0ca574e3..ee162dd50 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -414,9 +414,15 @@ public class DirCacheCheckout { for (int i = removed.size() - 1; i >= 0; i--) { String r = removed.get(i); file = new File(repo.getWorkTree(), r); - if (!file.delete() && file.exists()) - toBeDeleted.add(r); - else { + if (!file.delete() && file.exists()) { + // The list of stuff to delete comes from the index + // which will only contain a directory if it is + // a submodule, in which case we shall not attempt + // to delete it. A submodule is not empty, so it + // is safe to check this after a failed delete. + if (!file.isDirectory()) + toBeDeleted.add(r); + } else { if (!isSamePrefix(r, last)) removeEmptyParents(new File(repo.getWorkTree(), last)); last = r; @@ -654,11 +660,14 @@ public class DirCacheCheckout { if (i == null) { // make sure not to overwrite untracked files if (f != null) { - // a dirty worktree: the index is empty but we have a - // workingtree-file - if (mId == null || !mId.equals(f.getEntryObjectId())) { - conflict(name, null, h, m); - return; + // A submodule is not a file. We should ignore it + if (!FileMode.GITLINK.equals(m.getEntryFileMode())) { + // a dirty worktree: the index is empty but we have a + // workingtree-file + if (mId == null || !mId.equals(f.getEntryObjectId())) { + conflict(name, null, h, m); + return; + } } } @@ -720,21 +729,33 @@ public class DirCacheCheckout { * */ - if (hId.equals(iId)) { - if (f == null || f.isModified(dce, true)) + if (dce.getFileMode() == FileMode.GITLINK) { + // Submodules that disappear from the checkout must + // be removed from the index, but not deleted from disk. + remove(name); + } else { + if (hId.equals(iId)) { + if (f == null || f.isModified(dce, true)) + conflict(name, dce, h, m); + else + remove(name); + } else conflict(name, dce, h, m); - else - remove(name); - } else - conflict(name, dce, h, m); + } } else { if (!hId.equals(mId) && !hId.equals(iId) && !mId.equals(iId)) conflict(name, dce, h, m); else if (hId.equals(iId) && !mId.equals(iId)) { - if (dce != null && (f == null || f.isModified(dce, true))) + // For submodules just update the index with the new SHA-1 + if (dce != null + && FileMode.GITLINK.equals(dce.getFileMode())) { + update(name, mId, m.getEntryFileMode()); + } else if (dce != null + && (f == null || f.isModified(dce, true))) { conflict(name, dce, h, m); - else + } else { update(name, mId, m.getEntryFileMode()); + } } else { keep(dce); }