in org.eclipse.egit.core/src/org/eclipse/egit/core/op/RewordCommitOperation.java [105:235]
private void reword(IProgressMonitor monitor, RevWalk walk)
throws IOException, CoreException {
SubMonitor progress = SubMonitor.convert(monitor, MessageFormat.format(
CoreText.RewordCommitOperation_rewording,
Utils.getShortObjectId(commit)), 100);
commit = walk.parseCommit(commit);
if (newMessage.equals(commit.getFullMessage())) {
// Nothing to do.
return;
}
Ref ref = repository.exactRef(Constants.HEAD);
if (ref == null) {
// No HEAD: cannot reword
throw new TeamException(CoreText.RewordCommitOperation_noHead);
}
headId = ref.getObjectId();
if (headId == null || ObjectId.zeroId().equals(headId)) {
throw new TeamException(CoreText.RewordCommitOperation_noHead);
}
String headName = ref.isSymbolic() ? ref.getLeaf().getName()
: headId.name();
Deque<RevCommit> commits = new LinkedList<>();
walk.setRetainBody(true);
if (!commit.getId().equals(headId)) {
walk.sort(RevSort.TOPO);
walk.sort(RevSort.COMMIT_TIME_DESC, true);
walk.markStart(walk.parseCommit(headId));
for (RevCommit p : commit.getParents()) {
RevCommit parsed = walk.parseCommit(p);
walk.markUninteresting(parsed);
}
RevCommit c;
while ((c = walk.next()) != null) {
if (c.getId().equals(commit.getId())) {
break;
}
commits.push(c);
}
if (c == null) {
throw new TeamException(MessageFormat.format(
CoreText.RewordCommitOperation_notReachable,
Utils.getShortObjectId(commit)));
}
}
progress.worked(10);
progress.setWorkRemaining(commits.size() + 2);
PersonIdent committer = new PersonIdent(repository);
// Rewrite the message
CommitBuilder builder = copy(commit, commit.getParents(), committer,
newMessage);
// Signature will be invalid for the new commit. Try to re-sign.
File gpgProgram = GitSettings.getGpgExecutable();
GpgConfig gpgConfig = new GpgConfig(repository.getConfig()) {
@Override
public String getProgram() {
return gpgProgram != null ? gpgProgram.getAbsolutePath()
: super.getProgram();
}
};
boolean signAllCommits = gpgConfig.isSignCommits();
GpgSigner gpgSigner = GpgSetup.getDefault();
if (gpgSigner != null
&& (signAllCommits || commit.getRawGpgSignature() != null)) {
gpgSigner = sign(builder, gpgSigner, gpgConfig, committer, commit);
}
Map<ObjectId, ObjectId> rewritten = new HashMap<>();
String newCommitId = null;
try (ObjectInserter inserter = repository.newObjectInserter()) {
ObjectId newCommit = inserter.insert(builder);
rewritten.put(commit.getId(), newCommit);
newCommitId = newCommit.name();
progress.worked(1);
// Now rewrite all others: fill in new parents
for (RevCommit c : commits) {
RevCommit[] parents = c.getParents();
ObjectId[] newParents = new ObjectId[parents.length];
int i = 0;
boolean hadNew = false;
for (RevCommit p : parents) {
ObjectId newId = rewritten.get(p.getId());
if (newId != null) {
hadNew = true;
}
newParents[i++] = newId != null ? newId : p.getId();
}
if (!hadNew) {
continue;
}
committer = new PersonIdent(committer); // Update when
builder = copy(c, newParents, committer, c.getFullMessage());
if (gpgSigner != null
&& (signAllCommits || c.getRawGpgSignature() != null)) {
gpgSigner = sign(builder, gpgSigner, gpgConfig, committer,
c);
}
rewritten.put(c.getId(), inserter.insert(builder));
progress.worked(1);
}
inserter.flush();
}
// Update HEAD, and write ORIG_HEAD
ObjectId newHeadId = rewritten.get(headId);
RefUpdate ru = repository.updateRef(Constants.HEAD);
ru.setExpectedOldObjectId(headId);
ru.setNewObjectId(newHeadId);
ru.setForceUpdate(true);
ru.setRefLogMessage("rebase finished: returning to " + headName //$NON-NLS-1$
+ " after having reworded commit " + newCommitId, false); //$NON-NLS-1$
switch (ru.update(walk)) {
case NEW:
case NO_CHANGE:
case FORCED:
case FAST_FORWARD:
break;
default:
throw new TeamException(MessageFormat.format(
CoreText.RewordCommitOperation_cannotUpdateHead,
Utils.getShortObjectId(commit)));
}
ObjectId origHead = ru.getOldObjectId();
if (origHead != null) {
// TODO: JGit should handle ORIG_HEAD as a ref to guard against
// concurrent modifications, or there should be a way to copy
// the old head ObjectId atomically to ORIG_HEAD on the HEAD
// update.
repository.writeOrigHead(origHead);
}
progress.worked(1);
}