282

I've been wondering if there's an easy way to push and pull a local branch with a remote branch with a different name without always specifying both names.

For example:

$ git clone myrepo.git
$ git checkout -b newb
$ ...
$ git commit -m "Some change"
$ git push origin newb:remote_branch_name

Now if someone updates remote_branch_name, I can:

$ git pull

And everything is merged / fast-forwarded. However, if I make changes in my local "newb", I can't:

$ git push

Instead, I have to:

% git push origin newb:remote_branch_name

Seems a little silly. If git-pull uses git-config branch.newb.merge to determine where to pull from, why couldn't git-push have a similar config option? Is there a nice shortcut for this or should I just continue the long way?

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
jmacdonagh
  • 3,851
  • 3
  • 18
  • 14

10 Answers10

281

When you do the initial push add the -u parameter:

git push -u origin my_branch:remote_branch

Subsequent pushes will go where you want.

EDIT:

As per the comment, that only sets up pull.

git branch --set-upstream

should do it.

cambunctious
  • 8,391
  • 5
  • 34
  • 53
Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • 12
    `-u` just sets the upstream, which according to the question, is already set. He needs to set `push.default` to `upstrem` in order to get `push` to respect the upstream setting, since by default only `pull` does. – Brian Campbell Apr 21 '11 at 05:47
  • 3
    This doesn't seem to work - at least not on never versions of git – Thomas Watson Sep 21 '15 at 12:23
  • 1
    git branch --set-upstream only does the pull setup "pushRemote" needs to be set after this. – wheredidthatnamecomefrom Mar 14 '18 at 21:12
  • I don't think `git branch --set-upstream` is necessary. Note: my `git --version` is 2.17.1. – Gabriel Staples May 22 '20 at 01:01
  • The syntax you show above is important in, and referenced by, my answer here: [How to change the owner of a PR on GitHub / How to commandeer an open GitHub PR](https://stackoverflow.com/a/66539232/4561887). How did you learn that `from_branch:to_branch` syntax by the way? Is it buried in the `man git push` pages somewhere? – Gabriel Staples Dec 10 '21 at 03:47
  • Found it: it's actually near the top of `man git push` under the "`...`" section: "The format of a `` parameter is an optional plus `+`, followed by the source object ``, followed by a colon `:`, followed by the destination ref ``." And then later: "`:` part can be omitted—such a push will update a ref that `` normally updates without any `` on the command line." This is very non-intuitive and not obvious at all without an example. – Gabriel Staples Dec 10 '21 at 03:52
  • I had way too many questions about this stuff so I did a ton of research and experimenting and added my own, new answer here: https://stackoverflow.com/a/70302053/4561887 – Gabriel Staples Dec 10 '21 at 09:13
  • @wheredidthatnamecomefrom, I don't think that's correct. – Gabriel Staples Dec 10 '21 at 09:27
  • Don't know where my mind was at the time that and can't delete the comment either. The setup is per branch other than that `git push -u origin my_branch:remote_branch` should be enough. – wheredidthatnamecomefrom Dec 12 '21 at 18:07
  • thats why i keep scrolling for other solutions on stackoverflow – HERAwais Jun 05 '23 at 07:47
119

Sure. Just set your push.default to upstream to push branches to their upstreams (which is the same that pull will pull from, defined by branch.newb.merge), rather than pushing branches to ones matching in name (which is the default setting for push.default, matching).

git config push.default upstream

Note that this used to be called tracking not upstream before Git 1.7.4.2, so if you're using an older version of Git, use tracking instead. The push.default option was added in Git 1.6.4, so if you're on an older version than that, you won't have this option at all and will need to explicitly specify the branch to push to.

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • That was it! This applies to all branches that are tracking, but that's fine. Thanks! – jmacdonagh Apr 21 '11 at 23:45
  • I'd be interested to know whether there is a shorthand for the branch name I've checked out. I might just want to `git push buildserver .:test_this` where the `.` shall be the local branch name which I don't necessarily know. I could look it up, sure, but if there was a short hand, like the dot, for that, it'd be cool. – Frederick Nord Feb 14 '14 at 00:01
  • 2
    @FrederickNord `HEAD` is the shorthand you're looking for. `HEAD` is what points to the currently checked out branch, or directly to a particular commit if you have a detached head. – Brian Campbell Feb 14 '14 at 03:52
  • Thanks! This fixed the `Updates were rejected because a pushed branch tip is behind its remote` error for me. My local repo was up to date, but the names were just different. – canhazbits Dec 15 '14 at 19:22
  • This affects how `push` behaves for **all** branches in **all** your repos. You can limit it to just one repo with `--local`, but for a single branch, see [here](https://stackoverflow.com/a/76589598/5353461). – Tom Hale Jun 30 '23 at 14:03
30

The command by Adam is now deprecated. You can use:

git branch --set-upstream-to origin/my_remote_branch my_local_branch

to set the upstream branch of my_local_branch to origin/my_remote_branch.

Community
  • 1
  • 1
jobin
  • 2,600
  • 7
  • 32
  • 59
  • 7
    Can you provide a link supporting the information you share about -u being deprecated? Docs for latest version regarding push at [git-scm.com](https://git-scm.com/docs/git-push) seem to suggest it's current. Thanks in advance - it could be very helpful to readers to follow up for more info. – Kay V Jul 26 '16 at 14:31
  • Agree with @KayV, especially that I got this message when trying to create a new remote branch with a name different to my local branch: 'If you are planning to push out a new local branch that will track its remote counterpart, you may want to use "git push -u" to set the upstream config as you push.' – FBB May 22 '18 at 12:36
  • This only works for `fetch`, `merge`, and `pull`. For per-branch `push` config, see [this answer](https://stackoverflow.com/a/76589598/5353461). – Tom Hale Jun 30 '23 at 14:05
22

How can I push a local Git branch to a remote with a different name easily?

Summary:

Here is a short summary of just the key commands you need in general:

# push from your local `branch2` to a remote `branch1` (push to a branch with
# a different name) on the remote named `origin`
git push -u origin branch2:branch1
# pull from a remote branch `branch1` into your currently-checked-out branch
# (which could have a different name--ex: `branch2`)
git pull origin branch1

# Set your upstream to something new in case you want to change it; ex: set your
# currently-checked-out branch (perhaps `branch2`) to track `branch1` on the 
# remote named `origin`
git branch -u origin/branch1
# Unset your upstream
git branch --unset-upstream

# See what your upstream is currently set to
git branch -vv

Details:

The following sections are covered below, in this order:

  1. Pushing to another branch
  2. Pulling from another branch
  3. Setting and unsetting an upstream branch to track

There are too many incomplete and partial answers here which leave me with a lot of questions and a lot to be desired. So, after a bunch of effort and research and experimenting, here is my attempt at providing a complete solution.

1. Pushing from your local branch to a remote branch with a different name

To push FROM your local branch2 TO remote branch1, you must specify both branches like this:

# Push from local `branch2` to remote `branch1`
git push origin branch2:branch1

# General form: push from local `from_branch` to remote `to_branch`. 
# - Watch out!: see also the additional explanations and NB note below!
git push <remote> <from_branch>[:to_branch]

Notice, however, that the square brackets I have written in the general form above indicate the :to_branch part is optional. What I mean is that to push from a local branch with one name to a remote branch with a different name, that part is NOT optional, but, as a general git command, the command will run if you do not include the :to_branch part, meaning it is optional in that sense. But, it may produce unexpected results! Take a look at this command, for example:

# (push to a remote branch with the **same name** as the local branch)

# Reduced **and confusing** form: this pushes from local `branch2` (even if you
# don't currently have it checked-out!) to remote `branch2`.
git checkout branch3 
git push origin branch2          # Push from local branch2 to remote branch2

You might have local branch3 currently checked-out, and think that git push origin branch2 will push your local branch3 to the remote branch2, since you have branch3 currently checked-out on your system, but this is NOT what will happen! Rather, git push origin branch2 will push your local branch2 to your remote branch2, again, even if you do NOT have branch2 currently checked-out! git push origin branch2 is therefore an equivalent short-hand of this:

# These 2 commands are **exactly identical**! The 1st cmd is the short form
# of the 2nd. 
git push origin branch2          # Push from local branch2 to remote branch2
git push origin branch2:branch2  # Push from local branch2 to remote branch2

The short form of the cmd just above produces very confusing behavior if you think it will push from your currently-checked-out branch instead. Here is a Nota bene note summarizing the behavior described above:

NB: In the general form git push <remote> <from_branch>[:to_branch], if you don't specify the remote TO branch with :to_branch, it is assumed to be the same name as your local FROM branch, from_branch, on the remote! This means if you type only git push origin branch2 instead of git push origin some_other_branch:branch2, it pushes FROM your local branch2 TO the remote copy of branch2, EVEN IF YOU DIDNT HAVE branch2 locally checked-out at the time of running the command! This can be VERY CONFUSING if you thought typing git push origin branch2 had just told your currently-checked out branch, some_other_branch, to push to branch2 on the remote and instead, the local branch2 got pushed to the remote branch2.

The documentation for the general form (git push <remote> <from_branch>[:to_branch]) is hard to find, but it's actually found in the man git push pages near the top under the "<refspec>..." section:

The format of a <refspec> parameter is an optional plus +, followed by the source object <src>, followed by a colon :, followed by the destination ref <dst>.

And then later:

:<dst> part can be omitted—such a push will update a ref that <src> normally updates without any <refspec> on the command line.

I think this documentation is non-intuitive and very difficult to understand, however, without some examples and my explanation above.

[BETTER FORM OF git push] You can also set the upstream branch at the same time as pushing:

# Push from local `branch2` to the remote `branch1`, while also at the same time
# setting `branch2` to track `origin/branch1` as the upstream
git push -u origin branch2:branch1
# OR (same thing)
git push --set-upstream origin branch2:branch1
# General form
git push -u <remote> <from_branch>[:to_branch]

As part of the output of the command above, you should see:

Branch 'branch2' set up to track remote branch 'branch1' from 'origin'.

To make it obvious what is happening there, know that either of the two commands just above are equivalent to these two separate commands:

git push origin branch2:branch1
git branch -u origin/branch1

Now, to view what your branch's upstream branch is currently set to, run the double-verbose (-vv) git branch cmd:

git branch -vv

Sample output:
Here you can see that the upstream branch is origin/master, which means the master branch on the remote named origin:

* master b2f0466 [origin/master] c/array_filter_and_remove_element.c: add O(n) in-place solution

Notes:

  1. -vv above means "double verbose". This means it will print git branch not just verbosely, but double verbosely, or extra verbosely. The "extra verbose" content now printed includes the upstream branch in square brackets, as shown above: [origin/matser].
  2. You can view all your remotes with git remote -v. origin is the remote shown in the examples above.

2. Pulling from a remote branch with a different name to your local branch

[Recommended if you already have branch branch2 checked-out locally!] To pull FROM branch1 on the remote named origin, TO branch2, you must specify the remote branch to pull from, like this:

# THIS ASSUMES YOU ARE ALREADY CHECKED-OUT ON BRANCH `branch2`!

git pull origin branch1
# General form
git pull <remote> [from_branch]

You can also specify both branches, but I'm not entirely sure what the difference is in this case:

git pull origin branch1:branch2

# The general form seems to be:
git pull <remote> <from_branch>[:to_branch]

The following command only works if the remote and local branches have the same name! (therefore it does NOT answer this Stack Overflow question). This command is recommended if you do NOT already have branch some_branch checked-out!

# Pull FROM a remote branch named `some_branch` TO a local branch named
# `some_branch`, while you do NOT have `some_branch` locally checked-out.
git fetch origin some_branch:some_branch
# General form
git fetch <remote> <from_branch>:<to_branch>

# The above is a special form of `git fetch`, and (I believe) requires that 
# `from_branch` and `to_branch` are **the same branch name**. It is roughly 
# equivalent to the following *several* commands:
git checkout any_other_branch
# this `git fetch` cmd updates the **locally-stored**, hidden, remote-tracking
# branch named `origin/some_branch` with the latest changes from the branch
# by this name stored on the remote server named `origin`
git fetch origin some_branch 
git checkout some_branch
git merge origin/some_branch  # merge `origin/some_branch` into `some_branch`
git checkout any_other_branch # go back to the branch we started on

Notes:

  1. Unlike git push, git pull does NOT have a -u option.
  2. See also another of my answers: How to change the owner of a PR on GitHub / How to commandeer an open GitHub PR
  3. The git fetch origin some_branch:some_branch command is done with the same some_branch name used twice--in both locations in the command. The difference is simply that git fetch origin some_branch only updates the locally-stored, hidden, remote-tracking branch named origin/some_branch with the latest changes from the branch by this name stored on the remote server named origin, whereas git fetch origin some_branch:some_branch does that PLUS also updates the locally-stored visible some_branch with those changes too.
    1. If you feel confused about this, you need to learn that for every 1 some_branch you think you have, you actually have up to 3 branches: 1) a local branch some_branch, 2) a remote branch some_branch on a remote server named origin, and 3) and locally-stored, hidden, remote-tracking branch named origin/some_branch. Read here for more info. and for where I first learned this concept of 3 branches per branch: How do I delete a Git branch locally and remotely?. See also my comment here, under that answer.

3. Configuring your local branch to track or untrack a remote branch

You can set your local branch named branch2 to track an upstream branch named branch1 at the same time as pushing by using the git push -u cmd shown above.

You can also set your local branch named branch2 to track an upstream branch named branch1 like this:

# Set branch2 to track origin/branch1 (`branch1` on remote `origin`)
git branch --set-upstream-to=origin/branch1 branch2
# OR (same thing as just above)
git branch -u origin/branch1 branch2
# General form
git branch -u <remote>/<to_branch> [from_branch]

# OR, same as above if the currently-checked-out branch is `branch2`
git branch --set-upstream-to=origin/branch1
# OR (same thing as just above)
git branch -u origin/branch1
# General form
git branch -u <remote>/<to_branch>

To UNset your upstream branch for branch2, so it no longer tracks the previously-set upstream branch (which was origin/branch1 in the examples above), run this:

git branch --unset-upstream branch2
# OR, same as above if the currently-checked-out branch is `branch2`
git branch --unset-upstream

And again, as already shown above, to view what your branch's upstream branch is currently set to, run the double-verbose (-vv) git branch cmd:

git branch -vv

References:

  1. Where I first learned the git push -u origin local_FROM_branch:remote_TO_branch syntax: @Adam Dymitruk's answer
  2. https://devconnected.com/how-to-set-upstream-branch-on-git/
  3. How do I delete a Git branch locally and remotely?

Related git topics I've written about:

  1. BEGINNER:
    1. Create a branch in Git from another branch
  2. INTERMEDIATE:
    1. How to cherry-pick multiple commits
  3. ADVANCED:
    1. How to get just one file from another branch?
    2. Who is "us" and who is "them" according to Git?
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
  • Thanks, your answer is really detailed but a little hard to follow in short time: (e.g. EVEN IF YOU DIDNT HAVE `from_branch` locally checked-out at # the time of running the command! This can be VERY CONFUSING if # you *thought* you had just told your currently-checked out branch to push # to some branch on the remote and instead, the **local copy of that some # branch** (which you do NOT currently have checked-out) gets pushed to the # remote.) This part can be a little more concise? – Lan Si Dec 24 '21 at 00:01
  • 1
    @LanSi, this is a very confusing topic for sure, and difficult for me to explain. I updated my answer a bunch in an attempt to clarify it and make that part easier to understand. Let me know if it's easier to follow now. – Gabriel Staples Jan 03 '22 at 20:23
6

How to push to a branch of a different name on Git

You will usually push your local branch to a remote branch of the same name—but not always.

To push to a branch of a different name, you just need to specify the branch you want to push and the name of the branch you want to push to separated by a colon (:).

For example, if you want to push a branch called some-branch to my-feature:

(some-branch)$ git push origin some-branch:my-feature
Total 0 (delta 0), reused 0 (delta 0)
To github.com:johnmosesman/burner-repo.git
 + 728f0df...8bf04ea some-branch -> my-feature

How to push all local branches to the remote

You won't need to push all branches from your local very often, but if you do you can add the --all flag:

(main)$ git branch
* main
  my-feature

(main)$ git push --all
...
To github.com:johnmosesman/burner-repo.git
   b7f661f..6e36148  main -> main
 * [new branch]      my-feature -> my-feature
4

Yes, there is a config option to make git push to upstream branches by default.

Use the following set of statements so you don't have to do git push origin local:remote every time:

# Set remote branch with a different name as an upstream branch 
# for local branch currently checked out
git branch --set-upstream-to origin/remote_branch_name

# Change the default behavior for git-push (see manpage for git-config)
git config push.default upstream

# Now git will push to the upstream branch by default
git push

After setting the current branch's upstream to a remote branch with a different name, you need to change the default behavior of git push to upstream (see manpage for git-config). Now, git push will obey these rules and push to the set upstream.

Harsh Patel
  • 6,334
  • 10
  • 40
  • 73
messmania
  • 41
  • 2
  • This should be the accepted answer, since it's the only one that addresses both 1) that the local branch needs to be set to tracking the remote branch; and 2) the default behaviour of `push` has to be set as well. Also, it explains the solution in as few words as needed. – Codebird Jan 31 '23 at 09:29
2

Push and create a temporary remote branch

If you want to:

  • Push the current branch to remote under a new name, but:
  • Don't change the remote tracking branch of current branch, and:
  • Don't create a local branch under the new name,

Then it's as simple as this:

git push origin HEAD:temp-branch-name

Note: You can replace HEAD with any other branch or commit ID to push that instead.

ADTC
  • 8,999
  • 5
  • 68
  • 93
0

Here's the process that has worked for me.

git clone original-repo-url
git remote rename origin upstream
git remote add origin new-repo-url

Now your new repo will be ‘origin’ and the original repo is ‘upstream’. Confirm it by running git remote -v. (Side note: Upstream is used to fetch from the original repo - in order to keep your local copy in sync with the project you want to contribute to - and origin is used to pull and push since you can contribute to your own repo).

git push origin master

Now your new remote repo's master (on Github) will be in-sync with the original master, but it won't have any of the feature branches.

git rebase upstream/branch-name
git push origin master

Rebase is a smart merge. Then push to master again and you’ll see the selected feature branch as master on the new repo.

Optional:

git remote rm upstream
git remote add upstream new-repo-url
Geoffrey Hale
  • 10,597
  • 5
  • 44
  • 45
urubuz
  • 352
  • 1
  • 13
0

Two options:

  1. push all the repo's branches to where they get pulled from via push.default = upstream
  2. Change a single branch with remote.<name>.push

To have all your repo's branches push to the branch that they pull from, use:

git config --local push.default upstream

Note: this will affect other branches, also.


To setup a single branch's remote push pair (Example: local main to origin/master):

  1. Set the branch's remote

     git branch --set-upstream-to origin
    
  2. Set the remote's push mapping

    git config --local remote.origin.push main:master
    
Tom Hale
  • 40,825
  • 36
  • 187
  • 242
0

One cool thing you can do if you have a bunch of files in your local branch that you want to save to a different branch, is to do a git stash to save all your modified files (this is repository wide), then you do a git checkout remoteBranchYouWant then do a git stash pop and now all your modified files are ready in your newly checked-out branch and you can commit and push these up to the new branch as you wish.

Wulf
  • 379
  • 1
  • 6
  • 16