Git diff з номерами рядків (Git log з номерами рядків)


93

Коли я роблю a git diffабо a git log -p, як отримати номери рядків вихідних файлів, вбудованих у вихідні дані?

Я спробував це знайти man git-diff | grep "line numbers"і спробував погуглити, але нічого не отримав швидко.

Відповіді:


92

Ви не можете отримати зручні для читання номери рядків за допомогою git diff

На даний момент не існує жодних варіантів, щоб номери рядків відображалися вертикально збоку git diff.

Формат уніфікованої різниці

Ця інформація доступна у заголовках (c) для кожного зміни різниці, однак вона лише у форматі unified-diff :

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

Вихідний стан файлу представлений символом -, а новий стан представлений символом +(вони не означають доповнення та видалення в заголовку Hunk. startПредставляє номер початкового рядка кожної версії файлу та countкількість строк, які включені , починаючи з початкової точки.

Приклад

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

Верхній колонтитул

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

говорить, що попередня версія файлу починається з рядка 11 і включає 7 рядків:

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

тоді як наступна версія файлу також починається з рядка 11, а також включає 7 рядків.

Формат уніфікованої різниці насправді не призначений для споживання людиною

Як ви, напевно, можете зрозуміти, формат unified-diff не дозволяє легко з’ясувати номери рядків (принаймні, якщо ви не машина). Якщо вам дійсно потрібні номери рядків, які ви можете прочитати, вам потрібно буде використовувати інший інструмент, який відображатиме їх вам.

Додаткове читання


4
Ось grep для вилучення лише номерів рядків у модифікованих файлах, наприклад для використання для фільтрування звіту про контрольний стильgit diff --unified=0 | grep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'
Якуб Боченський

1
Коментар @ JakubBochenski досить добре вирішив мою проблему.
0xbe5077 (

Це дійсно корисно, лише якщо ви вказали --unified=0або -U0.
caw

Щойно я закінчив git diffn, випадаюча заміна (обгортка), git diffяка показує номери рядків і має повну сумісність з усіма способами використання та опціями git diff: stackoverflow.com/questions/24455377/…
Габріель Стейплз,

22

Ось ще два рішення, які розширюються на коді Енді Талковського.

Простий текст:

  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}'

Кольоровий текст, припускаючи, що \033[66mце формат для кольорових кодів:

  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}'

Код змінює рядки, які починаються з -і +до -1:-і +1:+, відповідно, і рядки, які починаються з ні до чого (5,6):. Цифри - це номери рядків із відповідного файлу.


Я помічаю, що це порушує вирівнювання (відступ) коду, тоді як рідний git diffретельно підтримує вирівнювання. Цей код зараз у мене над головою, тож чи готові ви його виправити? Іншими словами, коли один рядок говорить, +240:+а наступний рядок говорить (241,257):, вам потрібно додати додаткові пробіли до верхнього рядка, щоб його код підтримував належне вирівнювання та відступ до коду з нижнього рядка. Можливо, це легко можна зробити за допомогою друку?
Габріель Стейплз,

... я маю на увазі с printf.
Габріель Стейплз,


Не зважай; Зрозумів! Я щойно закінчив git diffn. Дивіться тут: stackoverflow.com/a/61997003/4561887 . Дякую @PFudd, за вашу відповідь. Я вивчив його і використовував для навчання, потім почав з нуля і писав git diffn. Після форматування, щоб я міг прочитати ваш код (дякую @EdMorton), я зміг навчитися з нього деяких чудових речей, які мені допомогли.
Габріель Стейплз,

6

Ось сценарій, який намагається це виправити - не перевіряв його в гніві, але, здається, це нормально. Він покладається на записи, які створює git diff, і використовує awk для підтримки підрахунку рядків.

# 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 

4

Ви можете використовувати git difftoolрізницю із зовнішнім редактором, який відображатиме номери рядків. Ось як це зробити за допомогою vim / vimdiff:

  1. Встановити vimdiff як git's difftool:

    git config --global diff.tool vimdiff
    
  2. Налаштуйте ~/.vimrcавтоматичне відображення номерів рядків під час використання vimdiff:

    if &diff
        set number
    endif
    
  3. Запустіть git difftool, який використовуватиме vimdiff з номерами рядків:

    git difftool
    

Тільки виконавши git difftool, він відкрив для мене інструмент tkdiff, який сам має функцію номера рядка. Дякую Wisbucky
Річардд

3

Швидкий спосіб - використовувати git diff -U0 . Це встановить для рядків контексту значення 0, що змусить значення @@ відповідати фактично зміненим рядкам. За замовчуванням значення @@ включають 3 рядки контексту до / після, що не зручно для людей.

Приклад:

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

Важко обчислити номери рядків змінених рядків, оскільки рядок 10 відноситься до першого рядка попереднього контексту. Фактичний номер рядка першого зміненого рядка становить 10 + 3 = 13. Щоб обчислити кількість змінених рядків, вам слід також відняти контекст до і після: 8-3-3 = 2.

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

Як бачите, встановлення context = 0 полегшує читання значень @@ для людей. Ви бачите, що змінені рядки починаються з рядка 13, а є 2 змінені рядки.

Це не ідеально, оскільки відображає лише номер рядка для кожного блоку. Якщо ви хочете бачити номери рядків для кожного рядка, використовуйте difftool для зовнішнього редактора. Див. Https://stackoverflow.com/a/50049752


3

Я хотів би використовувати git difftoolз Meld як мій difftool. Це легше розглянути, ніж git diff, має приємне паралельне порівняння графічного інтерфейсу та показує номери рядків на кожній стороні.

Налаштування:

  1. Вказівки щодо налаштування meld як вашого інструменту розробки для Windows або Linux

Зразок знімка екрану:

введіть тут опис зображення

Оновлення 24 травня 2020 р .:

Я щойно писав git diffnпротягом останніх кількох днів, щоб замінити їх git diffу командному рядку. Спробуй. Іншу мою відповідь див . Тут .


3

Починаючи з 24 травня 2020 року, тепер ви можете використовувати для цього сторонній інструмент git diffn(повне розкриття інформації: я це написав). Це легка обгортка навколо git diff, написана awkмовою програмування на основі шаблону / дії. Ось зразок результату запуску git diffn:

введіть тут опис зображення

Ось демонстрація:

1/3: Демо git diffn:

Створити цей файл:

hello_world.c:

#include <stdio.h>

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

    return 0;
}

