Làm thế nào để làm cho tiểu git nông?


139

Có thể có mô đun nông? Tôi có một siêu dự án với một số mô hình con, mỗi mô hình có một lịch sử lâu dài, vì vậy nó trở nên lớn không cần thiết kéo theo tất cả lịch sử đó.

Tất cả tôi đã tìm thấy là chủ đề chưa được trả lời này .

Tôi có nên hack git-subodule để thực hiện điều này?


1
" git submodule add/update" bây giờ có thể sao chép các kho lưu trữ mô đun con một cách nông cạn! Xem câu trả lời của tôi dưới đây
VonC

Câu trả lời:


133

Mới trong git1.8.4 sắp tới (tháng 7 năm 2013) :

" git submodule update" Có thể tùy ý sao chép các kho lưu trữ mô đun con một cách nông cạn.

(Và git 2.10 Q3 2016 cho phép ghi lại điều đó với git config -f .gitmodules submodule.<name>.shallow true.
Xem phần cuối của câu trả lời này)

Xem cam kết 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f :

Thêm --depthtùy chọn vào các lệnh thêm và cập nhật của "git subodule", sau đó được chuyển sang lệnh clone. Điều này hữu ích khi (các) mô hình con rất lớn và bạn không thực sự quan tâm đến bất cứ điều gì ngoại trừ cam kết mới nhất.

Các thử nghiệm được thêm vào và một số điều chỉnh chú ý đã được thực hiện để phù hợp với phần còn lại của testfile về "cập nhật mô hình con có thể xử lý các liên kết tượng trưng trong pwd".

Đã ký tắt: Fredrik Gustafsson <iveqy@iveqy.com>
Acked-by: Jens Lehmann<Jens.Lehmann@web.de>

Điều đó có nghĩa là điều này hoạt động:

git submodule add --depth 1 -- repository path
git submodule update --depth -- [<path>...]

Với:

--depth::

Tùy chọn này là hợp lệ cho addupdatecác lệnh.
Tạo một bản sao 'nông' với một lịch sử được cắt ngắn theo số lần sửa đổi được chỉ định.


atwyman thêm vào trong các ý kiến :

Theo như tôi có thể nói tùy chọn này không thể sử dụng được cho các mô hình con không theo dõi masterrất chặt chẽ. Nếu bạn đặt độ sâu 1, thì submodule updatechỉ có thể thành công nếu mô hình con cam kết bạn muốn là chủ mới nhất. Nếu không, bạn nhận được " fatal: reference is not a tree" .

Điều đó đúng.
Đó là, cho đến git 2.8 (tháng 3 năm 2016). Với 2.8, submodule update --depthcó thêm một cơ hội để thành công, ngay cả khi SHA1 có thể truy cập trực tiếp từ một trong các ĐẦU repo từ xa.

Xem cam kết fb43e31 (24 tháng 2 năm 2016) của Stefan Beller ( stefanbeller) .
Giúp đỡ: Junio ​​C Hamano ( gitster) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 9671a76 , ngày 26 tháng 2 năm 2016)

mô hình con: cố gắng hơn để tìm nạp sha1 cần thiết bằng cách tìm nạp trực tiếp sha1

Khi xem xét một thay đổi cũng cập nhật một mô hình con trong Gerrit, một thực tiễn đánh giá phổ biến là tải xuống và chọn bản vá cục bộ để kiểm tra nó.
Tuy nhiên, khi kiểm tra nó cục bộ, ' git submodule update' có thể không tìm nạp được mô hình con chính xác sha1 vì cam kết tương ứng trong mô hình con chưa phải là một phần của lịch sử dự án, mà chỉ là một thay đổi được đề xuất.

