diff --git a/spec/remote.spec.js b/spec/remote.spec.js index b4e01ac0..8c5dff7b 100644 --- a/spec/remote.spec.js +++ b/spec/remote.spec.js @@ -205,5 +205,12 @@ describe('Git Remotes', function() { ); }); + it('will push to the remote tracking branch WHILE NOT on branch if it is set up', function() { + expectTreeAsync( + 'git clone; git checkout -b foo o/master; git commit; go master; git push origin foo', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C2","id":"o/master","remoteTrackingBranchID":null},"foo":{"target":"C2","id":"foo","remoteTrackingBranchID":"o/master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C2","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"}},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); + }); diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 9be6916c..05ab031f 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -562,31 +562,33 @@ var commandConfig = { } var options = {}; + var destination; + var source; + var sourceObj; + // git push is pretty complex in terms of - // the arguments it wants as well -- see - // git pull for a more detailed description. + // the arguments it wants as well... get ready! var generalArgs = command.getGeneralArgs(); command.twoArgsImpliedOrigin(generalArgs); assertOriginSpecified(generalArgs); - var destination; - var source; var firstArg = generalArgs[1]; - if (firstArg) { - if (isColonRefspec(firstArg)) { - var refspecParts = firstArg.split(':'); - source = refspecParts[0]; - destination = validateBranchName(engine, refspecParts[1]); - } else { + if (firstArg && isColonRefspec(firstArg)) { + var refspecParts = firstArg.split(':'); + source = refspecParts[0]; + destination = validateBranchName(engine, refspecParts[1]); + } else { + if (firstArg) { // we are using this arg as destination AND source. the dest branch // can be created on demand but we at least need this to be a source // locally otherwise we will fail - source = destination = firstArg; + assertIsRef(engine, firstArg); + sourceObj = engine.refs[firstArg]; + } else { + // since they have not specified a source or destination, then + // we source from the branch we are on (or HEAD) + sourceObj = engine.getOneBeforeCommit('HEAD'); } - } else { - // since they have not specified a source or destination, then - // we source from the branch we are on (or HEAD) - var sourceObj = engine.getOneBeforeCommit('HEAD'); source = sourceObj.get('id'); // HOWEVER we push to either the remote tracking branch we have diff --git a/todo.txt b/todo.txt index ce96e3e8..b5641934 100644 --- a/todo.txt +++ b/todo.txt @@ -19,8 +19,6 @@ Argument things: aka fetch + merge, just like expected. ill probably still update o/master just for sanity. master is the source on the remote and HEAD is the source on local (place to merge). o/master gets updated regardless -2) ok so say I'm on a new branch banana thats not on remote. if I do "git push" then it will MAKE a new branch on remote and push my commits there. same thing with "git push origin banana". Basically banana has to be a local ref, and if so, it will just make the ref on remote. - so "git push origin branchNotOnLocal" fails but "git push origin someBranch" will make the someBranch on remote. 3) HOWEVER if I'm git push-ing on banana and I say "git push origin master" then it pretends Im checked out on master. aka master is both source and destination, as expected. this is really 3