Bagaimana cara mengembalikan perubahan saya ke submodule git?

271

Saya memiliki submodule git (RestKit) yang telah saya tambahkan ke repo saya.

Saya tidak sengaja mengubah beberapa file di sana dan saya ingin kembali ke versi sumber. Untuk melakukan itu, saya mencoba lari

Mac:app-ios user$ git submodule update RestKit

Tetapi seperti yang Anda lihat di sini, ini tidak berfungsi karena masih "konten yang dimodifikasi":

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

Bahkan

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

tidak mengembalikan file yang dimodifikasi secara lokal.
Bagaimana cara mereset konten submodule itu?

Eric
sumber
Jika git reset --hardtidak berhasil, pertama-tama coba tentukan cabang jarak jauh dengan git reset --hard origin/<branch_name>.
Jerry K.

Jawaban:

209

Pindah ke direktori submodule, lalu lakukan git reset --harduntuk mengatur ulang semua file yang diubah ke status komitmen terakhir mereka. Ketahuilah bahwa ini akan membuang semua perubahan yang tidak dilakukan.

Jamie Penney
sumber
6
pembaruan submodule git (bahkan tanpa --init) bekerja agar saya mengabaikan submodule "perubahan" ketika saya tidak benar-benar mengubah apa pun. Jika Anda pergi ke direktori submodule dan status git muncul kosong, coba ini alih-alih reset.
DNA eklektik
16
git submodule update --initbekerja untuk saya; tanpanya --inittidak bekerja sama sekali.
Per Lundberg
Hebat!! Saya membuat perubahan pada submodule dalam repo milik saya tempat saya mengimpornya. Dan ini mengembalikannya kembali ke apa yang seharusnya.
Noitidart
2
reset --hard tidak bekerja untuk saya, submodule saya masih tidak dapat deinit karena perubahan lokal.
Malhal
33
selain @markshiz, git submodule update -f --inituntuk kasus saya.
otiai10
280

Jika Anda ingin melakukan ini untuk semua submodul, tanpa harus mengubah direktori, Anda dapat melakukannya

git submodule foreach git reset --hard

Anda juga dapat menggunakan bendera rekursif untuk diterapkan ke semua submodul:

git submodule foreach --recursive git reset --hard

gagak
sumber
7
ini bekerja jauh lebih baik untuk otomasi daripada mencoba cd ke setiap direktori submodule.
Travis Castillo
4
Perhatikan bahwa Anda mungkin juga ingingit submodule foreach --recursive git clean -x -f -d
yoyo
1
di komputer saya (Windows menggunakan Git 2.22.0) Saya perlu tanda kutip tunggal di sekitar perintah git kedua saat menggunakan --recursive flag atau tidak akan berfungsi: git submodule foreach - 'git clean -x -f -d' rekursif
aatwo
196

Metode yang lebih aman dari semua jawaban sebelumnya:

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

Perintah pertama benar-benar "melepaskan" semua submodul, yang kedua kemudian membuat checkout baru dari mereka.
Dibutuhkan lebih lama daripada metode lain, tetapi akan bekerja apa pun keadaan submodul Anda.

qwertzguy
sumber
1
Sayangnya ini tidak bekerja dalam kasus saya (dengan file lokal yang dimodifikasi dalam git submodule), perintah "update --init" spewserror: Your local changes to the following files would be overwritten by checkout
rogerdpack
Untuk memperbarui submodule tertentu, lakukan: $ git submodule deinit -f - <submodule_path> dan kemudian $ git pembaruan submodule --init - <submodule_path>
Priyank
Saya mencoba semua metode di atas sampai saya mendapatkan yang ini. Bagi saya, ini adalah satu-satunya yang membuat git saya terlihat "bersih" (tanpa *saya PS1yang git status -unotidak dapat menjelaskan).
Guy Rapaport
60

Bagi saya, memiliki

git reset --hard

atur ulang submodule ke status di mana ia diperiksa, tidak perlu ke komit / status referensi repo utama. Saya masih akan memiliki "konten yang dimodifikasi" seperti kata OP. Jadi, untuk mendapatkan kembali submodule ke komit koreksi, saya menjalankan:

git submodule update --init

Lalu ketika saya melakukannya git status, itu bersih pada submodule.

checksum
sumber
sayangnya submodule update --initsepertinya tidak mengembalikan modifikasi lokal dalam kasus saya: |
rogerdpack
48

