How to synchronize two git repositories

雨燕双飞 提交于 2019-12-17 07:07:27

问题


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?


回答1:


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

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 one file.

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/config file in R2 will have an entry like this:

[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.bundle with incremental updates.

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

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.

machineB$ cd R2
machineB$ git pull



回答2:


See this blog post "Synchronizing Git repositories without a server " (by 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.

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).

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.

git push usb

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

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



回答3:


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.

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:

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

This works because as the wikipedia article on git says: "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."




回答4:


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.

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.)

The original question said: 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 ...

The push -all and push --tags command 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.

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.

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

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.



来源:https://stackoverflow.com/questions/4860166/how-to-synchronize-two-git-repositories

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!