Saya memiliki skrip yang berjalan rsync
dengan direktori kerja Git sebagai tujuan. Saya ingin skrip memiliki perilaku yang berbeda tergantung pada apakah direktori kerja bersih (tidak ada perubahan untuk dikomit), atau tidak. Misalnya, jika outputnya git status
seperti di bawah ini, saya ingin skrip keluar:
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
Jika direktori tidak bersih maka saya ingin menjalankan beberapa perintah lagi.
Bagaimana saya bisa memeriksa output seperti di atas dalam skrip shell?
shell-script
git
brentwpeterson
sumber
sumber
git reset --hard origin/branch
jika itu yang Anda inginkan ... seperti jika Anda mencoba untuk membersihkan setelah mengkompilasi sesuatu, dll.Jawaban:
Mengurai output
git status
adalah ide yang buruk karena output dimaksudkan agar dapat dibaca oleh manusia, tidak dapat dibaca mesin. Tidak ada jaminan bahwa output akan tetap sama di versi Git yang akan datang atau di lingkungan yang dikonfigurasi secara berbeda.Komentar UVV ada di jalur yang benar, tetapi sayangnya kode pengembalian
git status
tidak berubah ketika ada perubahan yang tidak dikomit. Namun, ia menyediakan--porcelain
opsi, yang menyebabkan outputgit status --porcelain
diformat dalam format skrip yang mudah diurai, dan akan tetap stabil di seluruh versi Git dan terlepas dari konfigurasi pengguna.Kita dapat menggunakan output kosong
git status --porcelain
sebagai indikator bahwa tidak ada perubahan yang dilakukan:Jika kami tidak peduli dengan file yang tidak dilacak dalam direktori kerja, kami dapat menggunakan
--untracked-files=no
opsi untuk mengabaikannya:Untuk menjadikan ini lebih kuat terhadap kondisi yang sebenarnya menyebabkan
git status
kegagalan tanpa hasilstdout
, kami dapat mempersempit pemeriksaan ke:Ini juga diperhatikan bahwa, meskipun
git status
tidak memberikan kode keluar berarti ketika direktori kerja najis,git diff
memberikan--exit-code
pilihan, yang membuatnya berperilaku mirip dengan diff utilitas, yaitu, keluar dengan statusnya1
ketika ada perbedaan dan0
ketika tidak ditemukan.Dengan ini, kita dapat memeriksa perubahan yang tidak dipentaskan dengan:
dan dipentaskan, tetapi tidak melakukan perubahan dengan:
Meskipun
git diff
dapat melaporkan file yang tidak dilacak dalam submodul melalui argumen yang sesuai--ignore-submodules
, sayangnya tampaknya tidak ada cara untuk melaporkannya pada file yang tidak dilacak dalam direktori kerja yang sebenarnya. Jika file yang tidak dilacak dalam direktori kerja relevan,git status --porcelain
mungkin itu yang terbaik.sumber
git status --porcelain
akan keluar dengan kode 0 bahkan jika ada perubahan tidak dilakukan untuk file komit dan tidak terlacak.git stash
akan melakukan sesuatu (itu tidak menghasilkan kode pengembalian yang berguna). Saya harus menambahkan--ignore-submodules
karena jika tidakgit status
akan menunjukkan perubahan submodule yanggit stash
mengabaikan.if [ -z
sedang dilakukan. The-z
berarti bahwa jika string berikut kosong, jika mengevaluasi ketrue
. Dengan kata lain, jika ini tidakgit status --porcelain
menghasilkan string, repo bersih. Jika tidak, daftar file yang diubah / ditambahkan / dihapus dan tidak lagi menjadi string kosong. Theif
kemudian mengevaluasi kefalse
.Menggunakan:
Kode kembali mencerminkan keadaan direktori kerja (0 = bersih, 1 = kotor). File yang tidak dilacak diabaikan.
sumber
git update-index --refresh
sebelumnyagit diff-index HEAD
. Info lebih lanjut: stackoverflow.com/q/34807971/1407170git add .
sebelum menerbitkannya. Biasanya ini cara menggunakannya dalam naskahset +e
sebelum panggilan kegit
, dan menambahkanset -e
lagi setelah Anda mengevaluasi$?
.Ekstensi kecil untuk jawaban André yang luar biasa .
Ini adalah salah satu cara untuk mengevaluasi hasil dan juga menghindari jebakan jika Anda berada dalam skrip yang sebelumnya diterbitkan set -e .
File yang tidak dilacak diabaikan.
sumber