From 521cc0e8091e0c5671f70927f50557d6dfe11766 Mon Sep 17 00:00:00 2001 From: Qusijue Date: Fri, 13 Aug 2021 19:11:00 +0500 Subject: [PATCH 1/3] rebase onto implemented --- src/js/git/commands.js | 14 +++++++++++++- src/js/git/index.js | 15 +++++++++++++++ src/js/models/commandModel.js | 20 +++++++++++++------- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 43bf328a..03b68cd0 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -615,7 +615,8 @@ var commandConfig = { '--interactive-test', '--aboveAll', '-p', - '--preserve-merges' + '--preserve-merges', + '--onto' ], regex: /^git +rebase($|\s)/, execute: function(engine, command) { @@ -645,6 +646,17 @@ var commandConfig = { return; } + if (commandOptions['--onto']) { + var args = commandOptions['--onto'].concat(generalArgs); + command.threeArgsImpliedHead(args, ' --onto'); + + engine.rebaseOnto(args[0], args[1], args[2], { + preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'] + }); + + return; + } + command.twoArgsImpliedHead(generalArgs); engine.rebase(generalArgs[0], generalArgs[1], { preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'] diff --git a/src/js/git/index.js b/src/js/git/index.js index 23ec0a95..b5970d2f 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -2165,6 +2165,21 @@ GitEngine.prototype.rebase = function(targetSource, currentLocation, options) { return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options); }; +GitEngine.prototype.rebaseOnto = function(targetSource, oldSource, unit, options) { + if (this.isUpstreamOf(unit, targetSource)) { + this.setTargetLocation(unit, this.getCommitFromRef(targetSource)); + this.command.setResult(intl.str('git-result-fastforward')); + + this.checkout(unit); + return; + } + + var stopSet = Graph.getUpstreamSet(this, targetSource); + var oldBranchSet = Graph.getUpstreamSet(this, oldSource); + var toRebaseRough = this.getUpstreamDiffFromSet(oldBranchSet, unit); + return this.rebaseFinish(toRebaseRough, stopSet, targetSource, unit, options); +}; + GitEngine.prototype.getUpstreamDiffSetFromSet = function(stopSet, location) { var set = {}; this.getUpstreamDiffFromSet(stopSet, location).forEach(function (commit) { diff --git a/src/js/models/commandModel.js b/src/js/models/commandModel.js index 0580f3d5..bb99123e 100644 --- a/src/js/models/commandModel.js +++ b/src/js/models/commandModel.js @@ -124,17 +124,23 @@ var Command = Backbone.Model.extend({ } }, - oneArgImpliedHead: function(args, option) { - this.validateArgBounds(args, 0, 1, option); + argImpliedHead: function (args, lower, upper, option) { + // our args we expect to be between {lower} and {upper} + this.validateArgBounds(args, lower, upper, option); // and if it's one, add a HEAD to the back - this.impliedHead(args, 0); + this.impliedHead(args, lower); + }, + + oneArgImpliedHead: function(args, option) { + this.argImpliedHead(args, 0, 1, option); }, twoArgsImpliedHead: function(args, option) { - // our args we expect to be between 1 and 2 - this.validateArgBounds(args, 1, 2, option); - // and if it's one, add a HEAD to the back - this.impliedHead(args, 1); + this.argImpliedHead(args, 1, 2, option); + }, + + threeArgsImpliedHead: function(args, option) { + this.argImpliedHead(args, 2, 3, option); }, oneArgImpliedOrigin: function(args) { From 87684bbdc865fd405d4500420e0cf73e759f7def Mon Sep 17 00:00:00 2001 From: Qusijue Date: Fri, 13 Aug 2021 21:00:46 +0500 Subject: [PATCH 2/3] add some tests for rebase onto --- __tests__/git.spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/__tests__/git.spec.js b/__tests__/git.spec.js index e080ecf8..f1e14629 100644 --- a/__tests__/git.spec.js +++ b/__tests__/git.spec.js @@ -423,4 +423,27 @@ describe('Git', function() { }); }); }); + + describe ('Git rebase onto', function () { + it('rebase onto with two arguments', function() { + return expectTreeAsync( + 'git commit; git commit; git switch -c F1 main~2; git commit; git commit; git switch -c F2; git commit; git commit; git rebase --onto main F1;', + '%7B%22branches%22%3A%7B%22main%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22main%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22F1%22%3A%7B%22target%22%3A%22C5%22%2C%22id%22%3A%22F1%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22F2%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22F2%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C6%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22F2%22%2C%22id%22%3A%22HEAD%22%7D%7D' + ); + }); + + it('rebase onto with three arguments', function() { + return expectTreeAsync( + 'git commit; git commit; git switch -c F1 main~2; git commit; git commit; git switch -c F2; git commit; git commit; git checkout C1; git rebase --onto main F1 F2;', + '%7B%22branches%22%3A%7B%22main%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22main%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22F1%22%3A%7B%22target%22%3A%22C5%22%2C%22id%22%3A%22F1%22%2C%22remoteTrackingBranchID%22%3Anull%7D%2C%22F2%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22F2%22%2C%22remoteTrackingBranchID%22%3Anull%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C6%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22F2%22%2C%22id%22%3A%22HEAD%22%7D%7D' + ); + }); + + it('rebase onto fast forward', function() { + return expectTreeAsync( + 'git switch -c F1; git commit; git switch -c F1; git commit;', + '{"branches":{"main":{"target":"C1","id":"main","remoteTrackingBranchID":null},"F1":{"target":"C2","id":"F1","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"F1","id":"HEAD"}}' + ); + }); + }); }); From ff28276c452aa8ef79aadc45e425a781e6e0b797 Mon Sep 17 00:00:00 2001 From: Qusijue Date: Fri, 13 Aug 2021 21:05:49 +0500 Subject: [PATCH 3/3] fix test 'rebase onto fast forward' --- __tests__/git.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/git.spec.js b/__tests__/git.spec.js index f1e14629..ac97d00c 100644 --- a/__tests__/git.spec.js +++ b/__tests__/git.spec.js @@ -441,7 +441,7 @@ describe('Git', function() { it('rebase onto fast forward', function() { return expectTreeAsync( - 'git switch -c F1; git commit; git switch -c F1; git commit;', + 'git switch -c F1; git commit; git rebase --onto F1 main;', '{"branches":{"main":{"target":"C1","id":"main","remoteTrackingBranchID":null},"F1":{"target":"C2","id":"F1","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"F1","id":"HEAD"}}' ); });