/** * 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(); } }
@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(); } }
/** * 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. * @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) throws CorruptObjectException, IOException { final DirCache c = new DirCache(indexLocation, fs); if (!c.lock()) throw new LockFailedException(indexLocation); try { c.read(); } catch (IOException e) { c.unlock(); throw e; } catch (RuntimeException e) { c.unlock(); throw e; } catch (Error e) { c.unlock(); throw e; } return c; }
@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()); }
@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 testWriteEmptyLockEmpty_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.lockDirCache(); assertEquals(0, dc.getEntryCount()); assertTrue(idx.exists()); assertTrue(lck.exists()); dc.unlock(); } }
/** * Executes the {@code commit} command with all the options and parameters collected by the setter * methods of this class. Each instance of this class should only be used for one invocation of * the command (means: one call to {@link #call()}) * * @return a {@link RevCommit} object representing the successful commit. * @throws NoHeadException when called on a git repo without a HEAD reference * @throws NoMessageException when called without specifying a commit message * @throws UnmergedPathsException when the current index contained unmerged paths (conflicts) * @throws ConcurrentRefUpdateException when HEAD or branch ref is updated concurrently by someone * else * @throws WrongRepositoryStateException when repository is not in the right state for committing * @throws AbortedByHookException if there are either pre-commit or commit-msg hooks present in * the repository and one of them rejects the commit. */ public RevCommit call() throws GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, AbortedByHookException { checkCallable(); Collections.sort(only); try (RevWalk rw = new RevWalk(repo)) { RepositoryState state = repo.getRepositoryState(); if (!state.canCommit()) throw new WrongRepositoryStateException( MessageFormat.format(JGitText.get().cannotCommitOnARepoWithState, state.name())); if (!noVerify) { Hooks.preCommit(repo, hookOutRedirect).call(); } processOptions(state, rw); if (all && !repo.isBare() && repo.getWorkTree() != null) { try (Git git = new Git(repo)) { git.add() .addFilepattern(".") // $NON-NLS-1$ .setUpdate(true) .call(); } catch (NoFilepatternException e) { // should really not happen throw new JGitInternalException(e.getMessage(), e); } } Ref head = repo.getRef(Constants.HEAD); if (head == null) throw new NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); // determine the current HEAD and the commit it is referring to ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}"); // $NON-NLS-1$ if (headId == null && amend) throw new WrongRepositoryStateException(JGitText.get().commitAmendOnInitialNotPossible); if (headId != null) if (amend) { RevCommit previousCommit = rw.parseCommit(headId); for (RevCommit p : previousCommit.getParents()) parents.add(p.getId()); if (author == null) author = previousCommit.getAuthorIdent(); } else { parents.add(0, headId); } if (!noVerify) { message = Hooks.commitMsg(repo, hookOutRedirect).setCommitMessage(message).call(); } // lock the index DirCache index = repo.lockDirCache(); try (ObjectInserter odi = repo.newObjectInserter()) { if (!only.isEmpty()) index = createTemporaryIndex(headId, index, rw); // Write the index as tree to the object database. This may // fail for example when the index contains unmerged paths // (unresolved conflicts) ObjectId indexTreeId = index.writeTree(odi); if (insertChangeId) insertChangeId(indexTreeId); // Create a Commit object, populate it and write it CommitBuilder commit = new CommitBuilder(); commit.setCommitter(committer); commit.setAuthor(author); commit.setMessage(message); commit.setParentIds(parents); commit.setTreeId(indexTreeId); ObjectId commitId = odi.insert(commit); odi.flush(); RevCommit revCommit = rw.parseCommit(commitId); RefUpdate ru = repo.updateRef(Constants.HEAD); ru.setNewObjectId(commitId); if (reflogComment != null) { ru.setRefLogMessage(reflogComment, false); } else { String prefix = amend ? "commit (amend): " //$NON-NLS-1$ : parents.size() == 0 ? "commit (initial): " //$NON-NLS-1$ : "commit: "; //$NON-NLS-1$ ru.setRefLogMessage(prefix + revCommit.getShortMessage(), false); } if (headId != null) ru.setExpectedOldObjectId(headId); else ru.setExpectedOldObjectId(ObjectId.zeroId()); Result rc = ru.forceUpdate(); switch (rc) { case NEW: case FORCED: case FAST_FORWARD: { setCallable(false); if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) { // Commit was successful. Now delete the files // used for merge commits repo.writeMergeCommitMsg(null); repo.writeMergeHeads(null); } else if (state == RepositoryState.CHERRY_PICKING_RESOLVED) { repo.writeMergeCommitMsg(null); repo.writeCherryPickHead(null); } else if (state == RepositoryState.REVERTING_RESOLVED) { repo.writeMergeCommitMsg(null); repo.writeRevertHead(null); } return revCommit; } case REJECTED: case LOCK_FAILURE: throw new ConcurrentRefUpdateException( JGitText.get().couldNotLockHEAD, ru.getRef(), rc); default: throw new JGitInternalException( MessageFormat.format( JGitText.get().updatingRefFailed, Constants.HEAD, commitId.toString(), rc)); } } finally { index.unlock(); } } catch (UnmergedPathException e) { throw new UnmergedPathsException(e); } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfCommitCommand, e); } }