Відображати лише відповідні ділянки різниці / латки на основі регулярного виразного випромінювання


20

git log -G<regex> -pє прекрасним інструментом пошуку історії кодової бази змін, що відповідають заданому шаблону. Однак, може виявитись непосильним розміщення відповідного лука у виводі різниць / виправлень у морі здебільшого невідповідних луків.

Звичайно, можна шукати вихід git logоригінального рядка / регулярного вираження, але це мало що дозволяє зменшити зоровий шум і відволікання багатьох незв'язаних змін.

Читаючи далі git log, я бачу, що є те --pickaxe-all, що є абсолютно протилежним тому, що я хочу: він розширює вихід (на весь набір змін), тоді як я хочу обмежити його (на певну частину).

По суті, я шукаю спосіб "розумно" розібрати розріз / виправлення на окремі номери, а потім здійснити пошук проти кожної частини (орієнтований лише на змінені лінії), відкинути лунки, які не відповідають, і вивести ці що роблять.

Чи існує такий інструмент, як я описав? Чи є кращий підхід для отримання відповідних / постраждалих луків?

Деякі початкові дослідження, які я зробив ...

  • Якби можна було grepвиводити diff / patch і робити значення параметрів контексту динамічними - скажімо, через регулярні вирази замість підрахунку рядків - цього може бути достатньо. Але grepце не зовсім побудовано таким чином (і я не обов'язково вимагаю цієї функції).

  • Я знайшов пакет пачутілів , який спочатку прозвучав так, ніби він відповідає моїм потребам. Але після прочитання його manсторінок інструменти не обробляють відповідні частини на основі регулярних виразів. (Вони можуть прийняти список хангів, хоча ...)

  • Нарешті я натрапив на splitpatch.rb , який, здається, добре впорається з розбором патча, але його потрібно буде значно вдосконалити, щоб обробляти патчі для читання за допомогою stdin, узгоджуючи потрібні парки, а потім виводити парки.


1
Не дуже те, що ви просили, але спробуйте git log -Gfoo | менше + / foo
James Youngman

Відповіді:


7

тут /programming//a/35434714/5305907 описаний спосіб робити те, що ви шукаєте. ефективно:

git diff -U1 | grepdiff 'console' --output-matching=hunk

На ньому показані лише перегони, які відповідають заданій рядковій "консолі".


Спасибі. grepdiffв основному те, що я хочу; я, мабуть, пропустив його варіант підбору! однак ... інформація про фіксацію git знімається grepdiff, тож після того як ви знайдете відповідний фрагмент, ви повинні зачарувати фіксацію sha від об'єкта / blob sha у заголовку diff - досить дорога операція. (див. stackoverflow.com/a/223890/2284440 ) це було б щось на зразокgit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
wrksprfct

також зауважте, що є голанг-версія,grepdiff яка має більше босоніж з точки зору прийнятих аргументів. зауважте, що коли збігається парка є останньою частиною в диференціалі, вона неправильно включає заголовок git commit наступного комітету - те, що мене повністю збило з пантелику, поки я не зрозумів, що відбувається!
wrksprfct

0

Не зовсім те, про що ви просите, але один із способів прорізати перегони - це режим інтерактивного додання Це вимагає, щоб ви перевірили комісію після патча, який вас цікавить

git checkout COMMIT_ID

потім поверніться ще один крок у VCS, але не у робочий каталог

git reset --soft HEAD^

(У цей момент різниця між індексом та робочою каталогом буде відповідати патчу, який вас цікавить.)

Тепер ви можете виконати git add -p. Це запустить інтерактивний сеанс, який має /опцію, що дозволяє знаходити перегони, у яких деяка лінія відповідає регексу. Особливо корисно, якщо ви дійсно хочете додатково обробити ці патчі (наприклад, підготовка часткової вишні).

На жаль, принаймні зараз /команда add -pпрацює лише в одному файлі, тому вам може знадобитися пропустити кілька невідповідних файлів.


0

Опираючись на відповідь, подану вище @nagu, та інші відповіді, я зміг дістатись git log -Gлише для того, щоб показати відповідні місця.

  1. Спочатку створіть сценарій десь у вашому $ PATH з цим вмістом:

    #!/bin/bash
    
    # pickaxe-diff : external diff driver for Git.
    #                To be used with the pickaxe options (git [log|show|diff[.*] [-S|-G])
    #                to only show hunks containing the searched string/regex.
    
    path=$1
    old_file=$2
    old_hex=$3
    old_mode=$4
    new_file=$5
    new_hex=$6
    new_mode=$7
    
    filtered_diff=$(diff -u -p $old_file $new_file | \
                    grepdiff "$GREPDIFF_REGEX" --output-matching=hunk | \
                    grep -v -e '+++ ' -e '--- ')
    
    a_path="a/$path"
    b_path="b/$path"
    
    echo "diff --git $a_path $b_path"
    echo "index $old_hex..$new_hex $old_mode"
    echo "--- $a_path"
    echo "+++ $b_path"
    echo "$filtered_diff"
  2. Зателефонуйте git log -Gта скажіть Git використовувати pickaxe-diffскрипт як зовнішній драйвер розгляду :

    export GREPDIFF_REGEX=<string>; 
    GIT_EXTERNAL_DIFF=pickaxe-diff git log -p --ext-diff -G $GREPDIFF_REGEX

    Це використовуватиме сценарій pickaxe-diff лише для створення розрізних файлів, тому решта git logрезультатів (хеш-повідомлення, повідомлення тощо) буде недоторканою.

Caveat
Спосіб роботи Git pickaxe полягає в тому, що він обмежує вихід файлами, чиї зміни змінюють заданий рядок / регулярний вираз. Це означає, що якщо інша команда в цих файлах також містить рядок пошуку / регекс, але не змінює його, він все одно відображатиметься з вищевказаним сценарієм. Це обмеження грепдіффа. У проекті patchutils є відкритий запит на --only-matchingвитяг, щоб додати прапор grepdiff, який би забезпечив необхідну функціональність для правильного фільтрації цих груп.


Я написав своє рішення в цій суті .

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