Здійснити:

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

Змініть його на це і збережіть файл:

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;
}

Тепер запустіть:

git diff

Ось результат git diffпершого для цілей порівняння:

$ 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
+}

І скріншот, щоб показати колір. Зверніть увагу, що виділений червоним кольором розділ просто показує порожні пробіли (у цьому випадку пробіли), які можна видалити:

введіть тут опис зображення

Тепер ось результат git diffn. Зауважте, що всі номери рядків чудово відображаються!

  • Номери рядків для видалених рядків знаходяться ліворуч, а -на крайньому лівому І праворуч від екрана відображається знак, :який допоможе вам краще бачити - чи подобається вашим очам сканувати праворуч від товстої кишки або вниз на дальньому ліворуч від екрана.
  • Номери рядків для доданих рядків розташовані далі праворуч і мають +знак у крайньому лівому куті І праворуч від :.
  • Номери рядків для незмінних рядків, показаних для контексту, відображаються як для лівого (старий файл), так і для правого (нового файлу), розділених символом ,.

Вихідні дані 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:+}

І скріншот, щоб показати колір. Зверніть увагу, що двокрапки НЕ кольорові та стилізовані, щоб відповідати навколишньому тексту зліва та праворуч. Це навмисна та розроблена поведінка, яка діє як візуальний роздільник між номерами рядків, доданими ліворуч, та вихідним git diffвиведенням праворуч.

введіть тут опис зображення

2/3: Що це?

З верхньої частиниgit-diffn.sh :

ОПИС:

git-diffn.sh

  1. випадаюча заміна, git diffяка також відображає рядки 'n'umbers! Використовуйте саме такgit diff , за винятком того, що ви також побачите ці прекрасні номери рядків, щоб допомогти вам зрозуміти свої зміни.

  2. оскільки це просто легка обгортка на основі мови awk git diff, вона приймає ВСІ параметри та параметри, які git diffприймає. Приклади:

  3. git diffn HEAD~

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

  5. працює з будь-яким із ваших git diffналаштувань кольору, навіть якщо ви використовуєте власні кольори

  6. Подивіться тут мою відповідь про те, як встановити власні кольори різниці, а також побачити скріншот виводу користувацького кольору з git diffn: Як ви налаштовуєте колір заголовка різниці в git diff?

  7. Ось кілька зразків git configкоманд з моєї відповіді вище, щоб встановити власні git diffкольори та атрибути (форматування тексту):

       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. в git diffn, кольоровий вихід за замовчуванням увімкнено; якщо ви хочете відключити вихідний колір, ви повинні використовувати --no-colorабо --color=never. Детальніше man git diffдив. Приклади:

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

3/3: Встановлення

  1. Windows (неперевірений): це може працювати всередині терміналу bash, який постачається з Git для Windows , але не перевіряється. Встановіть Git для Windows. Відкрийте термінал bash, який постачається в комплекті, і спробуйте слідувати інструкціям нижче. Мені потрібні тестери, які перевірять це в Git для Windows. Будь ласка, перегляньте та дайте відповідь тут: https://github.com/git-for-windows/git/issues/2635 .
  2. Mac (неперевірений): використовуйте термінал і дотримуйтесь інструкцій нижче. Можливо, вам доведеться встановити gawk. Якщо це так, спробуйте це : brew install gawk.
  3. Linux (протестовано на Ubuntu 18.04 і працює чудово): дотримуйтесь інструкцій терміналу нижче.

Варіант 1 (моя рекомендація): завантажте весь репо, а потім створіть символічне посилання на програму, щоб ви могли легко отримувати оновлення, виконуючиgit pull з репо, коли завгодно.

По-перше, cdтуди, де ви хочете встановити це. Потім запустіть:

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

Готово! Тепер просто зробіть останній крок нижче!

Варіант 2 (для тих, хто просто хоче файл 1): завантажте один раз лише один файл.

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

Готово! Тепер просто зробіть останній крок нижче!

Заключний крок:

Тепер закрийте і знову відкрийте термінал або перезавантажте його за допомогою . ~/.bashrc , і все готово!

git diffnтепер працюватиме як точна заміна git diff!


1

Ви можете спробувати

git blame

на файлі. Він показує вам комітер, ідентифікатор коміту та номер рядка для кожного рядка у файлі.


4
Проблема в тому, що він не показує вам різниці , про що просив оригінальний плакат. git blameпросто покаже поточний стан файлу з номерами рядків.

5
Я знав про звинувачення, але хтось погуглив, можливо, цього не мав. Це може комусь допомогти. Дякую за відповідь.
Drew LeSueur

git blameжодним чином не відповідає на питання; Я досить збентежений прихильниками тут
Майкл Мрозек,

Будь ласка, не розсилюйте stackoverflow відповідями, які не пов'язані з питаннями.
Ахмед

0

Спочатку налаштуйте свій інструмент git diff, наприклад, Meld

git config --global diff.tool meld

Потім потягніть свій difftool до якогось файлу:

git difftool -y config.rb

Пам’ятайте, що ви встановили номер рядка в уподобаннях вашого інструменту різниці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.