ChatGPT解决这个技术问题 Extra ChatGPT

Push local Git repo to new remote including all branches and tags

git

I have a local Git repo that I would like to push to a new remote repo (brand new repo set up on Beanstalk, if that matters). My local repo has a few branches and tags, and I would like to keep all of my history.

It looks like I basically just need to do a git push, but that only uploads the master branch.

How do I push everything so I get a full replica of my local repo on the remote?


p
p13i

To push all your branches, use either (replace REMOTE with the name of the remote, for example "origin"):

git push REMOTE '*:*'
git push REMOTE --all

To push all your tags:

git push REMOTE --tags

Finally, I think you can do this all in one command with:

git push REMOTE --mirror

However, in addition --mirror, will also push your remotes, so this might not be exactly what you want.


--all instead of *:* seems more friendly
my god............. i tore of the entire internet and i found out the ` --all ` switch is AAAAALLLLLLLLLLLLLL i needed!
Just noting that git push REMOTE --all returned No refs in common and none specified; doing nothing., while git push REMOTE "*:* actually pushed all branches to remote.
Use --dry-run to inspect what will happen, in case you have "tmp" or "feature" branches locally that you don't really want to update in REMOTE
If the original remote is still available, it is a nice idea to do git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
D
Daniel

In the case like me that you aquired a repo and are now switching the remote origin to a different repo, a new empty one...

So you have your repo and all the branches inside, but you still need to checkout those branches for the git push --all command to actually push those too.

You should do this before you push:

for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done

Followed by

git push --all

Strangely, git push '*:*' pushed all branches. git push -all just pushed the master. I was transporting repo from github to bitbucket.
Instead of checking out every single branch you should just do "git branch --track $remote". In huge repos checking out an old branch takes sometime
I had to make a small change for this to work: --track remotes/$remote instead of --track $remote. Here's the complete command line: for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
I allowed the master branch(s) by removing grep -v master. I started with a bare repo, and some repos have multiple branches with master in their name (i.e. master-next).
I found this question as a result of trying to sync two remote repositories that were clones back together. My team had moved from github to gitlab while work was suddenly introduced during the transition that relied on our old github CI pipeline. After that work concluded, we wanted to basically import a second time from github to gitlab without losing our gitlab progress. This worked better for me than the accepted answer.
C
Community

Here is another take on the same thing which worked better for the situation I was in. It solves the problem where you have more than one remote, would like to clone all branches in remote source to remote destination but without having to check them all out beforehand.