Nếu $sha1không phải là một phần của tìm nạp mặc định, chúng tôi sẽ cố gắng tìm nạp $sha1trực tiếp . Tuy nhiên, một số máy chủ không hỗ trợ tìm nạp trực tiếp bởi sha1, dẫn git-fetchđến lỗi nhanh chóng.
Chúng ta có thể thất bại ở đây vì sha1 vẫn còn thiếu sẽ dẫn đến thất bại sau này trong giai đoạn thanh toán, vì vậy thất bại ở đây là tốt như chúng ta có thể nhận được.


MVG chỉ ra trong các ý kiến để cam kết fb43e31 (git 2.9, tháng 2 năm 2016)

Dường như với tôi rằng cam kết fb43e31 yêu cầu cam kết bị thiếu bởi id SHA1, vì vậy uploadpack.allowReachableSHA1InWantuploadpack.allowTipSHA1InWantcác cài đặt trên máy chủ có thể sẽ ảnh hưởng đến việc này có hoạt động hay không.
Tôi đã viết một bài đăng lên danh sách git ngày hôm nay , chỉ ra cách sử dụng các mô đun con nông có thể được thực hiện để hoạt động tốt hơn cho một số tình huống, cụ thể là nếu cam kết cũng là một thẻ.
Hãy chờ xem.

Tôi đoán đây là một lý do tại sao fb43e31 làm cho việc tìm nạp cho một SHA1 cụ thể trở thành dự phòng sau khi tìm nạp cho nhánh mặc định.
Tuy nhiên, trong trường hợp của Lv tìm nạp bất cứ thứ gì, vì chúng tôi sẽ không thể đáp ứng yêu cầu mô hình con theo bất kỳ cách nào.


Cập nhật tháng 8 năm 2016 (3 năm sau)

Với Git 2.10 (quý 3 năm 2016), bạn sẽ có thể làm

 git config -f .gitmodules submodule.<name>.shallow true

Xem " Mô hình con Git không có trọng lượng thêm " để biết thêm.


Git 2.13 (quý 2 năm 2017) thêm vào cam kết 8d3047c (ngày 19 tháng 4 năm 2017) bởi Sebastian Schuberth ( sschuberth) .
(Được hợp nhất bởi Sebastian Schuberth - sschuberth- trong cam kết 8d3047c , ngày 20 tháng 4 năm 2017)

một bản sao của mô hình con này sẽ được thực hiện dưới dạng bản sao nông (với độ sâu lịch sử là 1)

Tuy nhiên, Ciro Santilli thêm vào các bình luận (và chi tiết trong câu trả lời của ông )

shallow = truebật .gitmoduleschỉ ảnh hưởng đến tham chiếu được theo dõi bởi ĐẦU của điều khiển từ xa khi sử dụng --recurse-submodules, ngay cả khi cam kết đích được chỉ ra bởi một nhánh và ngay cả khi bạn cũng đặt branch = mybranchtrên đó .gitmodules.


Git 2.20 (Q4 2018) cải thiện về hỗ trợ mô hình con, đã được cập nhật để đọc từ blob tại HEAD:.gitmodulesthời điểm .gitmodulesthiếu tệp từ cây làm việc.

Xem cam kết 2b1257e , cam kết 76e9bdc (ngày 25 Tháng 10 năm 2018), và cam kết b5c259f , cam kết 23dd8f5 , cam kết b2faad4 , cam kết 2502ffc , cam kết 996df4d , cam kết d1b13df , cam kết 45f5ef3 , cam kết bcbc780 (05 Tháng 10 năm 2018) bởi Antonio Ospite ( ao2) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết abb4824 , ngày 13 tháng 11 năm 2018)

submodule: hỗ trợ đọc .gitmoduleskhi nó không ở trong cây làm việc

Khi .gitmodulestệp không có sẵn trong cây làm việc, hãy thử sử dụng nội dung từ chỉ mục và từ nhánh hiện tại.
Điều này bao gồm trường hợp khi tệp là một phần của kho lưu trữ nhưng vì một số lý do, nó không được kiểm tra, ví dụ vì thanh toán thưa thớt.

