Hai kho git trong một thư mục?


86

Có thể có 2 kho lưu trữ git trong một thư mục không? Tôi nghĩ là không, nhưng nghĩ rằng tôi sẽ hỏi. Về cơ bản, tôi muốn kiểm tra các tệp cấu hình thư mục chính của mình (ví dụ: .emacs), tệp này sẽ phổ biến trên tất cả các máy tôi làm việc, nhưng có một kho lưu trữ thứ hai cho các tệp cục bộ (ví dụ: .emacs.local), chứa cấu hình máy cụ thể. Cách duy nhất tôi có thể nghĩ ra để làm điều đó là có cấu hình cục bộ trong một thư mục con và bỏ qua thư mục con đó khỏi kho lưu trữ git chính. Bất kỳ ý tưởng khác?


git subtreesẽ hoàn thành công việc.
Syd Pao

Nếu bạn không xử lý quá nhiều tệp, bạn cũng có thể tạo các liên kết / liên kết biểu tượng.
thdoan

Câu trả lời:


37

Nếu tôi hiểu bạn đang làm gì, bạn có thể xử lý tất cả trong một kho lưu trữ, sử dụng các nhánh riêng biệt cho từng máy và một nhánh chứa các tệp cấu hình thư mục chính chung của bạn.

Khởi tạo repo và cam kết các tệp chung cho nó, có thể đổi tên nhánh MASTER thành Common. Sau đó, tạo một nhánh riêng biệt từ đó cho từng máy mà bạn làm việc cùng và cam kết các tệp dành riêng cho máy vào nhánh đó. Bất cứ khi nào bạn thay đổi các tệp chung của mình, hãy hợp nhất nhánh chung vào từng nhánh máy và đẩy sang các máy khác của bạn (viết một tập lệnh cho điều đó nếu có nhiều).

Sau đó, trên mỗi máy, hãy kiểm tra nhánh của máy đó, nhánh này cũng sẽ bao gồm các tệp cấu hình chung.


Trong khi các mô-đun con cũng sẽ hoạt động, tôi nghĩ đây là cách tiếp cận tốt nhất cho tôi. Các tệp cục bộ sẽ tuân theo một mẫu và khi tôi thực hiện các thay đổi đối với mẫu trên nhánh MASTER, tôi có thể hợp nhất chúng vào các nhánh cục bộ của máy, cập nhật từng bước các tệp cấu hình cục bộ. Cảm ơn đã giúp đỡ!
Joe Casadonte

sử dụng cả Mercurial và Git.
Linc

171

Bài viết này đề cập đến vấn đề này tương đối tốt:

https://github.com/rrrene/gitscm-next/blob/master/app/views/blog/progit/2010-04-11-enosystem.markdown

Về cơ bản, nếu bạn đang làm việc từ dòng lệnh, điều này đơn giản hơn bạn có thể đoán. Giả sử bạn muốn có 2 git repo:

.gitone
.gittwo

Bạn có thể thiết lập chúng như vậy:

git init .
mv .git .gitone
git init .
mv .git .gittwo

Bạn có thể thêm một tệp và cam kết chỉ một tệp như vậy:

git --git-dir=.gitone add test.txt
git --git-dir=.gitone commit -m "Test"

Vì vậy, các tùy chọn cho git xuất hiện đầu tiên, sau đó là lệnh, sau đó là các tùy chọn của lệnh git. Bạn có thể dễ dàng có đủ bí danh một lệnh git như:

#!/bin/sh
alias gitone='git --git-dir=.gitone'
alias gittwo='git --git-dir=.gittwo'

Vì vậy, bạn có thể cam kết với cái này hay cái kia với một chút gõ ít hơn, chẳng hạn như gitone commit -m "blah".

Những gì dường như trở nên phức tạp hơn là bỏ qua. Vì .gitignore thường nằm trong thư mục gốc của dự án, bạn cần phải tìm cách chuyển đổi nó mà không cần chuyển đổi toàn bộ thư mục gốc. Hoặc, bạn có thể sử dụng .git / info /lude, nhưng tất cả các thao tác bỏ qua bạn thực hiện sau đó sẽ không được cam kết hoặc đẩy - điều này có thể gây khó khăn cho người dùng khác. Những người khác sử dụng một trong hai repo có thể đẩy một .gitignore, điều này có thể gây ra xung đột. Tôi không rõ cách tốt nhất để giải quyết những vấn đề này.

Nếu bạn thích các công cụ GUI như TortoiseGit, bạn cũng sẽ gặp một số thách thức. Bạn có thể viết một đoạn script nhỏ đổi tên .gitone hoặc .gittwo thành .git tạm thời để đáp ứng các giả định của công cụ này.


1
Đặt nó làm bí danh sẽ dẫn đến lỗi này: $ git config --global alias.pub '--git-dir = ~ / Server / www / .gitpublic' $ git pub add. Fat: bí danh 'pub' thay đổi các biến môi trường Bạn có thể sử dụng '! git' trong bí danh để thực hiện việc này. Bạn sẽ đặt "! Git" ở đâu trong trường hợp này?
JaredBroad

