git 如何同步两个git存储库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4860166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:00:09  来源:igfitidea点击:

How to synchronize two git repositories

gitoffline-mode

提问by szaman

I have two git repositories on different PCs. I have some local branches on every one of them. I don`t want to send this branches to remote server, just keep them local. How can I synchronize then without using a web? Can I just zip repository on one PC and move to another? Is that safe? Maybe I can export somehow newest changes from every branch?

我在不同的 PC 上有两个 git 存储库。我在每个地方都有一些当地分支机构。我不想将此分支发送到远程服务器,只需将它们保留在本地即可。那么如何在不使用网络的情况下进行同步?我可以在一台 PC 上压缩存储库并移动到另一台吗?那安全吗?也许我可以从每个分支以某种方式导出最新的更改?

采纳答案by VonC

Rather than making a bare clone, I prefer making a bundle(see "How can I email someone a git repository?"), which generates onefile, easier to copy around (on an USB stick for instance)

与其制作裸克隆,我更喜欢制作一个(参见“我如何通过电子邮件向某人发送 git 存储库?”),它会生成一个文件,更容易复制(例如在 USB 记忆棒上)

The bonus is that is does have some of the characteristics of a bare repo: you can pull from it or clone it.
But only have to worry about onefile.

好处是它确实具有裸存储库的一些特征:您可以从中提取或克隆它。
但是只需要担心一个文件。

machineB$ git clone /home/me/tmp/file.bundle R2

This will define a remote called "origin" in the resulting repository that lets you fetch and pull from the bundle. The $GIT_DIR/configfile in R2will have an entry like this:

这将origin在生成的存储库中定义一个名为“ ”的远程,它允许您从包中获取和拉取。中的$GIT_DIR/config文件R2将具有如下条目:

[remote "origin"]
    url = /home/me/tmp/file.bundle
    fetch = refs/heads/*:refs/remotes/origin/*

To update the resulting mine.git repository, you can fetch or pull after replacing the bundle stored at /home/me/tmp/file.bundlewith incremental updates.

After working some more in the original repository, you can create an incremental bundle to update the other repository:

要更新生成的 mine.git 存储库,您可以在/home/me/tmp/file.bundle使用增量更新替换存储在的包后获取或拉取。

在原始存储库中进行更多工作后,您可以创建一个增量包来更新另一个存储库:

machineA$ cd R1
machineA$ git bundle create file.bundle lastR2bundle..master
machineA$ git tag -f lastR2bundle master

You then transfer the bundle to the other machine to replace /home/me/tmp/file.bundle, and pull from it.

然后,您将捆绑包转移到另一台机器上以替换/home/me/tmp/file.bundle,并从中拉出。

machineB$ cd R2
machineB$ git pull

回答by mpenkov

See this blog post "Synchronizing Git repositories without a server "(by Victor Costan).

请参阅这篇博文“在没有服务器的情况下同步 Git 存储库”(作者Victor Costan)。

This post describes a method for pushing changes between two repositories without using a server with network connections to both hosts having repositories

这篇文章描述了一种在两个存储库之间推送更改的方法,而无需使用与具有存储库的两个主机的网络连接的服务器

Start up by creating a repository on the USB stick.

通过在 U 盘上创建存储库来启动。

mkdir /path/to/usb/stick/repository.git
git clone --local --bare . /path/to/usb/stick/repository.git

Then register the repository on the USB stick as a remote repository, and push the desired branch to it (if you don't want to push master, substitute your desired branch).

然后将 U 盘上的存储库注册为远程存储库,并将所需的分支推送到它(如果您不想推送 master,请替换您所需的分支)。

git remote add usb file:///path/to/usb/stick/repository.git
git push usb master

In the future, you can treat the USB repository as any other remote repository. Just make sure it's mounted :) For instance, the following pushes new changes to the USB repository.

将来,您可以将 USB 存储库视为任何其他远程存储库。只需确保它已安装:) 例如,以下将新更改推送到 USB 存储库。

git push usb

On the receiving end, mount the USB stick, and use a file URL for the repository

在接收端,挂载 U 盘,并使用存储库的文件 URL

file:///path/to/usb/stick/repository.git

A few handy commands:

一些方便的命令:

# cloning the repository on the USB stick
git clone file:///path/to/usb/stick/repository.git
# updating a repository cloned from the USB stick using the above command
git pull origin
# adding the USB stick repository as a remote for an existing repository
git remote add usb file:///path/to/usb/stick/repository.git
# updating from a remote repository configured using the above command
git pull usb master

回答by sage

Direct copy of a repository to the other file system is an alternative to bare clone or to bundle. After copying you can set the copied repo up directly as a local remote - unintuitive as local remote may seem - to fetch and merge into the first repository.

将存储库直接复制到其他文件系统是裸克隆或捆绑的替代方法。复制后,您可以将复制的 repo 直接设置为本地远程 - 本地远程可能看起来不直观 - 以获取并合并到第一个存储库中。

I.e. to merge repo2 from a second computer into ~/repo1, first copy repo2 to the repo1 file system at ~/repo2 (memory stick, network copy, etc.) and then you can use the answer to Git pulling changes between two local repositories:

即将第二台计算机上的 repo2 合并到 ~/repo1 中,首先将 repo2 复制到 ~/repo2 处的 repo1 文件系统(记忆棒、网络副本等),然后您可以使用Git 在两个本地存储库之间拉取更改的答案:

~/repo1 $ git remote add repo2 ~/repo2
~/repo1 $ git fetch repo2
~/repo1 $ git merge repo2/foo

This works because as the wikipedia article on gitsays: "A Git repository — data and metadata — is completely contained within its directory, so a normal system-level copy (or rename, or delete) of an entire Git repository is a safe operation. The resulting copy is both independent of and unaware of the original."

是可行的,因为正如维基百科上关于 git 的文章所说:“Git 存储库——数据和元数据——完全包含在其目录中,因此整个 Git 存储库的正常系统级副本(或重命名或删除)是安全的操作. 生成的副本既独立于原件,也不知道原件。”

回答by Ivan

I'd just like to add a little twist to things. The information in other posts seems right, but I'd like to mention a few extra things I do in practice.

我只是想给事情添加一点点扭曲。其他帖子中的信息似乎是正确的,但我想提一下我在实践中做的一些额外的事情。

If I do

如果我做

git remote -v

I get information like this

我得到这样的信息

USB_F   file:///f/Git_repositories/projectname.git (fetch)
USB_F   file:///f/Git_repositories/projectname.git (push)
USB_G   file:///g/Git_repositories/projectname.git (fetch)
USB_G   file:///g/Git_repositories/projectname.git (push)

Basically I have defined several remotes with USB names rather than just one as suggested since the drive letter allocated to my USB device changes depending on the port I insert it into.

基本上我已经定义了几个带有 USB 名称的遥控器,而不仅仅是一个建议的,因为分配给我的 USB 设备的驱动器号会根据我插入的端口而变化。

I then run a script with contents like this

然后我运行一个包含这样内容的脚本

cd /path/to/projectname

if [ -d /f/Git_repositories/projectname.git ] 
then
    git push USB_F --all
    git push USB_F --tags
fi
if [ -d /g/Git_repositories/projectname.git ] 
then
    git push USB_G --all
    git push USB_G --tags
fi

The intention is to push all branches and all tags to the USB repository if it exists and where ever it is. (The -d flag is checking for existence of the git repository directory and conditional code only executes if the directory exists.)

目的是将所有分支和所有标签推送到 USB 存储库(如果存在)以及它在哪里。( -d 标志正在检查 git 存储库目录是否存在,并且条件代码仅在目录存在时才执行。)

The original question said: I have some local brancheson every one of them. I don`t want to send this branches to remote server, just keep them local. How can I synchronize...