Điều này làm cho nó có thể sử dụng ít nhất là ' git submodule' lệnh mà đọc các gitmodulestập tin cấu hình mà không Populating đầy đủ các cây làm việc.

Viết thư .gitmodulesvẫn sẽ yêu cầu kiểm tra tệp, vì vậy hãy kiểm tra trước khi gọi config_set_in_gitmodules_file_gently.

Thêm một kiểm tra tương tự cũng git-submodule.sh::cmd_add()để dự đoán sự thất bại cuối cùng của git submodule addlệnh "" khi .gitmoduleskhông thể ghi an toàn; điều này ngăn lệnh rời khỏi kho lưu trữ ở trạng thái giả (ví dụ: kho lưu trữ mô hình con được sao chép nhưng .gitmoduleskhông được cập nhật vì config_set_in_gitmodules_file_gentlykhông thành công).

Hơn nữa, vì config_from_gitmodules()bây giờ truy cập vào kho đối tượng toàn cầu, cần phải bảo vệ tất cả các đường dẫn mã gọi hàm chống lại truy cập đồng thời vào kho đối tượng toàn cầu.
Hiện tại điều này chỉ xảy ra builtin/grep.c::grep_submodules(), vì vậy hãy gọi grep_read_lock()trước khi gọi mã liên quan config_from_gitmodules().

LƯU Ý: có một trường hợp hiếm hoi khi tính năng mới này chưa hoạt động đúng: các mô đun con lồng nhau mà không có .gitmodulestrong cây làm việc của chúng.


Lưu ý: Git 2.24 (Q4 2019) sửa lỗi segfault có thể xảy ra khi nhân bản mô đun con nông.

Xem cam kết ddb3c85 (30 tháng 9 năm 2019) của Ali Utku Selen ( auselen) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 678a9ca , ngày 09 tháng 10 năm 2019)


Git 2.25 (Q1 2020), làm rõ git submodule updatetài liệu.

Xem cam kết f0e58b3 (24 tháng 11 năm 2019) của Philippe Blain ( phil-blain) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết ef61045 , ngày 5 tháng 12 năm 2019)

doc: đề cập rằng 'git subodule update' tìm nạp các xác nhận bị thiếu

Được giúp đỡ: Junio ​​C Hamano
Được giúp đỡ: Julian Schindelin
Đã ký tắt: Philippe Blain

' git submoduleCập nhật' sẽ tìm nạp các xác nhận mới từ điều khiển mô hình con nếu không tìm thấy SHA-1 được ghi trong siêu dự án . Điều này đã không được đề cập trong tài liệu.


Cảnh báo: Với Git 2.25 (Q1 2020), sự tương tác giữa " git clone --recurse-submodules" và kho đối tượng thay thế được thiết kế không phù hợp.

Các tài liệu và mã đã được dạy để đưa ra các khuyến nghị rõ ràng hơn khi người dùng thấy thất bại.

Xem cam kết 4f3e57e , cam kết 10c64a0 (02 tháng 12 năm 2019) của Jonathan Tan ( jhowtan) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 5dd1d59 , ngày 10 tháng 12 năm 2019)

submodule--helper: tư vấn về lỗi thay thế gây tử vong

Đã ký: Jonathan Tan
Acked-by: Jeff King

Khi nhân bản đệ quy một siêu dự án với một số mô-đun nông được xác định trong nó .gitmodules, sau đó lặp lại với " --reference=<path>", một lỗi xảy ra. Ví dụ:

git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  master
git clone --recurse-submodules --branch=master -j8 \
  https://android.googlesource.com/platform/superproject \
  --reference master master2

thất bại với:

fatal: submodule '<snip>' cannot add alternate: reference repository
'<snip>' is shallow

Khi không thể thêm một thay thế được tính toán từ thay thế của siêu dự án, dù trong trường hợp này hay trường hợp khác, hãy khuyên về cách định submodule.alternateErrorStrategycấu hình tùy chọn cấu hình "" và sử dụng " --reference-if-able" thay vì " --reference" khi nhân bản.

