Added merge support to CommitCommand
The CommitCommand should take care to create a merge commit if the file $GIT_DIR/MERGE_HEAD exists. It should then read the parents for the merge commit out of this file. It should also take care that when commiting a merge and no commit message was specified to read the message from $GIT_DIR/MERGE_MSG. Finally the CommitCommand should remove these files if the commit succeeded. Change-Id: I4e292115085099d5b86546d2021680cb1454266c Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
This commit is contained in:
parent
3c667b328a
commit
6ca9843f3e
|
@ -42,14 +42,22 @@
|
||||||
*/
|
*/
|
||||||
package org.eclipse.jgit.api;
|
package org.eclipse.jgit.api;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.eclipse.jgit.errors.UnmergedPathException;
|
import org.eclipse.jgit.errors.UnmergedPathException;
|
||||||
|
import org.eclipse.jgit.lib.Constants;
|
||||||
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.PersonIdent;
|
import org.eclipse.jgit.lib.PersonIdent;
|
||||||
|
import org.eclipse.jgit.lib.RefUpdate;
|
||||||
import org.eclipse.jgit.lib.RepositoryTestCase;
|
import org.eclipse.jgit.lib.RepositoryTestCase;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
|
|
||||||
public class CommitAndLogCommandTests extends RepositoryTestCase {
|
public class CommitAndLogCommandTests extends RepositoryTestCase {
|
||||||
public void testSomeCommits() throws NoHeadException, NoMessageException,
|
public void testSomeCommits() throws NoHeadException, NoMessageException,
|
||||||
UnmergedPathException, ConcurrentRefUpdateException {
|
UnmergedPathException, ConcurrentRefUpdateException,
|
||||||
|
JGitInternalException, WrongRepositoryStateException {
|
||||||
|
|
||||||
// do 4 commits
|
// do 4 commits
|
||||||
Git git = new Git(db);
|
Git git = new Git(db);
|
||||||
|
@ -62,8 +70,8 @@ public void testSomeCommits() throws NoHeadException, NoMessageException,
|
||||||
|
|
||||||
// check that all commits came in correctly
|
// check that all commits came in correctly
|
||||||
PersonIdent defaultCommitter = new PersonIdent(db);
|
PersonIdent defaultCommitter = new PersonIdent(db);
|
||||||
PersonIdent expectedAuthors[] = new PersonIdent[] {
|
PersonIdent expectedAuthors[] = new PersonIdent[] { defaultCommitter,
|
||||||
defaultCommitter, committer, author, author };
|
committer, author, author };
|
||||||
PersonIdent expectedCommitters[] = new PersonIdent[] {
|
PersonIdent expectedCommitters[] = new PersonIdent[] {
|
||||||
defaultCommitter, committer, defaultCommitter, committer };
|
defaultCommitter, committer, defaultCommitter, committer };
|
||||||
String expectedMessages[] = new String[] { "initial commit",
|
String expectedMessages[] = new String[] { "initial commit",
|
||||||
|
@ -82,7 +90,8 @@ public void testSomeCommits() throws NoHeadException, NoMessageException,
|
||||||
|
|
||||||
// try to do a commit without specifying a message. Should fail!
|
// try to do a commit without specifying a message. Should fail!
|
||||||
public void testWrongParams() throws UnmergedPathException,
|
public void testWrongParams() throws UnmergedPathException,
|
||||||
NoHeadException, ConcurrentRefUpdateException {
|
NoHeadException, ConcurrentRefUpdateException,
|
||||||
|
JGitInternalException, WrongRepositoryStateException {
|
||||||
Git git = new Git(db);
|
Git git = new Git(db);
|
||||||
try {
|
try {
|
||||||
git.commit().setAuthor(author).call();
|
git.commit().setAuthor(author).call();
|
||||||
|
@ -95,7 +104,8 @@ public void testWrongParams() throws UnmergedPathException,
|
||||||
// exceptions
|
// exceptions
|
||||||
public void testMultipleInvocations() throws NoHeadException,
|
public void testMultipleInvocations() throws NoHeadException,
|
||||||
ConcurrentRefUpdateException, NoMessageException,
|
ConcurrentRefUpdateException, NoMessageException,
|
||||||
UnmergedPathException {
|
UnmergedPathException, JGitInternalException,
|
||||||
|
WrongRepositoryStateException {
|
||||||
Git git = new Git(db);
|
Git git = new Git(db);
|
||||||
CommitCommand commitCmd = git.commit();
|
CommitCommand commitCmd = git.commit();
|
||||||
commitCmd.setMessage("initial commit").call();
|
commitCmd.setMessage("initial commit").call();
|
||||||
|
@ -114,4 +124,31 @@ public void testMultipleInvocations() throws NoHeadException,
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testMergeEmptyBranches() throws IOException, NoHeadException,
|
||||||
|
NoMessageException, ConcurrentRefUpdateException,
|
||||||
|
JGitInternalException, WrongRepositoryStateException {
|
||||||
|
Git git = new Git(db);
|
||||||
|
git.commit().setMessage("initial commit").call();
|
||||||
|
RefUpdate r = db.updateRef("refs/heads/side");
|
||||||
|
r.setNewObjectId(db.resolve(Constants.HEAD));
|
||||||
|
assertEquals(r.forceUpdate(), RefUpdate.Result.NEW);
|
||||||
|
RevCommit second = git.commit().setMessage("second commit").setCommitter(committer).call();
|
||||||
|
db.updateRef(Constants.HEAD).link("refs/heads/side");
|
||||||
|
RevCommit firstSide = git.commit().setMessage("first side commit").setAuthor(author).call();
|
||||||
|
|
||||||
|
FileWriter wr = new FileWriter(new File(db.getDirectory(),
|
||||||
|
Constants.MERGE_HEAD));
|
||||||
|
wr.write(ObjectId.toString(db.resolve("refs/heads/master")));
|
||||||
|
wr.close();
|
||||||
|
wr = new FileWriter(new File(db.getDirectory(), Constants.MERGE_MSG));
|
||||||
|
wr.write("merging");
|
||||||
|
wr.close();
|
||||||
|
|
||||||
|
RevCommit commit = git.commit().call();
|
||||||
|
RevCommit[] parents = commit.getParents();
|
||||||
|
assertEquals(parents[0], firstSide);
|
||||||
|
assertEquals(parents[1], second);
|
||||||
|
assertTrue(parents.length==2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ blobNotFound=Blob not found: {0}
|
||||||
blobNotFoundForPath=Blob not found: {0} for path: {1}
|
blobNotFoundForPath=Blob not found: {0} for path: {1}
|
||||||
cannotBeCombined=Cannot be combined.
|
cannotBeCombined=Cannot be combined.
|
||||||
cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RefFilter {1}.
|
cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RefFilter {1}.
|
||||||
|
cannotCommitOnARepoWithState=Cannot commit on a repo with state: {0}
|
||||||
cannotCommitWriteTo=Cannot commit write to {0}
|
cannotCommitWriteTo=Cannot commit write to {0}
|
||||||
cannotConnectPipes=cannot connect pipes
|
cannotConnectPipes=cannot connect pipes
|
||||||
cannotConvertScriptToText=Cannot convert script to text
|
cannotConvertScriptToText=Cannot convert script to text
|
||||||
|
@ -137,6 +138,7 @@ errorOccurredDuringUnpackingOnTheRemoteEnd=error occurred during unpacking on th
|
||||||
errorReadingInfoRefs=error reading info/refs
|
errorReadingInfoRefs=error reading info/refs
|
||||||
exceptionCaughtDuringExecutionOfCommitCommand=Exception caught during execution of commit command
|
exceptionCaughtDuringExecutionOfCommitCommand=Exception caught during execution of commit command
|
||||||
exceptionOccuredDuringAddingOfOptionToALogCommand=Exception occured during adding of {0} as option to a Log command
|
exceptionOccuredDuringAddingOfOptionToALogCommand=Exception occured during adding of {0} as option to a Log command
|
||||||
|
exceptionOccuredDuringReadingOfGIT_DIR=Exception occured during reading of $GIT_DIR/{0}. {1}
|
||||||
expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF
|
expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF
|
||||||
expectedACKNAKGot=Expected ACK/NAK, got: {0}
|
expectedACKNAKGot=Expected ACK/NAK, got: {0}
|
||||||
expectedBooleanStringValue=Expected boolean string value
|
expectedBooleanStringValue=Expected boolean string value
|
||||||
|
|
|
@ -87,6 +87,7 @@ public static JGitText get() {
|
||||||
/***/ public String blobNotFoundForPath;
|
/***/ public String blobNotFoundForPath;
|
||||||
/***/ public String cannotBeCombined;
|
/***/ public String cannotBeCombined;
|
||||||
/***/ public String cannotCombineTreeFilterWithRevFilter;
|
/***/ public String cannotCombineTreeFilterWithRevFilter;
|
||||||
|
/***/ public String cannotCommitOnARepoWithState;
|
||||||
/***/ public String cannotCommitWriteTo;
|
/***/ public String cannotCommitWriteTo;
|
||||||
/***/ public String cannotConnectPipes;
|
/***/ public String cannotConnectPipes;
|
||||||
/***/ public String cannotConvertScriptToText;
|
/***/ public String cannotConvertScriptToText;
|
||||||
|
@ -197,6 +198,7 @@ public static JGitText get() {
|
||||||
/***/ public String errorReadingInfoRefs;
|
/***/ public String errorReadingInfoRefs;
|
||||||
/***/ public String exceptionCaughtDuringExecutionOfCommitCommand;
|
/***/ public String exceptionCaughtDuringExecutionOfCommitCommand;
|
||||||
/***/ public String exceptionOccuredDuringAddingOfOptionToALogCommand;
|
/***/ public String exceptionOccuredDuringAddingOfOptionToALogCommand;
|
||||||
|
/***/ public String exceptionOccuredDuringReadingOfGIT_DIR;
|
||||||
/***/ public String expectedACKNAKFoundEOF;
|
/***/ public String expectedACKNAKFoundEOF;
|
||||||
/***/ public String expectedACKNAKGot;
|
/***/ public String expectedACKNAKGot;
|
||||||
/***/ public String expectedBooleanStringValue;
|
/***/ public String expectedBooleanStringValue;
|
||||||
|
|
|
@ -42,8 +42,11 @@
|
||||||
*/
|
*/
|
||||||
package org.eclipse.jgit.api;
|
package org.eclipse.jgit.api;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jgit.JGitText;
|
import org.eclipse.jgit.JGitText;
|
||||||
import org.eclipse.jgit.dircache.DirCache;
|
import org.eclipse.jgit.dircache.DirCache;
|
||||||
|
@ -57,6 +60,7 @@
|
||||||
import org.eclipse.jgit.lib.RefUpdate;
|
import org.eclipse.jgit.lib.RefUpdate;
|
||||||
import org.eclipse.jgit.lib.RefUpdate.Result;
|
import org.eclipse.jgit.lib.RefUpdate.Result;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import org.eclipse.jgit.lib.RepositoryState;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
|
|
||||||
|
@ -76,6 +80,12 @@ public class CommitCommand extends GitCommand<RevCommit> {
|
||||||
|
|
||||||
private String message;
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parents this commit should have. The current HEAD will be in this list
|
||||||
|
* and also all commits mentioned in .git/MERGE_HEAD
|
||||||
|
*/
|
||||||
|
private List<ObjectId> parents = new LinkedList<ObjectId>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param repo
|
* @param repo
|
||||||
*/
|
*/
|
||||||
|
@ -96,6 +106,8 @@ protected CommitCommand(Repository repo) {
|
||||||
* when called without specifying a commit message
|
* when called without specifying a commit message
|
||||||
* @throws UnmergedPathException
|
* @throws UnmergedPathException
|
||||||
* when the current index contained unmerged pathes (conflicts)
|
* when the current index contained unmerged pathes (conflicts)
|
||||||
|
* @throws WrongRepositoryStateException
|
||||||
|
* when repository is not in the right state for committing
|
||||||
* @throws JGitInternalException
|
* @throws JGitInternalException
|
||||||
* a low-level exception of JGit has occurred. The original
|
* a low-level exception of JGit has occurred. The original
|
||||||
* exception can be retrieved by calling
|
* exception can be retrieved by calling
|
||||||
|
@ -106,9 +118,14 @@ protected CommitCommand(Repository repo) {
|
||||||
*/
|
*/
|
||||||
public RevCommit call() throws NoHeadException, NoMessageException,
|
public RevCommit call() throws NoHeadException, NoMessageException,
|
||||||
UnmergedPathException, ConcurrentRefUpdateException,
|
UnmergedPathException, ConcurrentRefUpdateException,
|
||||||
JGitInternalException {
|
JGitInternalException, WrongRepositoryStateException {
|
||||||
checkCallable();
|
checkCallable();
|
||||||
processOptions();
|
|
||||||
|
RepositoryState state = repo.getRepositoryState();
|
||||||
|
if (!state.canCommit())
|
||||||
|
throw new WrongRepositoryStateException(MessageFormat.format(
|
||||||
|
JGitText.get().cannotCommitOnARepoWithState, state.name()));
|
||||||
|
processOptions(state);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Ref head = repo.getRef(Constants.HEAD);
|
Ref head = repo.getRef(Constants.HEAD);
|
||||||
|
@ -117,7 +134,9 @@ public RevCommit call() throws NoHeadException, NoMessageException,
|
||||||
JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
|
JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
|
||||||
|
|
||||||
// determine the current HEAD and the commit it is referring to
|
// determine the current HEAD and the commit it is referring to
|
||||||
ObjectId parentID = repo.resolve(Constants.HEAD + "^{commit}");
|
ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}");
|
||||||
|
if (headId != null)
|
||||||
|
parents.add(0, headId);
|
||||||
|
|
||||||
// lock the index
|
// lock the index
|
||||||
DirCache index = DirCache.lock(repo);
|
DirCache index = DirCache.lock(repo);
|
||||||
|
@ -134,8 +153,8 @@ public RevCommit call() throws NoHeadException, NoMessageException,
|
||||||
commit.setCommitter(committer);
|
commit.setCommitter(committer);
|
||||||
commit.setAuthor(author);
|
commit.setAuthor(author);
|
||||||
commit.setMessage(message);
|
commit.setMessage(message);
|
||||||
if (parentID != null)
|
|
||||||
commit.setParentIds(new ObjectId[] { parentID });
|
commit.setParentIds(parents.toArray(new ObjectId[]{}));
|
||||||
commit.setTreeId(indexTreeId);
|
commit.setTreeId(indexTreeId);
|
||||||
ObjectId commitId = repoWriter.writeCommit(commit);
|
ObjectId commitId = repoWriter.writeCommit(commit);
|
||||||
|
|
||||||
|
@ -145,12 +164,20 @@ public RevCommit call() throws NoHeadException, NoMessageException,
|
||||||
ru.setRefLogMessage("commit : " + revCommit.getShortMessage(),
|
ru.setRefLogMessage("commit : " + revCommit.getShortMessage(),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
ru.setExpectedOldObjectId(parentID);
|
ru.setExpectedOldObjectId(headId);
|
||||||
Result rc = ru.update();
|
Result rc = ru.update();
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case NEW:
|
case NEW:
|
||||||
case FAST_FORWARD:
|
case FAST_FORWARD:
|
||||||
setCallable(false);
|
setCallable(false);
|
||||||
|
if (state == RepositoryState.MERGING_RESOLVED) {
|
||||||
|
// Commit was successful. Now delete the files
|
||||||
|
// used for merge commits
|
||||||
|
new File(repo.getDirectory(), Constants.MERGE_HEAD)
|
||||||
|
.delete();
|
||||||
|
new File(repo.getDirectory(), Constants.MERGE_MSG)
|
||||||
|
.delete();
|
||||||
|
}
|
||||||
return revCommit;
|
return revCommit;
|
||||||
case REJECTED:
|
case REJECTED:
|
||||||
case LOCK_FAILURE:
|
case LOCK_FAILURE:
|
||||||
|
@ -179,18 +206,41 @@ public RevCommit call() throws NoHeadException, NoMessageException,
|
||||||
* Sets default values for not explicitly specified options. Then validates
|
* Sets default values for not explicitly specified options. Then validates
|
||||||
* that all required data has been provided.
|
* that all required data has been provided.
|
||||||
*
|
*
|
||||||
|
* @param state
|
||||||
|
* the state of the repository we are working on
|
||||||
|
*
|
||||||
* @throws NoMessageException
|
* @throws NoMessageException
|
||||||
* if the commit message has not been specified
|
* if the commit message has not been specified
|
||||||
*/
|
*/
|
||||||
private void processOptions() throws NoMessageException {
|
private void processOptions(RepositoryState state) throws NoMessageException {
|
||||||
if (message == null)
|
|
||||||
// as long as we don't suppport -C option we have to have
|
|
||||||
// an explicit message
|
|
||||||
throw new NoMessageException(JGitText.get().commitMessageNotSpecified);
|
|
||||||
if (committer == null)
|
if (committer == null)
|
||||||
committer = new PersonIdent(repo);
|
committer = new PersonIdent(repo);
|
||||||
if (author == null)
|
if (author == null)
|
||||||
author = committer;
|
author = committer;
|
||||||
|
|
||||||
|
// when doing a merge commit parse MERGE_HEAD and MERGE_MSG files
|
||||||
|
if (state == RepositoryState.MERGING_RESOLVED) {
|
||||||
|
try {
|
||||||
|
parents = repo.readMergeHeads();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new JGitInternalException(MessageFormat.format(
|
||||||
|
JGitText.get().exceptionOccuredDuringReadingOfGIT_DIR,
|
||||||
|
Constants.MERGE_HEAD, e));
|
||||||
|
}
|
||||||
|
if (message == null) {
|
||||||
|
try {
|
||||||
|
message = repo.readMergeCommitMsg();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new JGitInternalException(MessageFormat.format(
|
||||||
|
JGitText.get().exceptionOccuredDuringReadingOfGIT_DIR,
|
||||||
|
Constants.MERGE_MSG, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (message == null)
|
||||||
|
// as long as we don't suppport -C option we have to have
|
||||||
|
// an explicit message
|
||||||
|
throw new NoMessageException(JGitText.get().commitMessageNotSpecified);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> and
|
||||||
|
* other copyright owners as documented in the project's IP log.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Distribution License v1.0 which accompanies this
|
||||||
|
* distribution, is reproduced below, and is available at
|
||||||
|
* http://www.eclipse.org/org/documents/edl-v10.php
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Eclipse Foundation, Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.eclipse.jgit.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when the state of the repository doesn't allow the execution
|
||||||
|
* of a certain command. E.g. when a CommitCommand should be executed on a
|
||||||
|
* repository with unresolved conflicts this exception will be thrown.
|
||||||
|
*/
|
||||||
|
public class WrongRepositoryStateException extends GitAPIException {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
WrongRepositoryStateException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
WrongRepositoryStateException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -518,6 +518,12 @@ public static byte[] encode(final String str) {
|
||||||
CHARSET = Charset.forName(CHARACTER_ENCODING);
|
CHARSET = Charset.forName(CHARACTER_ENCODING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** name of the file containing the commit msg for a merge commit */
|
||||||
|
public static final String MERGE_MSG = "MERGE_MSG";
|
||||||
|
|
||||||
|
/** name of the file containing the IDs of the parents of a merge commit */
|
||||||
|
public static final String MERGE_HEAD = "MERGE_HEAD";
|
||||||
|
|
||||||
private Constants() {
|
private Constants() {
|
||||||
// Hide the default constructor
|
// Hide the default constructor
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
package org.eclipse.jgit.lib;
|
package org.eclipse.jgit.lib;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -61,12 +62,14 @@
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.eclipse.jgit.dircache.DirCache;
|
|
||||||
import org.eclipse.jgit.JGitText;
|
import org.eclipse.jgit.JGitText;
|
||||||
|
import org.eclipse.jgit.dircache.DirCache;
|
||||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
import org.eclipse.jgit.errors.RevisionSyntaxException;
|
import org.eclipse.jgit.errors.RevisionSyntaxException;
|
||||||
import org.eclipse.jgit.util.FS;
|
import org.eclipse.jgit.util.FS;
|
||||||
|
import org.eclipse.jgit.util.IO;
|
||||||
|
import org.eclipse.jgit.util.RawParseUtils;
|
||||||
import org.eclipse.jgit.util.SystemReader;
|
import org.eclipse.jgit.util.SystemReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1338,4 +1341,55 @@ public ReflogReader getReflogReader(String refName) throws IOException {
|
||||||
return new ReflogReader(this, ref.getName());
|
return new ReflogReader(this, ref.getName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the information stored in the file $GIT_DIR/MERGE_MSG. In this
|
||||||
|
* file operations triggering a merge will store a template for the commit
|
||||||
|
* message of the merge commit.
|
||||||
|
*
|
||||||
|
* @return a String containing the content of the MERGE_MSG file or
|
||||||
|
* {@code null} if this file doesn't exist
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public String readMergeCommitMsg() throws IOException {
|
||||||
|
File mergeMsgFile = new File(gitDir, Constants.MERGE_MSG);
|
||||||
|
try {
|
||||||
|
return new String(IO.readFully(mergeMsgFile));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// MERGE_MSG file has disappeared in the meantime
|
||||||
|
// ignore it
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the information stored in the file $GIT_DIR/MERGE_HEAD. In this
|
||||||
|
* file operations triggering a merge will store the IDs of all heads which
|
||||||
|
* should be merged together with HEAD.
|
||||||
|
*
|
||||||
|
* @return a list of {@link Commit}s which IDs are listed in the MERGE_HEAD
|
||||||
|
* file or {@code null} if this file doesn't exist. Also if the file
|
||||||
|
* exists but is empty {@code null} will be returned
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public List<ObjectId> readMergeHeads() throws IOException {
|
||||||
|
File mergeHeadFile = new File(gitDir, Constants.MERGE_HEAD);
|
||||||
|
byte[] raw;
|
||||||
|
try {
|
||||||
|
raw = IO.readFully(mergeHeadFile);
|
||||||
|
} catch (FileNotFoundException notFound) {
|
||||||
|
return new LinkedList<ObjectId>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (raw.length == 0)
|
||||||
|
throw new IOException("MERGE_HEAD file empty: " + mergeHeadFile);
|
||||||
|
|
||||||
|
LinkedList<ObjectId> heads = new LinkedList<ObjectId>();
|
||||||
|
for (int p = 0; p < raw.length;) {
|
||||||
|
heads.add(ObjectId.fromString(raw, p));
|
||||||
|
p = RawParseUtils
|
||||||
|
.nextLF(raw, p + Constants.OBJECT_ID_STRING_LENGTH);
|
||||||
|
}
|
||||||
|
return heads;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue