ChatGPT解决这个技术问题 Extra ChatGPT

将本地 Git 存储库推送到新的远程,包括所有分支和标签

git

我有一个本地 Git 存储库,我想将它推送到一个新的远程存储库(如果重要的话,在 Beanstalk 上设置全新的存储库)。我的本地仓库有一些分支和标签,我想保留我的所有历史记录。

看起来我基本上只需要做一个 git push,但这只会上传 master 分支。

如何推送所有内容,以便在遥控器上获得本地仓库的完整副本?


p
p13i

要推送 all your branches,请使用(将 REMOTE 替换为遥控器的名称,例如“origin”):

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

要推动 all your tags

git push REMOTE --tags

最后,我认为您可以使用以下命令在一个命令中完成所有操作:

git push REMOTE --mirror

但是,除了 --mirror,还会推送您的遥控器,因此这可能不是您想要的。


--all 而不是 *:* 似乎更友好
我的上帝......我撕毁了整个互联网,我发现'--all'开关是我需要的AAAAALLLLLLLLLLLLLL!
只是注意到 git push REMOTE --all 返回 No refs in common and none specified; 什么都不做。而 git push REMOTE "*:* 实际上将所有分支推送到远程。
使用 --dry-run 检查会发生什么,以防您在本地有“tmp”或“feature”分支,而您真的不想在 REMOTE 中更新
如果原始遥控器仍然可用,最好执行 git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url
D
Daniel

在像我这样的情况下,您获得了一个仓库,现在正在将远程源切换到另一个仓库,一个新的空仓库......

所以你有你的 repo 和里面的所有分支,但你仍然需要检查这些分支,以便 git push --all 命令实际推送它们。

您应该在推送之前执行此操作:

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

其次是

git push --all

奇怪的是,git push '*:*' 推动了所有分支。 git push -all 刚推了主人。我正在将 repo 从 github 传输到 bitbucket。
而不是检查每个分支,您应该只执行“git branch --track $remote”。在巨大的仓库中检查一个旧的分支需要一些时间
我必须进行一些小改动才能使其正常工作:--track remotes/$remote 而不是 --track $remote。这是完整的命令行:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
我通过删除 grep -v master 来允许主分支。我从一个裸仓库开始,一些仓库有多个分支,名字中有 master(即 master-next)。
由于尝试将两个克隆的远程存储库同步回一起,我发现了这个问题。我的团队已经从 github 转移到了 gitlab,而在依赖我们旧的 github CI 管道的过渡期间突然引入了工作。工作结束后,我们基本上想在不丢失 gitlab 进度的情况下从 github 再次导入到 gitlab。这对我来说比接受的答案更好。
C
Community

这是对同一件事的另一种看法,它在我所处的情况下效果更好。它解决了您有多个遥控器的问题,希望将远程 source 中的所有分支克隆到远程 destination 但不必事先检查它们。

(我对 Daniel 的解决方案的问题是,如果我之前已经检查过它,它将拒绝从 source 远程检查跟踪分支,即它不会在推送之前更新我的本地分支)

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

注意:如果您不使用直接 CLI,则必须转义星号: git push destination +refs/remotes/source/\*:refs/heads/\* @mattalxndr

这会将远程 source 中的所有分支推送到 destination 中的头分支,可能会执行非快进推送。您仍然必须单独推送标签。


+1 这对我有用,从一个 remote 克隆到另一个。谢谢!
我必须避开星号:git push destination +refs/remotes/source/\*:refs/heads/\*
对我来说,这最终推动了一个名为 HEAD 的分支,我认为在这种情况下不是故意的。
很好的答案,与大家推荐的通常 --mirror 参数大不相同。非常适合您只想保持同步两个遥控器以实现自动化或审计目的的场景。
谢谢,这适用于 git push origin *:* 没有,没有 git clone --baregit clone --mirror 并且没有实现所有远程分支的循环。移动存储库的最终命令: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

这是我找到的最简洁的方式,前提是目的地是空的。切换到一个空文件夹,然后:

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

根据需要用 https://... 替换 file:///your/repo 等。


n
nomulex

就我而言,有效的是。

git push origin --all

简单易行。有用! origin 是远程 URL Git 存储库的别名。
M
Michał Zalewski

镜像存储库

创建存储库的裸克隆。

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

镜像推送到新的存储库。

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

删除您在步骤 1 中创建的临时本地存储库。

cd ..
rm -rf old-repository.git

镜像包含 Git 大文件存储对象的存储库

创建存储库的裸克隆。将示例用户名替换为拥有该存储库的个人或组织的名称,并将示例存储库名称替换为您要复制的存储库的名称。

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