Đó là chi tiết trong:

Với Git 2.25 (Q1 2020), sự tương tác giữa "git clone --recurse-subodules" và kho đối tượng thay thế được thiết kế không phù hợp.

Doc: giải thích mô đun con.alternateErrorStrargety

Đã ký: Jonathan Tan
Acked-by: Jeff King

Cam kết 31224cbdc7 (" clone: tùy chọn đệ quy và tham chiếu kích hoạt thay thế mô hình con", 2016-08-17, Git v2.11.0-rc0 - hợp nhất được liệt kê trong lô # 1 ) đã dạy Git để hỗ trợ các tùy chọn cấu hình " submodule.alternateLocation" và " submodule.alternateErrorStrategy" trên siêu dự án .

Nếu " submodule.alternateLocation" được cấu hình thành " superproject" trên siêu dự án, bất cứ khi nào một mô hình con của siêu dự án đó được sao chép, thay vào đó, nó sẽ tính toán đường dẫn thay thế tương tự cho mô hình con đó từ $GIT_DIR/objects/info/alternatessiêu dự án và tham chiếu nó.

Các " submodule.alternateErrorStrategy" tùy chọn xác định những gì sẽ xảy ra nếu thay thế mà không thể được tham chiếu.
Tuy nhiên, không rõ ràng rằng bản sao tiến hành như thể không có sự thay thế nào được chỉ định khi tùy chọn đó không được đặt thành "chết" (như có thể thấy trong các thử nghiệm trong 31224cbdc7 ).
Do đó, tài liệu cho phù hợp.

Các tài liệu hướng dẫn cấu hình submodule hiện nay bao gồm:

submodule.alternateErrorStrategy::

Chỉ định cách xử lý lỗi với các thay thế cho một mô hình con như được tính toán thông qua submodule.alternateLocation.
Giá trị có thể là ignore, info, die.
Mặc định là die.
Lưu ý rằng nếu được đặt thành ignorehoặc infonếu có lỗi với thay thế được tính toán, bản sao sẽ tiến hành như thể không có thay thế nào được chỉ định .


2
Ồ nó rất nhanh ! Thx cho câu trả lời bằng cách này. Oh và --depthshoudl cũng tranh luận;)
Brice

3
Dường như với tôi rằng cam kết fb43e31 yêu cầu cam kết bị thiếu bởi id SHA1, vì vậy uploadpack.allowReachableSHA1InWantuploadpack.allowTipSHA1InWantcác cài đặt trên máy chủ có thể sẽ ảnh hưởng đến việc này có hoạt động hay không. Tôi đã viết một bài đăng lên danh sách git hôm nay, chỉ ra cách sử dụng các mô đun con nông có thể được thực hiện để hoạt động tốt hơn cho một số tình huống, cụ thể là nếu cam kết cũng là một thẻ. Hãy chờ xem.
MvG

2
Với sự bổ sung gần đây của tùy chọn nông .gitmodules, --depth 1tùy chọn này có hoạt động đối với các nhánh không theo dõi chính chủ không?
CMCDragonkai

2
@CiroSantilli 死 六四 事件 Cảm ơn bạn đã chính xác và kiểm tra. Tôi đã bao gồm nhận xét của bạn trong câu trả lời để dễ nhìn hơn và đã nâng cao câu trả lời của bạn.
VonC

2
Không rõ câu trả lời là cách hiện tại để làm điều đó. Ngoài ra, không rõ liệu tất cả những điều đó là cần thiết mỗi khi ai đó sao chép bản sao mới hoặc các cài đặt mô hình con chim sẻ này trở thành một phần của repo tham chiếu các mô hình con này (ví dụ: mỗi bản sao mới và bản cập nhật mô hình con kết quả trong kiểm tra mô hình con chim sẻ)
Pavel P

26

