如何同步两个远程Git存储库?

如何同步两个远程Git存储库?,git,version-control,github,dvcs,Git,Version Control,Github,Dvcs,我有两个存储库URL,我想同步它们,以便它们都包含相同的内容。在Mercurial中,我想做的是: hg pull {repo1} hg pull {repo2} hg push -f {repo1} hg push -f {repo2} 这将导致两个回购协议中都有两个标头(我知道有两个标头并不常见,但我这样做是为了同步,需要非交互式。标头将从其中一个回购协议中手动合并,然后再次运行同步) 我想用Git做同样的事情。例如,在没有用户交互的情况下,将所有变更都纳入两个回购协议中,多个分支机构/负

我有两个存储库URL,我想同步它们,以便它们都包含相同的内容。在Mercurial中,我想做的是:

hg pull {repo1}
hg pull {repo2}
hg push -f {repo1}
hg push -f {repo2}
这将导致两个回购协议中都有两个标头(我知道有两个标头并不常见,但我这样做是为了同步,需要非交互式。标头将从其中一个回购协议中手动合并,然后再次运行同步)

我想用Git做同样的事情。例如,在没有用户交互的情况下,将所有变更都纳入两个回购协议中,多个分支机构/负责人/任何稍后要合并的内容。 我正试图在命令中使用URL来实现这一点,而不是添加远程(?),因为可能会涉及到许多repo,而为它们都添加别名只会使我的脚本更加复杂

我目前正在使用
gitclone--bar{repo1}
克隆repo,但是我正在努力“更新”它。我尝试了
getfetch{repo1}
,但这似乎并没有降低我的更改
git日志
仍然不显示repo1中添加的变更集

我还尝试在我的
推送
克隆
中使用
--mirror
,但这似乎是从本地不存在的repo2远程更改集,而我需要保留来自这两个repo的更改:/

最好的方法是什么

编辑:以便更清楚地了解我要做的事情

我有两个存储库(例如BitBucket和GitHub),希望人们能够推到其中一个(最终,一个是Git,一个是Mercurial,但现在让我们假设它们都是Git,以简化事情)。我需要能够运行一个脚本,该脚本将“同步”两个回购协议,使它们都包含两组更改,并且以后可能需要手动合并

最终,这意味着我可以与其中一个回购协议(例如Mercurial协议)进行交互,我的脚本将定期引入Git更改,我可以将其合并,然后它们将被推回


在Mercurial中,这是微不足道的!我只需从两个回购中拉出,然后用
-f/--force
推动,以允许推动多个头部。然后,任何人都可以克隆一个回购协议,合并头,然后推回。我想知道如何在Git中做最相似的事情。它必须是100%非交互式的,并且必须使两个repo都处于一种过程可以无限重复的状态(这意味着没有重写历史/更改变更集等)。

当您使用
git clone--mirror--bare
时,您可能没有看到提取实际上起作用,因为默认情况下,git没有列出它的远程分支。您可以使用
git branch-a
列出它们

我还没有为未命名的遥控器制定出语法,但是您可以根据url中的某些方案自动添加遥控器。。。在任何情况下,如果你为每一次回购选择一个唯一且一致的名称,可能效果最好,这样你就可以知道从哪里来的变化

但是,您可以尝试以下方法:

git clone --bare --mirror --origin thing1 {repo1} repo.git
cd repo.git
git fetch thing2 --mirror
git push thing1 --mirror
git push thing2 --mirror
完成此操作后,thing1将使thing2的所有分支随时可以合并为远程分支。您可以使用
git branch-a
列出远程分支

在github或bitbucket上,您将无法通过web界面看到这些远程分支,但是如果使用--mirror进行克隆,您可以看到它们,因此它们确实存在。

git fetch
之后尝试
git reset--hard HEAD
。然而,我不确定我是否完全理解你的目标。在运行fetch、reset和push命令之前,您需要将
cd
放入单独的存储库目录。

Git分支没有Mercurial意义上的“头”。只有一个东西叫做
HEAD
,它实际上是您当前签出的提交的一个符号链接。对于像GitHub这样的托管存储库,没有签出提交,只有存储库历史本身。(称为“裸”回购。)

造成这种差异的原因是Git分支名称完全是任意的;它们不必在存储库的副本之间进行匹配,您可以随心所欲地创建和销毁它们。[1]Git分支就像Python变量名一样,可以随意移动和粘贴任何值;Mercurial分支类似于C变量,它指的是固定的预分配内存位置,然后用数据填充

因此,当您使用Mercurial时,同一个分支有两个历史记录,因为分支名称在两个存储库中都是固定的有意义的东西。每个历史的叶子都是一个“头”,你通常会合并它们来创建一个头

但在Git中,获取远程分支实际上根本不会影响您的分支。如果从
origin
获取
master
分支,它只会进入一个名为
origin/master
的分支[2]
git pull origin master
只需两个步骤:将远程分支获取到
origin/master
,然后将另一个分支合并到当前分支中。但他们不必有相同的名字;您的分支可以称为
development
trunk
或其他任何名称。您可以将任何其他分支拉入或合并到其中,也可以将其推送到任何其他分支。吉特不在乎

这让我回到您的问题上来:您不能将“第二个”分支头推送到远程Git存储库,因为这个概念不存在。您可以推送到名称已损坏的分支(
bitbucket\u master
?),但据我所知,您无法远程更新远程设备的远程设备

不过,我认为你的计划没有多大意义,因为如果未合并的分支同时暴露在两个存储库中,你要么将它们都合并,要么将其中一个合并,然后在另一个之上镜像它。。。在这种情况下,您无缘无故地让第二个存储库处于无用状态

有什么理由你不能j
git pull origin master
git pull gitlab master
git push origin master
git push gitlab master
#!/bin/bash

# REPO_NAME=<repo>.git
# ORIGIN_URL=git@<host>:<project>/$REPO_NAME
# REPO1_URL=git@<host>:<project>/$REPO_NAME

rm -rf $REPO_NAME
git clone --bare $ORIGIN_URL
cd $REPO_NAME
git remote add --mirror=fetch repo1 $REPO1_URL
git fetch origin --tags ; git fetch repo1 --tags
git push origin --all ; git push origin --tags
git push repo1 --all ; git push repo1 --tags