导航到您刚刚克隆的存储库。

cd old-repository.git

拉入存储库的 Git 大文件存储对象。

git lfs fetch --all

镜像推送到新的存储库。

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

将存储库的 Git 大型文件存储对象推送到您的镜像。

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

删除您在步骤 1 中创建的临时本地存储库。

cd ..
rm -rf old-repository.git

以上说明来自 Github 帮助:https://help.github.com/articles/duplicating-a-repository/


虽然这在理论上可以回答问题,但it would be preferable在此处包含答案的基本部分,并提供链接以供参考。有关如何编写更好“基于链接”的答案的说明,请参阅here。谢谢!
也感谢添加 git lfs
s
scy

git-push 的联机帮助页值得一读。结合 this website,我在 .git/config 中编写了以下内容:

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

push = : 表示“推送任何‘匹配’的分支(即远程存储库中已经存在并具有本地对应的分支)”,而 push = refs/tags/* 表示“推送所有标签”。

所以现在我只需要运行 git push 来推送所有匹配的分支和所有标签。

是的,这不是 OP 想要的(所有要推送的分支必须已经存在于远程端),但对于那些在谷歌搜索“我如何同时推送分支和标签”时发现这个问题的人可能会有所帮助时间”。


F
Frizz1977

我最喜欢(也是最简单)的方式

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

我发现上面的答案还有一些不清楚的地方,会误导用户。首先,可以确定 git push new_origin --allgit push new_origin --mirror 不能复制所有的分支,它只是将您本地存在的分支复制到您的 new_origin。

以下是我测试过的两种有用的方法:

1,通过克隆裸repo复制。git clone --bare origin_url,然后进入文件夹,然后git push new_origin_url --mirror。这样,您也可以使用git clone --mirror origin_url--bare--mirror都会下载裸repo,不包括工作区。请参考this

2、如果你有一个使用git clone的git repo,这意味着你有裸repo和git工作空间,你可以使用git remote add new_origin new_origin_url,然后是git push new_origin +refs/remotes/origin/\*:refs/heads/\*,然后是git push new_origin --tags

通过这种方式,您将获得一个额外的 head 分支,这没有任何意义。


L
Luka Špoljarić

我正在从一个版本控制服务切换到另一个版本控制服务,需要克隆所有存储库,包括所有分支、标签和历史记录。

为了实现上述目标,我接下来做了:

手动将所有分支签出到本地存储库(签出脚本如下所示),

git push origin '*:*'

.sh 脚本用于将所有分支检出到本地存储库:

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

推送分支和标签(但不是远程):

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

这相当于将 git push--tags--all 选项组合在一起,而 git 似乎不允许这样做。


是否有其他选项可以从另一个遥控器推送?例如 +refs/remotes/source/*
C
Community

根据 @Daniel 的回答,我做了:

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

更好的是,| grep -v master 可以替换为 | sed 's/\*//'(我假设您排除了 master 以避免附加到当前选定分支的讨厌的小 *),它允许您包含 master 并避免任何master 不是您当前选择的分支时出现问题。也很抱歉发布了 necroposting,只是这个答案今天对我有帮助,如果它可以帮助我所在位置的其他人,我想分享我的修改......
P
Pratik Patel

下面的命令将推送所有分支(包括您从未签出但存在于您的 git 存储库中的分支,您可以通过 git branch -a 查看它们)

git push origin '*:*'

注意:当您迁移版本控制服务(即从 Gitlab 迁移到 GitHub)时,此命令会派上用场


在版本控制服务之间迁移,这正是我正在寻找的,干杯!
t
tom

我找到了最好和最简单的方法 https://www.metaltoad.com/blog/git-push-all-branches-new-remote,对我来说就像一个魅力,它将所有标签和分支从源推送到新的远程:

git remote add newremote new-remote-url

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

我使用了'git push --all -u newremote',但它只将签出的分支推送到newremote。