(The problem I had with Daniel's solution was that it would refuse to checkout a tracking branch from the source remote if I had previously checked it out already, ie, it would not update my local branch before the push)

git push destination +refs/remotes/source/*:refs/heads/*

Note: If you are not using direct CLI, you must escape the asterisks: git push destination +refs/remotes/source/\*:refs/heads/\* @mattalxndr

this will push all branches in remote source to a head branch in destination, possibly doing a non-fast-forward push. You still have to push tags separately.


+1 This worked for me, cloning from one remote to another. Thanks!
I had to escape the asterisks: git push destination +refs/remotes/source/\*:refs/heads/\*
For me, this wound up pushing a branch called HEAD, which I don't think is intentional in this scenario.
Excellent answer, far different than the usual --mirror parameter everybody recommends. Works perfectly for scenarios where you just want to keep sync'd two remotes for automation or auditing purposes.
Thankyou, this works where git push origin *:* did not, without a git clone --bare or git clone --mirror and without a loop to materialize all the remote branches. Final commands for moving a repository: 1) git clone oldurl 2) git remote set-url origin newurl 3) git push -u origin --tags 'refs/remotes/origin/*:refs/heads/*'
t
ta.speot.is

This is the most concise way I have found, provided the destination is empty. Switch to an empty folder and then:

# Note the period for cwd >>>>>>>>>>>>>>>>>>>>>>>> v
git clone --bare https://your-source-repo/repo.git .
git push --mirror https://your-destination-repo/repo.git

Substitute https://... for file:///your/repo etc. as appropriate.


n
nomulex

In my case what worked was.

git push origin --all

Simple and easy. It works! origin is alias for remote URL Git repository.
M
Michał Zalewski

Mirroring a repository

Create a bare clone of the repository.

git clone --bare https://github.com/exampleuser/old-repository.git

Mirror-push to the new repository.

cd old-repository.git
git push --mirror https://github.com/exampleuser/new-repository.git

Remove the temporary local repository you created in step 1.

cd ..
rm -rf old-repository.git

Mirroring a repository that contains Git Large File Storage objects

Create a bare clone of the repository. Replace the example username with the name of the person or organization who owns the repository, and replace the example repository name with the name of the repository you'd like to duplicate.

git clone --bare https://github.com/exampleuser/old-repository.git

Navigate to the repository you just cloned.

cd old-repository.git

Pull in the repository's Git Large File Storage objects.

git lfs fetch --all

Mirror-push to the new repository.

git push --mirror https://github.com/exampleuser/new-repository.git

Push the repository's Git Large File Storage objects to your mirror.

git lfs push --all https://github.com/exampleuser/new-repository.git

Remove the temporary local repository you created in step 1.

cd ..
rm -rf old-repository.git

Above instruction comes from Github Help: https://help.github.com/articles/duplicating-a-repository/


Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. See here for instructions how to write better "link-based" answers. Thanks!
Kudos for adding git lfs as well.
s
scy

The manpage for git-push is worth a read. Combined with this website I wrote the following in my .git/config:

[remote "origin"]
    url = …
    fetch = …
    push = :
    push = refs/tags/*

The push = : means "push any 'matching' branches (i.e. branches that already exist in the remote repository and have a local counterpart)", while push = refs/tags/* means "push all tags".

So now I only have to run git push to push all matching branches and all tags.

Yes, this is not quite what the OP wanted (all of the branches to push must already exist on the remote side), but might be helpful for those who find this question while googling for "how do I push branches and tags at the same time".


F
Frizz1977

My favorite (and simplest) way

git clone --mirror  OLD_GIT_URL
cd  NEW_CREATED_FOLDER
git remote add NEW-REMOTE NEW_GIT_URL
git push  NEW-REMOTE --mirror 

y
yanzi1225627

I found above answers still have some unclear things, which will mislead users. First, It's sure that git push new_origin --all and git push new_origin --mirror can't duplicate all branches of origin, it just duplicate your local existed branches to your new_origin.

Below is two useful methods I have tested:

1,duplicate by clone bare repo.git clone --bare origin_url, then enter the folder, and git push new_origin_url --mirror.By this way, you can also use git clone --mirror origin_url, both --bareand --mirror will download a bare repo,not including workspace. please refer this

2,If you have a git repo by using git clone, which means you have bare repo and git workspace, you can use git remote add new_origin new_origin_url, and then git push new_origin +refs/remotes/origin/\*:refs/heads/\*,and then git push new_origin --tags

By this way, you will get a extra head branch, which make no sense.


L
Luka Špoljarić

I was in a process of switching from one version control service to another and needed to clone all repositories including all branches, tags and history.

To achieve above I did next:

manually checkout all branches to local repository (script to checkout all shown below),

git push origin '*:*'

.sh script used to checkout all branches to local repository:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done

C
CEL

To push branches and tags (but not remotes):

git push origin 'refs/tags/*' 'refs/heads/*'

This would be equivalent to combining the --tags and --all options for git push, which git does not seem to allow.


Is there an additional option to push from another remote ? For instance with +refs/remotes/source/*
C
Community

Based in @Daniel answer I did:

for remote in \`git branch | grep -v master\`
do 
    git push -u origin $remote
done

Even better, | grep -v master can be replaced with | sed 's/\*//' (I'm assuming you excluded master to avoid the nasty little * that's prepended to the currently selected branch) which allows you to include master and avoid any problems when master is not your currently selected branch. Also sorry for necroposting, it's just that this answer helped me today and I wanted to share my modification if it can help others in my position...
P
Pratik Patel

Below command will push all the branches(including the ones which you have never checked-out but present in your git repo, you can see them by git branch -a)

git push origin '*:*'

NOTE: This command comes handy when you are migrating version control service(i.e migrating from Gitlab to GitHub)


Migrating between version control services and this is exactly what i'm searching for, cheers!
t
tom

I found the best and simplest method https://www.metaltoad.com/blog/git-push-all-branches-new-remote, 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


Hi but doing this also adds to you repo a HEAD brach that was not in the previous commit, do you know how to deal with that ?
Yeah, I also found that, I didn't do anything to it yet. You can delete it directly.
C
Cameron Tacklind

The main way to do what you want is to use the --all and --tags flags. Leaving out either will not push part of what you want. Unfortunately, they cannot be used together (don't see why) so they must be run one after the other.

git push --all
git push --tags

Another option that is relevant is the --prune option that removes any branches/tags on the remote that don't exist locally.

Alternatively, consider the --mirror option as it is basically equivalent to --all --tags --prune.

git push --mirror

P
PotatoFarmer

I found that none of these seemed to work properly for me. Feel free to flame this to death but for some reason couldn't get the other options to work properly.

Expected result was a repo "cloned" to another remote (ie from Github to another provider):

All branches are created on new remote

All branch history are created on new remote (this was missed on every solution I tried)

(this was missed on every solution I tried)

All tags are created on new remote

Source moves over (a given)

Non-destructive (giving pause to the --mirror option)

The major issue I was seeing was either all remote branches didn't get recreated in the new remote. If a command did, the new remote did not have the branch history (ie doing a git checkout branch; git log wouldn't show the expected branch commits).

I noticed git checkout -b branchname is NOT the same as git checkout branchname (the latter being what I needed). I notice git checkout --track branchname didn't appear to pull the branch history.

My Solution (powershell based):

Function Git-FetchRemoteBranches {
$originalbranch = (git symbolic-ref HEAD).split("/")[-1]

Foreach ($entry in (git branch -r)) {

If ($entry -like "*->*") {
  $branch = $entry.split("->")[2].split("/")[1]
}
  else {$branch = $entry.split("/")[1]}

Write-Host "--Trying git checkout " -NoNewline
Write-Host "$branch" -Foreground Yellow

git checkout $branch

Remove-Variable branch -Force

""}

#Switch back to original branch, if needed
If ( ((git symbolic-ref HEAD).split("/")[-1]) -ne $originalbranch) {
"Switching back to original branch"
git checkout $originalbranch
Remove-Variable originalbranch -Force
}
}

git clone http://remoterepo
cd remoterepo
Git-FetchRemoteBranches
git remote add newremote
git push newremote --all
git push newremote --tags #Not sure if neeeded, but added for good measure

A
Anonymous Ant

Here is What I solved [remote rejected] when I push local Git repo to new remote including all branches and tags

git clone --mirror old-repo

cd

git remote add new new-repo

git push new --mirror


A
Andrew Fox

Every time I Google how to do this I end up reading this same thread, but it doesn't get me where I need to be, so hopefully this will help my future self and others too.

I started a new local project that I want to push to my repo (BitBucket). Here is what I did:

navigate to my local project root initiate with: git init add all files with: git add . commit with: git commit -m "Initial commit" go to my repo (BitBucket) create new repository: new_project go back to my local project add the remote with: git remote add origin git@bitbucket.org:AndrewFox/new_project.git push the commit with: git push origin master -f

The -f flag is to force the push, otherwise it will identify that the two repo's are different and fail.


This is not what the original question was asking about. This is also really unsafe. You're telling people to throw away old commits. You should really basically never use the "force" option unless you really know what you're doing.
@CameronTacklind this is for a new project, so there are no commits.
The original question is asking about how to upload an existing project to a "new remote" and include all branches & tags. The "new remote" is empty and thus would not need a force. Again, you should basically never do a force push unless you really know what you're doing. Suggesting this to other users, especially without appropriate warnings, in particular for a case that doesn't need it, is going to hurt someone.
Fair point. I got these instructions from the BitBucket website and decided to share. Please edit my answer to include your warnings and potential issues, as I’m not as familiar as you are with it. Thank you for bringing this to my attention 👍🏼
P
Pratik

Run following to move existing repository to new remote with all branches and tags:

cd existing_repo
git remote rename origin old-origin
git remote add origin git@<repo-url.git>
for remote in `git branch -r `; do git checkout --track remotes/$remote ; done
git push -u origin --all
git push -u origin --tags