Git diff dengan nomor baris (Git log dengan nomor baris)

93

Ketika saya melakukan a git diffatau a git log -p, bagaimana cara mendapatkan nomor baris dari file sumber yang sejalan dengan output?

Saya mencoba untuk mencarinya man git-diff | grep "line numbers"dan saya mencoba googling tetapi tidak mendapatkan apa-apa dengan cepat.

Drew LeSueur
sumber

Jawaban:

92

Anda tidak bisa mendapatkan nomor baris yang dapat dibaca manusia dengan git diff

Saat ini tidak ada opsi untuk menampilkan nomor baris secara vertikal di samping git diff.

Format perbedaan-terpadu

Informasi itu tersedia di (c) hunk header untuk setiap perubahan di diff, itu hanya dalam format unified-diff :

@@ -start,count +start,count @@

Status asli file diwakili dengan -, dan status baru diwakili dengan +(ini tidak berarti penambahan dan penghapusan di header hunk. startMewakili nomor baris awal dari setiap versi file, dan countmewakili berapa banyak baris yang disertakan , mulai dari titik awal.

Contoh

diff --git a/osx/.gitconfig b/osx/.gitconfig
index 4fd8f04..fcd220c 100644
--- a/osx/.gitconfig
+++ b/osx/.gitconfig
@@ -11,7 +11,7 @@ <== HERE!
 [color "branch"]
        upstream = cyan
 [color "diff"]
-       meta = yellow
+       meta = cyan
        plain = white dim
        old = red bold
        new = green bold

Header cowok

@@ -11,7 +11,7 @@

mengatakan bahwa versi file sebelumnya dimulai pada baris 11, dan mencakup 7 baris:

11  [color "branch"]
12         upstream = cyan
13  [color "diff"]
14 -       meta = yellow
14 +       meta = cyan
15         plain = white dim
16         old = red bold
17         new = green bold

sedangkan versi file berikutnya juga dimulai pada baris 11, dan juga menyertakan 7 baris.

Format Unified-diff tidak benar-benar untuk konsumsi manusia

Seperti yang mungkin Anda ketahui, format unified-diff tidak membuatnya mudah untuk mengetahui nomor baris (setidaknya jika Anda bukan mesin). Jika Anda benar-benar menginginkan nomor baris yang dapat Anda baca, Anda harus menggunakan alat bantu yang akan menampilkannya untuk Anda.

Bacaan Tambahan

Khalid
sumber
4
Berikut adalah grep untuk mengekstrak hanya nomor baris dalam file yang dimodifikasi, misalnya untuk digunakan untuk memfilter laporan gaya-cekgit diff --unified=0 | grep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'
Jakub Bochenski
1
Komentar @ JakubBochenski menyelesaikan masalah saya dengan cukup baik.
0xbe5077ed
Ini hanya berguna jika Anda menentukan --unified=0atau -U0, meskipun.
gak
Saya baru saja selesai git diffn, pengganti drop-in (pembungkus) git diffyang menunjukkan nomor baris dan memiliki kompatibilitas penuh dengan semua penggunaan dan opsi git diff: stackoverflow.com/questions/24455377/…
Gabriel Staples
22

Berikut dua solusi lagi, memperluas kode Andy Talkowski.

Teks biasa:

  git diff | gawk 'match($0,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
   /^(---|\+\+\+|[^-+ ])/{print;next};\
   {line=substr($0,2)};\
   /^-/{print "-" left++ ":" line;next};\
   /^[+]/{print "+" right++ ":" line;next};\
   {print "(" left++ "," right++ "):"line}'

Teks berwarna, dengan asumsi \033[66mformat untuk kode warna:

  git diff --color=always | \
    gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
      match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
      bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
      {line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
      bare~/^-/{print "-"left++ ":" line;next};\
      bare~/^[+]/{print "+"right++ ":" line;next};\
      {print "("left++","right++"):"line;next}'

Kode mengubah baris yang dimulai dengan -dan +ke -1:-dan +1:+, masing-masing, dan baris yang dimulai dengan tanpa ke (5,6):. Angka adalah nomor baris dari file masing-masing.

PFudd
sumber
Saya perhatikan itu merusak keselarasan (lekukan) kode, sedangkan native git diffdengan hati-hati mempertahankan keselarasan. Kode ini ada di luar kepala saya saat ini, jadi apakah Anda bersedia memperbaikinya? Dengan kata lain, ketika satu baris mengatakan +240:+dan baris berikutnya mengatakan (241,257):, Anda perlu menambahkan beberapa spasi ekstra ke baris atas untuk membuat kodenya mempertahankan keselarasan dan indentasi yang tepat dengan kode dari baris bawah. Mungkin ini bisa dengan mudah dilakukan dengan cetakan?
Gabriel Staples
... Maksudku dengan printf.
Gabriel Staples
Lupakan; Saya mendapatkannya! Saya baru saja selesai git diffn. Lihat di sini: stackoverflow.com/a/61997003/4561887 . Terima kasih @PFudd, atas jawaban Anda. Saya mempelajarinya dan menggunakannya untuk belajar, lalu mulai dari awal dan menulis git diffn. Setelah diformat sehingga saya dapat membaca kode Anda (terima kasih @EdMorton), saya dapat mempelajari beberapa hal hebat darinya yang membantu saya.
Gabriel Staples
6

Berikut adalah skrip yang mencoba untuk memperbaikinya - tidak mengujinya dalam kemarahan tetapi tampaknya baik-baik saja. Ini bergantung pada rekaman yang dihasilkan git diff dan menggunakan awk untuk mempertahankan jumlah baris.

# Massage the @@ counts so they are usable
function prep1() {
   cat | awk -F',' 'BEGIN { convert = 0; }
       /^@@ / { convert=1; }
       /^/  { if ( convert == 1 ) { print $1,$2,$3;
              } else { print $0;
              }
              convert=0;
             }'
}

# Extract all new changes added with the line count
function prep2() {
  cat | awk 'BEGIN { display=0; line=0; left=0; out=1;}
     /^@@ / { out=0; inc=0; line=$4; line--; display=line; left=line;        }
     /^[-]/   { left++; display=left; inc=0; }
     /^[+]/   { line++; display=line; inc=0; }
     /^[-+][-+][-+] / { out=0; inc=0; }
     /^/    { 
               line += inc;
               left += inc;
               display += inc;
               if ( out == 1 ) {
                   print display,$0;
               } else {
                   print $0;
               }
               out = 1;
               inc = 1;
               display = line;
            }'
} 

git diff $1 | prep1 | prep2 
Andy Talkowski
sumber
4

Anda dapat menggunakan git difftooluntuk melakukan perbedaan dengan editor eksternal yang akan menampilkan nomor baris. Berikut cara melakukannya dengan vim / vimdiff:

  1. Tetapkan vimdiff sebagai git's difftool:

    git config --global diff.tool vimdiff
    
  2. Konfigurasi ~/.vimrcuntuk menampilkan nomor baris secara otomatis saat menggunakan vimdiff:

    if &diff
        set number
    endif
    
  3. Jalankan git difftool, yang akan menggunakan vimdiff dengan nomor baris:

    git difftool
    
bijak
sumber
Dengan hanya melakukan git difftool, ia membuka bagi saya alat tkdiff, yang dengan sendirinya memiliki fungsi nomor baris. Terima kasih wisbucky
Richardd
3

Cara cepat adalah menggunakan git diff -U0. Itu akan menyetel baris konteks ke 0, yang akan membuat nilai @@ cocok dengan baris yang diubah sebenarnya. Secara default, nilai @@ menyertakan 3 baris sebelum / sesudah konteks, yang tidak nyaman bagi manusia.

Contoh:

git diff # default
@@ -10,8 +10,8 @@

Ini sulit untuk menghitung nomor baris dari baris yang diubah karena baris 10 mengacu pada baris pertama dari konteks sebelumnya. Nomor baris sebenarnya dari baris pertama yang diubah adalah 10 + 3 = 13. Untuk menghitung jumlah garis yang berubah, maka Anda juga harus mengurangi konteks sebelum dan sesudah: 8-3-3 = 2.

git diff -U0
@@ -13,2 +13,2 @@

Seperti yang Anda lihat, menyetel konteks = 0 membuat nilai @@ lebih mudah dibaca manusia. Anda dapat melihat bahwa garis yang diubah mulai dari baris 13, dan ada 2 baris yang diubah.

Ini tidak sempurna, karena hanya menampilkan nomor baris untuk setiap blok. Jika Anda ingin melihat nomor baris untuk setiap baris, gunakan alat difftool untuk editor eksternal. Lihat https://stackoverflow.com/a/50049752

bijak
sumber
3

Saya suka menggunakan git difftooldengan meld sebagai difftool saya. Lebih mudah untuk dilihat daripada git diff, memiliki perbandingan tampilan berdampingan yang bagus, dan menunjukkan nomor baris di setiap sisi.

Mendirikan:

  1. Petunjuk tentang cara menyiapkan meld sebagai alat difftool untuk Windows atau Linux

Contoh Screenshot:

masukkan deskripsi gambar di sini

Pembaruan 24 Mei 2020:

Saya baru saja menulis git diffnselama beberapa hari terakhir untuk menjadi pengganti drop-in git diffpada baris perintah. Cobalah. Lihat jawaban saya yang lain di sini .

Gabriel Staples
sumber
3

Mulai 24 Mei 2020, Anda sekarang dapat menggunakan alat pihak ketiga git diffn(pengungkapan penuh: Saya menulisnya) untuk tujuan ini. Ini adalah pembungkus ringan git diff, ditulis dalam awkbahasa pemrograman berbasis pola / tindakan. Berikut adalah contoh keluaran dari menjalankan git diffn:

masukkan deskripsi gambar di sini

Berikut demo nya:

1/3: Demo git diffn :

Buat file ini:

hello_world.c:

#include <stdio.h>

int main()
{
    printf("Hello World\n");

    return 0;
}

Lakukan:

git add hello_world.c
git commit -m "add hello_world.c"

Ubah ke ini dan simpan file:

hello_world.c:

// Basic hello world example

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello Gabriel\n");
    
    int i = 700;
    printf("i = %i\n", i);
    return 0;
}

Sekarang jalankan:

git diff

Inilah keluaran git diffpertama untuk tujuan perbandingan:

$ git diff
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+// Basic hello world example
+
 #include <stdio.h>
 
-int main()
+int main(int argc, char *argv[])
 {
-    printf("Hello World\n");
-
+    printf("Hello Gabriel\n");
+    
+    int i = 700;
+    printf("i = %i\n", i);
     return 0;
-}
\ No newline at end of file
+}

Dan screenshot untuk menunjukkan warnanya. Perhatikan bahwa bagian yang disorot merah hanya menampilkan spasi kosong (dalam hal ini spasi) yang dapat dihapus:

masukkan deskripsi gambar di sini

Sekarang, inilah hasil dari git diffn. Perhatikan itu menunjukkan semua nomor baris dengan sempurna!

  • Nomor baris untuk baris yang dihapus ada di sebelah kiri, dan tunjukkan -tanda di paling kiri DAN di sebelah kanan :untuk membantu Anda melihat dengan lebih baik - apakah mata Anda suka melihat ke bawah ke kanan dari titik dua atau ke bawah di ujung kiri layar.
  • Nomor baris untuk baris yang ditambahkan lebih jauh ke kanan, dan menunjukkan +tanda di paling kiri DAN di kanan :.
  • Nomor baris untuk baris tidak berubah yang ditampilkan untuk konteks ditampilkan untuk kiri (file lama) DAN kanan (file baru), dipisahkan oleh a ,.

Hasil dari git diffn:

$ git diffn
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+        1:+// Basic hello world example
+        2:+
    1,   3: #include <stdio.h>
    2,   4: 
-   3     :-int main()
+        5:+int main(int argc, char *argv[])
    4,   6: {
-   5     :-    printf("Hello World\n");
-   6     :-
+        7:+    printf("Hello Gabriel\n");
+        8:+    
+        9:+    int i = 700;
+       10:+    printf("i = %i\n", i);
    7,  11:     return 0;
-   8     :-}
\ No newline at end of file
+       12:+}