Git: Push All Branches to a New Remote 作者 Keith Dechant, 软件架构师 这是你们中的一些人在使用 Git 存储库时可能遇到的场景。你有一个 Git 存储库的工作副本,比如来自旧服务器。但是您只有工作副本,并且无法访问来源。所以你不能只分叉它。但是你想将整个 repo 和所有分支历史推送到你的新遥控器。如果您的工作副本包含来自旧远程的跟踪分支(origin/branch1、origin/branch1 等),这是可能的。如果你这样做了,你就有了整个回购和历史。然而,就我而言,有几十个分支机构,其中一些或全部我从未在本地检查过。将它们全部推开似乎是一件沉重的事情。那么,如何进行呢?我确定了两个选项: 选项 1:检查每个分支并推送我可以这样做,我什至可以编写一个 Bash 脚本来提供帮助。但是,这样做会在每次结帐时更改我的工作文件,并为每个远程跟踪分支创建一个本地分支。对于大型回购,这会很慢。选项 2:在不更改工作副本的情况下推送 还有第二种选择,它不需要检查每个分支,不会在工作副本中创建无关的分支,甚至不需要修改工作副本中的文件。如果您的旧的不再活动的遥控器称为“oldremote”,而您的新遥控器称为“newremote”,您可以使用以下命令仅推送远程跟踪分支:git push newremote refs/remotes/oldremote/*:refs/ head/* 在某些情况下,也可以只推送分支的一个子集。如果分支名称以斜线命名(例如 oldremote/features/branch3、oldremote/features/branch4 等),您只能推送名称以“oldremote/features”开头的远程跟踪分支: git push newremote refs /remotes/oldremote/features/*:refs/heads/features/* 无论你推送所有分支还是只推送其中一些分支,Git 都会执行整个操作,而无需创建任何新的本地分支,也不会更改你的工作文件。每个与您的模式匹配的跟踪分支都将被推送到新的远程。有关该主题的更多信息,请查看 Stack Overflow 上的此线程。发布日期:2017 年 10 月 9 日


嗨,但是这样做也会给你增加一个 HEAD 分支,它不在之前的提交中,你知道如何处理吗?
是的,我也发现了,我还没有做任何事情。可以直接删除。
C
Cameron Tacklind

做您想做的事的主要方法是使用 --all --tags 标志。遗漏任何一个都不会推动你想要的部分。不幸的是,它们不能一起使用(不明白为什么),所以它们必须一个接一个地运行。

git push --all
git push --tags

另一个相关的选项是 --prune 选项,该选项删除远程上不存在本地的任何分支/标签。

或者,考虑 --mirror 选项,因为它基本上等同于 --all --tags --prune

git push --mirror

P
PotatoFarmer

我发现这些似乎都不适合我。随意将其烧死,但由于某种原因无法使其他选项正常工作。

预期的结果是回购“克隆”到另一个远程(即从 Github 到另一个提供者):

所有分支都在新的遥控器上创建

所有分支历史都是在新的遥控器上创建的(我尝试的每个解决方案都错过了这一点)

(我尝试的每个解决方案都错过了这一点)

所有标签均在新遥控器上创建

源移动(给定)

非破坏性(暂停 --mirror 选项)

我看到的主要问题是所有远程分支都没有在新远程中重新创建。如果有命令,则新远程没有分支历史记录(即执行 git checkout branch; git log 不会显示预期的分支提交)。

我注意到 git checkout -b branchnamegit checkout branchname 不同(后者是我需要的)。我注意到 git checkout --track branchname 似乎没有提取分支历史记录。

我的解决方案(基于 powershell):

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

这是我在将本地 Git 存储库推送到新远程(包括所有分支和标签)时解决的 [远程拒绝]

git clone --mirror old-repo

cd <名称-repo.git>

git 远程添加新的新仓库

git push new --mirror


A
Andrew Fox

每次我谷歌如何做到这一点时,我最终都会阅读相同的主题,但它并没有让我到达我需要的地方,所以希望这对我未来的自己和他人也有帮助。

我开始了一个新的本地项目,我想将它推送到我的仓库(BitBucket)。这是我所做的:

导航到我的本地项目根启动: git init 添加所有文件: git add 。提交方式: git commit -m "Initial commit" 转到我的仓库 (BitBucket) 创建新仓库:new_project 回到我的本地项目 添加远程: git remote add origin git@bitbucket.org:AndrewFox/new_project.git push提交: git push origin master -f

-f 标志是强制推送,否则会识别出两个 repo 不同而失败。


这不是最初的问题所要问的。这也确实不安全。您是在告诉人们丢弃旧的提交。除非您真的知道自己在做什么,否则您实际上应该基本上永远不要使用“强制”选项。
@CameronTacklind 这是一个新项目,所以没有提交。
最初的问题是询问如何将现有项目上传到“新远程”并包含所有分支和标签。 “新遥控器”是空的,因此不需要力量。同样,除非你真的知道自己在做什么,否则你基本上不应该用力推动。向其他用户建议这一点,尤其是在没有适当警告的情况下,尤其是在不需要它的情况下,会伤害到某人。
有道理。我从 BitBucket 网站获得了这些说明并决定分享。请编辑我的答案以包括您的警告和潜在问题,因为我不像您那样熟悉它。感谢您引起我的注意👍🏼
P
Pratik

运行以下命令将现有存储库移动到具有所有分支和标签的新远程:

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