Git 2.9.0 hỗ trợ các mô hình con nhân bản trực tiếp, vì vậy bây giờ bạn chỉ cần gọi:

git clone url://to/source/repository --recursive --shallow-submodules

2
Tùy chọn này hứa hẹn nhất, nhưng không thành công trên git 2.14.1, cam kết mô hình con không được theo dõi bởi một nhánh hoặc thẻ: stackoverflow.com/a/47374702/895245
Ciro Santilli 冠状 病 六四 法轮功

1
@CiroSantilli 死 六四 Hãy chắc chắn rằng máy chủ git của bạn cũng được cập nhật
KindDragon

Cảm ơn, tôi đã thử nghiệm cục bộ, không có máy chủ và trên GitHub mà tôi không thể cập nhật :-)
Ciro Santilli 郝海东 冠状 病 19/11/17

1
Tôi có cùng một vấn đề khi sử dụng git 2.20, nó không hoạt động khi mô hình con không nằm trên đỉnh của nhánh.
Zitrax

16

Theo câu trả lời của Ryan, tôi đã có thể đưa ra kịch bản đơn giản này lặp đi lặp lại qua tất cả các mô hình con và nhân bản chúng:

#!/bin/bash
git submodule init
for i in $(git submodule | sed -e 's/.* //'); do
    spath=$(git config -f .gitmodules --get submodule.$i.path)
    surl=$(git config -f .gitmodules --get submodule.$i.url)
    git clone --depth 1 $surl $spath
done
git submodule update

Tôi nhận được fatal: reference is not a tree: 88fb67b07621dfed054d8d75fd50672fb26349dfcho mỗi mô hình con
knocte


1
@knocte: Tôi đã viết câu trả lời của mình vào năm 2010. Mọi thứ đã thay đổi. Bạn không thể mong đợi tất cả mọi người duy trì tất cả các câu trả lời của họ. Tôi đã đánh dấu câu trả lời hợp lệ hiện tại là chấp nhận.
Mauricio Scheffer

13
@knocte Đây là một trong những lý do khiến tôi ngừng đóng góp cho Stackoverflow. Mọi người có những kỳ vọng không thực tế này. Nó sẽ là một công việc toàn thời gian để duy trì mỗi một trong số 1637 câu trả lời của tôi. Và sau đó cũng có những bình luận, tôi cho rằng tôi cũng phải duy trì chúng? Hãy xem ngày tháng, đó là những gì họ đang làm. Nếu bạn đọc một số blog .NET từ năm 2002 với mã bằng ArrayList thay vì List, bạn có sử dụng nó không? Bạn có yêu cầu tác giả cập nhật bài viết của mình không? Nguyên tắc tương tự áp dụng ở đây.
Mauricio Scheffer

1
s / statusquo / tiến trình /
knocte

8

Đọc qua "nguồn" git-subodule, có vẻ như git submodule addcó thể xử lý các mô hình con đã có kho lưu trữ của chúng. Trong trường hợp đó...

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
$ git submodule add $remotesub1 $sub1
#repeat as necessary...

Bạn sẽ muốn đảm bảo rằng các cam kết được yêu cầu nằm trong repo mô đun con, vì vậy hãy đảm bảo bạn đặt một - thích hợp.

Chỉnh sửa: Bạn có thể thoát khỏi nhiều bản sao mô hình con thủ công theo sau bởi một bản cập nhật duy nhất:

$ git clone $remote1 $repo
$ cd $repo
$ git clone --depth 5 $remotesub1 $sub1
#repeat as necessary...
$ git submodule update

5
Bây giờ với git 1.8.0, bạn không thể sao chép một kho lưu trữ bên trong một kho lưu trữ nữa. Vì vậy, giải pháp này không hoạt động nữa.
Bohr

7