Dan screenshot untuk menunjukkan warnanya. Perhatikan bahwa titik dua TIDAK diwarnai atau diatur gaya agar sesuai dengan teks di sekitarnya di kiri dan kanan. Ini adalah perilaku yang disengaja dan dirancang untuk bertindak sebagai pemisah visual antara nomor baris yang ditambahkan di kiri dan git diffkeluaran asli di kanan.

masukkan deskripsi gambar di sini

2/3: Apa itu?

Dari atasgit-diffn.sh :

DESKRIPSI:

git-diffn.sh

  1. pengganti drop-in git diffyang juga menunjukkan baris 'n'umbers! Gunakan persis seperti itu git diff, kecuali Anda akan melihat nomor baris yang indah ini juga untuk membantu Anda memahami perubahan Anda.

  2. karena ini hanya pembungkus berbasis bahasa awk yang ringan git diff, ia menerima SEMUA opsi dan parameter yang git diffmenerima. Contoh:

  3. git diffn HEAD~

  4. git diffn HEAD~3..HEAD~2

  5. berfungsi dengan git diffpengaturan warna Anda , bahkan jika Anda menggunakan warna kustom

  6. Lihat jawaban saya di sini untuk cara mengatur warna diff khusus, serta untuk melihat tangkapan layar dari keluaran warna khusus dari git diffn: Bagaimana Anda menyesuaikan warna header diff di git diff?

  7. Berikut adalah beberapa contoh git configperintah dari jawaban saya di atas untuk mengatur git diffwarna dan atribut khusus (pemformatan teks):

       git config --global color.diff.meta "blue"
       git config --global color.diff.old "black red strike"
       git config --global color.diff.new "black green italic"
       git config --global color.diff.context "yellow bold"
    
  8. di git diffn, keluaran warna AKTIF secara default; jika Anda ingin menonaktifkan warna keluaran, Anda harus menggunakan --no-coloratau --color=never. Lihat man git diffuntuk detailnya. Contoh:

     git diffn --color=never HEAD~
     git diffn --no-color HEAD~3..HEAD~2
    

