diff --git a/spec/git.spec.js b/spec/git.spec.js index d9deed34..8127b3d0 100644 --- a/spec/git.spec.js +++ b/spec/git.spec.js @@ -148,5 +148,12 @@ describe('Git', function() { '%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22side%22%7D%2C%22bug%22%3A%7B%22target%22%3A%22C8%22%2C%22id%22%3A%22bug%22%7D%2C%22wut%22%3A%7B%22target%22%3A%22C8%22%2C%22id%22%3A%22wut%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%22C4%22%3A%7B%22parents%22%3A%5B%22C2%22%2C%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C5%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C6%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C6%27%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C4%22%2C%22C6%27%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C8%22%3A%7B%22parents%22%3A%5B%22C3%27%22%2C%22C6%22%5D%2C%22id%22%3A%22C8%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22bug%22%2C%22id%22%3A%22HEAD%22%7D%7D' ); }); + + it('does not fast forward on merge if specified', function() { + expectTreeAsync( + 'git commit; go -b side HEAD~1; git commit; git merge master; go master; git merge side --no-ff', + '{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null,"localBranchesThatTrackThis":null},"side":{"target":"C4","id":"side","remoteTrackingBranchID":null,"localBranchesThatTrackThis":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"},"C4":{"parents":["C2","C3"],"id":"C4"}},"HEAD":{"target":"master","id":"HEAD"}}' + ); + }); }); diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 2bee92f5..0d04e487 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -381,11 +381,18 @@ var commandConfig = { merge: { regex: /^git +merge($|\s)/, + options: [ + '--no-ff' + ], execute: function(engine, command) { + var commandOptions = command.getOptionsMap(); var generalArgs = command.getGeneralArgs(); command.validateArgBounds(generalArgs, 1, 1); - var newCommit = engine.merge(generalArgs[0]); + var newCommit = engine.merge( + generalArgs[0], + { noFF: !!commandOptions['--no-ff'] } + ); if (newCommit === undefined) { // its just a fast forwrard diff --git a/src/js/git/index.js b/src/js/git/index.js index a7ee43fb..ff514e7d 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -2005,7 +2005,8 @@ GitEngine.prototype.mergeCheck = function(targetSource, currentLocation) { return this.isUpstreamOf(targetSource, currentLocation) || sameCommit; }; -GitEngine.prototype.merge = function(targetSource) { +GitEngine.prototype.merge = function(targetSource, options) { + options = options || {}; var currentLocation = 'HEAD'; // first some conditions @@ -2016,6 +2017,11 @@ GitEngine.prototype.merge = function(targetSource) { } if (this.isUpstreamOf(currentLocation, targetSource)) { + if (options.noFF) { + throw new GitError({ + msg: intl.todo('Merge aborted because no-fast-forward was specified!') + }); + } // just set the target of this current location to the source this.setTargetLocation(currentLocation, this.getCommitFromRef(targetSource)); // get fresh animation to happen