Browse Source

Handle initial checkout correctly

As described in native gits file "git-read-tree.txt" git has in a
special mode when doing the "initial" checkout. "Initial" means that the
index is empty before the checkout. This was not handled correctly in
JGit and is fixed in this commit. Also see
https://github.com/git/git/blob/master/Documentation/git-read-tree.txt#L181

Change-Id: I9b9d1bd9ebf349cfca420c891c7b099a18d07ba4
stable-3.5
Christian Halstrick 10 years ago committed by Robin Stocker
parent
commit
cf9b01b09a
  1. 19
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
  2. 15
      org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java

19
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java

@ -72,6 +72,8 @@ import org.eclipse.jgit.errors.CheckoutConflictException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
@ -213,6 +215,23 @@ public class DirCacheCheckoutTest extends RepositoryTestCase {
assertIndex(mkmap("x", "x"));
}
/**
* Test first checkout in a repo
*
* @throws Exception
*/
@Test
public void testInitialCheckout() throws Exception {
Git git = new Git(db);
TestRepository<Repository> db_t = new TestRepository<Repository>(db);
BranchBuilder master = db_t.branch("master");
master.commit().add("f", "1").message("m0").create();
assertFalse(new File(db.getWorkTree(), "f").exists());
git.checkout().setName("master").call();
assertTrue(new File(db.getWorkTree(), "f").exists());
}
private DirCacheCheckout resetHard(RevCommit commit)
throws NoWorkTreeException,
CorruptObjectException, IOException {

15
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java vendored

@ -110,6 +110,8 @@ public class DirCacheCheckout {
private ArrayList<String> toBeDeleted = new ArrayList<String>();
private boolean emptyDirCache;
/**
* @return a list of updated paths and objectIds
*/
@ -168,6 +170,7 @@ public class DirCacheCheckout {
this.headCommitTree = headCommitTree;
this.mergeCommitTree = mergeCommitTree;
this.workingTree = workingTree;
this.emptyDirCache = (dc == null) || (dc.getEntryCount() == 0);
}
/**
@ -716,7 +719,8 @@ public class DirCacheCheckout {
* 0 nothing nothing nothing (does not happen)
* 1 nothing nothing exists use M
* 2 nothing exists nothing remove path from index
* 3 nothing exists exists yes keep index
* 3 nothing exists exists yes keep index if not in initial checkout
* , otherwise use M
* nothing exists exists no fail
* </pre>
*/
@ -743,9 +747,12 @@ public class DirCacheCheckout {
// in the index there is nothing (e.g. 'git rm ...' was
// called before). Ignore the cached deletion and use what we
// find in Merge. Potentially updates the file.
if (equalIdAndMode(hId, hMode, mId, mMode))
keep(dce);
else
if (equalIdAndMode(hId, hMode, mId, mMode)) {
if (emptyDirCache)
update(name, mId, mMode);
else
keep(dce);
} else
conflict(name, dce, h, m);
}
} else {

Loading…
Cancel
Save