3/3: Instalasi

  1. Windows (belum teruji): ini dapat bekerja di dalam terminal bash yang disertakan dengan Git untuk Windows , tetapi belum teruji. Instal Git untuk Windows. Buka terminal bash yang menyertainya, dan coba ikuti instruksi di bawah ini. Saya memerlukan beberapa penguji yang akan menguji ini di Git untuk Windows. Silakan lihat dan jawab di sini: https://github.com/git-for-windows/git/issues/2635 .
  2. Mac (belum teruji): gunakan terminal dan ikuti instruksi di bawah ini. Anda mungkin perlu menginstal gawk. Jika demikian, coba ini : brew install gawk.
  3. Linux (diuji pada Ubuntu 18.04 dan berfungsi dengan sempurna): ikuti petunjuk terminal di bawah ini.

Opsi 1 (rekomendasi saya): unduh seluruh repo dan kemudian buat symlink ke program sehingga Anda dapat dengan mudah menerima pembaruan dengan melakukan a git pulldari repo kapan pun Anda mau.

Pertama, cdke mana pun Anda ingin menginstal ini. Lalu lari:

git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.git
cd eRCaGuy_dotfiles/useful_scripts
mkdir -p ~/bin
ln -si "${PWD}/git-diffn.sh" ~/bin/git-diffn

