Có vẻ như hai kịch bản khác nhau đang được trộn lẫn với nhau trong cuộc thảo luận này:
cảnh 1
Sử dụng các con trỏ của kho lưu trữ cha mẹ của tôi cho các mô hình con, tôi muốn kiểm tra cam kết trong mỗi mô hình con mà kho lưu trữ mẹ đang trỏ tới, có thể sau lần lặp đầu tiên qua tất cả các mô hình con và cập nhật / kéo chúng từ xa.
Điều này, như đã chỉ ra, được thực hiện với
git submodule foreach git pull origin BRANCH
git submodule update
Kịch bản 2, mà tôi nghĩ là những gì OP đang nhắm đến
Nội dung mới đã xảy ra trong một hoặc nhiều mô hình con và tôi muốn 1) kéo các thay đổi này và 2) cập nhật kho lưu trữ cha mẹ để trỏ đến cam kết CHÍNH (mới nhất) của các mô hình con này.
Điều này sẽ được thực hiện bởi
git submodule foreach git pull origin BRANCH
git add module_1_name
git add module_2_name
......
git add module_n_name
git push origin BRANCH
Không thực tế lắm, vì bạn sẽ phải mã hóa n đường dẫn đến tất cả các mô hình con n, ví dụ như một tập lệnh để cập nhật các con trỏ cam kết của kho lưu trữ mẹ.
Sẽ thật tuyệt khi có một lần lặp tự động thông qua mỗi mô hình con, cập nhật con trỏ kho lưu trữ cha mẹ (sử dụng git add
) để trỏ đến phần đầu của mô hình con.
Đối với điều này, tôi đã thực hiện kịch bản Bash nhỏ này:
git-update-submodules.sh
#!/bin/bash
APP_PATH=$1
shift
if [ -z $APP_PATH ]; then
echo "Missing 1st argument: should be path to folder of a git repo";
exit 1;
fi
BRANCH=$1
shift
if [ -z $BRANCH ]; then
echo "Missing 2nd argument (branch name)";
exit 1;
fi
echo "Working in: $APP_PATH"
cd $APP_PATH
git checkout $BRANCH && git pull --ff origin $BRANCH
git submodule sync
git submodule init
git submodule update
git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"
for i in $(git submodule foreach --quiet 'echo $path')
do
echo "Adding $i to root repo"
git add "$i"
done
git commit -m "Updated $BRANCH branch of deployment repo to point to latest head of submodules"
git push origin $BRANCH
Để chạy nó, thực thi
git-update-submodules.sh /path/to/base/repo BRANCH_NAME
Xây dựng
Trước hết, tôi giả sử rằng nhánh có tên $ BRANCH (đối số thứ hai) tồn tại trong tất cả các kho lưu trữ. Hãy làm cho điều này thậm chí còn phức tạp hơn.
Một vài phần đầu tiên là một số kiểm tra rằng các đối số là có. Sau đó, tôi lấy nội dung mới nhất của kho lưu trữ cha mẹ (tôi thích sử dụng --ff (chuyển tiếp nhanh) bất cứ khi nào tôi chỉ thực hiện thao tác kéo. Tôi đã loại bỏ, BTW).
git checkout $BRANCH && git pull --ff origin $BRANCH
Sau đó, một số khởi tạo mô hình con, có thể là cần thiết, nếu các mô hình con mới đã được thêm hoặc chưa được khởi tạo:
git submodule sync
git submodule init
git submodule update
Sau đó, tôi cập nhật / kéo tất cả các mô hình con:
git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"
Lưu ý một số điều: Trước hết, tôi đang xâu chuỗi một số lệnh Git bằng cách sử dụng &&
- có nghĩa là lệnh trước đó phải thực thi mà không gặp lỗi.
Sau khi kéo thành công có thể (nếu tìm thấy công cụ mới trên điều khiển từ xa), tôi thực hiện một cú đẩy để đảm bảo rằng một cam kết hợp nhất có thể không bị bỏ lại trên máy khách. Một lần nữa, nó chỉ xảy ra nếu một cú kéo thực sự mang lại những thứ mới.
Cuối cùng, trận chung kết || true
đảm bảo rằng kịch bản tiếp tục bị lỗi. Để thực hiện công việc này, mọi thứ trong phép lặp phải được gói trong dấu ngoặc kép và các lệnh Git được gói trong dấu ngoặc đơn (ưu tiên toán tử).
Phần ưa thích của tôi:
for i in $(git submodule foreach --quiet 'echo $path')
do
echo "Adding $i to root repo"
git add "$i"
done
Lặp lại tất cả các mô hình con - với --quiet
, loại bỏ đầu ra 'Nhập MODULE_PATH'. Sử dụng'echo $path'
(phải ở trong dấu ngoặc đơn), đường dẫn đến mô hình con được ghi vào đầu ra.
Danh sách các đường dẫn mô hình con tương đối này được ghi lại trong một mảng ( $(...)
) - cuối cùng lặp lại điều này và làm git add $i
để cập nhật kho lưu trữ mẹ.
Cuối cùng, một cam kết với một số thông báo giải thích rằng kho lưu trữ mẹ đã được cập nhật. Cam kết này sẽ bị bỏ qua theo mặc định, nếu không có gì được thực hiện. Đẩy cái này về nguồn gốc, và bạn đã hoàn thành.
Tôi có một kịch bản chạy chương trình này trong một công việc của Jenkins , chuỗi này được triển khai tự động theo lịch trình sau đó và nó hoạt động như một cơ duyên.
Tôi hy vọng điều này sẽ giúp ích cho ai đó.
--remote
tùy chọn, có lẽ sẽ hữu ích khi đánh dấu đó là câu trả lời được chấp nhận thay vì cách tiếp cận "bằng tay" trong câu trả lời của Jason?