diff --git a/__tests__/remote.spec.js b/__tests__/remote.spec.js index a5e4140f..8bf7ed3c 100644 --- a/__tests__/remote.spec.js +++ b/__tests__/remote.spec.js @@ -389,5 +389,20 @@ describe('Git Remotes', function() { ); }); + it('uses --push to delete commits', function() { + expectTreeAsync( + 'git commit; git clone;git reset HEAD~1;git push --force', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}', + ); + }); + + it('uses --push to delete commits and can push again after', function() { + expectTreeAsync( + 'git commit; git clone;git reset HEAD~1;git push --force;git commit; git push ', + '{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C3","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}', + ); + }); + + }); diff --git a/src/js/git/index.js b/src/js/git/index.js index 91cf563f..f8ecfd4a 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -1074,8 +1074,31 @@ GitEngine.prototype.push = function(options) { this.origin, this, branchOnRemote, - sourceLocation + sourceLocation, + /* options */ { + dontThrowOnNoFetch: true, + } ); + if (!commitsToMake.length) { + if (!options.force) { + // We are already up to date, and we cant be deleting + // either since we dont have --force + throw new GitError({ + msg: intl.str('git-error-origin-fetch-uptodate') + }); + } else { + var sourceCommit = this.getCommitFromRef(sourceBranch); + var originCommit = this.getCommitFromRef(branchOnRemote); + if (sourceCommit.id === originCommit.id) { + // This is essentially also being up to date + throw new GitError({ + msg: intl.str('git-error-origin-fetch-uptodate') + }); + } + // Otherwise fall through! We will update origin + // and essentially delete the commit + } + } // now here is the tricky part -- the difference between local master // and remote master might be commits C2, C3, and C4, but the remote