From 71b8b80bbe1b95f3bdae17350f9fa66fa24d0073 Mon Sep 17 00:00:00 2001 From: Kai Annacker Date: Wed, 7 Dec 2022 13:31:45 +0100 Subject: [PATCH] Support new --update-refs option for rebase --- __tests__/git.spec.js | 7 +++++++ src/js/git/commands.js | 6 ++++-- src/js/git/index.js | 19 ++++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/__tests__/git.spec.js b/__tests__/git.spec.js index 0272b796..6c962c49 100644 --- a/__tests__/git.spec.js +++ b/__tests__/git.spec.js @@ -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() { return expectTreeAsync( 'git revert HEAD', diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 49e3675c..15dc4152 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -631,7 +631,8 @@ var commandConfig = { '--aboveAll', '-p', '--preserve-merges', - '--onto' + '--onto', + '--update-refs' ], regex: /^git +rebase($|\s)/, execute: function(engine, command) { @@ -674,7 +675,8 @@ var commandConfig = { command.twoArgsImpliedHead(generalArgs); engine.rebase(generalArgs[0], generalArgs[1], { - preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'] + preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'], + updateRefs: !!commandOptions['--update-refs'] }); } }, diff --git a/src/js/git/index.js b/src/js/git/index.js index eaddf854..440df559 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -2386,6 +2386,7 @@ GitEngine.prototype.rebaseFinish = function( ) { options = options || {}; // 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 deferred = options.deferred || Q.defer(); var chain = options.chain || deferred.promise; @@ -2406,6 +2407,7 @@ GitEngine.prototype.rebaseFinish = function( // now pop all of these commits onto targetLocation var base = this.getCommitFromRef(targetSource); var hasStartedChain = false; + var refsToUpdate = []; // each step makes a new commit var chainStep = function(oldCommit) { var newId = this.rebaseAltID(oldCommit.get('id')); @@ -2425,6 +2427,17 @@ GitEngine.prototype.rebaseFinish = function( base = newCommit; 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( newCommit, this.gitVisuals @@ -2439,6 +2452,10 @@ GitEngine.prototype.rebaseFinish = function( }, this); chain = chain.then(function() { + refsToUpdate.forEach(function(refToUpdate) { + this.setTargetLocation(refToUpdate.id, refToUpdate.newCommit); + }.bind(this)); + if (this.resolveID(currentLocation).get('type') == 'commit') { // we referenced a commit like git rebase C2 C1, so we have // to manually check out C1' @@ -2497,7 +2514,7 @@ GitEngine.prototype.merge = function(targetSource, options) { // since we specify parent 1 as the first parent, it is the "main" parent // and the node will be displayed below that branch / commit / whatever var commitParents = [parent1]; - + if (!options.squash) { // a squash commit doesn't include the reference to the second parent commitParents.push(parent2);