最初的问题是:在每个地方都有一些当地分支机构。我不想将此分支发送到远程服务器,只需将它们保留在本地即可。怎么同步...

The push -alland push --tagscommand do this synchronizing, making sure that all the branches and tags are pushed to the USB repository, even new ones that the USB repository was unaware of. There is no defaulting to master or needing to know the names of branches and handling them one by one.

推-all推--tags命令来执行此同步,确保所有的分支和标签都推到USB存储库,甚至新的USB存储库并不知情。没有默认master或者需要知道分支的名称并一一处理它们。

I run this for backup purposes so I've only shown the push side of things, and reduced the number of projects and repositories. In reality I backup multiple projects to multiple locations, but it's only the repeated USB items that are relevant here.

我运行它是为了备份目的,所以我只展示了事情的推动方面,并减少了项目和存储库的数量。实际上,我将多个项目备份到多个位置,但只有重复的 USB 项目与此处相关。

Another thing that is rather obvious but that I have not seen mentioned, is that in order to sync PC A and PC B, you'd need to

另一件相当明显但我没有看到提到的事情是,为了同步 PC A 和 PC B,您需要

1. sync PC A and the USB device
2. sync PC B and the USB device
3. sync PC A and the USB device again!

Or viewed differently, go

或者换个角度看,去

PC A -> USB -> PC B
PC B -> USB -> PC A

so that ultimately the branches and tags are the same on the two machines.

这样最终分支和标签在两台机器上是相同的。