Làm cách nào để hoàn nguyên các thay đổi của tôi thành mô hình con git?


270

Tôi có một mô hình con git (RestKit) mà tôi đã thêm vào repo của mình.

Tôi đã vô tình thay đổi một số tệp trong đó và tôi muốn quay lại phiên bản nguồn. Để làm điều đó, tôi đã cố gắng chạy

Mac:app-ios user$ git submodule update RestKit

Nhưng như bạn có thể thấy ở đây, điều này không hoạt động vì nó vẫn là "nội dung được sửa đổi":

Mac:app-ios user$ git status
...
#   modified:   RestKit (modified content)

Cũng

Mac:app-ios user$ git submodule update -f RestKit 

không hoàn nguyên các tập tin sửa đổi cục bộ.
Làm cách nào để đặt lại nội dung của mô hình con đó?


Nếu git reset --hardkhông hoạt động, trước tiên hãy thử chỉ định chi nhánh từ xa với git reset --hard origin/<branch_name>.
Jerry K.

Câu trả lời:


208

Di chuyển vào thư mục của mô hình con, sau đó thực hiện git reset --hardđể đặt lại tất cả các tệp đã sửa đổi về trạng thái cam kết cuối cùng của chúng. Hãy lưu ý rằng điều này sẽ loại bỏ tất cả các thay đổi không cam kết.


6
Cập nhật mô hình con git (ngay cả khi không có --init) hoạt động để tôi từ bỏ "thay đổi" mô hình con khi tôi thực sự không thay đổi bất cứ điều gì. Nếu bạn đi đến thư mục mô hình con và trạng thái git xuất hiện trống, hãy thử điều này thay vì đặt lại.
DNA chiết trung

16
git submodule update --initđã làm cho tôi; không có --initnó không hoạt động.
Per Lundberg

Tuyệt vời!! Tôi đã thực hiện các thay đổi cho mô hình con trong một repo của tôi nơi tôi đã nhập nó. Andthis hoàn nguyên nó trở lại như những gì nó được cho là.
Noitidart

2
thiết lập lại - không làm việc cho tôi, mô hình con của tôi vẫn không thể bị hủy vì những thay đổi cục bộ.
malhal

33
ngoài @markshiz, git submodule update -f --initcho trường hợp của tôi.
otiai10

280

Nếu bạn muốn làm điều này cho tất cả các mô hình con, mà không phải thay đổi thư mục, bạn có thể thực hiện

git submodule foreach git reset --hard

Bạn cũng có thể sử dụng cờ đệ quy để áp dụng cho tất cả các mô hình con:

git submodule foreach --recursive git reset --hard


7
điều này hoạt động tốt hơn nhiều cho tự động hóa hơn là cố gắng cd vào mỗi thư mục mô hình con.
Travis Castillo

4
Lưu ý rằng bạn cũng có thể muốngit submodule foreach --recursive git clean -x -f -d
yoyo

1
trên máy của tôi (Windows sử dụng Git 2.22.0) Tôi cần một dấu ngoặc đơn xung quanh lệnh git thứ hai khi sử dụng cờ --recursive hoặc nó sẽ không hoạt động: git subodule foreach --recursive 'git clean -x -f -d'
aatwo

196

Một phương pháp không an toàn hơn tất cả các câu trả lời trước:

git submodule deinit -f .
git submodule update --init

Lệnh đầu tiên hoàn toàn "hủy liên kết" tất cả các mô hình con, lệnh thứ hai sau đó thực hiện kiểm tra mới chúng.
Nó mất nhiều thời gian hơn các phương thức khác, nhưng sẽ hoạt động bất kể trạng thái của các mô đun con của bạn.


1
Đáng tiếc điều này không hoạt động trong trường hợp của tôi (với các tệp cục bộ đã sửa đổi trong mô hình con git), lệnh "update --init" spewserror: Your local changes to the following files would be overwritten by checkout
rogerdpack

Để cập nhật mô hình con cụ thể, hãy thực hiện: $ git Subodule deinit -f - <subsodule_path> và sau đó cập nhật mô hình con $ git --init - <subsodule_path>
Priyank

Tôi đã thử tất cả các phương pháp trên cho đến khi tôi nhận được phương pháp này. Đối với tôi, đây là chỉ có một mà có git tôi tìm kiếm "sạch" (không có *trong tôi PS1git status -unokhông thể giải thích).
Guy Rapaport

60

Tốt cho tôi, có

git reset --hard

chỉ cần đặt lại mô hình con về trạng thái mà nó đã kiểm tra, không cần thiết cho cam kết / trạng thái tham chiếu repo của chính. Tôi vẫn sẽ có "nội dung sửa đổi" như OP đã nói. Vì vậy, để đưa mô hình con trở lại cam kết sửa lỗi, tôi chạy:

git submodule update --init

Sau đó, khi tôi làm git status, nó sạch trên mô hình con.


rất tiếc submodule update --initlà dường như không hoàn nguyên các sửa đổi cục bộ trong trường hợp của tôi: |
rogerdpack

48

làm 4 bước tuần tự:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f