Tóm tắt hành vi lỗi / bất ngờ / gây phiền nhiễu kể từ Git 2.14.1

  1. shallow = truetrong .gitmoduleschỉ ảnh hưởng git clone --recurse-submodulesnếu HEADtrong những điểm submodule từ xa đến yêu cầu cam kết, ngay cả khi mục tiêu cam kết được trỏ đến bởi một chi nhánh, và thậm chí nếu bạn đặt branch = mybranchtrên .gitmoduleslà tốt.

    Kịch bản thử nghiệm cục bộ . Hành vi tương tự trên GitHub 2017-11, nơi HEADđược điều khiển bởi cài đặt repo chi nhánh mặc định:

    git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow
    cd test-shallow-submodule-top-branch-shallow/mod
    git log
    # Multiple commits, not shallow.
    
  2. git clone --recurse-submodules --shallow-submodulesthất bại nếu cam kết không được tham chiếu bởi một nhánh hoặc thẻ với một thông báo : error: Server does not allow request for unadvertised object.

    Kịch bản thử nghiệm cục bộ . Hành vi tương tự trên GitHub:

    git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha
    # error
    

    Tôi cũng đã hỏi trong danh sách gửi thư: https://marc.info/?l=git&m=151863590026582&w=2 và câu trả lời là:

    Về lý thuyết điều này nên dễ dàng. :)

    Trong thực tế không nhiều, thật không may. Điều này là do nhân bản sẽ chỉ nhận được mẹo mới nhất của một nhánh (thường là chủ). Không có cơ chế trong bản sao để chỉ định chính xác sha1 muốn.

    Giao thức dây hỗ trợ cho việc hỏi chính xác sha1s, do đó cần được bảo hiểm. (Hãy cẩn thận: nó chỉ hoạt động nếu toán tử máy chủ kích hoạt uploadpack.allowReachableSHA1InWant mà github không AFAICT)

    git-fetch cho phép tìm nạp sha1 tùy ý, vì vậy, một cách giải quyết bạn có thể chạy tìm nạp sau bản sao đệ quy bằng cách sử dụng "cập nhật mô hình con git" vì nó sẽ sử dụng tìm nạp sau bản sao ban đầu.

Thử nghiệm TODO : allowReachableSHA1InWant.


Có vẻ như không có cách nào đơn giản để kiểm tra hàm băm cam kết tách rời cho mô hình con và có những người dùng xuôi dòng git clone --recursivechỉ tìm nạp cam kết cụ thể đó.
CMCDragonkai

3

Là các vị trí chính tắc cho mô hình con của bạn từ xa? Nếu vậy, bạn có ổn với nhân bản chúng một lần không? Nói cách khác, bạn có muốn các bản sao nông chỉ vì bạn đang phải chịu sự lãng phí băng thông của các bản sao con thường xuyên (re)?

Nếu bạn muốn nhân bản nông để tiết kiệm không gian đĩa cục bộ, thì câu trả lời của Ryan Graham có vẻ là một cách tốt để đi. Tự nhân bản các kho lưu trữ để chúng nông. Nếu bạn nghĩ rằng nó sẽ hữu ích, hãy thích nghi git submoduleđể hỗ trợ nó. Gửi email đến danh sách hỏi về nó (lời khuyên để thực hiện nó, đề xuất trên giao diện, v.v.). Theo tôi, những người có khá nhiều người ủng hộ những người đóng góp tiềm năng muốn tha thiết nâng cao Git theo những cách xây dựng.