1
@JaredBroad Thú vị - Tôi đã đề nghị bạn sử dụng bí danh Bash, không phải bí danh git. Giống nhưalias gitone='git --git-dir=.gitone'
Chris Moschini

10
Bạn có thể định cấu hình các repo để sử dụng các tệp loại trừ của riêng chúng và bạn có thể theo dõi chúng, tức là gitone config core.excludesfile gitone.excludegitone add gitone.exclude. Tôi đã thực hiện một kịch bản mà mở rộng trên giải pháp này: github.com/capr/multigit

2
@JaredBroad tôi đã làm nó như thế này git config --global alias.youralias '!git --git-dir="/d/MyProject/_git"'rồi git youralias status:)
starikovs

1
Nếu bạn giả định rằng .gitignorecác tệp thường được thiết lập và quên, thì bạn có thể tạo các bản sao khác nhau cho mỗi repo, sau đó sao chép phiên bản có liên quan vào thư mục như một phần của bí danh. Điều này áp dụng cho các tệp khác trong thư mục gốc có thể xung đột, chẳng hạn như README.md.gitattributes.
thdoan

15

Hãy xem git submodule .

Các mô-đun con cho phép các kho lưu trữ nước ngoài được nhúng trong một thư mục con chuyên dụng của cây nguồn, luôn được trỏ đến một cam kết cụ thể.


8
Không tốt cho các tệp cần nằm trên thư mục gốc của bạn. Cơ hội duy nhất ở đó, là lấp đầy gốc của các liên kết tượng trưng vào những thứ này.
WhyNotHugo

6

RichiH đã viết một công cụ có tên là vcsh , một công cụ để quản lý các tập tin dotfiles bằng cách sử dụng các repo giả mạo của git để đưa nhiều hơn một thư mục làm việc vào $ HOME. Không liên quan gì đến csh AFAIK.

Tuy nhiên, nếu bạn có nhiều thư mục, thì một giải pháp thay thế cho các mô-đun con git (gây khó khăn trong các trường hợp tốt nhất và việc sử dụng ví dụ này không phải là trường hợp tốt nhất) là gitslave để kiểm tra các kho nô lệ trên đầu của một chi nhánh mọi lúc và không yêu cầu quy trình ba bước để thực hiện thay đổi trong repo công ty con (kiểm tra chi nhánh chính xác, thực hiện & cam kết thay đổi, sau đó vào siêu dự án và thực hiện cam kết mô hình con mới).


6

Có thể bằng cách sử dụng biến GIT_DIRnhưng có nhiều cảnh báo nếu bạn không biết mình đang làm gì.


4

Vâng, mô-đun con có thể là những gì bạn muốn. Một tùy chọn khác sẽ là để bản sao làm việc của bạn trong một thư mục con và sau đó trỏ các liên kết tượng trưng từ thư mục chính của bạn tới các tệp quan tâm.


3

phương pháp ưa thích của tôi là sử dụng repo trong subir và sử dụng các liên kết tượng trưng đệ quy:

git clone repo1
cd somerepo
git clone repo2
cd repo2
./build

trong đó tệp tin ' repo / build ' trông giống như sau:

#!/bin/bash 
SELF_PATH="$(dirname "$(readlink -f "$0")" )"  # get current dir 
cd .. && git stash && git clean -f -d ''       # remove previous symlinks
cp -sR "$SELF_PATH"/* ../.                     # create recursive symlinks in root

thận trọng : không sử dụng 'git add.'


0

Tùy chọn khác là để chúng trên các thư mục riêng biệt và tạo các liên kết cứng tượng trưng từ thư mục này sang thư mục khác.

Ví dụ: nếu có các kho:

  1. Repo1 / FolderA
  2. Repo1 / FolderB

Và:

  1. Repo2 / FolderC

Bạn có thể liên kết biểu tượng các thư mục FolderAFolderBtừ Repo1 vào Repo2. Đối với windows, lệnh chạy trên Repo1 sẽ là:

User@Repo1$ mklink /J FullPath/Repo2/FolderA FullPath/Repo1/FolderA
User@Repo1$ mklink /J FullPath/Repo2/FolderB FullPath/Repo1/FolderB
User@Repo1$ printf "/FolderA/*\n/FolderB/*\n" >> .gitignore

Đối với các tệp trên các kho lưu trữ chính, bạn sẽ cần phải liên kết biểu tượng từng tệp một, đồng thời thêm chúng vào kho lưu trữ .gitignoređể tránh nhiễu, trừ khi bạn muốn.


0

Tuyên bố từ chối trách nhiệm: Đây không phải là quảng cáo. Tôi là nhà phát triển của thư viện được cung cấp.

Tôi đã tạo một phần mở rộng git để xử lý các trường hợp bạn muốn trộn nhiều kho vào một thư mục. Ưu điểm của lib là theo dõi các kho lưu trữ và xung đột tệp. bạn có thể tìm thấy nó trên github . Ngoài ra còn có 2 kho lưu trữ ví dụ để dùng thử.

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.