2
Người duy nhất đã giúp tôi là tốt.
Victor Sergienko

Câu hỏi, nếu mô hình con là mới, sẽ không có tệp .git trong thư mục đó, đúng không? bong bóng lệnh git cho repo cha?
santiago arizti

1
@jiahut Ngay cả sau khi làm điều này, tôi vẫn có "(cam kết mới") bên cạnh mô hình con của mình khi thực hiện 'trạng thái git' từ cha mẹ?
David Doria

1
@DavidDoria git submodule updatelà những gì đã cố định (new commits)cho tôi.
ubershmekel

31

Điều này làm việc cho tôi, bao gồm đệ quy thành các mô đun con (có lẽ đó là lý do tại sao -f của bạn không hoạt động, vì bạn đã thay đổi một mô hình con bên trong mô hình con):

git submodule update -f --recursive

11

Trước tiên hãy thử điều này, như những người khác đã nói:

git submodule update --init

Nếu điều đó không hoạt động, hãy thay đổi thư mục mô hình con và sử dụng lệnh sau để xem liệu có bất kỳ thay đổi nào đối với mô hình con không:

git status

Nếu có thay đổi đối với mô hình con của bạn, hãy loại bỏ chúng. Xác minh rằng bạn không thể thấy bất kỳ thay đổi nào khi bạn chạy "trạng thái git".

Tiếp theo, quay trở lại kho lưu trữ chính và chạy lại "git subodule update --init".


9

Kể từ Git 2.14 (quý 3 năm 2017), bạn không cần phải đi vào từng mô hình con để thực hiện git reset(như trong git submodule foreach git reset --hard)

Đó là bởi vì git reset chính nó bây giờ biết làm thế nào để đệ quy đi vào các mô hình con.

Xem cam kết 35b96d1 (ngày 21 tháng 4 năm 2017) và cam kết f2d4899 , cam kết 823bab0 , cam kết cd279e2 (18 tháng 4 năm 2017) của Stefan Beller ( stefanbeller) .
(Được hợp nhất bởi Junio ​​C Hamano - gitster- trong cam kết 5f074ca , ngày 29 tháng 5 năm 2017)

dựng sẵn / thiết lập lại: thêm --recurse-mô đun con

git-reset là một trình điều khiển cây làm việc khác, cần được dạy về các mô đun con.

Khi người dùng sử dụng git-reset và yêu cầu lặp lại thành các mô hình con, điều này sẽ đặt lại các mô hình con thành tên đối tượng như được ghi trong siêu dự án, tách ra các ĐẦU.

Cảnh báo : sự khác biệt giữa:

  • git reset --hard --recurse-submodule
  • git submodule foreach git reset --hard

là cái trước cũng sẽ thiết lập lại cây làm việc repo cha mẹ chính của bạn, vì cái sau sẽ chỉ đặt lại cây làm việc mô đun con.
Vì vậy, sử dụng một cách thận trọng.


7

Đối với git <= 2.13, hai lệnh này được kết hợp sẽ đặt lại repos của bạn với các mô đun con đệ quy:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init

3

Điều này hoạt động với các thư viện của chúng tôi chạy GIT v1.7.1, nơi chúng tôi có repo gói DEV và repo gói LIVE. Bản thân các kho lưu trữ không có gì ngoài vỏ để đóng gói tài sản cho một dự án. tất cả các mô hình con.

LIVE không bao giờ được cập nhật có chủ ý, tuy nhiên các tệp bộ đệm hoặc tai nạn có thể xảy ra, khiến repo bị bẩn. Các mô hình con mới được thêm vào DEV cũng phải được khởi tạo trong LIVE.

Kho lưu trữ gói trong DEV

Ở đây chúng tôi muốn kéo tất cả các thay đổi ngược dòng mà chúng tôi chưa biết, sau đó chúng tôi sẽ cập nhật kho lưu trữ gói của chúng tôi.

# Recursively reset to the last HEAD
git submodule foreach --recursive git reset --hard

# Recursively cleanup all files and directories
git submodule foreach --recursive git clean -fd

# Recursively pull the upstream master
git submodule foreach --recursive git pull origin master

# Add / Commit / Push all updates to the package repo
git add .
git commit -m "Updates submodules"
git push   

Gói lưu trữ trong LIVE

Ở đây chúng tôi muốn lấy các thay đổi được cam kết với kho DEV, nhưng không biết các thay đổi ngược dòng.

# Pull changes
git pull

# Pull status (this is required for the submodule update to work)
git status

# Initialize / Update 
git submodule update --init --recursive

2

Nếu bạn muốn loại bỏ tất cả các thay đổi trong toàn bộ kho lưu trữ cùng với các mô-đun phụ, bạn có thể sử dụng

git restore . --recurse-submodules

Điều này sẽ hoàn tác tất cả các thay đổi được thực hiện trong kho lưu trữ và trong các mô-đun phụ.


0

cách của tôi để thiết lập lại tất cả các mô hình con (KHÔNG tách rời và giữ nhánh "chính" của chúng):

git subodule foreach 'git checkout master && git reset --hard $ sha1'

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.