Nếu bạn ổn khi thực hiện một bản sao đầy đủ của mỗi mô hình con (cộng với các lần tìm nạp sau để cập nhật chúng), bạn có thể thử sử dụng --referencetùy chọn git submodule update(trong Git 1.6.4 trở lên) để tham khảo các cửa hàng đối tượng cục bộ (ví dụ: tạo các --mirrorbản sao của kho lưu trữ mô đun con chính tắc, sau đó sử dụng --referencetrong các mô hình con của bạn để trỏ đến các bản sao cục bộ này). Chỉ cần chắc chắn để đọc về git clone --reference/ git clone --sharedtrước khi sử dụng --reference. Vấn đề có khả năng duy nhất với gương tham chiếu sẽ là nếu chúng kết thúc tìm nạp các bản cập nhật không chuyển tiếp nhanh (mặc dù bạn có thể bật reflog và mở rộng cửa sổ hết hạn của chúng để giúp giữ lại mọi cam kết bị bỏ rơi có thể gây ra sự cố). Bạn không nên có bất kỳ vấn đề nào miễn là

  • bạn không thực hiện bất kỳ cam kết mô hình con cục bộ nào, hoặc
  • bất kỳ cam kết nào bị bỏ lại do không chuyển tiếp nhanh mà các kho lưu trữ chính tắc có thể xuất bản không phải là tổ tiên cho các cam kết mô hình con cục bộ của bạn, hoặc
  • bạn rất siêng năng trong việc giữ các mô hình con cục bộ của bạn được khởi động lại trên bất kỳ thứ gì không nhanh về phía trước có thể được xuất bản trong kho lưu trữ mô hình con chính tắc.

Nếu bạn đi với một cái gì đó như thế này và có bất kỳ cơ hội nào bạn có thể thực hiện các cam kết mô đun con cục bộ trong cây làm việc của mình, thì có lẽ nên tạo một hệ thống tự động để đảm bảo các đối tượng quan trọng được tham chiếu bởi các mô hình con đã kiểm tra không còn lại lơ lửng trong kho lưu trữ gương (và nếu có bất kỳ được tìm thấy, sao chép chúng vào kho lưu trữ cần chúng).

Và, như git clonetrang man nói, không sử dụng--reference nếu bạn không hiểu những hàm ý này.

# Full clone (mirror), done once.
git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git
git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git

# Reference the full clones any time you initialize a submodule
git clone $super_url super
cd super
git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super
git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super

# To avoid extra packs in each of the superprojects' submodules,
#   update the mirror clones before any pull/merge in super-projects.
for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done

cd super
git pull             # merges in new versions of submodules
git submodule update # update sub refs, checkout new versions,
                     #   but no download since they reference the updated mirrors

Thay vào đó, thay vì . Bạn sẽ cần phải đóng lại bất kỳ mô hình con đã thanh toán hiện có nào để có được các liên kết cứng. Bạn sẽ tiết kiệm băng thông bằng cách chỉ tải xuống một lần vào các gương, sau đó tìm nạp cục bộ từ các tệp đó vào các mô hình con đã kiểm tra. Liên kết cứng sẽ tiết kiệm không gian đĩa (mặc dù các lần tìm nạp có xu hướng tích lũy và được sao chép qua nhiều phiên bản của kho lưu trữ đối tượng của mô đun con đã kiểm tra; liên kết cứng).--reference , bạn có thể sử dụng bản sao nhân bản kết hợp với chức năng liên kết cứng mặc định git clonebằng cách sử dụng máy nhân bản cục bộ làm nguồn cho các mô hình con của bạn. Trong các bản sao siêu dự án mới, hãy làm git submodule init, chỉnh sửa các URL mô hình con .git/configđể chỉ vào các gương cục bộ, sau đó làmgit submodule update


2

Tôi đã tạo ra một phiên bản hơi khác, vì khi nó không chạy ở rìa chảy máu, điều mà không phải dự án nào cũng làm được. Các bổ sung mô hình con tiêu chuẩn không hoạt động cũng như kịch bản ở trên. Vì vậy, tôi đã thêm một tra cứu băm cho thẻ ref và nếu nó không có, nó sẽ trở lại bản sao đầy đủ.

#!/bin/bash
git submodule init
git submodule | while read hash name junk; do
    spath=$(git config -f .gitmodules --get submodule.$name.path)
    surl=$(git config -f .gitmodules --get submodule.$name.url)
    sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d")
    if [ -z $sbr ]; then
        git clone $surl $spath
    else
        git clone -b $sbr --depth 1 --single-branch $surl $spath
    fi
