757

I'd like to push and pull all the branches by default, including the newly created ones.

Is there a setting that I can define for it?

Otherwise, when I add a new branch, locally and I want to pull it from the server, what is the simplest way to do it?

I created a new branch with the same name and tried to pull but it doesn't work. Asks me for all the remote config of the branch. How do I set it.

lprsd
  • 84,407
  • 47
  • 135
  • 168

14 Answers14

1558

The simplest way is to do:

git push --all origin

This will push tags and branches.

saurabheights
  • 3,967
  • 2
  • 31
  • 50
brimble2010
  • 17,796
  • 7
  • 28
  • 45
  • 15
    Among dozens of answers that I found on SO and other places, this is the simplest way to push a newly created local branch, without touching configuration. Thanks! – András Szepesházi Jun 24 '12 at 15:12
  • 198
    And if you add `-u` once, e.g. `git push --all origin -u`, tracking is setup and after that you can simply use `git push`. – Alec Aug 09 '12 at 14:54
  • 29
    For git version 1.7.12.3 I had to use `git push --tags origin` to push all tags. – thisgeek Oct 18 '12 at 18:23
  • 22
    Also look at "--mirror" instead of "--all" this push more stuff – Loda Jul 05 '13 at 11:22
  • 2
    @Loda - Is "--mirror" going to do what the poster wants? We had a guy vaporize all branches on the remote repo with "--mirror" (he only had master checked out when he did "--mirror"). I suspect there's a way to fix up your refs/remote/* but didn't have time to play with it and ended up restoring from backup. – Scott Aug 22 '13 at 16:38
  • 2
    @Scott "--mirror" does more stuff than just pushing news branch. and it does it differently. (ie: force the update, delete old branch, ...). It does more than what the poster asked. Anyway, according to http://stackoverflow.com/q/3333102/154272 and https://www.kernel.org/pub/software/scm/git/docs/git-push.html, this is probably NOT the best way to go. – Loda Aug 30 '13 at 09:22
  • 2
    To also push the tags from 1.8.3 on you can use `git push --all --follow-tags origin` – asmaier Dec 17 '13 at 14:18
  • 23
    WARNING: If you have a bunch of LOCAL branches that you have not cleaned up (features, hotfix's) - or did not clean up properly (me), this will flood your remote. Damn. And we just did a pruning. Not sure why my local had so many branches left over. – Jack Apr 03 '14 at 21:15
  • 5
    It didn't push tags for me.. I had to do `git push --tags origin` as well – Matej Apr 14 '14 at 15:53
  • to push all local branches, git push --all – MinhajulAnwar Jan 18 '16 at 05:46
  • 1
    We were trying to move our repo, but only had checked out a couple of the branches. Origin had all the branches. git push --all seems to push only the local branches and not the tracking branches. So I guess you have to checkout all branches before trying to push. – wayofthefuture Feb 27 '17 at 15:07
  • 2
    this doesn't push **all** branches (as OP asked) but only **all local** branches, so for me this doesn't work cause I want to copy **all** branches from one repo to another via local repo, but only master (checkouted) and local branches are pushed – vladkras Feb 26 '18 at 11:53
  • @vladkras what other branches would you be aiming to push other than local ones? – brimble2010 Feb 26 '18 at 13:24
  • @vladkras sorry, I didn't read your comment correctly and now cannot edit. My response: this is because git is distributed so any commands that you issue are to interact with your *local* set of branches and tags. As you mentioned, you'd have to have all of the branches and tags locally for this command to work. I would say that this is not something that people would do often. – brimble2010 Feb 26 '18 at 13:42
154

With modern git you always fetch all branches (as remote-tracking branches into refs/remotes/origin/* namespace, visible with git branch -r or git remote show origin).

By default (see documentation of push.default config variable) you push matching branches, which means that first you have to do git push origin branch for git to push it always on git push.

If you want to always push all branches, you can set up push refspec. Assuming that the remote is named origin you can either use git config:

$ git config --add remote.origin.push '+refs/heads/*:refs/heads/*'
$ git config --add remote.origin.push '+refs/tags/*:refs/tags/*'

or directly edit .git/config file to have something like the following:

[remote "origin"]
        url = user@example.com:/srv/git/repo.git
        fetch = +refs/heads/*:refs/remotes/origin/*
        fetch = +refs/tags/*:refs/tags/*
        push  = +refs/heads/*:refs/heads/*
        push  = +refs/tags/*:refs/tags/*
Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
  • 3
    @Merc: `git push --all origin` is good for one time publishing all branches and tags, though default up till current version 'matching' semantic would mean that you would push all branches afterwards... unless you add new branch or tag. The **setting** to *"push [...] all the branches by default"* is as written. – Jakub Narębski Sep 16 '13 at 12:51
  • You could improve the answer to add the way to reconfigure Git this way. This is useful for users having set the simple mode. – Dereckson Feb 20 '14 at 13:54
  • 3
    This has changed since git 2.0. Push default is simple, not matching any more. – mike Sep 07 '14 at 13:17
  • I tried this and got an error on push: `fatal: Invalid refspec ''+refs/heads/*:refs/heads/*''` **(Note: I'm on git 2.0. I'm still working out how to fix this.)** – Brian Lacy Dec 22 '15 at 23:04
  • 1
    @BrianLacy it looks to me like you have quotes around the refspec in the configuration. Just open config file in editor and check. – Jakub Narębski Dec 23 '15 at 08:49
  • 2
    Now default value for `push.default` is `simple`. – hasanghaforian Apr 21 '16 at 07:36
  • On my git 1.9.5 git push --all origin does not push all tags. It pushes all branches. – Ivan Nov 25 '16 at 15:46
  • A separate git push --tags origin is required to push the tags. This can be verified easily as when git push --tags origin is rerun the behaviour is different, saying it is all up to date. – Ivan Nov 25 '16 at 15:48
40

I had used below commands to migrate all branches to the new repository.

~$ git clone --mirror <url_of_old_repo>
~$ cd <name_of_old_repo>
~$ git remote add new-origin <url_of_new_repo>
~$ git push new-origin master
~$ git push new-origin --mirror

NOTE: I had to use second last (i.e. push master first) command while cloning a repo from Atlassian Stash to AWS CodeCommit (blank repo). I am not sure the reason, but after pushing (git push new-origin --mirror) default branch was referring to some other branch than master.

vikas027
  • 5,282
  • 4
  • 39
  • 51
  • 1
    Perfect for moving a repo to another host. Thank you! – Pelmered Jul 05 '16 at 10:04
  • 2
    This is indeed only useful method. Use `git push new_origin --all`just push your current local branches to new_origin, not all branches of origin. – yanzi1225627 Aug 31 '16 at 15:38
  • Just noting that this makes a `--bare` repository, which is a bit different from a regular repository, it only has the `.git` files, not your files. It's perfectly enough if you are not going to do work in it. See `--bare` and `--mirror` https://git-scm.com/docs/git-clone. – jmmut Oct 20 '16 at 08:14
  • All though it only has the .git files and not the actual source code, if you perform a remote update it will re-fetch everything from the origin to the destination. – SanthoshM Aug 01 '17 at 18:21
  • This was a lifesaver! This "master before mirror" method fixed issue with Bitbucket being the destination and believing a different branch other than "master" was the main branch. – Toddius Zho Aug 17 '18 at 20:37
  • 1
    This did not work for me for some reason... Maybe because my repository was private. Anyways I found more info here: https://docs.github.com/en/repositories/creating-and-managing-repositories/duplicating-a-repository and used the step, which is pretty much the same and it worked. Just FYI, had made my source and target, public. – Nitin Kumar Mar 18 '22 at 02:36
  • @jmmut It is very simple to convert mirror repo to normal repo, one change in config and git reset --hard. https://stackoverflow.com/q/10637378/11173412 – Валерий Заподовников Feb 16 '23 at 21:05
34

Including the + in the push spec is probably a bad idea, as it means that git will happily do a non-fast-forward push even without -f, and if the remote server is set up to accept those, you can lose history.

Try just this:

$ git config --add remote.origin.push 'refs/heads/*:refs/heads/*'
$ git config --add remote.origin.push 'refs/tags/*:refs/tags/*'
$ git config --add remote.origin.fetch 'refs/heads/*:refs/remotes/origin/*'
$ git config --add remote.origin.fetch 'refs/tags/*:refs/tags/*'
Michiel de Mare
  • 41,982
  • 29
  • 103
  • 134
Mark Reed
  • 341
  • 3
  • 2
  • You can also add the `--global` option to each of these to make this the global default for all your repositories. – Ether Feb 06 '12 at 18:47
  • It is unfortunate that the + is added automatically by git when doing `git remote add`. – Ether Feb 07 '12 at 19:24
16

If you are moving branches to a new repo from an old one and do NOT have all the old repo branches local, you will need to track them first.

for remote in `git branch -r | grep -v '\->'`; do git branch --track $remote; done

Then add your new remote repo:

git remote add bb <path-to-new-repo>

Then you can push all using this command:

git push -u bb --all

Or you can configure the repo using the git config commands noted in the other responses here if you are not doing this one time or are only looking to move local branches.

The important point, the other responses only push all LOCAL branches. If the branches only exist on an alternate REMOTE repository they will not move without tracking them first. The for loop presented here will help with that.

James M. Greene
  • 1,251
  • 1
  • 16
  • 23
Lance Cleveland
  • 3,098
  • 1
  • 33
  • 36
  • BTW, I am using "bb" in place of "origin" here because I assume your original/old repository was named "origin" and is likely still attached to that label. "bb" is for Bitbucket, where I moved my original repo to, but you can call it something more applicable like "neworigin" if you prefer. – Lance Cleveland Apr 18 '13 at 03:38
  • 4
    That didn't work for me. Ended up with all remote branches tracking the same local branch :/ – jhsowter Dec 16 '14 at 10:35
  • 4
    AFAIK this shouldn't work, as per @jhsowter comment. the right command for me to track a remote branch in a newly cloned repo is `git branch --track reponame origin/reponame` otherwise you'll get all the remote branches tracked on the current local branch – Alessandro Fazzi Jan 12 '16 at 10:43
  • I changed the repo-collecting snippet to `git branch -r | grep -v '\->' | sed 's/ origin\///'`, which gives just the remote branch name. – Paul Hicks May 20 '18 at 23:37
11

If you are moving all branches to a new repo from an old one then in your local repo you need to set up tracking of each branch to existing origin branches, before pushing to the new repo, otherwise all your origin branches won’t appear in the new origin. Do this manually by tracking or checking out each branch, or use the one liner:

for remote in `git branch -r | grep -v '\->' | grep -v master`; do git branch --track `echo $remote|sed 's=origin/=='` `echo $remote`; done

This one line command is based on versions of it in other answers on this page, but is arguably better because:

  1. it correctly sets up the branch tracking, unlike some older variants of this command on this page which only supply one parameter to --track and thus each branch ends up tracking master - not good
  2. names the local branches without the prefix “origin/” which I personally don’t want - and is consistent with what happens when you checkout a branch normally.
  3. skips tracking master since that is already happening
  4. doesn’t actually checkout anything thus is fast
  5. avoids stumbling over the -> in the output of git branch -r

Next, if you are switching origins, replace the link to the old origin and point to a new remote. Ensure you create the new remote first, using bitbucket/github GUI, but don’t add any files to it or there will be a merge problem. E.g.

git remote set-url origin git@bitbucket.org:YOUR/SOMEREPO.git

Now push. Note the second command is needed to push the tags as well:

git push -u --all origin
git push --tags origin
abulka
  • 1,316
  • 13
  • 18
7

I found the best and simplest method here, just as @kumarahul posted, works like a charm for me, it will push all the tags and branches from origin to the new remote:

git remote add newremote new-remote-url

git push newremote --tags refs/remotes/origin/*:refs/heads/*

I used 'git push --all -u newremote', but it only push the checkouted branches to the newremote.

Git: Push All Branches to a New Remote

by Keith Dechant , Software Architect

Here's a scenario some of you might have encountered with your Git repositories. You have a working copy of a Git repo, say from an old server. But you only have the working copy, and the origin is not accessible. So you can't just fork it. But you want to push the whole repo and all the branch history to your new remote.

This is possible if your working copy contains the tracking branches from the old remote (origin/branch1, origin/branch1, etc.). If you do, you have the entire repo and history.

However, in my case there were dozens of branches, and some or all of them I had never checked out locally. Pushing them all seemed like a heavy lift. So, how to proceed?

I identified two options:

Option 1: Checkout every branch and push I could do this, and I could even write a Bash script to help. However, doing this would change my working files with each checkout, and would create a local branch for each of the remote tracking branches. This would be slow with a large repo.

Option 2: Push without changing your working copy There is a second alternative, which doesn't require a checkout of each branch, doesn't create extraneous branches in the working copy, and doesn't even modify the files in the working copy.

If your old, no-longer-active remote is called "oldremote" and your new remote is called "newremote", you can push just the remote tracking branches with this command:

git push newremote refs/remotes/oldremote/*:refs/heads/*

In some cases, it's also possible to push just a subset of the branches. If the branch names are namespaced with a slash (e.g., oldremote/features/branch3, oldremote/features/branch4, etc.), you can push only the remote tracking branches with names beginning with "oldremote/features":

git push newremote refs/remotes/oldremote/features/*:refs/heads/features/*

Whether you push all the branches or just some of them, Git will perform the entire operation without creating any new local branches, and without making changes to your working files. Every tracking branch that matches your pattern will be pushed to the new remote.

For more information on the topic, check out this thread on Stack Overflow.

Date posted: October 9, 2017

tom
  • 317
  • 3
  • 9
6

To see all the branches with out using git branch -a you should execute:

for remote in `git branch -r`; do git branch --track $remote; done
git fetch --all
git pull --all

Now you can see all the branches:

git branch

To push all the branches try:

git push --all
tokhi
  • 21,044
  • 23
  • 95
  • 105
4

The full procedure that worked for me to transfer ALL branches and tags is, combining the answers of @vikas027 and @kumarahul:

~$ git clone <url_of_old_repo>
~$ cd <name_of_old_repo>
~$ git remote add new-origin <url_of_new_repo>
~$ git push new-origin --mirror
~$ git push new-origin refs/remotes/origin/*:refs/heads/*
~$ git push new-origin --delete HEAD

The last step is because a branch named HEAD appears in the new remote due to the wildcard

Amir
  • 1,871
  • 1
  • 12
  • 10
3

If you are pushing from one remote origin to another, you can use this:

git push newremote refs/remotes/oldremote/*:refs/heads/*

This worked for me. Reffer to this: https://www.metaltoad.com/blog/git-push-all-branches-new-remote

kumarahul
  • 396
  • 4
  • 10
1

Solution without hardcoding origin in config

Use the following in your global gitconfig

[remote]
    push = +refs/heads/*
    push = +refs/tags/*

This pushes all branches and all tags

Why should you NOT hardcode origin in config?

If you hardcode:

  1. You'll end up with origin as a remote in all repos. So you'll not be able to add origin, but you need to use set-url.
  2. If a tool creates a remote with a different name push all config will not apply. Then you'll have to rename the remote, but rename will not work because origin already exists (from point 1) remember :)

Fetching is taken care of already by modern git

As per Jakub Narębski's answer:

With modern git you always fetch all branches (as remote-tracking branches into refs/remotes/origin/* namespace

Dheeraj Bhaskar
  • 18,633
  • 9
  • 63
  • 66
1

Add your new remote repo and the last step will exclude the HEAD branch when you push

git clone <url_of_old_repo>
cd <name_of_old_repo>
git remote add new-origin <url_of_new_repo>
git ls-remote . | grep 'refs/remotes/origin/' | grep -v 'HEAD' | awk -F 'origin/' '{print $2}' | xargs -i git push -f new-origin  --tags refs/remotes/origin/{}:refs/heads/{}
keginx
  • 11
  • 2
0

first add the remote git to your loacl with

git remote add remote_name remote_address

and after you just need to do it with the following command

git push --all remote_name
mohsen
  • 4,698
  • 1
  • 33
  • 54
0

The 2012 answer mentions git push --all origin as "This will push tags and branches."

Well... no: it will push only all branches (i.e. refs under refs/heads/, not under refs/tags/)

That is why in 2023, with Git 2.41, the answer to "Set up git to pull and push all branches" would be:

git push -u --branches

Because with Git 2.41 (Q2 2023), "git push --all"(man) gained an alias git push --branches(man)".

See commit 022fbb6 (12 May 2023) by Elijah Newren (newren).
See commit 425b4d7 (06 May 2023) by Teng Long (dyrone).
(Merged by Junio C Hamano -- gitster -- in commit f37da97, 15 May 2023)

push: introduce '--branches' option

Signed-off-by: Teng Long

The '--all' option of git-push(man) built-in cmd support to push all branches (refs under refs/heads) to remote.
Under the usage, a user can easlily work in some scenarios, for example, branches synchronization and batch upload.

The '--all' was introduced for a long time, meanwhile, git supports to customize the storage location under refs/".
When a new Git user see the usage like, 'git push origin --all', we might feel like we're pushing all the refs instead of just branches without looking at the documents until we found the related description of it or '--mirror'.

To ensure compatibility, we cannot rename '--all' to another name directly, one way is, we can try to add a new option '--heads' which be identical with the functionality of '--all' to let the user understand the meaning of representation more clearly.
Actually, We've more or less named options this way already, for example, in 'git-show-ref' and 'git ls-remote'(man).

git push now includes in its man page:

'git push' [--all | --branches | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]

git push now includes in its man page:

--branches

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250