diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java index ba0847bd8..67e1879d3 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java @@ -326,6 +326,33 @@ public void testContentMerge() throws Exception { assertEquals(RepositoryState.MERGING, db.getRepositoryState()); } + @Test + public void testMergeTag() throws Exception { + Git git = new Git(db); + + writeTrashFile("a", "a"); + git.add().addFilepattern("a").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("b", "b"); + git.add().addFilepattern("b").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + Ref tag = git.tag().setAnnotated(true).setMessage("my tag 01") + .setName("tag01").setObjectId(secondCommit).call(); + + checkoutBranch("refs/heads/master"); + + writeTrashFile("a", "a2"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("main").call(); + + MergeResult result = git.merge().include(tag).setStrategy(MergeStrategy.RESOLVE).call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + } + @Test public void testMergeMessage() throws Exception { Git git = new Git(db); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index 1f68a7df2..162105b78 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -77,6 +77,8 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevObject; +import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.treewalk.FileTreeIterator; @@ -150,13 +152,16 @@ public RevCommit call() throws GitAPIException, NoHeadException, checkCallable(); Collections.sort(only); - RepositoryState state = repo.getRepositoryState(); - if (!state.canCommit()) - throw new WrongRepositoryStateException(MessageFormat.format( - JGitText.get().cannotCommitOnARepoWithState, state.name())); - processOptions(state); + RevWalk rw = new RevWalk(repo); try { + RepositoryState state = repo.getRepositoryState(); + if (!state.canCommit()) + throw new WrongRepositoryStateException(MessageFormat.format( + JGitText.get().cannotCommitOnARepoWithState, + state.name())); + processOptions(state, rw); + if (all && !repo.isBare() && repo.getWorkTree() != null) { Git git = new Git(repo); try { @@ -182,8 +187,7 @@ public RevCommit call() throws GitAPIException, NoHeadException, if (headId != null) if (amend) { - RevCommit previousCommit = new RevWalk(repo) - .parseCommit(headId); + RevCommit previousCommit = rw.parseCommit(headId); for (RevCommit p : previousCommit.getParents()) parents.add(p.getId()); if (author == null) @@ -196,7 +200,7 @@ public RevCommit call() throws GitAPIException, NoHeadException, DirCache index = repo.lockDirCache(); try { if (!only.isEmpty()) - index = createTemporaryIndex(headId, index); + index = createTemporaryIndex(headId, index, rw); ObjectInserter odi = repo.newObjectInserter(); try { @@ -219,56 +223,51 @@ public RevCommit call() throws GitAPIException, NoHeadException, ObjectId commitId = odi.insert(commit); odi.flush(); - RevWalk revWalk = new RevWalk(repo); - try { - RevCommit revCommit = revWalk.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): " - : "commit: "; - ru.setRefLogMessage( - prefix + revCommit.getShortMessage(), false); + 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): " + : "commit: "; + 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) { + // 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); } - 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) { - // 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 { - revWalk.release(); + 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 { odi.release(); @@ -281,6 +280,8 @@ public RevCommit call() throws GitAPIException, NoHeadException, } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfCommitCommand, e); + } finally { + rw.dispose(); } } @@ -297,7 +298,8 @@ private void insertChangeId(ObjectId treeId) throws IOException { + changeId.getName() + "\n"); //$NON-NLS-1$ } - private DirCache createTemporaryIndex(ObjectId headId, DirCache index) + private DirCache createTemporaryIndex(ObjectId headId, DirCache index, + RevWalk rw) throws IOException { ObjectInserter inserter = null; @@ -317,7 +319,7 @@ private DirCache createTemporaryIndex(ObjectId headId, DirCache index) int fIdx = treeWalk.addTree(new FileTreeIterator(repo)); int hIdx = -1; if (headId != null) - hIdx = treeWalk.addTree(new RevWalk(repo).parseTree(headId)); + hIdx = treeWalk.addTree(rw.parseTree(headId)); treeWalk.setRecursive(true); String lastAddedFile = null; @@ -473,11 +475,14 @@ private int lookupOnly(String pathString) { * * @param state * the state of the repository we are working on + * @param rw + * the RevWalk to use * * @throws NoMessageException * if the commit message has not been specified */ - private void processOptions(RepositoryState state) throws NoMessageException { + private void processOptions(RepositoryState state, RevWalk rw) + throws NoMessageException { if (committer == null) committer = new PersonIdent(repo); if (author == null && !amend) @@ -487,6 +492,12 @@ private void processOptions(RepositoryState state) throws NoMessageException { if (state == RepositoryState.MERGING_RESOLVED) { try { parents = repo.readMergeHeads(); + if (parents != null) + for (int i = 0; i < parents.size(); i++) { + RevObject ro = rw.parseAny(parents.get(i)); + if (ro instanceof RevTag) + parents.set(i, rw.peel(ro)); + } } catch (IOException e) { throw new JGitInternalException(MessageFormat.format( JGitText.get().exceptionOccurredDuringReadingOfGIT_DIR,