Change-Id: I73f38492b6a2e7fd6e77005efd0a8a8c65763e74tags/v3.5.0.201409071800-rc1
/** | /** | ||||
* Evaluate the {@code --git-dir} option and open the repository. | * Evaluate the {@code --git-dir} option and open the repository. | ||||
* | * | ||||
* @param gitdir | |||||
* @param aGitdir | |||||
* the {@code --git-dir} option given on the command line. May be | * the {@code --git-dir} option given on the command line. May be | ||||
* null if it was not supplied. | * null if it was not supplied. | ||||
* @return the repository to operate on. | * @return the repository to operate on. | ||||
* @throws IOException | * @throws IOException | ||||
* the repository cannot be opened. | * the repository cannot be opened. | ||||
*/ | */ | ||||
protected Repository openGitDir(String gitdir) throws IOException { | |||||
protected Repository openGitDir(String aGitdir) throws IOException { | |||||
RepositoryBuilder rb = new RepositoryBuilder() // | RepositoryBuilder rb = new RepositoryBuilder() // | ||||
.setGitDir(gitdir != null ? new File(gitdir) : null) // | |||||
.setGitDir(aGitdir != null ? new File(aGitdir) : null) // | |||||
.readEnvironment() // | .readEnvironment() // | ||||
.findGitDir(); | .findGitDir(); | ||||
if (rb.getGitDir() == null) | if (rb.getGitDir() == null) |
} | } | ||||
/** | /** | ||||
* @param commit | |||||
* @param aCommit | |||||
* a reference to a commit which is merged with the current head | * a reference to a commit which is merged with the current head | ||||
* @return {@code this} | * @return {@code this} | ||||
*/ | */ | ||||
public MergeCommand include(Ref commit) { | |||||
public MergeCommand include(Ref aCommit) { | |||||
checkCallable(); | checkCallable(); | ||||
commits.add(commit); | |||||
commits.add(aCommit); | |||||
return this; | return this; | ||||
} | } | ||||
/** | /** | ||||
* @param commit | |||||
* @param aCommit | |||||
* the Id of a commit which is merged with the current head | * the Id of a commit which is merged with the current head | ||||
* @return {@code this} | * @return {@code this} | ||||
*/ | */ | ||||
public MergeCommand include(AnyObjectId commit) { | |||||
return include(commit.getName(), commit); | |||||
public MergeCommand include(AnyObjectId aCommit) { | |||||
return include(aCommit.getName(), aCommit); | |||||
} | } | ||||
/** | /** | ||||
* @param name | * @param name | ||||
* a name given to the commit | * a name given to the commit | ||||
* @param commit | |||||
* @param aCommit | |||||
* the Id of a commit which is merged with the current head | * the Id of a commit which is merged with the current head | ||||
* @return {@code this} | * @return {@code this} | ||||
*/ | */ | ||||
public MergeCommand include(String name, AnyObjectId commit) { | |||||
public MergeCommand include(String name, AnyObjectId aCommit) { | |||||
return include(new ObjectIdRef.Unpeeled(Storage.LOOSE, name, | return include(new ObjectIdRef.Unpeeled(Storage.LOOSE, name, | ||||
commit.copy())); | |||||
aCommit.copy())); | |||||
} | } | ||||
/** | /** |
FileUtils.delete(currentCommitFile); | FileUtils.delete(currentCommitFile); | ||||
} | } | ||||
private RebaseResult finishRebase(RevCommit newHead, | |||||
boolean lastStepWasForward) throws IOException, GitAPIException { | |||||
private RebaseResult finishRebase(RevCommit finalHead, | |||||
boolean lastStepIsForward) throws IOException, GitAPIException { | |||||
String headName = rebaseState.readFile(HEAD_NAME); | String headName = rebaseState.readFile(HEAD_NAME); | ||||
updateHead(headName, newHead, upstreamCommit); | |||||
updateHead(headName, finalHead, upstreamCommit); | |||||
boolean stashConflicts = autoStashApply(); | boolean stashConflicts = autoStashApply(); | ||||
FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); | FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); | ||||
if (stashConflicts) | if (stashConflicts) | ||||
return RebaseResult.STASH_APPLY_CONFLICTS_RESULT; | return RebaseResult.STASH_APPLY_CONFLICTS_RESULT; | ||||
if (lastStepWasForward || newHead == null) | |||||
if (lastStepIsForward || finalHead == null) | |||||
return RebaseResult.FAST_FORWARD_RESULT; | return RebaseResult.FAST_FORWARD_RESULT; | ||||
return RebaseResult.OK_RESULT; | return RebaseResult.OK_RESULT; | ||||
} | } | ||||
private RevCommit squashIntoPrevious(boolean sequenceContainsSquash, | private RevCommit squashIntoPrevious(boolean sequenceContainsSquash, | ||||
RebaseTodoLine nextStep) | RebaseTodoLine nextStep) | ||||
throws IOException, GitAPIException { | throws IOException, GitAPIException { | ||||
RevCommit newHead; | |||||
RevCommit retNewHead; | |||||
String commitMessage = rebaseState | String commitMessage = rebaseState | ||||
.readFile(MESSAGE_SQUASH); | .readFile(MESSAGE_SQUASH); | ||||
commitMessage = interactiveHandler | commitMessage = interactiveHandler | ||||
.modifyCommitMessage(commitMessage); | .modifyCommitMessage(commitMessage); | ||||
} | } | ||||
newHead = new Git(repo).commit() | |||||
retNewHead = new Git(repo).commit() | |||||
.setMessage(stripCommentLines(commitMessage)) | .setMessage(stripCommentLines(commitMessage)) | ||||
.setAmend(true).call(); | .setAmend(true).call(); | ||||
rebaseState.getFile(MESSAGE_SQUASH).delete(); | rebaseState.getFile(MESSAGE_SQUASH).delete(); | ||||
} else { | } else { | ||||
// Next step is either Squash or Fixup | // Next step is either Squash or Fixup | ||||
newHead = new Git(repo).commit() | |||||
retNewHead = new Git(repo).commit() | |||||
.setMessage(commitMessage).setAmend(true) | .setMessage(commitMessage).setAmend(true) | ||||
.call(); | .call(); | ||||
} | } | ||||
return newHead; | |||||
return retNewHead; | |||||
} | } | ||||
private static String stripCommentLines(String commitMessage) { | private static String stripCommentLines(String commitMessage) { | ||||
return ourCommitName; | return ourCommitName; | ||||
} | } | ||||
private void updateHead(String headName, RevCommit newHead, RevCommit onto) | |||||
private void updateHead(String headName, RevCommit aNewHead, RevCommit onto) | |||||
throws IOException { | throws IOException { | ||||
// point the previous head (if any) to the new commit | // point the previous head (if any) to the new commit | ||||
if (headName.startsWith(Constants.R_REFS)) { | if (headName.startsWith(Constants.R_REFS)) { | ||||
RefUpdate rup = repo.updateRef(headName); | RefUpdate rup = repo.updateRef(headName); | ||||
rup.setNewObjectId(newHead); | |||||
rup.setNewObjectId(aNewHead); | |||||
rup.setRefLogMessage("rebase finished: " + headName + " onto " //$NON-NLS-1$ //$NON-NLS-2$ | rup.setRefLogMessage("rebase finished: " + headName + " onto " //$NON-NLS-1$ //$NON-NLS-2$ | ||||
+ onto.getName(), false); | + onto.getName(), false); | ||||
Result res = rup.forceUpdate(); | Result res = rup.forceUpdate(); |
} | } | ||||
/** | /** | ||||
* @param ignoreRepositoryState | |||||
* @param willIgnoreRepositoryState | |||||
* @return {@code this} | * @return {@code this} | ||||
* @since 3.2 | * @since 3.2 | ||||
*/ | */ | ||||
public StashApplyCommand ignoreRepositoryState(boolean ignoreRepositoryState) { | |||||
this.ignoreRepositoryState = ignoreRepositoryState; | |||||
public StashApplyCommand ignoreRepositoryState(boolean willIgnoreRepositoryState) { | |||||
this.ignoreRepositoryState = willIgnoreRepositoryState; | |||||
return this; | return this; | ||||
} | } | ||||
Config cfg = new Config(); | Config cfg = new Config(); | ||||
for (Project proj : bareProjects) { | for (Project proj : bareProjects) { | ||||
String name = proj.path; | String name = proj.path; | ||||
String uri = proj.name; | |||||
String nameUri = proj.name; | |||||
cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$ | cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$ | ||||
cfg.setString("submodule", name, "url", uri); //$NON-NLS-1$ //$NON-NLS-2$ | |||||
cfg.setString("submodule", name, "url", nameUri); //$NON-NLS-1$ //$NON-NLS-2$ | |||||
// create gitlink | // create gitlink | ||||
DirCacheEntry dcEntry = new DirCacheEntry(name); | DirCacheEntry dcEntry = new DirCacheEntry(name); | ||||
ObjectId objectId; | ObjectId objectId; | ||||
if (ObjectId.isId(proj.revision)) | if (ObjectId.isId(proj.revision)) | ||||
objectId = ObjectId.fromString(proj.revision); | objectId = ObjectId.fromString(proj.revision); | ||||
else { | else { | ||||
objectId = callback.sha1(uri, proj.revision); | |||||
objectId = callback.sha1(nameUri, proj.revision); | |||||
} | } | ||||
if (objectId == null) | if (objectId == null) | ||||
throw new RemoteUnavailableException(uri); | |||||
throw new RemoteUnavailableException(nameUri); | |||||
dcEntry.setObjectId(objectId); | dcEntry.setObjectId(objectId); | ||||
dcEntry.setFileMode(FileMode.GITLINK); | dcEntry.setFileMode(FileMode.GITLINK); | ||||
builder.add(dcEntry); | builder.add(dcEntry); | ||||
for (CopyFile copyfile : proj.copyfiles) { | for (CopyFile copyfile : proj.copyfiles) { | ||||
byte[] src = callback.readFile( | byte[] src = callback.readFile( | ||||
uri, proj.revision, copyfile.src); | |||||
nameUri, proj.revision, copyfile.src); | |||||
objectId = inserter.insert(Constants.OBJ_BLOB, src); | objectId = inserter.insert(Constants.OBJ_BLOB, src); | ||||
dcEntry = new DirCacheEntry(copyfile.dest); | dcEntry = new DirCacheEntry(copyfile.dest); | ||||
dcEntry.setObjectId(objectId); | dcEntry.setObjectId(objectId); |
*/ | */ | ||||
private DirCache dircacheFromTree(ObjectId treeId) throws IOException { | private DirCache dircacheFromTree(ObjectId treeId) throws IOException { | ||||
DirCache ret = DirCache.newInCore(); | DirCache ret = DirCache.newInCore(); | ||||
DirCacheBuilder builder = ret.builder(); | |||||
TreeWalk tw = new TreeWalk(reader); | |||||
tw.addTree(treeId); | |||||
tw.setRecursive(true); | |||||
while (tw.next()) { | |||||
DirCacheEntry e = new DirCacheEntry(tw.getRawPath()); | |||||
e.setFileMode(tw.getFileMode(0)); | |||||
e.setObjectId(tw.getObjectId(0)); | |||||
builder.add(e); | |||||
DirCacheBuilder aBuilder = ret.builder(); | |||||
TreeWalk atw = new TreeWalk(reader); | |||||
atw.addTree(treeId); | |||||
atw.setRecursive(true); | |||||
while (atw.next()) { | |||||
DirCacheEntry e = new DirCacheEntry(atw.getRawPath()); | |||||
e.setFileMode(atw.getFileMode(0)); | |||||
e.setObjectId(atw.getObjectId(0)); | |||||
aBuilder.add(e); | |||||
} | } | ||||
builder.finish(); | |||||
aBuilder.finish(); | |||||
return ret; | return ret; | ||||
} | } | ||||
} | } |
} | } | ||||
class HttpObjectDB extends WalkRemoteObjectDatabase { | class HttpObjectDB extends WalkRemoteObjectDatabase { | ||||
private final URL objectsUrl; | |||||
private final URL httpObjectsUrl; | |||||
HttpObjectDB(final URL b) { | HttpObjectDB(final URL b) { | ||||
objectsUrl = b; | |||||
httpObjectsUrl = b; | |||||
} | } | ||||
@Override | @Override | ||||
URIish getURI() { | URIish getURI() { | ||||
return new URIish(objectsUrl); | |||||
return new URIish(httpObjectsUrl); | |||||
} | } | ||||
@Override | @Override | ||||
@Override | @Override | ||||
WalkRemoteObjectDatabase openAlternate(final String location) | WalkRemoteObjectDatabase openAlternate(final String location) | ||||
throws IOException { | throws IOException { | ||||
return new HttpObjectDB(new URL(objectsUrl, location)); | |||||
return new HttpObjectDB(new URL(httpObjectsUrl, location)); | |||||
} | } | ||||
@Override | @Override | ||||
@Override | @Override | ||||
FileStream open(final String path) throws IOException { | FileStream open(final String path) throws IOException { | ||||
final URL base = objectsUrl; | |||||
final URL base = httpObjectsUrl; | |||||
final URL u = new URL(base, path); | final URL u = new URL(base, path); | ||||
final HttpConnection c = httpOpen(u); | final HttpConnection c = httpOpen(u); | ||||
switch (HttpSupport.response(c)) { | switch (HttpSupport.response(c)) { |
* position to start reading the raw buffer. | * position to start reading the raw buffer. | ||||
* @param end | * @param end | ||||
* one past the end of the raw buffer (length is end - pos). | * one past the end of the raw buffer (length is end - pos). | ||||
* @param mode | |||||
* @param pathMode | |||||
* the mode of the path. | * the mode of the path. | ||||
* @return -1 if this entry sorts first; 0 if the entries are equal; 1 if | * @return -1 if this entry sorts first; 0 if the entries are equal; 1 if | ||||
* p's entry sorts first. | * p's entry sorts first. | ||||
*/ | */ | ||||
public int pathCompare(byte[] buf, int pos, int end, int mode) { | |||||
return pathCompare(buf, pos, end, mode, 0); | |||||
public int pathCompare(byte[] buf, int pos, int end, int pathMode) { | |||||
return pathCompare(buf, pos, end, pathMode, 0); | |||||
} | } | ||||
private int pathCompare(byte[] b, int bPos, int bEnd, int bMode, int aPos) { | private int pathCompare(byte[] b, int bPos, int bEnd, int bMode, int aPos) { |
*/ | */ | ||||
public static File createTempDir(String prefix, String suffix, File dir) | public static File createTempDir(String prefix, String suffix, File dir) | ||||
throws IOException { | throws IOException { | ||||
final int RETRY = 1; // When something bad happens, retry once. | |||||
for (int i = 0; i < RETRY; i++) { | |||||
final int RETRIES = 1; // When something bad happens, retry once. | |||||
for (int i = 0; i < RETRIES; i++) { | |||||
File tmp = File.createTempFile(prefix, suffix, dir); | File tmp = File.createTempFile(prefix, suffix, dir); | ||||
if (!tmp.delete()) | if (!tmp.delete()) | ||||
continue; | continue; |