2010-08-28 36 views
46

Tôi đã hai hoặc nhiều dự án (hãy gọi cho họ ProjectFooProjectBar) có một số mã chung mà tôi đặt trong một submodule.Git cam kết submodule chung (chi nhánh chính)

hiểu biết của tôi là nếu tôi cam kết thay đổi cho một submodule từ bên trong ProjectFoo nó sẽ ở trong một cái đầu tách ra rằng chỉ có tất cả ProjectFoo nhái có thể thấy:

(master) $ cd ProjectFooBarCommoneSubmodule/ 
(master) $ git commit -am "Common code fix." 
(56f21fb0...) $ git push 
Everything up-to-date 

Đó có thể là vì master chi nhánh đã không thay đổi. Tôi có thể có thể làm một cái gì đó như git checkout master && git merge Everything up-to-date nhưng điều đó có vẻ khá xấu xí. Có thể là git reset --hard master sẽ thực hiện tương tự nhưng có vẻ thậm chí còn xấu hơn.

Cách có mã chung được chia sẻ bởi dự án, cập nhật từ trong vòng các dự án đó sử dụng? Nói cách khác, cam kết rằng submodule nên cập nhật tất cả các kho khác nhau (kho, không chỉ nhái) mà sử dụng cùng một submodule.

---- CHỈNH SỬA ----

Kho lưu trữ đã kiểm tra của tôi rõ ràng đã bị hỏng và hỏng. Nó nên đã làm việc ngay từ đầu như vậy (trên ProjectFoo trong ví dụ này):

(master) $ cd ProjectFooBarCommoneSubmodule/ 
(master) $ git commit -am "Common code fix." 
(master) $ git push 
.... 
    fbfdd71..0acce63 master -> master 
(master) $ cd .. 
(master) $ git add ProjectFooBarCommoneSubmodule 
(master) $ git commit -m "Submodule update." 

Sau đó, để có được sự thay đổi từ các dự án khác, như ProjectBar:

(master) $ cd ProjectFooBarCommoneSubmodule/ 
(master) $ git pull 

Would cập nhật lên mã phổ biến mới nhất. A git checkout master có thể được yêu cầu nếu nó trên một đầu tách rời.

Trả lời

60

Câu trả lời ngắn:

cd ProjectFooBarCommoneSubmodule 
git checkout master 
<Do your editing> 
git commit --all -m "Lots of fixes" 
git push submodule_origin master 
cd .. 

git add ProjectFooBarCommoneSubmodule 
git commit -m "Bumped up the revision of ProjectFooBarCommoneSubmodule" 
git push origin master 

càng dài một:

submodules Git được một cơ chế phụ thuộc, nơi có dự án chính (nói A) định nghĩa một sửa đổi quy định tại một tiểu dự án (nói B), trong đó sẽ được sử dụng trong dự án xây dựng A. Để công cụ hữu ích, hành vi có thể dự đoán được từ quan điểm A: s. Tất cả các loại điều khó chịu có thể xảy ra, là những thay đổi của dự án B: tự động được nhập, trong đó các lỗi biên dịch có lẽ là những thay đổi tốt nhất, vì A sẽ nhận thấy các lỗi thất bại ngay lập tức. Đây là lý do tại sao đầu B: s được giữ trong trạng thái tách rời.

Trạng thái của B được lưu trữ trong A (kiểm tra git submodule status) và thay đổi sửa đổi phải được thực hiện và cam kết trong A, để cho nó có hiệu lực. Đây là những gì xảy ra trong ví dụ trên, A thay đổi số sửa đổi được lưu trữ trong repo, và bumps lên phiên bản mới nhất. Quá trình này sẽ phải được lặp lại trong repo chính khác, vì vậy không có tự động "sử dụng tổng thể" chuyển AFAIK.

BTW. Các Git book chapter on submodulessubmodule man page chứa rất nhiều thông tin hữu ích về submodules, như sử dụng bình thường và những cạm bẫy điển hình là tốt. Worth kiểm tra ra.


EDIT: Tôi sẽ cố gắng giải thích điều này tốt hơn

tôi lấy sự tự do để tạo các dự án ví dụ về my github account. Các cam kết là vô nghĩa và chứa rác, nhưng việc thiết lập nên được tốt. Vui lòng kiểm tra để làm theo.

Cả ProjectFoo và ProjectBar đều chia sẻ mã trong mô-đun con chung.

ProjectFooBarCommoneSubmodule: thạc sĩ là 6850e4e4c1fac49de398

Trong ProjectFoo:

git submodule status 

-6850e4e4c1fac49de39890703f21486ca04b87a0 chung

Trong ProjectBar:

git submodule status 

-6850e4e4c1fac49de39890703f21486ca04b87a0 common

Vì vậy, cả hai điểm vào cùng một sửa đổi, phải không? Bí quyết ở đây là để xem, ProjectFoo và ProjectBar trỏ đến sửa đổi (6850e4e4c1fac49de39890703f21486ca04b87a0) không phải chi nhánh (chính), mặc dù chúng giống nhau. Người đầu tiên là một người đứng đầu tách rời, và người kia là một chi nhánh được đặt tên.

