// Update refs
for (Ref ref : changedRefs) {
if (!ref.getName().startsWith(Ref.REFS_PREFIX)) {
continue;
}
Ref updatedRef = ref;
Optional<Ref> repoRef = command(RefParse.class).setName(ref.getName()).call();
if (repoRef.isPresent() && repositoryChanged(repoRef.get())) {
if (rebase) {
// Try to rebase
transaction.command(CheckoutOp.class).setSource(ref.getName())
.setForce(true).call();
try {
transaction.command(RebaseOp.class)
.setUpstream(Suppliers.ofInstance(repoRef.get().getObjectId()))
.call();
} catch (RebaseConflictsException e) {
Throwables.propagate(e);
}
updatedRef = transaction.command(RefParse.class).setName(ref.getName())
.call().get();
} else {
// sync transactions have to use merge to prevent divergent history
transaction.command(CheckoutOp.class).setSource(ref.getName())
.setForce(true).call();
try {
transaction.command(MergeOp.class)
.setAuthor(authorName.orNull(), authorEmail.orNull())
.addCommit(Suppliers.ofInstance(repoRef.get().getObjectId()))
.call();
} catch (NothingToCommitException e) {
// The repo commit is already in our history, this is a fast
// forward.
}
updatedRef = transaction.command(RefParse.class).setName(ref.getName())
.call().get();
}
}
LOGGER.debug(String.format("commit %s %s -> %s", ref.getName(), ref.getObjectId(),
updatedRef.getObjectId()));
command(UpdateRef.class).setName(ref.getName())
.setNewValue(updatedRef.getObjectId()).call();
if (currentBranch.equals(ref.getName())) {
// Update HEAD, WORK_HEAD and STAGE_HEAD
command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(ref.getName()).call();
command(UpdateRef.class).setName(Ref.WORK_HEAD)
.setNewValue(updatedRef.getObjectId()).call();
command(UpdateRef.class).setName(Ref.STAGE_HEAD)
.setNewValue(updatedRef.getObjectId()).call();
}
}
// TODO: What happens if there are unstaged or staged changes in the repository when
// a transaction is committed?