Cập nhật một mô hình con cho cam kết mới nhất


269

Tôi có một dự án A là một thư viện và nó được sử dụng trong dự án B.

Cả hai dự án A và B đều có một kho lưu trữ riêng trên github NHƯNG bên trong B, chúng ta có một mô hình con của A.

Tôi đã chỉnh sửa một số lớp trên thư viện, trong repo A, tôi đã đẩy vào repo từ xa, vì vậy thư viện (repo A) được cập nhật.

Các cập nhật này không phản ánh trên "tham chiếu" (mô hình con) mô hình con đề cập đến một cam kết trước đó .... tôi nên làm gì để cập nhật mô hình con trên git?

Câu trả lời:


358

Nhập thư mục mô hình con:

cd projB/projA

Kéo repo từ dự án A của bạn (sẽ không cập nhật trạng thái git của cha mẹ bạn, dự án B):

git pull origin master

Quay trở lại thư mục gốc và kiểm tra cập nhật:

cd ..
git status

Nếu mô hình con được cập nhật trước đó, nó sẽ hiển thị một cái gì đó như dưới đây:

# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

Sau đó, cam kết cập nhật:

git add projB/projA
git commit -m "projA submodule updated"

CẬP NHẬT

Như @paul đã chỉ ra, kể từ git 1.8, chúng ta có thể sử dụng

git submodule update --remote --merge

để cập nhật mô hình con vào cam kết từ xa mới nhất. Nó sẽ thuận tiện trong hầu hết các trường hợp.


35
BTW, nếu bạn không phải là chủ sở hữu của mô hình con, bạn chỉ có thể làm git submodule updatekhi có người khác cập nhật projA (bạn sẽ nhận được một id xác nhận mới).
Kjuly

tôi sở hữu repo chính subodule (proj A) nhưng tôi là người đi làm trong proj B.
fat

@Kjuly Sau khi cam kết, làm thế nào để đẩy nó vào điều khiển từ xa? Có phải chỉ là git push?
KR29

1
@ KR29 đúng, và cmd đầy đủ là git push <remote> <branch>, ví dụ git push origin dev.
Kjuly

2
git submodule updatechỉ hoạt động mà không có cờ khi một cam kết đã được kéo (trong proj B) cập nhật các ref cho mô hình con trong câu hỏi (proj A). Để cập nhật proj B để tham chiếu HEADnhánh theo dõi từ xa cho proj A, bạn sẽ muốn làm git submodule update --remote --mergenhư thể hiện trong câu trả lời của Paul Hatcher bên dưới.
Ben Burns

109

Vì git 1.8 bạn có thể làm

git submodule update --remote --merge

Điều này sẽ cập nhật mô hình con vào cam kết từ xa mới nhất. Sau đó, bạn sẽ cần phải cam kết thay đổi để gitlink trong kho lưu trữ mẹ được cập nhật

git commit

Và sau đó đẩy các thay đổi như không có điều này, danh tính SHA-1, việc trỏ đến mô hình con sẽ không được cập nhật và do đó, thay đổi sẽ không hiển thị cho bất kỳ ai khác.


Mặc dù tôi làm git commitmọi người khác vẫn không thấy nó. On branch master Your branch is up-to-date with 'origin/master'. Changes not staged for commit: modified: SubmoduleA (new commits) modified: SubmoduleB (new commits)
Tối đa

1
Bạn đã thực hiện "git đẩy" sau khi cam kết, hãy nhớ rằng cam kết chỉ thay đổi kho lưu trữ cục bộ của bạn, bạn phải đẩy nó ra điều khiển từ xa để mọi người khác thấy nó
Paul Hatcher

Thiếu từ câu trả lời này (nhưng lưu ý trong các câu trả lời khác bên dưới): (các) mô hình con được cập nhật cần phải được tổ chức git addtrước khi cam kết.
joshng

1
@joshng Tôi cảm thấy rằng tất cả những người đang ở thời điểm họ đang làm việc trên các mô hình con sẽ hiểu điều đó. Đây là bài viết duy nhất giúp tôi ra ngoài, cảm ơn rất nhiều.
Husk Rekoms

38

Nếu bạn cập nhật một mô hình con và cam kết với nó, bạn cần đi đến repo chứa hoặc cấp cao hơn và thêm thay đổi ở đó.

git status

sẽ hiển thị một cái gì đó như:

modified:
   some/path/to/your/submodule

Thực tế là mô hình con không đồng bộ cũng có thể được nhìn thấy với

git submodule

đầu ra sẽ hiển thị:

+afafaffa232452362634243523 some/path/to/your/submodule

Điểm cộng chỉ ra rằng mô hình con của bạn đang chỉ ra phía trước nơi repo hàng đầu mong đợi nó trỏ đến.

chỉ cần thêm thay đổi này:

git add some/path/to/your/submodule

và cam kết:

git commit -m "referenced newer version of my submodule"

Khi bạn đẩy các thay đổi của mình lên, hãy đảm bảo bạn đẩy lên thay đổi trong mô hình con trước và sau đó đẩy thay đổi tham chiếu trong repo bên ngoài. Bằng cách này, những người cập nhật sẽ luôn có thể chạy thành công

git submodule update

Thông tin thêm về các mô hình con có thể được tìm thấy ở đây http://progit.org/book/ch6-6.html .


Nếu bạn không thấy +khi bạn chạy git submodule, hãy đảm bảo bạn đã khởi tạo và nhập các mô hình con. Các lệnh cho đó là git submodule initgit submodule update, tương ứng.
fureigh

19

Phiên bản đơn

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"

2

Một vài trong số các câu trả lời khác khuyên bạn nên hợp nhất / cam kết trong thư mục của mô hình con, mà IMO có thể trở nên hơi lộn xộn.

Giả sử máy chủ từ xa được đặt tên originvà chúng tôi muốn masternhánh của mô hình con, tôi có xu hướng sử dụng:

git submodule foreach "git fetch && git reset --hard origin/master"

Lưu ý: Điều này sẽ thực hiện thiết lập lại cứng trên mỗi mô hình con - nếu bạn không muốn điều này, bạn có thể thay đổi --hardthành --soft.


1

Dự án của tôi nên sử dụng 'mới nhất' cho mô hình con. Trên Mac OSX 10.11, git phiên bản 2.7.1, tôi không cần phải truy cập vào thư mục mô hình con của mình để thu thập các cam kết của nó. Tôi chỉ làm thường xuyên

git pull --rebase 

ở cấp cao nhất và nó đã cập nhật chính xác mô hình con của tôi.


0

Phản ứng của Andy đã làm việc cho tôi bằng cách thoát khỏi đường dẫn $:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"

Có khả năng lý do tại sao câu trả lời của @Andy Webov không yêu cầu thoát là vì họ đã sử dụng các trích dẫn đơn lẻ trên đường dẫn, ví dụ: '$path'
S0AndS0
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.