done
git submodule update 

2

Tham khảo Làm thế nào để sao chép kho git với sửa đổi / thay đổi cụ thể?

Tôi đã viết một tập lệnh đơn giản mà không có vấn đề gì khi tham chiếu mô hình con của bạn ở xa chủ

git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'

Tuyên bố này sẽ lấy phiên bản tham chiếu của mô hình con.

Việc này rất nhanh nhưng bạn không thể cam kết chỉnh sửa của mình trên mô hình con (bạn phải tìm nạp nó trước khi https://stackoverflow.com/a/17937889/3156509 )

đầy đủ:

#!/bin/bash
git submodule init
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
git submodule update --recursive

1

Bản sao nông của một mô hình con là hoàn hảo bởi vì chúng chụp nhanh tại một phiên bản / thay đổi cụ thể. Thật dễ dàng để tải xuống một zip từ trang web vì vậy tôi đã cố gắng cho một kịch bản.

#!/bin/bash
git submodule deinit --all -f
for value in $(git submodule | perl -pe 's/.*(\w{40})\s([^\s]+).*/\1:\2/'); do
  mysha=${value%:*}
  mysub=${value#*:}
  myurl=$(grep -A2 -Pi "path = $mysub" .gitmodules | grep -Pio '(?<=url =).*/[^.]+')
  mydir=$(dirname $mysub)
  wget $myurl/archive/$mysha.zip
  unzip $mysha.zip -d $mydir
  test -d $mysub && rm -rf $mysub
  mv $mydir/*-$mysha $mysub
  rm $mysha.zip
done
git submodule init

git submodule deinit --all -f xóa cây mô đun con cho phép tập lệnh có thể tái sử dụng.

git submodulelấy 40 char sha1 theo sau là một đường dẫn tương ứng với cùng .gitmodules. Tôi sử dụng perl để nối thông tin này, được phân cách bằng dấu hai chấm, sau đó sử dụng phép biến đổi để phân tách các giá trị thành myshamysub .

Đây là các khóa quan trọng vì chúng ta cần sha1 để tải xuống và đường dẫn để tương quan với url.gitmodules.

Đưa ra một mục con mô hình điển hình:

[submodule "label"]
    path = localpath
    url = https://github.com/repository.git

myurlCác phím trên path =sau đó nhìn 2 dòng sau để nhận giá trị. Phương pháp này có thể không hoạt động nhất quán và yêu cầu sàng lọc. Url grep loại bỏ mọi .gittham chiếu loại còn lại bằng cách khớp với cuối cùng /và bất cứ điều gì lên đến a ..

mydirmysubtrừ một trận chung kết/name mà thư mục sẽ dẫn đến tên mô hình con.

Tiếp theo là một wget định dạng của url lưu trữ zip có thể tải xuống. Điều này có thể thay đổi trong tương lai.

Giải nén tệp mydirsẽ là thư mục con được chỉ định trong đường dẫn mô hình con. Thư mục kết quả sẽ là thành phần cuối cùng của url- sha1.

Kiểm tra xem liệu thư mục con được chỉ định trong đường dẫn mô đun con có tồn tại không và xóa nó để cho phép đổi tên thư mục được trích xuất.

mv đổi tên thư mục giải nén chứa sha1 của chúng ta thành đường dẫn mô hình chính xác của nó.

Xóa tập tin zip đã tải xuống.

Sơ đồ mô đun

Đây là một bằng chứng WIP về khái niệm hơn là một giải pháp. Khi nó hoạt động, kết quả là một bản sao nông của một mô hình con tại một bộ thay đổi được chỉ định.

Nếu kho lưu trữ lại một mô hình con cho một cam kết khác, hãy chạy lại tập lệnh để cập nhật.

Lần duy nhất một tập lệnh như thế này sẽ hữu ích là cho việc xây dựng địa phương không hợp tác của một dự án nguồn.

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.