Bagaimana cara menemukan komit git terbaru yang memodifikasi file?

180

Saya ingin mencari komit terbaru yang memodifikasi file sumber.

Saya dapat menggunakan git blameuntuk melihat semua tanggal untuk komit oleh setiap baris, tetapi sulit untuk melihat persis komit mana yang terakhir menyentuh file.

Bagaimana saya bisa menemukan komit terakhir yang menyentuh file yang diberikan dalam repositori git saya?

Cory Klein
sumber

Jawaban:

230

git log mendukung melihat riwayat file tertentu (dan direktori), sehingga Anda dapat menyebutnya seperti ini:

git log my/file.c

Jika Anda benar-benar hanya ingin daftar satu terbaru komit, misalnya untuk menggunakannya dalam naskah, gunakan -n 1opsi:

git log -n 1 --pretty=format:%H -- my/file.c

--pretty=format:%hmemberitahu git loguntuk menunjukkan hanya hash komit. The --separater berhenti nama file dari mendapatkan ditafsirkan sebagai nama komit, hanya dalam kasus itu ambigu.

Jo Liss
sumber
12
Jika Anda ingin tahu kapan terakhir kali sebuah file dimodifikasi terlepas dari cabang, Anda dapat mempertimbangkan semua cabang dengan menambahkan --allopsi.
KC
44

Jika Anda hanya ingin menemukan komit terbaru, maka Anda tidak ingin git-log, Anda ingin git-rev-list, yang mencantumkan objek komit yang mengubah file itu, di jalur komit itu, dimulai dengan yang terbaru (secara kronologis). Sederhananya:

git rev-list -1 <commit> <filename>

Karena git-rev-listdalam kasus Anda, Anda hanya menyediakan:

  • Jumlah komitmen untuk disertakan, atau -1 hanya untuk yang terbaru,
  • Cabang (atau melakukan id) untuk mulai melihat kembali dari, KEPALA jika Anda sudah di atasnya, atau --semua jika Anda ingin semua komit diketahui, dan
  • Jalur relatif ke file Anda.

Ini hanya mengembalikan ID komit terbaru di cabang saat ini untuk mengubah file itu, mis: 215095e2e338525be0baeeebdf66bfbb304e7270

Untuk contoh yang lebih kompleks, Anda dapat menggunakan nama tag, dan bahkan referensi jarak jauh, dan menyertakan nama jalur relatif dengan wildcard, misalnya:

git rev-list origin/user/bob/testbranch -1 src/bfiles/*.txt

... Yang akan memberi tahu Anda apa perubahan terbaru ke pertandingan wildcard dalam sejarah cabang itu. Opsi untuk rev-list sangat ekstrem, ini adalah salah satu perintah pipa yang paling penting, sehingga Anda dapat memasukkan atau mengecualikan hampir semua kriteria yang dapat Anda bayangkan.

Tentu saja, lihat halaman Manual git-rev-list (1) .

Michael Erickson
sumber
Anda benar-benar tidak menjelaskan mengapa menggunakan git-loglebih rendah.
Piotr Dobrogost
7
Saya tidak akan mengatakan inferior, hanya saja ia menyediakan informasi asing secara default. git-rev-list hanya mengembalikan ID komit, yang Anda inginkan jika Anda akan memasukkan respons ke dalam skrip atau proses otomatisasi lainnya. git-log mengembalikan informasi tentang komit terpilih, pertama dengan menggunakan git-rev-list untuk mengumpulkan id komitmen, kemudian mengumpulkan informasi pada setiap komit. Jika Anda hanya akan menyaring informasi komit dan menggunakan id, maka Anda bisa menggunakan git-rev-list di tempat pertama. Karena log didasarkan pada rev-list, maka dibutuhkan sebagian besar parameter filter yang sama.
Michael Erickson
3
git-logadalah porselen, git-rev-listpipa ledeng.
blitzen9872
27

Jika Anda hanya ingin mendapatkan hash dari commit terbaru untuk memodifikasi set file tertentu (dan ingin menghindari awk) Anda dapat menggunakan:

git log -n 1 --pretty=format:%h -- <path>

Ini bisa berguna untuk mendapatkan hash komit untuk selanjutnya digunakan bersama git describe.

Misalnya (jika berguna bagi siapa saja) ...

Saya membuat id versi saat ini dengan mempertimbangkan komit terbaru untuk mengubah file sumber apa pun (dengan asumsi Anda menandai versi dengan tag seperti mycode-1.2.1):

COMMIT=$(git log -n 1 --pretty=format:%h -- *.c *.h)
if VN=$(git describe --always --abbrev=5 --match "mycode-*" $COMMIT 2>/dev/null) &&
case "$VN" in
mycode-*)
    git update-index -q --refresh
    test -z "$(git diff-index --name-only HEAD *.c *.h)" ||
    VN="$VN-mod" ;;
*) VN="mycode-unknown-g$VN" ;;
esac
then
    continue
else
VN="mycode-unknown"
fi

Ini menghasilkan id seperti:

  • mycode-1.2.1 - ketika status file sumber saat ini sesuai dengan versi yang ditandai
  • mycode-1.2.1-g3k7s2 - ketika status file sumber saat ini sesuai dengan komit setelah versi yang ditandai
  • mycode-1.2.1-g3k7s2-mod - ketika keadaan saat ini dari file sumber telah dimodifikasi sejak komit terakhir mengikuti versi yang ditandai
  • mycode-unknown - ketika belum ada tag versi yang dibuat
TheBamf
sumber
5
$VNsepertinya semacam mimpi buruk undead SVN
ThorSummoner
10

Saya tidak yakin apakah ini yang Anda inginkan tetapi jika Anda melakukan git log <thefile>untuk mendapatkan commit yang mengubah file itu. Anda dapat memilih yang paling atas. Seharusnya yang Anda cari.

Noufal Ibrahim
sumber
4
jika Anda menggunakan git log -n1 -- <thefile>(atau menyalurkan output ke head -1jika Anda ingin menyia-nyiakan sumber daya) Anda tidak harus secara manual memilih baris teratas (lihat jawaban Jo Liss )
Tobias Kienzler
4
Poin yang bagus. Saya pikir Anda juga dapat melewati -ndan menggunakan -1secara langsung.
Noufal Ibrahim
3

Untuk mendapatkan referensi hanya pada satu baris, cobalah:

git log -n1 --oneline <path> | awk '{print $1;}'
aplikasi cepat
sumber
2

Setelah Anda memiliki id SHA dari komit yang ingin Anda lihat menggunakan git log FILENAME, Anda harus dapat melakukan git show SHA_ID_HEREuntuk melihat apa yang Anda lakukan untuk komit tertentu. Anda bahkan tidak perlu memasukkan seluruh ID; 6 karakter pertama harus cukup.

Joe
sumber
4
itu sedikit lebih banyak daripada yang diminta OP, tetapi FYI Anda dapat menggabungkan ini menjadi satu-liner:git show $(git log -1 --pretty="%H" -- FILENAME)
Tobias Kienzler