2011-02-01 33 views
32

Tôi có hai kho lưu trữ git trên các máy tính khác nhau. Tôi có một số chi nhánh địa phương trên mỗi một trong số họ. Tôi không muốn gửi chi nhánh này đến máy chủ từ xa, chỉ cần giữ chúng ở địa phương. Làm thế nào tôi có thể đồng bộ hóa sau đó mà không cần sử dụng một trang web? Tôi có thể nén kho lưu trữ trên một máy tính và chuyển sang một máy tính khác không? Có an toàn không? Có lẽ tôi có thể xuất các thay đổi mới nhất bằng cách nào đó từ mọi chi nhánh?Cách đồng bộ hóa hai kho lưu trữ git

+1

Sự khác biệt duy nhất giữa kho lưu trữ git trên "máy chủ" (nếu có sự khác biệt) là repo trên máy chủ có thể là trống. Hãy nghĩ về máy tính khác chính xác theo cách bạn nghĩ về máy chủ. –

Trả lời

24

Thay vì thực hiện một bản sao trần , Tôi thích tạo một bundle (xem "How can I email someone a git repository?"), tạo ra một tập tin, dễ dàng hơn để sao chép xung quanh (trên một thanh USB chẳng hạn)

Tiền thưởng là có một số đặc điểm của một repo trần: bạn có thể kéo từ nó hoặc sao chép nó.
Nhưng chỉ phải lo lắng về một tệp.

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

này sẽ xác định một từ xa gọi là "origin" trong kho lưu trữ kết quả cho phép bạn lấy và kéo từ bó. Các tập tin $GIT_DIR/config trong R2 sẽ có một entry như thế này:

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

Để cập nhật kho mine.git kết quả, bạn có thể lấy hoặc kéo sau khi thay thế bó bảo quản ở /home/me/tmp/file.bundle với bản cập nhật gia tăng.

Sau khi làm việc một số chi tiết trong kho ban đầu, bạn có thể tạo một gói gia tăng để cập nhật các kho khác:

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

Sau đó bạn chuyển bó vào máy khác để thay thế /home/me/tmp/file.bundle, và kéo nó ra.

machineB$ cd R2 
machineB$ git pull 
+1

@Cacovsky: cảm ơn bạn đã chỉnh sửa và liên kết cố định. – VonC

22

Xem this blog post "Synchronizing Git repositories without a server " (theo Victor Costan).

bài này mô tả một phương pháp để đẩy những thay đổi giữa hai kho mà không sử dụng một máy chủ với các kết nối mạng cho cả hai host có kho

Khởi động bằng cách tạo ra một kho lưu trữ trên thẻ nhớ USB.

Sau đó, đăng ký kho lưu trữ trên thanh USB làm kho lưu trữ từ xa và đẩy chi nhánh mong muốn vào nó (nếu bạn không muốn đẩy chính, thay thế nhánh bạn muốn).

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

Trong tương lai, bạn có thể xử lý kho lưu trữ USB như bất kỳ kho lưu trữ từ xa nào khác. Chỉ cần chắc chắn rằng nó được gắn kết :) Ví dụ, sau đây đẩy những thay đổi mới vào kho lưu trữ USB.

git push usb 

Trên cuối tiếp nhận, gắn kết thanh USB, và sử dụng một URL tập tin cho kho

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

Một vài lệnh tiện dụng:

# 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 
+1

Không bao giờ dựa hoàn toàn * vào liên kết bên ngoài: bạn không biết nó sẽ kéo dài bao lâu. Với http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/, thông tin đó sẽ có sẵn mãi mãi. – VonC

+0

Ah, cảm ơn vì điều đó. Tôi sẽ dọn dẹp văn bản. – misha

+0

sẽ đầu tiên "git clone --local" tốt hơn là "git clone --no-hardlinks" để làm cho nó rõ ràng rõ ràng rằng nó cần phải là một bản sao sâu? –

5

bản sao trực tiếp của một kho lưu trữ cho hệ thống tập tin khác là một thay thế cho trần clone hoặc bó. Sau khi sao chép, bạn có thể thiết lập repo được sao chép trực tiếp như một điều khiển từ xa cục bộ - không trực quan như điều khiển từ xa cục bộ - để tìm nạp và hợp nhất vào kho lưu trữ đầu tiên.

