Bagaimana saya bisa mengecek apakah saya memiliki perubahan yang tidak dikomit di repositori git saya:
- Perubahan ditambahkan ke indeks tetapi tidak dilakukan
- File yang tidak dilacak
dari naskah?
git-status
tampaknya selalu mengembalikan nol dengan git versi 1.6.4.2.
diff
menunjukkan ada atau tidaknya perbedaan daripada keberhasilan menjalankan perintah maka Anda perlu menggunakan--exit-code
atau--quiet
. Perintah git umumnya sangat konsisten dengan mengembalikan kode keluar nol atau tidak nol untuk menunjukkan keberhasilan perintah.Jawaban:
Waktu yang tepat! Saya menulis posting blog tentang hal ini beberapa hari yang lalu, ketika saya menemukan cara untuk menambahkan informasi status git ke prompt saya.
Inilah yang saya lakukan:
Untuk status kotor:
Untuk file yang tidak dilacak (Perhatikan
--porcelain
tandagit status
yang memberi Anda hasil parse -able yang bagus):Meskipun
git diff --shortstat
lebih nyaman, Anda juga dapat menggunakangit status --porcelain
untuk mendapatkan file kotor:Catatan:
2>/dev/null
Filter menyaring pesan kesalahan sehingga Anda dapat menggunakan perintah ini pada direktori non-git. (Mereka hanya akan kembali0
untuk jumlah file.)Edit :
Inilah pos-posnya:
Menambahkan Informasi Status Git ke Prompt Terminal Anda
Prompt Shell yang diaktifkan dengan Git
sumber
__git_ps1
. Ini menunjukkan nama-nama cabang, termasuk perlakuan khusus jika Anda sedang dalam proses rebase, sedang mendaftar, bergabung, atau membagi dua. Dan Anda dapat mengatur variabel lingkunganGIT_PS1_SHOWDIRTYSTATE
untuk mendapatkan tanda bintang untuk perubahan yang tidak dipentaskan dan plus untuk perubahan yang dipentaskan. (Saya pikir Anda juga bisa mendapatkannya untuk menunjukkan file yang tidak terlacak, dan memberi Anda beberapagit-describe
output)git diff --shortstat
akan memberikan false negative jika perubahan sudah ada dalam indeks.git status --porcelain
lebih disukai, karenagit diff --shortstat
tidak akan menangkap file kosong yang baru dibuat. Anda dapat mencobanya di setiap pohon yang bersih:touch foo && git diff --shortstat
Kunci untuk “scripting” Git yang andal adalah menggunakan perintah 'plumbing'.
Pengembang berhati-hati ketika mengubah perintah plumbing untuk memastikan mereka menyediakan antarmuka yang sangat stabil (yaitu kombinasi yang diberikan keadaan repositori, stdin, opsi baris perintah, argumen, dll. Akan menghasilkan output yang sama di semua versi Git di mana perintah / opsi ada). Variasi keluaran baru dalam perintah plumbing dapat diperkenalkan melalui opsi baru, tetapi itu tidak dapat memperkenalkan masalah untuk program yang telah ditulis terhadap versi yang lebih lama (mereka tidak akan menggunakan opsi baru, karena tidak ada (atau setidaknya ada tidak digunakan) pada saat skrip ditulis).
Sayangnya perintah Git 'sehari-hari' adalah perintah 'porselen', sehingga sebagian besar pengguna Git mungkin tidak terbiasa dengan perintah pipa ledeng. Perbedaan antara perintah porselen dan pipa ledeng dibuat di halaman utama git (lihat subbagian berjudul Perintah tingkat tinggi (porselen) dan perintah tingkat rendah (pipa ledeng) .
Untuk mengetahui tentang perubahan yang tidak dikomit, Anda mungkin perlu
git diff-index
(membandingkan indeks (dan mungkin melacak bit pohon kerja) dengan beberapa pohon lain (misalnyaHEAD
)), mungkingit diff-files
(membandingkan pohon kerja dengan indeks), dan mungkingit ls-files
(daftar file, misalnya daftar tidak terlacak , file tidak ditandai).(Perhatikan bahwa dalam perintah di bawah ini,
HEAD --
digunakan sebagai gantiHEAD
karena jika tidak, perintah gagal jika ada file bernamaHEAD
.)Untuk memeriksa apakah repositori telah melakukan perubahan (belum berkomitmen) gunakan ini:
0
maka tidak ada perbedaan (1
berarti ada perbedaan).Untuk memeriksa apakah pohon yang bekerja memiliki perubahan yang dapat dipentaskan:
git diff-index
(0
== tidak ada perbedaan;1
== perbedaan).Untuk memeriksa apakah kombinasi indeks dan file yang dilacak di pohon kerja memiliki perubahan sehubungan dengan
HEAD
:HEAD
). Dalam situasi yang sama ini, kedua perintah yang terpisah akan menghasilkan laporan "perbedaan yang ada".Anda juga menyebutkan file yang tidak dilacak. Anda mungkin berarti "tidak terlacak dan tidak ditandai", atau Anda mungkin berarti "tidak terlacak" (termasuk file yang diabaikan). Apa pun itu,
git ls-files
adalah alat untuk pekerjaan itu:Untuk "tidak terlacak" (akan menyertakan file yang diabaikan, jika ada):
Untuk "tidak terlacak dan tidak ditandai":
Pikiran pertama saya adalah memeriksa apakah perintah ini memiliki output:
0
maka tidak ada file yang tidak terlacak. Jika keluar1
maka ada file yang tidak terlacak.Ada kemungkinan kecil bahwa ini akan menerjemahkan keluar abnormal dari
git ls-files
menjadi "tidak ada file terlacak" laporan (keduanya menghasilkan keluar tidak nol dari perintah di atas). Versi yang sedikit lebih kuat mungkin terlihat seperti ini:git ls-files
untuk menyebar. Dalam hal ini, jalan keluar yang tidak nol dapat berarti “ada file yang tidak dilacak” atau itu bisa berarti kesalahan terjadi. Jika Anda ingin hasil "kesalahan" dikombinasikan dengan hasil "tidak ada file yang tidak terlacak", gunakantest -n "$u"
(di mana keluar0
berarti "beberapa file yang tidak terlacak", dan bukan-nol berarti kesalahan atau "tidak ada file yang tidak dilacak").Gagasan lain adalah menggunakan
--error-unmatch
untuk menyebabkan keluar non-nol ketika tidak ada file yang tidak terlacak. Ini juga berisiko menyatukan "tidak ada file yang tidak dilacak" (keluar1
) dengan "terjadi kesalahan" (keluar bukan nol, tapi mungkin128
). Tetapi memeriksa untuk kode keluar0
vs.1
vs bukan nol mungkin cukup kuat:Salah satu
git ls-files
contoh di atas dapat diambil--exclude-standard
jika Anda ingin mempertimbangkan hanya file yang tidak terlacak dan tidak di-retensi.sumber
git ls-files --others
memberikan file lokal tidak terlacak, sedangkangit status --porcelain
jawaban yang diterima memberikan semua file tidak terlacak yang berada di bawah repositori git. Saya bukan yang mana dari poster asli yang diinginkan, tetapi perbedaan antara keduanya menarik.--error-unmatch
. Coba (misalnya)git ls-files --other --error-unmatch --exclude-standard .
(catat periode trailing, ini merujuk pada cwd; jalankan ini dari direktori tingkat atas pohon yang bekerja).git update-index -q --refresh
sebelumdiff-index
untuk menghindari beberapa "false positive" yang disebabkan oleh ketidakcocokan stat (2) informasi.git update-index
kebutuhan! Ini penting jika ada sesuatu yang menyentuh file tanpa membuat modifikasi.--porcelain
daftar solusi semua file yang tidak terlacak ditemukan di seluruh git repositori (file dikurangi git-diabaikan), bahkan jika Anda berada di dalam salah satu subdirektorinya.Dengan asumsi Anda menggunakan git 1.7.0 atau lebih baru ...
Setelah membaca semua jawaban di halaman ini dan beberapa percobaan, saya pikir metode yang menyentuh kombinasi yang tepat antara kebenaran dan singkatnya adalah:
Sementara git memungkinkan banyak nuansa antara apa yang dilacak, abaikan, tidak terlacak tetapi tidak ditandai, dan seterusnya, saya percaya kasus penggunaan yang umum adalah untuk mengotomatiskan skrip pembuatan, di mana Anda ingin menghentikan semuanya jika checkout Anda tidak bersih.
Dalam hal ini, masuk akal untuk mensimulasikan apa yang akan dilakukan programmer: ketik
git status
dan lihat outputnya. Tetapi kami tidak ingin mengandalkan kata-kata tertentu yang muncul, jadi kami menggunakan--porcelain
mode yang diperkenalkan di 1.7.0; ketika diaktifkan, direktori bersih tidak menghasilkan output.Kemudian kita gunakan
test -n
untuk melihat apakah ada output atau tidak.Perintah ini akan mengembalikan 1 jika direktori kerja bersih dan 0 jika ada perubahan yang harus dilakukan. Anda dapat mengubah
-n
ke-z
jika Anda menginginkan yang sebaliknya. Ini berguna untuk merantai ini ke perintah dalam skrip. Sebagai contoh:Ini secara efektif mengatakan "baik tidak ada perubahan yang dibuat atau mematikan alarm"; one-liner ini mungkin lebih disukai daripada jika-pernyataan tergantung pada skrip yang Anda tulis.
sumber
test -n "$(git diff origin/$branch)"
, untuk membantu mencegah komitmen lokal agar tidak diizinkan dalam penerapanImplementasi dari jawaban VonC :
sumber
Telah melihat beberapa jawaban ini ... (dan memiliki berbagai masalah pada * nix dan windows, yang merupakan persyaratan yang saya miliki) ... menemukan berikut ini berfungsi dengan baik ...
Untuk memeriksa kode keluar di * nix
Untuk memeriksa kode keluar di jendela $
Bersumber dari https://github.com/sindresorhus/pure/issues/115 Terima kasih kepada @paulirish pada pos itu untuk berbagi
sumber
Mengapa tidak merangkum '
git status
dengan skrip yang:Dengan begitu, Anda dapat menggunakan status 'yang disempurnakan' itu dalam skrip Anda.
Seperti yang 0xfe sebutkan dalam jawabannya yang luar biasa ,
git status --porcelain
sangat berperan dalam solusi berbasis skrip apa punsumber
Satu kemungkinan DIY, diperbarui untuk mengikuti saran 0xfe
Seperti dicatat oleh Chris Johnsen , ini hanya bekerja pada Git 1.7.0 atau lebih baru.
sumber
--porcelain
bendera ditambahkan? Tidak bekerja dengan 1.6.4.2.git status --short
begitu.git status --porcelain
dangit status --short
keduanya diperkenalkan pada 1.7.0.--porcelain
Itu diperkenalkan khusus untuk memungkinkangit status --short
untuk memvariasikan formatnya di masa depan. Jadi,git status --short
akan mengalami masalah yang sama sepertigit status
(output dapat berubah sewaktu-waktu karena itu bukan perintah 'plumbing').Saya cukup sering membutuhkan cara sederhana untuk gagal membangun jika pada akhir eksekusi ada file yang dilacak yang dimodifikasi atau file yang tidak terlacak yang tidak diabaikan.
Ini cukup penting untuk menghindari kasus di mana build menghasilkan sisa makanan.
Sejauh ini, perintah terbaik yang saya gunakan adalah:
Ini mungkin terlihat agak rumit dan saya akan sangat menghargai jika ada yang menemukan varian singkat bahwa ini mempertahankan perilaku yang diinginkan:
sumber
@ eduard-wirch jawabannya cukup lengkap, tetapi karena saya ingin memeriksa keduanya sekaligus, inilah varian terakhir saya.
Ketika tidak mengeksekusi menggunakan set -e atau yang setara, kita malah bisa melakukan
u="$(git ls-files --others)" || exit 1
(atau mengembalikan jika ini berfungsi untuk fungsi yang digunakan)Jadi untracked_files, hanya disetel jika perintah berhasil dengan benar.
setelah itu, kita dapat memeriksa kedua properti, dan mengatur variabel (atau apa pun).
sumber
Ini adalah variasi yang lebih ramah shell untuk mengetahui apakah ada file yang tidak dilacak ada di repositori:
Ini tidak memotong proses kedua
grep
,, dan tidak perlu memeriksa apakah Anda berada di repositori git atau tidak. Yang berguna untuk prompt shell, dll.sumber
Anda juga bisa melakukannya
. Ini akan menambahkan kata "-dirty" di akhir jika mendeteksi pohon yang bekerja kotor. Menurut
git-describe(1)
:. Peringatan: file yang tidak dilacak tidak dianggap "kotor", karena, seperti yang dinyatakan dalam manual, itu hanya peduli pada pohon yang berfungsi.
sumber
Mungkin ada kombinasi yang lebih baik dari jawaban dari thread ini .. tapi karya-karya ini bagi saya ... untuk Anda
.gitconfig
's[alias]
bagian ...sumber
Tes otomatis paling sederhana yang saya gunakan untuk mendeteksi keadaan kotor = perubahan apa pun termasuk file yang tidak terlacak :
CATATAN:
add --all
diff-index
tidak melihat file yang tidak terlacak.git reset
setelah menguji kode kesalahan untuk kembali panggung semuanya.sumber
Inilah cara terbaik dan terbersih. Jawaban yang dipilih tidak berfungsi untuk saya karena beberapa alasan, itu tidak mengambil perubahan yang dipentaskan yang merupakan file baru yang tidak dilakukan.
sumber