@Test public void testUnsupportedOptionalExtension() throws Exception { final DirCache dc = new DirCache(pathOf("gitgit.index.ZZZZ"), FS.DETECTED); dc.read(); assertEquals(1, dc.getEntryCount()); assertEquals("A", dc.getEntry(0).getPathString()); }
@Test public void testPathsReset() throws Exception { setupRepository(); DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName()); assertNotNull(preReset); git.add().addFilepattern(untrackedFile.getName()).call(); // 'a.txt' has already been modified in setupRepository // 'notAddedToIndex.txt' has been added to repository git.reset().addPath(indexFile.getName()).addPath(untrackedFile.getName()).call(); DirCacheEntry postReset = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName()); assertNotNull(postReset); Assert.assertNotSame(preReset.getObjectId(), postReset.getObjectId()); Assert.assertEquals(prestage.getObjectId(), postReset.getObjectId()); // check that HEAD hasn't moved ObjectId head = db.resolve(Constants.HEAD); assertEquals(secondCommit, head); // check if files still exist assertTrue(untrackedFile.exists()); assertTrue(indexFile.exists()); assertTrue(inHead(indexFile.getName())); assertTrue(inIndex(indexFile.getName())); assertFalse(inIndex(untrackedFile.getName())); }
private void assumeUnchanged(String path) throws IOException { final DirCache dirc = db.lockDirCache(); final DirCacheEntry ent = dirc.getEntry(path); if (ent != null) ent.setAssumeValid(true); dirc.write(); if (!dirc.commit()) throw new IOException("could not commit"); }
/** * Create a new in-core index representation, lock it, and read from disk. * * <p>The new index will be locked and then read before it is returned to the caller. Read * failures are reported as exceptions and therefore prevent the method from returning a partially * populated index. On read failure, the lock is released. * * @param repository repository containing the index to lock and read * @param indexChangedListener listener to be informed when DirCache is committed * @return a cache representing the contents of the specified index file (if it exists) or an * empty cache if the file does not exist. * @throws IOException the index file is present but could not be read, or the lock could not be * obtained. * @throws CorruptObjectException the index file is using a format or extension that this library * does not support. * @since 2.0 */ public static DirCache lock( final Repository repository, final IndexChangedListener indexChangedListener) throws CorruptObjectException, IOException { DirCache c = lock(repository.getIndexFile(), repository.getFS(), indexChangedListener); c.repository = repository; return c; }
/** * Create a new in-core index representation, lock it, and read from disk. * * <p>The new index will be locked and then read before it is returned to the caller. Read * failures are reported as exceptions and therefore prevent the method from returning a partially * populated index. On read failure, the lock is released. * * @param indexLocation location of the index file on disk. * @param fs the file system abstraction which will be necessary to perform certain file system * operations. * @param indexChangedListener listener to be informed when DirCache is committed * @return a cache representing the contents of the specified index file (if it exists) or an * empty cache if the file does not exist. * @throws IOException the index file is present but could not be read, or the lock could not be * obtained. * @throws CorruptObjectException the index file is using a format or extension that this library * does not support. */ public static DirCache lock( final File indexLocation, final FS fs, IndexChangedListener indexChangedListener) throws CorruptObjectException, IOException { DirCache c = lock(indexLocation, fs); c.registerIndexChangedListener(indexChangedListener); return c; }
@Test public void testReadIndex_DirCacheTree() throws Exception { final Map<String, CGitIndexRecord> cList = readLsFiles(); final Map<String, CGitLsTreeRecord> cTree = readLsTree(); final DirCache dc = new DirCache(index, FS.DETECTED); assertEquals(0, dc.getEntryCount()); dc.read(); assertEquals(cList.size(), dc.getEntryCount()); final DirCacheTree jTree = dc.getCacheTree(false); assertNotNull(jTree); assertEquals("", jTree.getNameString()); assertEquals("", jTree.getPathString()); assertTrue(jTree.isValid()); assertEquals( ObjectId.fromString("698dd0b8d0c299f080559a1cffc7fe029479a408"), jTree.getObjectId()); assertEquals(cList.size(), jTree.getEntrySpan()); final ArrayList<CGitLsTreeRecord> subtrees = new ArrayList<CGitLsTreeRecord>(); for (final CGitLsTreeRecord r : cTree.values()) { if (FileMode.TREE.equals(r.mode)) subtrees.add(r); } assertEquals(subtrees.size(), jTree.getChildCount()); for (int i = 0; i < jTree.getChildCount(); i++) { final DirCacheTree sj = jTree.getChild(i); final CGitLsTreeRecord sc = subtrees.get(i); assertEquals(sc.path, sj.getNameString()); assertEquals(sc.path + "/", sj.getPathString()); assertTrue(sj.isValid()); assertEquals(sc.id, sj.getObjectId()); } }
public void testNoPostOrder() throws Exception { final DirCache tree = db.readDirCache(); { final DirCacheBuilder b = tree.builder(); b.add(makeFile("a")); b.add(makeFile("b/c")); b.add(makeFile("b/d")); b.add(makeFile("q")); b.finish(); assertEquals(4, tree.getEntryCount()); } final TreeWalk tw = new TreeWalk(db); tw.reset(); tw.setPostOrderTraversal(false); tw.addTree(new DirCacheIterator(tree)); assertModes("a", REGULAR_FILE, tw); assertModes("b", TREE, tw); assertTrue(tw.isSubtree()); assertFalse(tw.isPostChildren()); tw.enterSubtree(); assertModes("b/c", REGULAR_FILE, tw); assertModes("b/d", REGULAR_FILE, tw); assertModes("q", REGULAR_FILE, tw); }
@Test public void testPathsResetWithUnmerged() throws Exception { setupRepository(); String file = "a.txt"; writeTrashFile(file, "data"); git.add().addFilepattern(file).call(); git.commit().setMessage("commit").call(); DirCache index = db.lockDirCache(); DirCacheBuilder builder = index.builder(); builder.add(createEntry(file, FileMode.REGULAR_FILE, 1, "")); builder.add(createEntry(file, FileMode.REGULAR_FILE, 2, "")); builder.add(createEntry(file, FileMode.REGULAR_FILE, 3, "")); builder.add(createEntry("b.txt", FileMode.REGULAR_FILE)); assertTrue(builder.commit()); assertEquals( "[a.txt, mode:100644, stage:1]" + "[a.txt, mode:100644, stage:2]" + "[a.txt, mode:100644, stage:3]" + "[b.txt, mode:100644]", indexState(0)); git.reset().addPath(file).call(); assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]", indexState(0)); }
/** * Creates an in-memory index of the ticket change. * * @param changeId * @param change * @return an in-memory index * @throws IOException */ private DirCache createIndex(Repository db, long ticketId, Change change) throws IOException, ClassNotFoundException, NoSuchFieldException { String ticketPath = toTicketPath(ticketId); DirCache newIndex = DirCache.newInCore(); DirCacheBuilder builder = newIndex.builder(); Set<String> ignorePaths = new TreeSet<String>(); try (ObjectInserter inserter = db.newObjectInserter()) { // create/update the journal // exclude the attachment content List<Change> changes = getJournal(db, ticketId); changes.add(change); String journal = TicketSerializer.serializeJournal(changes).trim(); byte[] journalBytes = journal.getBytes(Constants.ENCODING); String journalPath = ticketPath + "/" + JOURNAL; final DirCacheEntry journalEntry = new DirCacheEntry(journalPath); journalEntry.setLength(journalBytes.length); journalEntry.setLastModified(change.date.getTime()); journalEntry.setFileMode(FileMode.REGULAR_FILE); journalEntry.setObjectId( inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, journalBytes)); // add journal to index builder.add(journalEntry); ignorePaths.add(journalEntry.getPathString()); // Add any attachments to the index if (change.hasAttachments()) { for (Attachment attachment : change.attachments) { // build a path name for the attachment and mark as ignored String path = toAttachmentPath(ticketId, attachment.name); ignorePaths.add(path); // create an index entry for this attachment final DirCacheEntry entry = new DirCacheEntry(path); entry.setLength(attachment.content.length); entry.setLastModified(change.date.getTime()); entry.setFileMode(FileMode.REGULAR_FILE); // insert object entry.setObjectId( inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, attachment.content)); // add to temporary in-core index builder.add(entry); } } for (DirCacheEntry entry : getTreeEntries(db, ignorePaths)) { builder.add(entry); } // finish the index builder.finish(); } return newIndex; }
@Test public void testReadMissing_TempIndex() throws Exception { final File idx = new File(db.getDirectory(), "tmp_index"); assertFalse(idx.exists()); final DirCache dc = DirCache.read(idx, db.getFS()); assertNotNull(dc); assertEquals(0, dc.getEntryCount()); }
@Test public void testUnsupportedRequiredExtension() throws Exception { final DirCache dc = new DirCache(pathOf("gitgit.index.aaaa"), FS.DETECTED); try { dc.read(); fail("Cache loaded an unsupported extension"); } catch (CorruptObjectException err) { assertEquals("DIRC extension 'aaaa'" + " not supported by this version.", err.getMessage()); } }
protected DirCache readTree(RevTree tree) throws IOException, MissingObjectException, IncorrectObjectTypeException { DirCache dc = DirCache.newInCore(); if (tree != null) { DirCacheBuilder b = dc.builder(); b.addTree(new byte[0], DirCacheEntry.STAGE_0, reader, tree); b.finish(); } return dc; }
@Test public void testCorruptChecksumAtFooter() throws Exception { final DirCache dc = new DirCache(pathOf("gitgit.index.badchecksum"), FS.DETECTED); try { dc.read(); fail("Cache loaded despite corrupt checksum"); } catch (CorruptObjectException err) { assertEquals("DIRC checksum mismatch", err.getMessage()); } }
@Test public void testReadIndex_LsFiles() throws Exception { final Map<String, CGitIndexRecord> ls = readLsFiles(); final DirCache dc = new DirCache(index, FS.DETECTED); assertEquals(0, dc.getEntryCount()); dc.read(); assertEquals(ls.size(), dc.getEntryCount()); { final Iterator<CGitIndexRecord> rItr = ls.values().iterator(); for (int i = 0; rItr.hasNext(); i++) assertEqual(rItr.next(), dc.getEntry(i)); } }
@Test public void testPathsResetOnUnbornBranch() throws Exception { git = new Git(db); writeTrashFile("a.txt", "content"); git.add().addFilepattern("a.txt").call(); // Should assume an empty tree, like in C Git 1.8.2 git.reset().addPath("a.txt").call(); DirCache cache = db.readDirCache(); DirCacheEntry aEntry = cache.getEntry("a.txt"); assertNull(aEntry); }
/** * The resolve conflict way of three way merging * * @param baseTree * @param headTree * @param mergeTree * @param ignoreConflicts Controls what to do in case a content-merge is done and a conflict is * detected. The default setting for this should be <code>false</code>. In this case the * working tree file is filled with new content (containing conflict markers) and the index is * filled with multiple stages containing BASE, OURS and THEIRS content. Having such non-0 * stages is the sign to git tools that there are still conflicts for that path. * <p>If <code>true</code> is specified the behavior is different. In case a conflict is * detected the working tree file is again filled with new content (containing conflict * markers). But also stage 0 of the index is filled with that content. No other stages are * filled. Means: there is no conflict on that path but the new content (including conflict * markers) is stored as successful merge result. This is needed in the context of {@link * RecursiveMerger} where when determining merge bases we don't want to deal with * content-merge conflicts. * @return whether the trees merged cleanly * @throws IOException * @since 3.5 */ protected boolean mergeTrees( AbstractTreeIterator baseTree, RevTree headTree, RevTree mergeTree, boolean ignoreConflicts) throws IOException { builder = dircache.builder(); DirCacheBuildIterator buildIt = new DirCacheBuildIterator(builder); tw = new NameConflictTreeWalk(reader); tw.addTree(baseTree); tw.addTree(headTree); tw.addTree(mergeTree); tw.addTree(buildIt); if (workingTreeIterator != null) { tw.addTree(workingTreeIterator); } else { tw.setFilter(TreeFilter.ANY_DIFF); } if (!mergeTreeWalk(tw, ignoreConflicts)) { return false; } if (!inCore) { // No problem found. The only thing left to be done is to // checkout all files from "theirs" which have been selected to // go into the new index. checkout(); // All content-merges are successfully done. If we can now write the // new index we are on quite safe ground. Even if the checkout of // files coming from "theirs" fails the user can work around such // failures by checking out the index again. if (!builder.commit()) { cleanUp(); throw new IndexWriteException(); } builder = null; } else { builder.finish(); builder = null; } if (getUnmergedPaths().isEmpty() && !failed()) { resultTree = dircache.writeTree(getObjectInserter()); return true; } else { resultTree = null; return false; } }
/** * Construct a tree from a specific listing of file entries. * * @param entries the files to include in the tree. The collection does not need to be sorted * properly and may be empty. * @return reference to the tree specified by the entry list. * @throws Exception */ public RevTree tree(final DirCacheEntry... entries) throws Exception { final DirCache dc = DirCache.newInCore(); final DirCacheBuilder b = dc.builder(); for (final DirCacheEntry e : entries) b.add(e); b.finish(); ObjectId root; try { root = dc.writeTree(inserter); inserter.flush(); } finally { inserter.release(); } return pool.lookupTree(root); }
private static DirCache readTree(final Repository pdb, final Ref branch) throws MissingObjectException, IncorrectObjectTypeException, IOException { try (RevWalk rw = new RevWalk(pdb)) { final DirCache dc = DirCache.newInCore(); final DirCacheBuilder b = dc.builder(); b.addTree( new byte[0], // no prefix path DirCacheEntry.STAGE_0, // standard stage pdb.newObjectReader(), rw.parseTree(branch.getObjectId())); b.finish(); return dc; } }
@Test public void testHardResetOnUnbornBranch() throws Exception { git = new Git(db); File fileA = writeTrashFile("a.txt", "content"); git.add().addFilepattern("a.txt").call(); // Should assume an empty tree, like in C Git 1.8.2 git.reset().setMode(ResetType.HARD).call(); DirCache cache = db.readDirCache(); DirCacheEntry aEntry = cache.getEntry("a.txt"); assertNull(aEntry); assertFalse(fileA.exists()); assertNull(db.resolve(Constants.HEAD)); }
/** * Reverts the worktree after an unsuccessful merge. We know that for all modified files the old * content was in the old index and the index contained only stage 0. In case if inCore operation * just clear the history of modified files. * * @throws IOException * @throws CorruptObjectException * @throws NoWorkTreeException * @since 3.4 */ protected void cleanUp() throws NoWorkTreeException, CorruptObjectException, IOException { if (inCore) { modifiedFiles.clear(); return; } DirCache dc = db.readDirCache(); Iterator<String> mpathsIt = modifiedFiles.iterator(); while (mpathsIt.hasNext()) { String mpath = mpathsIt.next(); DirCacheEntry entry = dc.getEntry(mpath); if (entry != null) DirCacheCheckout.checkoutEntry(db, entry, reader); mpathsIt.remove(); } }
public CommitBuilder rm(String path) { DirCacheEditor e = tree.editor(); e.add(new DeletePath(path)); e.add(new DeleteTree(path)); e.finish(); return this; }
@Test public void testWriteEmptyUnlock_RealIndex() throws Exception { final File idx = new File(db.getDirectory(), "index"); final File lck = new File(db.getDirectory(), "index.lock"); assertFalse(idx.exists()); assertFalse(lck.exists()); final DirCache dc = db.lockDirCache(); assertEquals(0, lck.length()); dc.write(); assertEquals(12 + 20, lck.length()); dc.unlock(); assertFalse(idx.exists()); assertFalse(lck.exists()); }
/** * Execute this checkout * * @return <code>false</code> if this method could not delete all the files which should be * deleted (e.g. because of of the files was locked). In this case {@link #getToBeDeleted()} * lists the files which should be tried to be deleted outside of this method. Although <code> * false</code> is returned the checkout was successful and the working tree was updated for * all other files. <code>true</code> is returned when no such problem occurred * @throws IOException */ public boolean checkout() throws IOException { try { return doCheckout(); } finally { dc.unlock(); } }
public RevCommit create() throws Exception { if (self == null) { TestRepository.this.tick(tick); final org.eclipse.jgit.lib.CommitBuilder c; c = new org.eclipse.jgit.lib.CommitBuilder(); c.setParentIds(parents); setAuthorAndCommitter(c); c.setMessage(message); ObjectId commitId; try { c.setTreeId(tree.writeTree(inserter)); commitId = inserter.insert(c); inserter.flush(); } finally { inserter.release(); } self = pool.lookupCommit(commitId); if (branch != null) branch.update(self); } return self; }
private static void assertV3TreeEntry( int indexPosition, String path, boolean skipWorkTree, boolean intentToAdd, DirCache dc) { final DirCacheEntry entry = dc.getEntry(indexPosition); assertEquals(path, entry.getPathString()); assertEquals(skipWorkTree, entry.isSkipWorkTree()); assertEquals(intentToAdd, entry.isIntentToAdd()); }
@Test public void testLockMissing_RealIndex() throws Exception { final File idx = new File(db.getDirectory(), "index"); final File lck = new File(db.getDirectory(), "index.lock"); assertFalse(idx.exists()); assertFalse(lck.exists()); final DirCache dc = db.lockDirCache(); assertNotNull(dc); assertFalse(idx.exists()); assertTrue(lck.exists()); assertEquals(0, dc.getEntryCount()); dc.unlock(); assertFalse(idx.exists()); assertFalse(lck.exists()); }
@Test public void testDetectUnmergedPaths() throws Exception { final DirCache dc = db.readDirCache(); final DirCacheEntry[] ents = new DirCacheEntry[3]; ents[0] = new DirCacheEntry("a", 1); ents[0].setFileMode(FileMode.REGULAR_FILE); ents[1] = new DirCacheEntry("a", 2); ents[1].setFileMode(FileMode.REGULAR_FILE); ents[2] = new DirCacheEntry("a", 3); ents[2].setFileMode(FileMode.REGULAR_FILE); final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) b.add(ents[i]); b.finish(); assertTrue(dc.hasUnmergedPaths()); }
@Test public void testWriteEmptyReadEmpty_RealIndex() throws Exception { final File idx = new File(db.getDirectory(), "index"); final File lck = new File(db.getDirectory(), "index.lock"); assertFalse(idx.exists()); assertFalse(lck.exists()); { final DirCache dc = db.lockDirCache(); dc.write(); assertTrue(dc.commit()); assertTrue(idx.exists()); } { final DirCache dc = db.readDirCache(); assertEquals(0, dc.getEntryCount()); } }
CommitBuilder(CommitBuilder prior) throws Exception { branch = prior.branch; DirCacheBuilder b = tree.builder(); for (int i = 0; i < prior.tree.getEntryCount(); i++) b.add(prior.tree.getEntry(i)); b.finish(); parents.add(prior.create()); }
@Override protected boolean mergeImpl() throws IOException { if (implicitDirCache) dircache = getRepository().lockDirCache(); try { return mergeTrees(mergeBase(), sourceTrees[0], sourceTrees[1], false); } finally { if (implicitDirCache) dircache.unlock(); } }