lakukan 4 langkah berurutan:

git submodule foreach git reset --hard HEAD
git submodule update
git submodule foreach "git checkout master; git pull"
git submodule foreach git clean -f
jiahut
sumber
2
Satu-satunya yang membantu saya juga.
Victor Sergienko
pertanyaan, jika submodule baru, tidak akan ada file .git di dalam direktori itu, benar? akankah perintah git gelembung ke repo induk?
santiago arizti
1
@jiahut Bahkan setelah melakukan ini, saya masih memiliki "(komit baru") di sebelah submodule saya ketika melakukan 'git status' dari orang tua?
David Doria
1
@ Davidvidoria git submodule updateadalah apa yang diperbaiki (new commits)untuk saya.
ubershmekel
31

Ini bekerja untuk saya, termasuk secara rekursif menjadi submodula (mungkin itu sebabnya -f Anda tidak berfungsi, karena Anda mengubah submodule di dalam submodule):

git submodule update -f --recursive
Sergiu Todirascu
sumber
12

Pertama coba ini, seperti yang orang lain katakan:

git submodule update --init

Jika itu tidak berhasil, ubah ke direktori submodule dan gunakan perintah berikut untuk melihat apakah ada perubahan pada submodule:

git status

Jika ada perubahan pada submodule Anda, singkirkan. Pastikan Anda tidak dapat melihat perubahan apa pun saat menjalankan "git status".

Selanjutnya, kembali ke repositori utama dan jalankan "git submodule update --init" lagi.

Jean Libera
sumber
9

Sejak Git 2.14 (Q3 2017), Anda tidak harus masuk ke setiap submodule untuk melakukan git reset(seperti pada git submodule foreach git reset --hard)

Itu karena git reset sendiri tahu sekarang bagaimana secara rekursif masuk ke submodules.

Lihat komit 35b96d1 (21 Apr 2017), dan komit f2d4899 , komit 823bab0 , komit cd279e2 (18 Apr 2017) oleh Stefan Beller ( stefanbeller) .
(Digabung oleh Junio ​​C Hamano - gitster- di commit 5f074ca , 29 Mei 2017)

builtin / reset: tambahkan --recurse-submodules switch

git-reset adalah manipulator pohon yang berfungsi, yang harus diajarkan tentang submodul.

Ketika seorang pengguna menggunakan git-reset dan meminta untuk kembali menjadi submodul, ini akan mengatur ulang submodul ke nama objek seperti dicatat dalam proyek super, melepaskan HEADs.

Peringatan : perbedaan antara:

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

adalah bahwa yang pertama juga akan mereset pohon induk repo induk utama Anda, karena yang terakhir hanya akan mengatur ulang pohon kerja submodula.
Jadi gunakan dengan hati-hati.

VONC
sumber
7

Untuk git <= 2.13 kedua perintah ini dikombinasikan akan mengatur ulang repo Anda dengan submodul rekursif:

git submodule foreach --recursive git reset --hard
git submodule update --recursive --init
cmcginty
sumber
3

Ini berfungsi dengan perpustakaan kami yang menjalankan GIT v1.7.1, di mana kami memiliki repo paket DEV dan repo paket LIVE. Repositori itu sendiri hanyalah cangkang untuk mengemas aset untuk suatu proyek. semua submodul.

LIVE tidak pernah diperbarui dengan sengaja, namun file cache atau kecelakaan dapat terjadi, sehingga repo kotor. Subkodul baru yang ditambahkan ke DEV juga harus diinisialisasi dalam LIVE.

Paket Repositori dalam DEV

Di sini kami ingin menarik semua perubahan hulu yang belum kami sadari, kemudian kami akan memperbarui repositori paket kami.

# 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   

Paket Repositori dalam LIVE

Di sini kami ingin menarik perubahan yang dikomit ke repositori DEV, tetapi bukan perubahan hulu yang tidak diketahui.

# Pull changes
git pull

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

# Initialize / Update 
git submodule update --init --recursive
David H.
sumber
2

Jika Anda ingin membuang semua perubahan di seluruh repositori bersama dengan sub modul, Anda dapat menggunakan

git restore . --recurse-submodules

Ini akan membatalkan semua perubahan yang dibuat dalam repositori dan dalam sub modul.

Nitin Garg
sumber
0

cara saya untuk mengatur ulang semua submodula (TANPA melepaskan & menjaga cabang "master" mereka):

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

alex_1948511
sumber