mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-28 17:00:04 +02:00
Merge pull request #195 from ptsoccer/master
Add testable interactive rebase
This commit is contained in:
commit
67413c42b6
3 changed files with 106 additions and 14 deletions
|
@ -57,6 +57,27 @@ describe('Git', function() {
|
||||||
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%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%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%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%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Interactive rebase', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'gc; git checkout -b side C1; gc; git rebase -i master --interactive-test',
|
||||||
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22side%22%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%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Interactive rebases with commit re-ordering', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'gc;gc;git rebase -i C0 --interactive-test C3,C1',
|
||||||
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22master%22%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%22C3%27%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22id%22%3A%22HEAD%22%2C%22target%22%3A%22master%22%7D%7D'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Switch branch and execute interactive rebase', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'git branch test;git rebase -i C0 test --interactive-test',
|
||||||
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%7D%2C%22test%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22test%22%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%22C1%27%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22tags%22%3A%7B%7D%2C%22HEAD%22%3A%7B%22id%22%3A%22HEAD%22%2C%22target%22%3A%22test%22%7D%7D'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('Reverts', function() {
|
it('Reverts', function() {
|
||||||
expectTreeAsync(
|
expectTreeAsync(
|
||||||
|
@ -127,6 +148,13 @@ describe('Git', function() {
|
||||||
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%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%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%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%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('checks out after an interactive rebase', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'git commit; git checkout -b bugFix C1; git commit; git rebase -i master --interactive-test;git checkout master',
|
||||||
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C2%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%27%22%2C%22id%22%3A%22bugFix%22%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%22C1%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('solves merging level', function() {
|
it('solves merging level', function() {
|
||||||
expectTreeAsync(
|
expectTreeAsync(
|
||||||
|
@ -141,6 +169,13 @@ describe('Git', function() {
|
||||||
'{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}'
|
'{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('solves rebase level with interactive rebase', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'git checkout -b bugFix;git commit;git checkout master;git commit;git checkout bugFix;git rebase -i master --interactive-test',
|
||||||
|
'{"branches":{"master":{"target":"C1","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('does a whole bunch of crazy merging', function() {
|
it('does a whole bunch of crazy merging', function() {
|
||||||
expectTreeAsync(
|
expectTreeAsync(
|
||||||
|
|
|
@ -569,6 +569,7 @@ var commandConfig = {
|
||||||
sc: /^gr($|\s)/,
|
sc: /^gr($|\s)/,
|
||||||
options: [
|
options: [
|
||||||
'-i',
|
'-i',
|
||||||
|
'--interactive-test',
|
||||||
'--aboveAll',
|
'--aboveAll',
|
||||||
'-p',
|
'-p',
|
||||||
'--preserve-merges'
|
'--preserve-merges'
|
||||||
|
@ -581,12 +582,23 @@ var commandConfig = {
|
||||||
if (commandOptions['-i']) {
|
if (commandOptions['-i']) {
|
||||||
var args = commandOptions['-i'].concat(generalArgs);
|
var args = commandOptions['-i'].concat(generalArgs);
|
||||||
command.twoArgsImpliedHead(args, ' -i');
|
command.twoArgsImpliedHead(args, ' -i');
|
||||||
engine.rebaseInteractive(
|
|
||||||
args[0],
|
if (commandOptions['--interactive-test']) {
|
||||||
args[1], {
|
engine.rebaseInteractiveTest(
|
||||||
aboveAll: !!commandOptions['--aboveAll']
|
args[0],
|
||||||
}
|
args[1], {
|
||||||
);
|
interactiveTest: commandOptions['--interactive-test']
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
engine.rebaseInteractive(
|
||||||
|
args[0],
|
||||||
|
args[1], {
|
||||||
|
aboveAll: !!commandOptions['--aboveAll'],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2070,15 +2070,10 @@ GitEngine.prototype.getUpstreamDiffFromSet = function(stopSet, location) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, options) {
|
GitEngine.prototype.getInteractiveRebaseCommits = function(targetSource, currentLocation) {
|
||||||
options = options || {};
|
|
||||||
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
|
||||||
// but it will look similar.
|
|
||||||
|
|
||||||
// now get the stop set
|
|
||||||
var stopSet = Graph.getUpstreamSet(this, targetSource);
|
var stopSet = Graph.getUpstreamSet(this, targetSource);
|
||||||
|
|
||||||
var toRebaseRough = [];
|
var toRebaseRough = [];
|
||||||
|
|
||||||
// standard BFS
|
// standard BFS
|
||||||
var pQueue = [this.getCommitFromRef(currentLocation)];
|
var pQueue = [this.getCommitFromRef(currentLocation)];
|
||||||
|
|
||||||
|
@ -2101,12 +2096,62 @@ GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation,
|
||||||
toRebase.push(commit);
|
toRebase.push(commit);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!toRebase.length) {
|
if (!toRebase.length) {
|
||||||
throw new GitError({
|
throw new GitError({
|
||||||
msg: intl.str('git-error-rebase-none')
|
msg: intl.str('git-error-rebase-none')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toRebase;
|
||||||
|
};
|
||||||
|
|
||||||
|
GitEngine.prototype.rebaseInteractiveTest = function(targetSource, currentLocation, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// Get the list of commits that would be displayed to the user
|
||||||
|
var toRebase = this.getInteractiveRebaseCommits(targetSource, currentLocation);
|
||||||
|
|
||||||
|
var rebaseMap = {};
|
||||||
|
_.each(toRebase, function(commit) {
|
||||||
|
var id = commit.get('id');
|
||||||
|
rebaseMap[id] = commit;
|
||||||
|
});
|
||||||
|
|
||||||
|
var rebaseOrder;
|
||||||
|
if (options['interactiveTest'].length === 0) {
|
||||||
|
// If no commits were explicitly specified for the rebase, act like the user didn't change anything
|
||||||
|
// in the rebase dialog and hit confirm
|
||||||
|
rebaseOrder = toRebase;
|
||||||
|
} else {
|
||||||
|
// Get the list and order of commits specified
|
||||||
|
var idsToRebase = options['interactiveTest'][0].split(',');
|
||||||
|
|
||||||
|
// Verify each chosen commit exists in the list of commits given to the user
|
||||||
|
var extraCommits = [];
|
||||||
|
rebaseOrder = [];
|
||||||
|
_.each(idsToRebase, function(id) {
|
||||||
|
if (id in rebaseMap) {
|
||||||
|
rebaseOrder.push(rebaseMap[id]);
|
||||||
|
} else {
|
||||||
|
extraCommits.push(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (extraCommits.length > 0) {
|
||||||
|
// What to do here?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rebaseFinish(rebaseOrder, {}, targetSource, currentLocation);
|
||||||
|
};
|
||||||
|
|
||||||
|
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
||||||
|
// but it will look similar.
|
||||||
|
var toRebase = this.getInteractiveRebaseCommits(targetSource, currentLocation);
|
||||||
|
|
||||||
// now do stuff :D since all our validation checks have passed, we are going to defer animation
|
// now do stuff :D since all our validation checks have passed, we are going to defer animation
|
||||||
// and actually launch the dialog
|
// and actually launch the dialog
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue