Làm cách nào để bạn tổ chức nhiều kho lưu trữ git, để tất cả chúng được sao lưu cùng nhau?


98

Với SVN, tôi có một kho lưu trữ lớn duy nhất mà tôi lưu giữ trên một máy chủ và đăng xuất trên một vài máy. Đây là một hệ thống sao lưu khá tốt và cho phép tôi dễ dàng làm việc trên bất kỳ máy nào. Tôi có thể kiểm tra một dự án cụ thể, cam kết và nó đã cập nhật dự án 'chính' hoặc tôi có thể kiểm tra toàn bộ.

Bây giờ, tôi có một loạt các kho lưu trữ git, cho các dự án khác nhau, một số trong số đó có trên github. Tôi cũng có kho lưu trữ SVN mà tôi đã đề cập, được nhập qua lệnh git-svn ..

Về cơ bản, tôi thích có tất cả mã của mình (không chỉ các dự án mà còn các đoạn mã và đoạn mã ngẫu nhiên, một số thứ như CV của tôi, các bài báo tôi đã viết, các trang web tôi đã thực hiện, v.v.) trong một kho lưu trữ lớn mà tôi có thể dễ dàng sao chép vào điều khiển từ xa máy hoặc thẻ nhớ / ổ cứng làm bản sao lưu.

Vấn đề là, vì nó là một kho lưu trữ riêng và git không cho phép kiểm tra ra khỏi một thư mục cụ thể (mà tôi có thể đẩy lên github như một dự án riêng biệt, nhưng các thay đổi xuất hiện trong cả kho chính và kho phụ repo)

Tôi có thể sử dụng hệ thống mô-đun con git, nhưng nó không hoạt động theo cách tôi muốn (mô-đun con là con trỏ đến các kho lưu trữ khác và không thực sự chứa mã thực, vì vậy nó vô dụng để sao lưu)

Hiện tại, tôi có một thư mục git-repos (ví dụ: ~ / code_projects / proj1 / .git / ~ / code_projects / proj2 / .git /) và sau khi thực hiện các thay đổi đối với proj1 git push github, tôi sao chép các tệp vào ~ / Tài liệu / mã / python / dự án / proj1 / và thực hiện một lần cam kết duy nhất (thay vì nhiều cái trong kho riêng lẻ). Sau đó, làm git push backupdrive1, git push mymemorystickv.v.

Vì vậy, câu hỏi: Làm thế nào để mã cá nhân và các dự án của bạn với kho lưu trữ git, đồng thời giữ chúng được đồng bộ hóa và sao lưu?

Câu trả lời:


74

Tôi sẽ mạnh mẽ khuyên chống lại việc đưa dữ liệu không liên quan trong một kho lưu trữ Git nhất định. Chi phí tạo kho lưu trữ mới khá thấp, và đó là một tính năng giúp giữ các dòng họ khác nhau hoàn toàn tách biệt.

Chống lại ý tưởng đó có nghĩa là kết thúc với một lịch sử rối rắm không cần thiết, điều này khiến việc quản lý trở nên khó khăn hơn và - quan trọng hơn - các công cụ "khảo cổ học" ít hữu ích hơn vì kết quả là loãng. Ngoài ra, như bạn đã đề cập, Git giả định rằng "đơn vị nhân bản" là kho lưu trữ và thực tế phải làm như vậy vì bản chất phân tán của nó.

Một giải pháp là giữ mọi dự án / gói / v.v. dưới dạng kho lưu trữ trống của riêng nó (tức là không có cây làm việc) theo phân cấp phù hợp, như:

/repos/a.git
/repos/b.git
/repos/c.git

Sau khi một vài quy ước đã được thiết lập, việc áp dụng các thao tác quản trị (sao lưu, đóng gói, xuất bản web) cho hệ thống phân cấp hoàn chỉnh, đóng vai trò không hoàn toàn khác với các kho lưu trữ SVN "nguyên khối". Làm việc với các kho lưu trữ này cũng trở nên tương tự như quy trình làm việc SVN, với việc bổ sung rằng người ta có thể sử dụng các cam kết cục bộ và các nhánh:

svn checkout   --> git clone
svn update     --> git pull
svn commit     --> git push

Bạn có thể có nhiều điều khiển từ xa trong mỗi bản sao đang hoạt động, để dễ dàng đồng bộ hóa giữa nhiều bên:

$ cd ~/dev
$ git clone /repos/foo.git       # or the one from github, ...
$ cd foo
$ git remote add github ...
$ git remote add memorystick ...

Sau đó, bạn có thể tìm nạp / kéo từ từng "nguồn", làm việc và cam kết cục bộ, sau đó đẩy ("sao lưu") đến từng điều khiển từ xa này khi bạn đã sẵn sàng với một cái gì đó như (lưu ý cách đẩy các cam kết và lịch sử giống nhau đến mỗi điều khiển từ xa!):

$ for remote in origin github memorystick; do git push $remote; done

Cách dễ nhất để biến một kho lưu trữ đang hoạt động hiện có ~/dev/foo thành một kho lưu trữ trống như vậy có lẽ là:

$ cd ~/dev
$ git clone --bare foo /repos/foo.git
$ mv foo foo.old
$ git clone /repos/foo.git

mà hầu hết tương đương với - svn importnhưng không loại bỏ lịch sử "địa phương" hiện có.

Lưu ý: mô-đun con là một cơ chế bao gồm các dòng họ có liên quan được chia sẻ , vì vậy tôi thực sự sẽ không coi chúng là một công cụ thích hợp cho vấn đề bạn đang cố gắng giải quyết.


18
Thực tế là tôi tiếp tục kết thúc với rất nhiều kho lưu trữ riêng biệt và viết các tập lệnh đơn giản để giúp quản lý tất cả chúng khiến tôi cảm thấy rằng có điều gì đó còn thiếu trong git. Tôi chỉ không thể quyết định chính xác nó là gì hoặc phải làm gì với nó.
DonGar

Chà, bạn cũng quản lý nhiều dự án riêng biệt chứ? Mối quan hệ 1-1 giữa các dự án và kho lưu trữ cảm thấy hợp lý trong một thế giới phân tán, nhưng tôi vẫn sắp xếp các kho lưu trữ trống trong một cây thư mục chung để dễ dàng sao lưu và quản trị. (Nói cách khác, Git / Hg / Bzr buộc bạn phải tách biệt quản trị khỏi các nhiệm vụ của dự án, trong khi hầu hết các quy trình làm việc của SVN kết hợp cả hai; hiện nay thường thấy mọi người ủy thác phần quản trị cho GitHub hoặc các nhà cung cấp khác.)
Damien Diederen

2
ý tưởng này chỉ có ý nghĩa nếu bạn lưu trữ các dự án của riêng mình và / hoặc tất cả chúng đều là mã nguồn mở. Nếu không, bạn sẽ cần trên github bạn sẽ cần các dự án tin không giới hạn mà có thể nhận tốn kém
dkinzer

2
Thay vì "for remote in origin github memorystick; do git push $ remote; done", người ta cũng có thể định cấu hình một điều khiển từ xa đặc biệt để đẩy bằng một lệnh duy nhất tới nhiều điều khiển từ xa: stackoverflow.com/questions/36862/… . (Có thể thuận tiện hơn trong một số trường hợp.)
imz - Ivan Zakharyaschev

2
Tôi nghĩ điều còn thiếu là một cách mà git có thể giữ các đối tượng của nó tách biệt theo cây con để một "kho lưu trữ" duy nhất có thể bao gồm các đơn vị được đồng bộ hóa riêng biệt mặc dù có thể phân tách (được tải xuống riêng lẻ mà không có phần còn lại) theo cách mà mọi người có thể làm việc trên tập hợp con mà không biết về phần còn lại của nó.
peterk

28

Tôi muốn thêm vào câu trả lời của Damien khi anh ấy đề xuất:

$ for remote in origin github memorystick; do git push $remote; done

Bạn có thể thiết lập một điều khiển từ xa đặc biệt để đẩy đến tất cả các điều khiển từ xa thực riêng lẻ bằng 1 lệnh; Tôi tìm thấy nó tại http://marc.info/?l=git&m=116231242118202&w=2 :

Vì vậy, đối với "git push" (đẩy các nhánh giống nhau nhiều lần), bạn thực sự có thể làm những gì tôi làm:

  • .git / config chứa:

    [remote "all"]
    url = master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
    url = login.osdl.org:linux-2.6.git
    
  • và bây giờ git push all mastersẽ đẩy nhánh "chính" đến cả hai
    kho lưu trữ từ xa đó.

Bạn cũng có thể tiết kiệm việc nhập URL hai lần bằng cách sử dụng contruction:

[url "<actual url base>"]
    insteadOf = <other url base>

3

Tôi cũng tò mò về các cách được đề xuất để xử lý điều này và sẽ mô tả thiết lập hiện tại mà tôi sử dụng (với SVN). Về cơ bản tôi đã tạo một kho lưu trữ chứa hệ thống phân cấp hệ thống tệp nhỏ bao gồm các dirs bin và lib của riêng nó. Có tập lệnh trong gốc của cây này sẽ thiết lập môi trường của bạn để thêm các bin, lib, v.v. này vào các biến môi trường thích hợp. Vì vậy, thư mục gốc về cơ bản trông giống như:

./bin/            # prepended to $PATH
./lib/            # prepended to $LD_LIBRARY_PATH
./lib/python/     # prepended to $PYTHONPATH
./setup_env.bash  # sets up the environment

Bây giờ bên trong / bin và / lib có nhiều dự án và thư viện tương ứng của chúng. Tôi biết đây không phải là một dự án tiêu chuẩn, nhưng người khác trong nhóm của tôi rất dễ dàng kiểm tra repo, chạy tập lệnh 'setup_env.bash' và có các phiên bản cập nhật nhất của tất cả các dự án cục bộ trong Thủ tục thanh toán. Họ không phải lo lắng về việc cài đặt / cập nhật / usr / bin hoặc / usr / lib và nó giúp đơn giản hóa việc có nhiều lần kiểm tra và môi trường bản địa hóa cho mỗi lần kiểm tra. Ai đó cũng có thể chỉ cần rm toàn bộ kho lưu trữ và không phải lo lắng về việc gỡ cài đặt bất kỳ chương trình nào.

Điều này đang hoạt động tốt đối với chúng tôi và tôi không chắc liệu chúng tôi có thay đổi nó hay không. Vấn đề với điều này là có rất nhiều dự án trong một kho lưu trữ lớn này. Có cách chuẩn git / Hg / bzr để tạo ra một môi trường như thế này và chia nhỏ các dự án thành các kho lưu trữ của riêng chúng không?


3

, Tôi chưa thử lồng các kho lưu trữ git vì tôi chưa gặp phải tình huống cần thiết. Như tôi đã đọc trên kênh #git, git dường như bị nhầm lẫn khi lồng các kho lưu trữ, tức là bạn đang cố gắng git-init bên trong kho lưu trữ git. Cách duy nhất để quản lý cấu trúc git lồng nhau là sử dụng git-submodulehoặc repotiện ích của Android .

Đối với trách nhiệm sao lưu mà bạn đang mô tả, tôi nói là ủy thác nó ... Đối với tôi, tôi thường đặt kho lưu trữ "nguồn gốc" cho mỗi dự án tại một ổ đĩa mạng tại nơi làm việc được sao lưu thường xuyên bởi các công nghệ CNTT bằng chiến lược sao lưu của họ sự lựa chọn. Nó đơn giản và tôi không phải lo lắng về nó. ;)


2

Điều gì về việc sử dụng mr để quản lý nhiều kho Git của bạn cùng một lúc:

Lệnh mr (1) có thể kiểm tra, cập nhật hoặc thực hiện các hành động khác trên một tập hợp các kho lưu trữ như thể chúng là một kho lưu trữ kết hợp. Nó hỗ trợ bất kỳ sự kết hợp nào của subversion, git, cvs, bleurial, bzr, darcs, cvs, vcsh, kho lưu trữ hóa thạch và xác thực, đồng thời có thể dễ dàng thêm hỗ trợ cho các hệ thống kiểm soát sửa đổi khác. [...]

Nó rất có thể cấu hình thông qua kịch bản shell đơn giản. Một số ví dụ về những điều nó có thể làm bao gồm:

[...]

  • Khi cập nhật kho lưu trữ git, hãy kéo từ hai luồng ngược dòng khác nhau và hợp nhất cả hai lại với nhau.
  • Chạy nhiều bản cập nhật kho lưu trữ song song, giúp tăng tốc đáng kể quá trình cập nhật.
  • Hãy nhớ các thao tác không thành công do máy tính xách tay đang ngoại tuyến, để có thể thử lại khi máy tính xách tay trực tuyến trở lại.

1

Có một phương pháp khác để có các kho git lồng nhau, nhưng nó không giải quyết được vấn đề bạn đang gặp phải. Tuy nhiên, đối với những người khác đang tìm kiếm giải pháp, tôi đã:

Trong repo git cấp cao nhất chỉ cần ẩn thư mục trong .gitignore chứa repo git lồng nhau. Điều này giúp bạn dễ dàng có hai repo git riêng biệt (nhưng lồng vào nhau!).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.