Browse Source

Implement rebase.autostash

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>
stable-3.3
Stefan Lay 11 years ago committed by Matthias Sohn
parent
commit
f86a488e32
  1. 137
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
  2. 114
      org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
  3. 15
      org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java
  4. 15
      org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
  5. 3
      org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
  6. 15
      org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java

137
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java

@ -68,9 +68,14 @@ import org.eclipse.jgit.api.errors.JGitInternalException;
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;
@ -82,6 +87,8 @@ import org.eclipse.jgit.lib.RepositoryState;
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;
@ -1567,6 +1574,136 @@ public class RebaseCommandTest extends RepositoryTestCase {
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();

114
org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java

@ -70,6 +70,7 @@ import org.eclipse.jgit.api.errors.NoHeadException;
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;
@ -79,6 +80,7 @@ import org.eclipse.jgit.dircache.DirCacheIterator;
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;
@ -158,6 +160,10 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
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
*/ */
@ -257,6 +263,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
.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)),
@ -272,8 +279,10 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
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())
@ -339,6 +348,57 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
} }
} }
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()))
@ -432,10 +492,13 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
} }
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;
@ -809,16 +872,9 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
// 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); Ref head = getHead();
if (head == null || head.getObjectId() == null)
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, Constants.HEAD));
String headName; String headName = getHeadName(head);
if (head.isSymbolic())
headName = head.getTarget().getName();
else
headName = head.getObjectId().getName();
ObjectId headId = head.getObjectId(); ObjectId headId = head.getObjectId();
if (headId == null) if (headId == null)
throw new RefNotFoundException(MessageFormat.format( throw new RefNotFoundException(MessageFormat.format(
@ -857,7 +913,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
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());
@ -893,6 +949,23 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
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;
} }
@ -907,10 +980,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
*/ */
public RevCommit tryFastForward(RevCommit newCommit) throws IOException, public RevCommit tryFastForward(RevCommit newCommit) throws IOException,
GitAPIException { GitAPIException {
Ref head = repo.getRef(Constants.HEAD); Ref head = getHead();
if (head == null || head.getObjectId() == null)
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, Constants.HEAD));
ObjectId headId = head.getObjectId(); ObjectId headId = head.getObjectId();
if (headId == null) if (headId == null)
@ -920,11 +990,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
if (walk.isMergedInto(newCommit, headCommit)) if (walk.isMergedInto(newCommit, headCommit))
return newCommit; return newCommit;
String headName; String headName = getHeadName(head);
if (head.isSymbolic())
headName = head.getTarget().getName();
else
headName = head.getObjectId().getName();
return tryFastForward(headName, headCommit, newCommit); return tryFastForward(headName, headCommit, newCommit);
} }
@ -1004,7 +1070,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
} }
} }
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;
@ -1053,9 +1120,12 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
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 {

15
org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java

@ -165,6 +165,18 @@ public class RebaseResult {
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;
}
}; };
/** /**
@ -189,6 +201,9 @@ public class RebaseResult {
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;

15
org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java

@ -90,6 +90,8 @@ public class StashApplyCommand extends GitCommand<ObjectId> {
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
* *
@ -113,6 +115,16 @@ public class StashApplyCommand extends GitCommand<ObjectId> {
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;
@ -143,7 +155,8 @@ public class StashApplyCommand extends GitCommand<ObjectId> {
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()));

3
org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java

@ -154,6 +154,7 @@ public class StashCreateCommand extends GitCommand<RevCommit> {
/** /**
* 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}
* *
@ -185,6 +186,8 @@ public class StashCreateCommand extends GitCommand<RevCommit> {
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);

15
org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java

@ -77,6 +77,13 @@ public class ConfigConstants {
/** 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";
@ -136,6 +143,14 @@ public class ConfigConstants {
/** 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";

Loading…
Cancel
Save