I.e. sáp nhập repo2 từ một máy tính thứ hai vào ~/repo1, sao chép repo2 đầu tiên với hệ thống tập tin repo1 tại ~/repo2 (thẻ nhớ, copy mạng, vv) và sau đó bạn có thể sử dụng câu trả lời cho Git pulling changes between two local repositories:

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

Điều này hoạt động vì như the wikipedia article on git nói: "Kho lưu trữ Git - dữ liệu và siêu dữ liệu - hoàn toàn nằm trong thư mục của nó, vì vậy một bản sao mức hệ thống bình thường (hoặc đổi tên hoặc xóa) của toàn bộ kho Git là một hoạt động an toàn. bản sao là cả độc lập và không biết bản gốc. "

+0

có ai có nhiều kiến ​​thức hơn tôi xác nhận điều này không? @sage nếu tôi chỉ muốn sao lưu thư mục của tôi (trong đó có chứa .git của tôi) bằng cách sao chép-dán vào một thanh USB, điều đó sẽ không đủ? –

+2

@nutty - Sao chép trực tiếp không hoạt động tốt để chuyển repo ở trạng thái chính xác của nó và tôi thường làm điều đó. Tuy nhiên, đối với một số trường hợp sử dụng, tôi thấy thích hợp hơn để có thể kéo/hợp nhất từ ​​vị trí đĩa này sang vị trí đĩa khác (ví dụ: khi tôi đã chỉnh sửa cả vị trí repo và tôi muốn đồng bộ hóa chúng). Git là thú vị chứa trong vấn đề này. :-) – sage

0

Tôi chỉ muốn thêm chút vặn vẹo vào mọi thứ. Thông tin trong các bài đăng khác có vẻ đúng, nhưng tôi muốn đề cập đến một vài điều bổ sung mà tôi làm trong thực tế.

Nếu tôi làm

git remote -v 

tôi nhận được thông tin như thế này

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) 

Về cơ bản tôi đã xác định nhiều điều khiển từ xa với những cái tên USB thay vì chỉ một như đề xuất kể từ khi ký tự ổ đĩa được phân bổ cho thiết bị USB của tôi thay đổi tùy thuộc vào cổng tôi chèn nó vào.

sau đó tôi chạy một kịch bản có nội dung như thế này

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 

Mục đích là để thúc đẩy các ngành và tất cả các thẻ vào kho USB nếu nó tồn tại và ở đâu bao giờ nó được. (Cờ -d đang kiểm tra sự tồn tại của thư mục kho chứa git và mã điều kiện chỉ thực hiện nếu thư mục tồn tại.)

Câu hỏi ban đầu cho biết: Tôi có một số chi nhánh địa phương trên mỗi một trong số chúng. Tôi không muốn gửi chi nhánh này đến máy chủ từ xa, chỉ cần giữ chúng ở địa phương. Làm thế nào tôi có thể đồng bộ hóa ...

Các đẩy -allđẩy --tags lệnh làm đồng bộ hóa này, đảm bảo rằng tất cả các chi nhánh và các thẻ được đẩy lên kho lưu trữ USB, thậm chí những cái mới mà kho lưu trữ USB không biết. Không có mặc định để làm chủ hoặc cần phải biết tên của các chi nhánh và xử lý từng cái một.

Tôi chạy mục này cho mục đích sao lưu, vì vậy tôi chỉ hiển thị mặt đẩy của mọi thứ và giảm số lượng dự án và kho lưu trữ.Trong thực tế tôi sao lưu nhiều dự án đến nhiều địa điểm, nhưng nó chỉ là các mục USB lặp đi lặp lại có liên quan ở đây.

Một điều đó là khá rõ ràng nhưng mà tôi chưa thấy đề cập, đó là để đồng bộ hóa PC A và PC B, bạn sẽ cần phải

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! 

Hoặc xem cách khác nhau, đi

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

để cuối cùng các nhánh và thẻ giống nhau trên hai máy.

Các vấn đề liên quan