Selesai! Sekarang lakukan saja langkah terakhir di bawah ini!

Opsi 2 (bagi yang hanya menginginkan 1 file): unduh satu file sekali saja.

mkdir -p ~/bin
cd ~/bin
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/git-diffn.sh
chmod +x git-diffn.sh
mv git-diffn.sh git-diffn

Selesai! Sekarang lakukan saja langkah terakhir di bawah ini!

Langkah terakhir:

Sekarang tutup dan buka kembali terminal Anda, atau sumber kembali dengan . ~/.bashrc, dan Anda selesai!

git diffnsekarang akan berfungsi sebagai pengganti mampir yang tepat untuk git diff!

Gabriel Staples
sumber
1

Anda dapat mencoba

git blame

di file. Ini menunjukkan kepada Anda pelaku, komit id, dan nomor baris untuk setiap baris dalam file.

Juan
sumber
4
Masalahnya adalah ini tidak menunjukkan perbedaan , yang diminta oleh poster asli. git blamehanya akan menunjukkan status file saat ini dengan nomor baris.
5
Saya tahu tentang git menyalahkan, tetapi seseorang yang googling mungkin tidak tahu. Ini mungkin membantu seseorang. Terimakasih telah menjawab.
Drew LeSueur
git blamesama sekali tidak menjawab pertanyaan itu; Saya cukup bingung dengan suara positif di sini
Michael Mrozek
Harap jangan spam stackoverflow dengan jawaban yang tidak terkait dengan pertanyaan.
Ahmed
0

Pertama, konfigurasikan alat git diff Anda, misalnya Meld

git config --global diff.tool meld

Kemudian, cabut difftool Anda pada beberapa file:

git difftool -y config.rb

Ingat mengatur nomor baris dalam preferensi alat diff Anda.

HaxtraZ
sumber