This feature was introduced in native git with version 1.8.4. Bug: 422951 Change-Id: I42f194174d64d7ada6631e2156c2a7bf93b5e91c Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>tags/v3.2.0.201312181205-r
import org.eclipse.jgit.api.errors.RefNotFoundException; | import org.eclipse.jgit.api.errors.RefNotFoundException; | ||||
import org.eclipse.jgit.api.errors.UnmergedPathsException; | import org.eclipse.jgit.api.errors.UnmergedPathsException; | ||||
import org.eclipse.jgit.api.errors.WrongRepositoryStateException; | import org.eclipse.jgit.api.errors.WrongRepositoryStateException; | ||||
import org.eclipse.jgit.diff.DiffEntry; | |||||
import org.eclipse.jgit.dircache.DirCacheCheckout; | import org.eclipse.jgit.dircache.DirCacheCheckout; | ||||
import org.eclipse.jgit.errors.AmbiguousObjectException; | |||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException; | |||||
import org.eclipse.jgit.errors.MissingObjectException; | |||||
import org.eclipse.jgit.junit.RepositoryTestCase; | import org.eclipse.jgit.junit.RepositoryTestCase; | ||||
import org.eclipse.jgit.lib.AbbreviatedObjectId; | import org.eclipse.jgit.lib.AbbreviatedObjectId; | ||||
import org.eclipse.jgit.lib.ConfigConstants; | |||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.ObjectId; | import org.eclipse.jgit.lib.ObjectId; | ||||
import org.eclipse.jgit.lib.PersonIdent; | import org.eclipse.jgit.lib.PersonIdent; | ||||
import org.eclipse.jgit.merge.MergeStrategy; | import org.eclipse.jgit.merge.MergeStrategy; | ||||
import org.eclipse.jgit.revwalk.RevCommit; | import org.eclipse.jgit.revwalk.RevCommit; | ||||
import org.eclipse.jgit.revwalk.RevWalk; | import org.eclipse.jgit.revwalk.RevWalk; | ||||
import org.eclipse.jgit.treewalk.TreeWalk; | |||||
import org.eclipse.jgit.treewalk.filter.TreeFilter; | |||||
import org.eclipse.jgit.util.FileUtils; | import org.eclipse.jgit.util.FileUtils; | ||||
import org.eclipse.jgit.util.IO; | import org.eclipse.jgit.util.IO; | ||||
import org.eclipse.jgit.util.RawParseUtils; | import org.eclipse.jgit.util.RawParseUtils; | ||||
assertEquals(RepositoryState.SAFE, db.getRepositoryState()); | assertEquals(RepositoryState.SAFE, db.getRepositoryState()); | ||||
} | } | ||||
@Test | |||||
public void testRebaseWithAutoStash() | |||||
throws Exception { | |||||
// create file0, add and commit | |||||
db.getConfig().setBoolean(ConfigConstants.CONFIG_REBASE_SECTION, null, | |||||
ConfigConstants.CONFIG_KEY_AUTOSTASH, true); | |||||
writeTrashFile("file0", "file0"); | |||||
git.add().addFilepattern("file0").call(); | |||||
git.commit().setMessage("commit0").call(); | |||||
// create file1, add and commit | |||||
writeTrashFile(FILE1, "file1"); | |||||
git.add().addFilepattern(FILE1).call(); | |||||
RevCommit commit = git.commit().setMessage("commit1").call(); | |||||
// create topic branch and checkout / create file2, add and commit | |||||
createBranch(commit, "refs/heads/topic"); | |||||
checkoutBranch("refs/heads/topic"); | |||||
writeTrashFile("file2", "file2"); | |||||
git.add().addFilepattern("file2").call(); | |||||
git.commit().setMessage("commit2").call(); | |||||
// checkout master branch / modify file1, add and commit | |||||
checkoutBranch("refs/heads/master"); | |||||
writeTrashFile(FILE1, "modified file1"); | |||||
git.add().addFilepattern(FILE1).call(); | |||||
git.commit().setMessage("commit3").call(); | |||||
// checkout topic branch / modify file0 | |||||
checkoutBranch("refs/heads/topic"); | |||||
writeTrashFile("file0", "unstaged modified file0"); | |||||
// rebase | |||||
assertEquals(Status.OK, | |||||
git.rebase().setUpstream("refs/heads/master").call() | |||||
.getStatus()); | |||||
checkFile(new File(db.getWorkTree(), "file0"), | |||||
"unstaged modified file0"); | |||||
checkFile(new File(db.getWorkTree(), FILE1), "modified file1"); | |||||
checkFile(new File(db.getWorkTree(), "file2"), "file2"); | |||||
assertEquals("[file0, mode:100644, content:file0]" | |||||
+ "[file1, mode:100644, content:modified file1]" | |||||
+ "[file2, mode:100644, content:file2]", | |||||
indexState(CONTENT)); | |||||
assertEquals(RepositoryState.SAFE, db.getRepositoryState()); | |||||
} | |||||
@Test | |||||
public void testRebaseWithAutoStashConflictOnApply() throws Exception { | |||||
// create file0, add and commit | |||||
db.getConfig().setBoolean(ConfigConstants.CONFIG_REBASE_SECTION, null, | |||||
ConfigConstants.CONFIG_KEY_AUTOSTASH, true); | |||||
writeTrashFile("file0", "file0"); | |||||
git.add().addFilepattern("file0").call(); | |||||
git.commit().setMessage("commit0").call(); | |||||
// create file1, add and commit | |||||
writeTrashFile(FILE1, "file1"); | |||||
git.add().addFilepattern(FILE1).call(); | |||||
RevCommit commit = git.commit().setMessage("commit1").call(); | |||||
// create topic branch and checkout / create file2, add and commit | |||||
createBranch(commit, "refs/heads/topic"); | |||||
checkoutBranch("refs/heads/topic"); | |||||
writeTrashFile("file2", "file2"); | |||||
git.add().addFilepattern("file2").call(); | |||||
git.commit().setMessage("commit2").call(); | |||||
// checkout master branch / modify file1, add and commit | |||||
checkoutBranch("refs/heads/master"); | |||||
writeTrashFile(FILE1, "modified file1"); | |||||
git.add().addFilepattern(FILE1).call(); | |||||
git.commit().setMessage("commit3").call(); | |||||
// checkout topic branch / modify file0 | |||||
checkoutBranch("refs/heads/topic"); | |||||
writeTrashFile("file1", "unstaged modified file1"); | |||||
// rebase | |||||
assertEquals(Status.STASH_APPLY_CONFLICTS, | |||||
git.rebase().setUpstream("refs/heads/master").call() | |||||
.getStatus()); | |||||
checkFile(new File(db.getWorkTree(), "file0"), "file0"); | |||||
checkFile( | |||||
new File(db.getWorkTree(), FILE1), | |||||
"<<<<<<< HEAD\nmodified file1\n=======\nunstaged modified file1\n>>>>>>> stash\n"); | |||||
checkFile(new File(db.getWorkTree(), "file2"), "file2"); | |||||
assertEquals( | |||||
"[file0, mode:100644, content:file0]" | |||||
+ "[file1, mode:100644, stage:1, content:file1]" | |||||
+ "[file1, mode:100644, stage:2, content:modified file1]" | |||||
+ "[file1, mode:100644, stage:3, content:unstaged modified file1]" | |||||
+ "[file2, mode:100644, content:file2]", | |||||
indexState(CONTENT)); | |||||
assertEquals(RepositoryState.SAFE, db.getRepositoryState()); | |||||
List<DiffEntry> diffs = getStashedDiff(); | |||||
assertEquals(1, diffs.size()); | |||||
assertEquals(DiffEntry.ChangeType.MODIFY, diffs.get(0).getChangeType()); | |||||
assertEquals("file1", diffs.get(0).getOldPath()); | |||||
} | |||||
private List<DiffEntry> getStashedDiff() throws AmbiguousObjectException, | |||||
IncorrectObjectTypeException, IOException, MissingObjectException { | |||||
ObjectId stashId = db.resolve("stash@{0}"); | |||||
RevWalk revWalk = new RevWalk(db); | |||||
RevCommit stashCommit = revWalk.parseCommit(stashId); | |||||
List<DiffEntry> diffs = diffWorkingAgainstHead(stashCommit, revWalk); | |||||
return diffs; | |||||
} | |||||
private TreeWalk createTreeWalk() { | |||||
TreeWalk walk = new TreeWalk(db); | |||||
walk.setRecursive(true); | |||||
walk.setFilter(TreeFilter.ANY_DIFF); | |||||
return walk; | |||||
} | |||||
private List<DiffEntry> diffWorkingAgainstHead(final RevCommit commit, | |||||
RevWalk revWalk) | |||||
throws IOException { | |||||
TreeWalk walk = createTreeWalk(); | |||||
RevCommit parentCommit = revWalk.parseCommit(commit.getParent(0)); | |||||
try { | |||||
walk.addTree(parentCommit.getTree()); | |||||
walk.addTree(commit.getTree()); | |||||
return DiffEntry.scan(walk); | |||||
} finally { | |||||
walk.release(); | |||||
} | |||||
} | |||||
private int countPicks() throws IOException { | private int countPicks() throws IOException { | ||||
int count = 0; | int count = 0; | ||||
File todoFile = getTodoFile(); | File todoFile = getTodoFile(); |
import org.eclipse.jgit.api.errors.NoMessageException; | import org.eclipse.jgit.api.errors.NoMessageException; | ||||
import org.eclipse.jgit.api.errors.RefAlreadyExistsException; | import org.eclipse.jgit.api.errors.RefAlreadyExistsException; | ||||
import org.eclipse.jgit.api.errors.RefNotFoundException; | import org.eclipse.jgit.api.errors.RefNotFoundException; | ||||
import org.eclipse.jgit.api.errors.StashApplyFailureException; | |||||
import org.eclipse.jgit.api.errors.UnmergedPathsException; | import org.eclipse.jgit.api.errors.UnmergedPathsException; | ||||
import org.eclipse.jgit.api.errors.WrongRepositoryStateException; | import org.eclipse.jgit.api.errors.WrongRepositoryStateException; | ||||
import org.eclipse.jgit.diff.DiffFormatter; | import org.eclipse.jgit.diff.DiffFormatter; | ||||
import org.eclipse.jgit.internal.JGitText; | import org.eclipse.jgit.internal.JGitText; | ||||
import org.eclipse.jgit.lib.AbbreviatedObjectId; | import org.eclipse.jgit.lib.AbbreviatedObjectId; | ||||
import org.eclipse.jgit.lib.AnyObjectId; | import org.eclipse.jgit.lib.AnyObjectId; | ||||
import org.eclipse.jgit.lib.ConfigConstants; | |||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.NullProgressMonitor; | import org.eclipse.jgit.lib.NullProgressMonitor; | ||||
import org.eclipse.jgit.lib.ObjectId; | import org.eclipse.jgit.lib.ObjectId; | ||||
private static final String MESSAGE_SQUASH = "message-squash"; //$NON-NLS-1$ | private static final String MESSAGE_SQUASH = "message-squash"; //$NON-NLS-1$ | ||||
private static final String AUTOSTASH = "autostash"; //$NON-NLS-1$ | |||||
private static final String AUTOSTASH_MSG = "On {0}: autostash"; | |||||
/** | /** | ||||
* The available operations | * The available operations | ||||
*/ | */ | ||||
.resolve(upstreamCommitId)); | .resolve(upstreamCommitId)); | ||||
break; | break; | ||||
case BEGIN: | case BEGIN: | ||||
autoStash(); | |||||
if (stopAfterInitialization | if (stopAfterInitialization | ||||
|| !walk.isMergedInto( | || !walk.isMergedInto( | ||||
walk.parseCommit(repo.resolve(Constants.HEAD)), | walk.parseCommit(repo.resolve(Constants.HEAD)), | ||||
RebaseResult res = initFilesAndRewind(); | RebaseResult res = initFilesAndRewind(); | ||||
if (stopAfterInitialization) | if (stopAfterInitialization) | ||||
return RebaseResult.INTERACTIVE_PREPARED_RESULT; | return RebaseResult.INTERACTIVE_PREPARED_RESULT; | ||||
if (res != null) | |||||
if (res != null) { | |||||
autoStashApply(); | |||||
return res; | return res; | ||||
} | |||||
} | } | ||||
if (monitor.isCancelled()) | if (monitor.isCancelled()) | ||||
} | } | ||||
} | } | ||||
private void autoStash() throws GitAPIException, IOException { | |||||
if (repo.getConfig().getBoolean(ConfigConstants.CONFIG_REBASE_SECTION, | |||||
ConfigConstants.CONFIG_KEY_AUTOSTASH, false)) { | |||||
String message = MessageFormat.format( | |||||
AUTOSTASH_MSG, | |||||
Repository | |||||
.shortenRefName(getHeadName(getHead()))); | |||||
RevCommit stashCommit = Git.wrap(repo).stashCreate().setRef(null) | |||||
.setWorkingDirectoryMessage( | |||||
message) | |||||
.call(); | |||||
if (stashCommit != null) { | |||||
FileUtils.mkdir(rebaseState.getDir()); | |||||
rebaseState.createFile(AUTOSTASH, stashCommit.getName()); | |||||
} | |||||
} | |||||
} | |||||
private boolean autoStashApply() throws IOException, GitAPIException { | |||||
boolean conflicts = false; | |||||
if (rebaseState.getFile(AUTOSTASH).exists()) { | |||||
String stash = rebaseState.readFile(AUTOSTASH); | |||||
try { | |||||
Git.wrap(repo).stashApply().setStashRef(stash) | |||||
.ignoreRepositoryState(true).call(); | |||||
} catch (StashApplyFailureException e) { | |||||
conflicts = true; | |||||
RevWalk rw = new RevWalk(repo); | |||||
ObjectId stashId = repo.resolve(stash); | |||||
RevCommit commit = rw.parseCommit(stashId); | |||||
updateStashRef(commit, commit.getAuthorIdent(), | |||||
commit.getShortMessage()); | |||||
} | |||||
} | |||||
return conflicts; | |||||
} | |||||
private void updateStashRef(ObjectId commitId, PersonIdent refLogIdent, | |||||
String refLogMessage) throws IOException { | |||||
Ref currentRef = repo.getRef(Constants.R_STASH); | |||||
RefUpdate refUpdate = repo.updateRef(Constants.R_STASH); | |||||
refUpdate.setNewObjectId(commitId); | |||||
refUpdate.setRefLogIdent(refLogIdent); | |||||
refUpdate.setRefLogMessage(refLogMessage, false); | |||||
if (currentRef != null) | |||||
refUpdate.setExpectedOldObjectId(currentRef.getObjectId()); | |||||
else | |||||
refUpdate.setExpectedOldObjectId(ObjectId.zeroId()); | |||||
refUpdate.forceUpdate(); | |||||
} | |||||
private RebaseResult processStep(RebaseTodoLine step, boolean shouldPick) | private RebaseResult processStep(RebaseTodoLine step, boolean shouldPick) | ||||
throws IOException, GitAPIException { | throws IOException, GitAPIException { | ||||
if (Action.COMMENT.equals(step.getAction())) | if (Action.COMMENT.equals(step.getAction())) | ||||
} | } | ||||
private RebaseResult finishRebase(RevCommit newHead, | private RebaseResult finishRebase(RevCommit newHead, | ||||
boolean lastStepWasForward) throws IOException { | |||||
boolean lastStepWasForward) throws IOException, GitAPIException { | |||||
String headName = rebaseState.readFile(HEAD_NAME); | String headName = rebaseState.readFile(HEAD_NAME); | ||||
updateHead(headName, newHead, upstreamCommit); | updateHead(headName, newHead, upstreamCommit); | ||||
boolean stashConflicts = autoStashApply(); | |||||
FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); | FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); | ||||
if (stashConflicts) | |||||
return RebaseResult.STASH_APPLY_CONFLICTS_RESULT; | |||||
if (lastStepWasForward || newHead == null) | if (lastStepWasForward || newHead == null) | ||||
return RebaseResult.FAST_FORWARD_RESULT; | return RebaseResult.FAST_FORWARD_RESULT; | ||||
return RebaseResult.OK_RESULT; | return RebaseResult.OK_RESULT; | ||||
// we need to store everything into files so that we can implement | // we need to store everything into files so that we can implement | ||||
// --skip, --continue, and --abort | // --skip, --continue, and --abort | ||||
Ref head = repo.getRef(Constants.HEAD); | |||||
if (head == null || head.getObjectId() == null) | |||||
throw new RefNotFoundException(MessageFormat.format( | |||||
JGitText.get().refNotResolved, Constants.HEAD)); | |||||
Ref head = getHead(); | |||||
String headName; | |||||
if (head.isSymbolic()) | |||||
headName = head.getTarget().getName(); | |||||
else | |||||
headName = head.getObjectId().getName(); | |||||
String headName = getHeadName(head); | |||||
ObjectId headId = head.getObjectId(); | ObjectId headId = head.getObjectId(); | ||||
if (headId == null) | if (headId == null) | ||||
throw new RefNotFoundException(MessageFormat.format( | throw new RefNotFoundException(MessageFormat.format( | ||||
Collections.reverse(cherryPickList); | Collections.reverse(cherryPickList); | ||||
// create the folder for the meta information | // create the folder for the meta information | ||||
FileUtils.mkdir(rebaseState.getDir()); | |||||
FileUtils.mkdir(rebaseState.getDir(), true); | |||||
repo.writeOrigHead(headId); | repo.writeOrigHead(headId); | ||||
rebaseState.createFile(REBASE_HEAD, headId.name()); | rebaseState.createFile(REBASE_HEAD, headId.name()); | ||||
return null; | return null; | ||||
} | } | ||||
private static String getHeadName(Ref head) { | |||||
String headName; | |||||
if (head.isSymbolic()) | |||||
headName = head.getTarget().getName(); | |||||
else | |||||
headName = head.getObjectId().getName(); | |||||
return headName; | |||||
} | |||||
private Ref getHead() throws IOException, RefNotFoundException { | |||||
Ref head = repo.getRef(Constants.HEAD); | |||||
if (head == null || head.getObjectId() == null) | |||||
throw new RefNotFoundException(MessageFormat.format( | |||||
JGitText.get().refNotResolved, Constants.HEAD)); | |||||
return head; | |||||
} | |||||
private boolean isInteractive() { | private boolean isInteractive() { | ||||
return interactiveHandler != null; | return interactiveHandler != null; | ||||
} | } | ||||
*/ | */ | ||||
public RevCommit tryFastForward(RevCommit newCommit) throws IOException, | public RevCommit tryFastForward(RevCommit newCommit) throws IOException, | ||||
GitAPIException { | GitAPIException { | ||||
Ref head = repo.getRef(Constants.HEAD); | |||||
if (head == null || head.getObjectId() == null) | |||||
throw new RefNotFoundException(MessageFormat.format( | |||||
JGitText.get().refNotResolved, Constants.HEAD)); | |||||
Ref head = getHead(); | |||||
ObjectId headId = head.getObjectId(); | ObjectId headId = head.getObjectId(); | ||||
if (headId == null) | if (headId == null) | ||||
if (walk.isMergedInto(newCommit, headCommit)) | if (walk.isMergedInto(newCommit, headCommit)) | ||||
return newCommit; | return newCommit; | ||||
String headName; | |||||
if (head.isSymbolic()) | |||||
headName = head.getTarget().getName(); | |||||
else | |||||
headName = head.getObjectId().getName(); | |||||
String headName = getHeadName(head); | |||||
return tryFastForward(headName, headCommit, newCommit); | return tryFastForward(headName, headCommit, newCommit); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
private RebaseResult abort(RebaseResult result) throws IOException { | |||||
private RebaseResult abort(RebaseResult result) throws IOException, | |||||
GitAPIException { | |||||
try { | try { | ||||
ObjectId origHead = repo.readOrigHead(); | ObjectId origHead = repo.readOrigHead(); | ||||
String commitId = origHead != null ? origHead.name() : null; | String commitId = origHead != null ? origHead.name() : null; | ||||
JGitText.get().abortingRebaseFailed); | JGitText.get().abortingRebaseFailed); | ||||
} | } | ||||
} | } | ||||
boolean stashConflicts = autoStashApply(); | |||||
// cleanup the files | // cleanup the files | ||||
FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); | FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); | ||||
repo.writeCherryPickHead(null); | repo.writeCherryPickHead(null); | ||||
if (stashConflicts) | |||||
return RebaseResult.STASH_APPLY_CONFLICTS_RESULT; | |||||
return result; | return result; | ||||
} finally { | } finally { |
public boolean isSuccessful() { | public boolean isSuccessful() { | ||||
return false; | return false; | ||||
} | } | ||||
}, | |||||
/** | |||||
* Applying stash resulted in conflicts | |||||
* | |||||
* @since 3.2 | |||||
*/ | |||||
STASH_APPLY_CONFLICTS { | |||||
@Override | |||||
public boolean isSuccessful() { | |||||
return true; | |||||
} | |||||
}; | }; | ||||
/** | /** | ||||
static final RebaseResult INTERACTIVE_PREPARED_RESULT = new RebaseResult( | static final RebaseResult INTERACTIVE_PREPARED_RESULT = new RebaseResult( | ||||
Status.INTERACTIVE_PREPARED); | Status.INTERACTIVE_PREPARED); | ||||
static final RebaseResult STASH_APPLY_CONFLICTS_RESULT = new RebaseResult( | |||||
Status.STASH_APPLY_CONFLICTS); | |||||
private final Status status; | private final Status status; | ||||
private final RevCommit currentCommit; | private final RevCommit currentCommit; |
private boolean applyIndex = true; | private boolean applyIndex = true; | ||||
private boolean ignoreRepositoryState; | |||||
/** | /** | ||||
* Create command to apply the changes of a stashed commit | * Create command to apply the changes of a stashed commit | ||||
* | * | ||||
return this; | return this; | ||||
} | } | ||||
/** | |||||
* @param ignoreRepositoryState | |||||
* @return {@code this} | |||||
* @since 3.2 | |||||
*/ | |||||
public StashApplyCommand ignoreRepositoryState(boolean ignoreRepositoryState) { | |||||
this.ignoreRepositoryState = ignoreRepositoryState; | |||||
return this; | |||||
} | |||||
private ObjectId getStashId() throws GitAPIException { | private ObjectId getStashId() throws GitAPIException { | ||||
final String revision = stashRef != null ? stashRef : DEFAULT_REF; | final String revision = stashRef != null ? stashRef : DEFAULT_REF; | ||||
final ObjectId stashId; | final ObjectId stashId; | ||||
StashApplyFailureException { | StashApplyFailureException { | ||||
checkCallable(); | checkCallable(); | ||||
if (repo.getRepositoryState() != RepositoryState.SAFE) | |||||
if (!ignoreRepositoryState | |||||
&& repo.getRepositoryState() != RepositoryState.SAFE) | |||||
throw new WrongRepositoryStateException(MessageFormat.format( | throw new WrongRepositoryStateException(MessageFormat.format( | ||||
JGitText.get().stashApplyOnUnsafeRepository, | JGitText.get().stashApplyOnUnsafeRepository, | ||||
repo.getRepositoryState())); | repo.getRepositoryState())); |
/** | /** | ||||
* Set the reference to update with the stashed commit id | * Set the reference to update with the stashed commit id | ||||
* If null, no reference is updated | |||||
* <p> | * <p> | ||||
* This value defaults to {@link Constants#R_STASH} | * This value defaults to {@link Constants#R_STASH} | ||||
* | * | ||||
private void updateStashRef(ObjectId commitId, PersonIdent refLogIdent, | private void updateStashRef(ObjectId commitId, PersonIdent refLogIdent, | ||||
String refLogMessage) throws IOException { | String refLogMessage) throws IOException { | ||||
if (ref == null) | |||||
return; | |||||
Ref currentRef = repo.getRef(ref); | Ref currentRef = repo.getRef(ref); | ||||
RefUpdate refUpdate = repo.updateRef(ref); | RefUpdate refUpdate = repo.updateRef(ref); | ||||
refUpdate.setNewObjectId(commitId); | refUpdate.setNewObjectId(commitId); |
/** The "submodule" section */ | /** The "submodule" section */ | ||||
public static final String CONFIG_SUBMODULE_SECTION = "submodule"; | public static final String CONFIG_SUBMODULE_SECTION = "submodule"; | ||||
/** | |||||
* The "rebase" section | |||||
* | |||||
* @since 3.2 | |||||
*/ | |||||
public static final String CONFIG_REBASE_SECTION = "rebase"; | |||||
/** The "gc" section */ | /** The "gc" section */ | ||||
public static final String CONFIG_GC_SECTION = "gc"; | public static final String CONFIG_GC_SECTION = "gc"; | ||||
/** The "autosetuprebase" key */ | /** The "autosetuprebase" key */ | ||||
public static final String CONFIG_KEY_AUTOSETUPREBASE = "autosetuprebase"; | public static final String CONFIG_KEY_AUTOSETUPREBASE = "autosetuprebase"; | ||||
/** | |||||
* The "autostash" key | |||||
* | |||||
* @since 3.2 | |||||
*/ | |||||
public static final String CONFIG_KEY_AUTOSTASH = "autostash"; | |||||
/** The "name" key */ | /** The "name" key */ | ||||
public static final String CONFIG_KEY_NAME = "name"; | public static final String CONFIG_KEY_NAME = "name"; | ||||