Di git, apakah ada cara untuk menampilkan file simpanan yang tidak terlacak tanpa menerapkan simpanan?

100

Jika saya menjalankan git stash -u, saya dapat menyimpan file yang tidak terlacak. Namun, file yang tidak terlacak tersebut tidak muncul sama sekali dengan git stash show stash@{0}. Apakah ada cara untuk menampilkan file simpanan yang tidak terlacak tanpa menerapkan simpanan?

Max Nanasy
sumber

Jawaban:

121

File yang tidak dilacak disimpan di induk ketiga dari komit simpanan. (Ini sebenarnya tidak didokumentasikan, tetapi cukup jelas dari Komit yang memperkenalkan fitur -u, 787513 ... , dan cara dokumentasi lainnya untukgit-stash hal-hal frase ... atau hanya dengan melakukan git log --graph stash@{0})

Anda hanya dapat melihat bagian "tidak terlacak" dari simpanan melalui:

git show stash@{0}^3

atau, hanya pohon "tidak terlacak" itu sendiri, melalui:

git show stash@{0}^3:

atau, file "tidak terlacak" tertentu di pohon, melalui:

git show stash@{0}^3:<path/to/file>

Sayangnya, tidak ada cara yang baik untuk mendapatkan ringkasan perbedaan antara semua status bertahap + tidak bertahap + tidak terlacak vs "saat ini". yaitu: git show stash@{0}tidak dapat dibuat untuk menyertakan file yang tidak terlacak. Ini karena objek pohon dari komit simpanan itu sendiri, yang disebut stash@{0}:, tidak menyertakan perubahan apa pun dari induk "tidak bertingkat" yang ketiga.

Hal ini disebabkan cara penyimpanan kembali diterapkan: file terlacak dapat dengan mudah diterapkan sebagai patch, sedangkan file yang tidak terlacak hanya dapat diterapkan, secara teori, sebagai "file utuh".

Will Palmer
sumber
Jadi orang tua dari komit simpanan adalah (1. Komit simpanan dibuat terhadap 2. Indeks 3. Salinan tidak terlacak), dan komit simpanan itu sendiri berisi copy pekerjaan terlacak? git stash showtampaknya memperlihatkan perbedaan antara copy pekerjaan dan # 1 (kode yang relevan dari git-stash.sh:, git diff ${FLAGS:---stat} $b_commit $w_commitdi mana $ b_commit adalah # 1 dan $ w_commit adalah komit simpanan); apakah ada cara built-in untuk git stash showmenyertakan # 3?
Max Nanasy
Seperti yang Anda katakan, saya belum menemukan cara untuk mendapatkan tampilan ringkasan tunggal simpanan, tetapi Anda dapat melihat informasi lengkap dalam satu perintah dengan: git log --graph --topo-order -m -u. matthewlmcclure.com/s/2014/01/10/…
Matt McClure
4
Perhatikan bahwa Anda mendapatkan kesalahan jelek ( fatal: ambiguous argument 'stash@{0}^3': unknown revision or path not in the working tree.) jika Anda sebenarnya tidak memiliki file yang tidak terlacak di simpanan itu (tetapi Anda pikir Anda melakukannya).
Randall
2
@antak: nope, git stash showtidak tidak menampilkan file tidak terlacak (berlaku untuk setidaknya git 2.7.4):
Norbert Berci
1
Catatan (2.13.2-linux): git stash poppertama-tama akan mencoba memulihkan file yang tidak terlacak, kemudian mencoba memulihkan file yang terlacak. Jika operasi terakhir gagal (mis. Konflik), operasi pertama tidak dibatalkan (untracked-file-stash akan tetap apa adanya tetapi file tidak dihapus dari disk), jadi meskipun Anda memperbaiki konflik, pop berikutnya akan gagal bagaimanapun.
Marinos An
22

Anda dapat membuat daftar semua komit simpanan dengan perintah berikut:

git rev-list -g stash

Karena simpanan direpresentasikan sebagai komit gabungan 3 arah dari HEAD, indeks, dan komit "root" tanpa induk dari file yang tidak terlacak, simpanan file yang tidak terlacak dapat dicantumkan dengan memasukkan keluaran di atas ke dalam berikut:

git rev-list -g stash | git rev-list --stdin --max-parents=0

Aplikasi berguna di atas:

Tampilkan hanya file yang tidak terlacak dan disimpan

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git show --stat

Tentu saja, hapus --statuntuk melihat konten file.

Temukan file tertentu

git rev-list -g stash | xargs -n1 git ls-tree -r | sort -u | grep <pattern>

Grep file yang tidak terlacak

git rev-list -g stash | git rev-list --stdin --max-parents=0 | xargs git grep <pattern>

Buat daftar semua konten dari semua simpanan

git rev-list -g stash | git rev-list --stdin | xargs git show --stat
Steve
sumber
10

Untuk mencantumkan file yang tidak terlacak di simpanan:

git ls-tree -r stash@{0}^3 --name-only

Untuk menampilkan perbedaan lengkap dari semua file yang tidak terlacak (dengan konten):

git show stash@{0}^3

Perintah ini membaca simpanan terakhir (terbaru). Untuk simpanan sebelumnya, tambah angka di belakang "simpanan @", misalnya stash@{2}untuk simpanan kedua dari simpanan terakhir.

Alasan ini berfungsi adalah karena git stashmembuat komit gabungan untuk setiap simpanan, yang dapat dirujuk sebagai stash@{0},stash@{1} dll. Orang tua pertama dari komit ini adalah HEAD pada saat penyimpanan, induk kedua berisi perubahan pada file yang dilacak, dan ketiga (yang mungkin tidak ada) perubahan pada file yang tidak terlacak.

Ini sebagian dijelaskan dalam halaman manual di bawah "Diskusi" .

bijak
sumber
5

Untuk melihat semua file di simpanan (baik dilacak maupun tidak terlacak), saya menambahkan alias ini ke konfigurasi saya:

showstash = "!if test -z $1; then set -- 0; fi; git show --stat stash@{$1} && git show --stat stash@{$1}^3 2>/dev/null || echo No untracked files -"

Ini membutuhkan satu argumen simpanan mana yang ingin Anda lihat. Perhatikan bahwa ini akan tetap menampilkannya dalam dua daftar back-to-back.

The if...fiBagian perubahan bash argumen $ 1 ke 0 jika tidak ada disahkan.

Randall
sumber
5

Solusi: Menentukan file sebelum menyimpannya akan git stash show -pberfungsi seperti yang diharapkan.

git add .
git stash save

Catatan: Cara ini memberi kekuatan menambahkan bagian interaktif juga, begini caranya .
Perhatian: Pastikan Anda tidak memiliki pekerjaan bertahap, atau Anda tidak akan dapat membedakannya.
Ini mungkin berguna.

kita
sumber