4

Let's say we have an upstream git repository which is the official home of a project, and origin is our own remote git repository (e.g. a github fork).

On the command line, I would rebase to the master before issuing a PR with

git pull --rebase upstream master

but how do I do this in magit? The F command allows a --rebase but that's always against my origin as far as I can tell.

Ideally, I'd like to do this with a single command under the F menu as it is a very common operation for me.

fommil
  • 5,757
  • 8
  • 41
  • 81
  • 2
    On the next branch (to be 2.1.0), the rebase menu has an 'o' action to select another branch. So this would be 'F-ro'. – Kyle Meyer Mar 12 '15 at 20:21

2 Answers2

5

In magit, you can use the C-u prefix argument to allow you to set the remote for push and pull operations. You would type C-u F -r F upstream<RET> to do this. If you need to also specify the branch name, you can double the C-u prefix: C-u C-u F -r F upstream<RET> master<RET>. In the next version of Magit, 2.1.0, this will be available in the more accessible F -r o rather than having to use the prefix argument.

If that's too cumbersome, I suggest setting the upstream explicitly in your .git/config; then all pulls will come from that upstream. You can do this with git branch -u upstream/master while on your local branch, or git branch -u upstream/master mybranch if you're on a different branch. Then, whether you use Magit or git on the command line, a simple git pull --rebase or F -r F will pull from the configured branch.

If you need to push to your own personal repo while pulling from a different repo, you can always set up a separate remotes for pushes and pulls. There is no convenient command wrapper for this that I know of, but if you edit your .git/config directly, you would do so as follows:

[branch "mybranch"]
remote = upstream
pushremote = origin
merge = refs/heads/master

If you're doing this, and will always be rebasing your local branch, you could even add:

rebase = true

And not have to specify --rebase ever time you pull.

If you want to do this for your whole repo, instead of a single branch, you can use:

[remote]
pushdefault = origin

And then have the branches pull from their configured upstream, but push to your own repo.

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • `C-u F` and `F C-u` don't seem to be recognised (also, this is getting dangerously close to rude if there was a `k` flag! :-P) – fommil Mar 12 '15 at 17:27
  • What version of magit are you using? Also, did you see my edit in which I listed the full command? The `C-u` comes before the first `F`, in case that wasn't clear. – Brian Campbell Mar 12 '15 at 17:28
  • oh, that did ask for the ref, even though it seemed to be silently ignored until the end. But 1) this didn't work because my upstream branch has a different name 2) This is ridiculously complex... I'd like a single command for this that appears in the list. Is that possible? – fommil Mar 12 '15 at 17:34
  • 1
    @fommil To specify a branch as well, you press `C-u` twice. `C-u C-u F -r F upstream master`. It will allow you to autocomplete on the remote and branch names, so you don't have to type the entire thing. There isn't another way to do it from within Magit. `C-u` is an Emacs convention for this kind of thing; it's the "Universal argument" that many commands use to distinguish between different variants; in Magit, for the push and pull commands, adding it once allows you to change the remote and twice the remote and branch. – Brian Campbell Mar 12 '15 at 17:44
  • @fommil However, what you could do to make it more convenient is set your upstream branch for this branch, to be `upstream/master`; you can do that with `git branch -u upstream/master` while on your local branch (or `git branch -u upstream/master mybranch` if you're not currently on it). You can see the change that makes in your `.git/config`, where you will now be configured to push and pull from that particular upstream, so you won't need to specify it ever time. – Brian Campbell Mar 12 '15 at 17:46
  • setting my upstream branch to be upstream/master would be an absolute disaster. An accidental push would nuke my team's repo and we'd have to get into version rewriting. I think I'll stick with the CLI for this... I'm afraid `magit` just falls short on a few things. Is there no way to script this? – fommil Mar 12 '15 at 17:54
  • @fommil Of course you can script it; everything is written in elisp, you could add your own menu entry for doing what you want. I'm just answering your question by showing how you currently do it in magit. Anyhow, updated my answer further to describe how you can set different branches for pushing and pulling in your `.git/config`, which I think should do what you need. – Brian Campbell Mar 12 '15 at 18:20
  • thanks! The separate remote and pushremote is new to me and probably solves the problem... I hope it works for my whole repo and not just one branch. – fommil Mar 12 '15 at 21:45
  • @fommil Updated again with how to make it the default for your whole repo, instead of the single branch – Brian Campbell Mar 12 '15 at 21:50
  • omg, this is amazing. I came here asking a question about magit and it turns out I've been doing git wrong for all these years! This one little line has just completely simplified my workflow – fommil Mar 12 '15 at 22:00
  • this doesn't seem to work from magit. Your suggestion works fine from the command line (which is still a great improvement to my workflow!), but magit push (at least in dry run) is ignoring both branch-level `pushdefault` and any remote.pushdefault in my global config. – fommil Mar 13 '15 at 09:35
1

If you open magit-pull-popup, there's a variable/option to toggle rebase.

Nick
  • 167
  • 3
  • 9