0

I give this new interface the benefit of a doubt, but I'm close to just removing this version and going back to something earlier and more friendly.

There appears to be no way, at least not on the surface to push your changes to new branch, i.e. Say, you've checked out branch A, created branch B from it and now you want to push your branch B while at the same time creating a branch with the same name in remote repository. Something you'd typically achieve by running:

git push -u origin B

There is no way that I can see in the pop-up buffer to accomplish this. When I use -u in combination with o - I am prompted for another branch = useless. When I combine this with m - instead of creating new branch, Magit tries to push the local branch tracking A - this is completely useless behavior. t and T pushes tags, so in this case is useless too.

There's also no option to just push, which was one of the reasons to use Magit instead of just typing this on the command line...


To prevent further attempts to mark this as a duplicate: this question is not about pushing to the remote branch tracked by local branch (possible by pressing P u) this is about creating a branch in remote repository named after local branch and pushing into it (all at once), something that can be achieved by typing:

git push -u origin B
wvxvw
  • 11,222
  • 2
  • 30
  • 55
  • Did you try `P u`? – wasamasa Dec 17 '15 at 15:54
  • 1
    See this question: http://emacs.stackexchange.com/questions/18759/pushing-with-p-p-does-not-work-for-me In your case it sounds like you want : `P -u e`. After you set your upstream this way, you should be able to use `P u` to push in the way that `P P` worked in the past. Again, see the linked question and answers for details as to why this is the case – elethan Dec 17 '15 at 15:57
  • @elethan Yes that's it, except it's kinda useless since it means typing a little more than I would type when simply using Git... I really don't understand the rationale for this change. – wvxvw Dec 17 '15 at 16:18
  • @wasamasa `P u` doesn't work since the branch doesn't track anything in remote. – wvxvw Dec 17 '15 at 16:19
  • `P u` should work every time after you initially set the upstream branch. It was a pain for me at first too, just because I was so used to pressing `P P` to push, but now I am used to `P u` and don't really notice a difference. You just need a few extra steps when you initially set up your upstream branch, and I think that is part of the rational behind the change: making you take a few more steps to avoid potential mistakes when setting the branch to push from or pull from (you will notice similar changes when you try to pull). – elethan Dec 17 '15 at 16:23
  • @elethan well, my question isn't about what happens after I set upstream branch... It's about an easy way to specify one (there are obvious "difficult" ways s.a. for eg. typing `:` followed by proper Git command to do it. Thus, this is not a discussion about `P P` vs `P u` it is about setting upstream for a branch which doesn't have one yet. – wvxvw Dec 17 '15 at 16:39
  • 1
    That is what `P -u e` is for. From the `magit-status` buffer: `P`: bring up the popup for push options; `-u`: let `magit` know that you want to set the upstream branch; `e`: for "elsewhere" to push push to a remote branch; So four keystrokes from the magit status buffer - at least this works in my case. Then once you hit return, you will be promted to select a branch to push to. Should save a few keystrokes compared to `git push -u origin B` – elethan Dec 17 '15 at 16:47
  • @elethan Yes, I know about that option too, but it doesn't qualify as "easy" since it involves even more typing than plain Git command. I.e. in my view, the presence of this option doesn't save the day, the requirement is that I don't type the name of the branch since Magit has already been given that info, asking it again would be stupid. – wvxvw Dec 17 '15 at 16:59
  • 2
    Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/33112/discussion-between-elethan-and-wvxvw). – elethan Dec 17 '15 at 17:07
  • Press `M-n` or `` at the prompt for the destination, and Magit will offer a likely candidate. (Many Emacs commands provide useful suggestions if you go 'forward' in the prompt's history rather than backwards). A one-time `P -u e M-n RET` would typically push `` to `origin/`, whilst setting that upstream for future usage with `P u`. There's no need to manually type the name of the upstream branch. – phils Dec 17 '15 at 22:24
  • @phils sorry, I cannot try this right now, but if you tried and are sure it works, please make it an answer. I'll accept it. – wvxvw Dec 18 '15 at 17:06

3 Answers3

8

Ideally the relevant part of the popup looks like this:

Push feature to
 p myfork/feature
 u origin/master
 e elsewhere

But in your case it probably looks like this:

Push feature to
 e elsewhere

The p and u variants are missing because the relevant options are not set. p pushes to the configured push-remote, while u pushes to the configured upstream branch.


Edit: I have added another way of setting the upstream and push-remote. By default you would now see the following if both of them are unset:

Push feature to
 p pushRemote, after setting that
 u @{upstream}, after setting that
 e elsewhere

See this question for more information.


The upstream branch, as suggested by the word "upstream", should be used for the "official" branch on the "official" remote. I.e. the branch on which most work is based and into which much changes should eventually be merged. Often this is "master" on "origin", i.e. "origin/master"; but it could also be something like "origin/maint" or "origin/next".

If you always work on just one branch "master" then the upstream branch and the branch you push to are the same, but if you use feature branches, then you don't want to push directly to "master".

A branch "feature" should usually be pushed to "feature" on "myfork", i.e. "myfork/feature". But because there might be more than one remote, e.g. "origin" and "myfork", you have to tell Git where you want to push to. This is done by setting the variable branch.pushDefault:

git config branch.pushDefault myfork

You can also use b M-p to do the same. Keep pressing M-p until the remote which should be used as the push-remote is highlighted.

Often the push-remote should be the same for all branches, but when that is not the case, then you can override it for a single branch using e.g. branch.<feature>.pushRemote. That variable too can be set from the branching popup.

The concept of a push-remote, which is destinct from the upstream, existed in Git for many years, but Magit did not support it until v2.4. If you don't want to push-remote, because it "is an unnecessary complication", then you can just abuse the upstream as before.

But of course that too has to be configured. Usually the upstream is automatically set when you create a branch. But if that is not the case or if you need to change the value, then that to can be done from the branching popup, using b u (if you want to change the value then you have to press that twice, because the first time just unsets the old value).

You can also do that directly from the pushing popup using the --set-upstream argument. In the popup first press - u to turn on that switch. Then you have to invoke a command which lets you choose where you want to push too. It seems fairly obvious that the correct command to do that is "Push feature to elsewhere". The word "elsewhere" is used here because usually a branch has an upstream and a push-to branch. If neither of the two is already configured, then the working might seem a bit strange, but it should still convey that you get to choose where that "elsewhere" is, i.e. to which branch you want to push. So press e.

The next time you come to the pushing popup it will look like this:

Push feature to
 u myfork/feature
 e elsewhere

But I recommend you instead make use of the distinction between the upstream and the push-remote and configure them as described above. One huge advantage of the push-remote is that you usually only have to configure it once per repository.

tarsius
  • 25,298
  • 4
  • 69
  • 109
  • 3
    wvxvw: Bear in mind that there are many different needs based on many different development circumstances (some of which are very different to your own), and it's evidentially *really hard* to find a happy medium where no one is complaining to tarsius, because everyone wants Magit to default to their own preferred/required workflow. Your "imaginary users and imaginary needs" comment is way off base. I'm sure that *constructive* criticism that accepts that things were done for a reason and suggests compatible improvements would be more helpful. – phils Dec 17 '15 at 22:03
  • 3
    @wvxvw You raise some valid points ("elsewhere" is ambiguous, if there's just one remote it *might* be a good idea to just use that). I will think about those issues. But you also assume that because you don't need a feature that the fast majority of users does not need it either and that the feature is misguided. The slogan for this release is "deal with the fact that everyone has a different opinion on how branching and pushing should work". I have actually thought about these things, and while there is room for improvement, the general concepts are a good compromise. Also: stop the insults. – tarsius Dec 17 '15 at 23:29
3

There's typically no need to manually type the name of the desired upstream branch.

Press M-n or <down> at the prompt, and Magit will offer a likely candidate.

(Many Emacs commands will provide useful suggestions if you go 'forwards' in the prompt's 'history' instead of backwards.)

Therefore a one-time P -u e M-n RET would typically push <branch> to origin/<branch>, whilst setting that upstream for future usage with P u.

phils
  • 48,657
  • 3
  • 76
  • 115
2

I have already provided another, more complete answer, but because another answer was accepted, which no longer is correct, I additionally provide this TL;DR answer.

Note that I already intended to make this change when you posed your question. (You are using the development version, so you have to expect that sometimes a feature only exists in an unfinished and suboptimal state.)


Assuming that you have not customized any variables related to this and the upstream has not been configured yet, you will see this:

Push feature to
 p pushRemote, after setting that
 u @{upstream}, after setting that
 e elsewhere

Now type u, causing Set upstream of feature and push there to appear in the minibuffer. The default completion candidate likely is origin/master, but origin/feature is offered as another candidate. How you select the desired candidate of course depends on the completion framework you use, but generally speaking pressing M-n or <down> a few times should do the trick.

The next time you enter the popup, you will see this instead:

Push feature to
 p pushRemote, after setting that
 u origin/feature
 e elsewhere

Pressing u now pushes to origin/feature without prompting or asking for confirmation.

tarsius
  • 25,298
  • 4
  • 69
  • 109