Support new --update-refs option for rebase

This commit is contained in:
Kai Annacker 2022-12-07 13:31:45 +01:00
parent 1db218b874
commit 71b8b80bbe
3 changed files with 29 additions and 3 deletions

View file

@ -95,6 +95,13 @@ describe('Git', function() {
); );
}); });
it('Rebases and updates refs', function() {
return expectTreeAsync(
'git commit; git checkout -b ref1 HEAD^; git commit; git checkout -b ref2; git commit; git checkout -b ref3; git commit; git rebase main --update-refs',
'%7B%0D%0A%22branches%22%3A%20%7B%0D%0A%22main%22%3A%20%7B%0D%0A%22target%22%3A%20%22C2%22%2C%0D%0A%22id%22%3A%20%22main%22%0D%0A%7D%2C%0D%0A%22ref1%22%3A%20%7B%0D%0A%22target%22%3A%20%22C3%27%22%2C%0D%0A%22id%22%3A%20%22ref1%22%0D%0A%7D%2C%0D%0A%22ref2%22%3A%20%7B%0D%0A%22target%22%3A%20%22C4%27%22%2C%0D%0A%22id%22%3A%20%22ref2%22%0D%0A%7D%2C%0D%0A%22ref3%22%3A%20%7B%0D%0A%22target%22%3A%20%22C5%27%22%2C%0D%0A%22id%22%3A%20%22ref3%22%0D%0A%7D%0D%0A%7D%2C%0D%0A%22commits%22%3A%20%7B%0D%0A%22C0%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%5D%2C%0D%0A%22id%22%3A%20%22C0%22%2C%0D%0A%22rootCommit%22%3A%20true%0D%0A%7D%2C%0D%0A%22C1%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C0%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C1%22%0D%0A%7D%2C%0D%0A%22C2%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C1%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C2%22%0D%0A%7D%2C%0D%0A%22C3%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C1%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C3%22%0D%0A%7D%2C%0D%0A%22C4%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C3%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C4%22%0D%0A%7D%2C%0D%0A%22C5%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C4%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C5%22%0D%0A%7D%2C%0D%0A%22C3%27%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C2%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C3%27%22%0D%0A%7D%2C%0D%0A%22C4%27%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C3%27%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C4%27%22%0D%0A%7D%2C%0D%0A%22C5%27%22%3A%20%7B%0D%0A%22parents%22%3A%20%5B%0D%0A%22C4%27%22%0D%0A%5D%2C%0D%0A%22id%22%3A%20%22C5%27%22%0D%0A%7D%0D%0A%7D%2C%0D%0A%22tags%22%3A%20%7B%7D%2C%0D%0A%22HEAD%22%3A%20%7B%0D%0A%22id%22%3A%20%22HEAD%22%2C%0D%0A%22target%22%3A%20%22ref3%22%0D%0A%7D%0D%0A%7D'
);
});
it('Reverts', function() { it('Reverts', function() {
return expectTreeAsync( return expectTreeAsync(
'git revert HEAD', 'git revert HEAD',

View file

@ -631,7 +631,8 @@ var commandConfig = {
'--aboveAll', '--aboveAll',
'-p', '-p',
'--preserve-merges', '--preserve-merges',
'--onto' '--onto',
'--update-refs'
], ],
regex: /^git +rebase($|\s)/, regex: /^git +rebase($|\s)/,
execute: function(engine, command) { execute: function(engine, command) {
@ -674,7 +675,8 @@ var commandConfig = {
command.twoArgsImpliedHead(generalArgs); command.twoArgsImpliedHead(generalArgs);
engine.rebase(generalArgs[0], generalArgs[1], { engine.rebase(generalArgs[0], generalArgs[1], {
preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'] preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'],
updateRefs: !!commandOptions['--update-refs']
}); });
} }
}, },

View file

@ -2386,6 +2386,7 @@ GitEngine.prototype.rebaseFinish = function(
) { ) {
options = options || {}; options = options || {};
// now we have the all the commits between currentLocation and the set of target to rebase. // now we have the all the commits between currentLocation and the set of target to rebase.
var localBranches = this.getLocalBranches();
var destinationBranch = this.resolveID(targetSource); var destinationBranch = this.resolveID(targetSource);
var deferred = options.deferred || Q.defer(); var deferred = options.deferred || Q.defer();
var chain = options.chain || deferred.promise; var chain = options.chain || deferred.promise;
@ -2406,6 +2407,7 @@ GitEngine.prototype.rebaseFinish = function(
// now pop all of these commits onto targetLocation // now pop all of these commits onto targetLocation
var base = this.getCommitFromRef(targetSource); var base = this.getCommitFromRef(targetSource);
var hasStartedChain = false; var hasStartedChain = false;
var refsToUpdate = [];
// each step makes a new commit // each step makes a new commit
var chainStep = function(oldCommit) { var chainStep = function(oldCommit) {
var newId = this.rebaseAltID(oldCommit.get('id')); var newId = this.rebaseAltID(oldCommit.get('id'));
@ -2425,6 +2427,17 @@ GitEngine.prototype.rebaseFinish = function(
base = newCommit; base = newCommit;
hasStartedChain = true; hasStartedChain = true;
if (options.updateRefs) {
refsToUpdate = refsToUpdate.concat(
localBranches
.filter(function(localBranch) {
return this.getCommitFromRef(localBranch.id).get('id') == oldCommit.get('id');
}.bind(this))
.map(function(localBranch) {
return { id: localBranch.id, newCommit: newCommit };
}));
}
return this.animationFactory.playCommitBirthPromiseAnimation( return this.animationFactory.playCommitBirthPromiseAnimation(
newCommit, newCommit,
this.gitVisuals this.gitVisuals
@ -2439,6 +2452,10 @@ GitEngine.prototype.rebaseFinish = function(
}, this); }, this);
chain = chain.then(function() { chain = chain.then(function() {
refsToUpdate.forEach(function(refToUpdate) {
this.setTargetLocation(refToUpdate.id, refToUpdate.newCommit);
}.bind(this));
if (this.resolveID(currentLocation).get('type') == 'commit') { if (this.resolveID(currentLocation).get('type') == 'commit') {
// we referenced a commit like git rebase C2 C1, so we have // we referenced a commit like git rebase C2 C1, so we have
// to manually check out C1' // to manually check out C1'