Nếu bạn muốn thực hiện một số sửa lỗi trên ProjectFooBarCommoneSubmodule, bạn có thể chuyển đến thư mục con, ví dụ: ProjectFoo, và chọn chi nhánh thay vì sửa đổi:

git checkout master 
<Do your coding and pushing here> 

Sau đó đi tới thư mục trên, và kiểm tra tình trạng submodule git. Nó sẽ cho bạn biết, rằng bạn đã không đồng bộ. Ví dụ:

git submodule status 

+ e24bd2bf45d52171a63b67ac05cd4be0ac965f60 chung (người đứng đầu/master-1-ge24bd2b)

Bây giờ bạn có thể làm một git add, để thiết lập các tham chiếu đến đặc biệt này cam kết (ge24bd ...), làm một cam kết , và sau này các điểm tham chiếu submodule để sửa đổi này, mà cũng sẽ xảy ra để được làm chủ trên ProjectFooBarCommoneSubmodule.

Bây giờ bạn cũng cần phải cập nhật tham chiếu trong ProjectBar. Tới ProjectBar/phổ biến, và làm git fetch xứ hàng hóa (đây là một nhanh về phía trước hợp nhất), làm

git checkout master 
cd .. 
git add common 
git commit -m "Bumped up the revision" 
git push origin master # to publish the revision bump to everybody else 

Vì vậy, như với bất kỳ kho git, bạn không cần phải làm việc trên một đầu tách ra. Bạn có thể làm việc trên master, hoặc tạo một nhánh có tên. Dù bằng cách nào, hãy chắc chắn rằng thượng nguồn chứa các thay đổi ProjectFooBarCommoneSubmodule, hoặc bạn sẽ phá vỡ cả ProjectFoo và ProjectBar, nếu họ tham chiếu cái gì đó không tồn tại.Hy vọng điều này giải thích nó tốt hơn

+0

Cảm ơn, tôi thấy chương đó. Đáng buồn là tôi không tìm thấy câu trả lời rõ ràng cho câu hỏi của tôi. Bạn nói rằng không có tổng thể sử dụng tự động, vì vậy nếu một tiểu dự án chung, hãy nói một thư viện, cập nhật? Không phải là một bản cập nhật submodule 'git' sẽ cập nhật tất cả các dự án dựa vào thư viện đó? Tôi muốn làm như vậy nhưng cập nhật thư viện đó trực tiếp từ bất kỳ dự án chính nào của tôi. Nếu điều đó là không thể, thì điều gì sẽ là lựa chọn thay thế? – Wernight

+0

Kho Git không chứa bất kỳ thông tin nào về người đã nhân bản chúng. Đây là lý do tại sao nó không thể đẩy ra những thay đổi cho tất cả các dòng vô tính. Làm cho mọi thứ đơn giản, tôi nghĩ bạn đang mong đợi một cái gì đó giống như các liên kết tượng trưng, ​​vì vậy mọi thứ sẽ được truyền đi ngay lập tức, trong khi các bản sao giống như "tar, gzip, copy, unzip". Điều quan trọng là có lẽ chỉ cần xuất bản số sửa đổi thay đổi trong Foo và Bar. Bất kỳ ai tìm nạp thay đổi sẽ thấy số sửa đổi thay đổi vào lần tiếp theo. Bất cứ điều gì tốt hơn thế, tôi sẽ nói, không. Tôi sẽ rất vui khi được chứng minh là sai trong điều này. –

+0

Chắc chắn nhân bản phải thực hiện cập nhật hoặc kéo theo cách thủ công. Câu hỏi của tôi là, làm thế nào? Hai dự án, không phải là bản sao, chia sẻ một mã phổ biến trong một mô-đun con Git. Có sự lựa chọn nào khác hơn ProjectFoo cam kết mô-đun con để tách rời đầu, sau đó ProjectBar (KHÔNG một bản sao) kết hợp các thay đổi (nếu điều đó thậm chí có thể, tôi không biết nơi những thay đổi được lưu trữ). – Wernight

2

Trên submodule: git push origin HEAD:master

0

Nếu bạn muốn cam kết và đẩy tất cả các môđun con cùng một lúc làm: git submodule foreach 'git commit -a' ; git submodule foreach 'git push --all' ; git commit -a && \ git push --all --recurse-submodules=on-demand

0

Để hợp nhất thay đổi từ TRỤ tách ra thành bậc thầy, chạy:

git rebase HEAD master 

thạc sĩ sau đó kiểm tra (sử dụng -f cho lực):

git checkout master 

Nếu bạn có nhiều mô-đun con để xử lý, hãy sử dụng: git submodule foreach, ví dụ:

git submodule foreach git pull origin master -r 
0

Tôi chỉ làm:

git submodule foreach git push -u origin master

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