Звинувачення в Git - попередні зобов'язання?


390

Чи можливо побачити, хто редагував певний рядок перед повідомленням про комісію git blame, як історія комітетів для даного рядка?

Наприклад, я запускаю наступне (на чудовому uncrustifyпроекті):

$ git blame -L10,+1 src/options.cpp
^fe25b6d (Ben Gardner 2009-10-17 13:13:55 -0500 10) #include "prototypes.h"

Як я можу дізнатись, хто редагував цей рядок, перш ніж здійснити команду fe25b6d? А хто редагував це перед тим комітом?


7
якщо причиною пошуку попередніх комісій є зміни білого простору, скористайтеся -wопцією. Є також -Mдля переміщеного / скопійованого коду
brita_

Щоб шукати всі зобов’язання, пов’язані з певним словом, дивіться мій сценарій нижче
VonC

Ось корисний сценарій, щоб додати цю функціональність на github greasyfork.org/en/scripts/…
Аарон Хоффман

3
Не впевнений, як виглядав github, коли @AaronHoffman опублікував, але звинувачувати в тому чи іншому звинуваченні за попередні версії - в Github зараз .
ruffin

Відповіді:


389
git blame -L 10,+1 fe25b6d^ -- src/options.cpp

Ви можете вказати версію для git blame, щоб оглянути назад, починаючи з (замість за замовчуванням HEAD); fe25b6d^є батьком fe25b6d.


106
Чи можете ви отримати повну історію, не потребуючи повторного введення команди з різними хешами?
Андерс Зоммарін

13
Я не вірю, що у Git є вбудований спосіб отримувати будь-яку провину, яка торкнулася номера рядка (що має сенс, оскільки даний рядок може не мати послідовного номера рядка протягом історії файлу через вставки та видалення рядків).
Бурштин

17
@ Amber: Досить впевнений, що ти маєш рацію, що ця функція не існує, але, схоже, вона могла бути реалізована наївно, просто зробивши те, що зробить людина: звинувачуйте її один раз, хапайте повідомлену інформацію, звинувачуйте, що , і так далі.
Каскабель

15
git gui дозволяє досить легко перевірити історію рядка, оскільки версії можна натискати.
Zitrax

5
@shadyabhi --зазвичай використовується як роздільник аргументів командного рядка - у випадку з Git зазвичай використовується для відокремлення речей, як хеш-файли, зі списку імен файлів.
Бурштин

191

Ви можете використовувати git log -L для перегляду еволюції діапазону ліній.

Наприклад :

git log -L 15,23:filename.txt

означає "простежити еволюцію рядків 15-23 у файлі з назвою filename.txt".


12
Це ґрунтовна відповідь і стосується питання Андерса Зоммаріна вище про те, як побачити зміни певних рядків у часі.
bigtex777

4
FYI: git log -L <start>, <end>: <file> вимагає Git 1.8.4+ див.: Git-scm.com/docs/git-log#git-log--Lltstartgtltendgtltfilegt для параметрів синтаксису
Neon

30

Відповідь Амбер правильна, але я вважав її незрозумілою; Синтаксис:

git blame {commit_id} -- {path/to/file}

Примітка: the --використовується для відділення дерева-ish sha1 від відносних шляхів файлів. 1

Наприклад:

git blame master -- index.html

Повна заслуга Амбер за те, що він знав усі речі! :)


1
Я згоден з вашими настроями. Однак система коментарів занадто обмежена, щоб чітко представляти всю інформацію. Я додав зміст цієї відповіді до коментаря; хоча я наполягаю на тому, щоб залишити цю відповідь місцем для полегшення доступу.
ThorSummoner

1
Це може бути або окрема публікація, або редагування. Мені це подобається як окрема відповідь.
Flimm

27

Ви можете перевірити:

git gui blame <filename>

Дає вам гарне графічне відображення змін, таких як "git blama", але з натисканням посилань на рядок, щоб перейти до попередніх комісій. Наведіть курсор на посилання, щоб отримати спливаюче вікно з деталями фіксації. Не мої кредити ... знайдено тут:

http://zsoltfabok.com/blog/2012/02/git-blame-line-history/

git guiє графічним інтерфейсом Tcl / Tc для git. Без будь-яких інших параметів він запускає досить простий, але корисний графічний додаток для створення файлів, перехоплень або навіть одиночних рядків та інших подібних команд, таких як поправка, повернення, натискання ... Це частина набору git stock. У Windows він включений в інсталятор. На debian - я не знаю про інші * nix системи - його потрібно встановлювати окремо:

apt-get install git-gui

З документів:

https://git-scm.com/docs/git-gui

ОПИС

Графічний користувальницький інтерфейс для Git на основі Tcl / Tk. git gui зосереджується на тому, щоб дозволити користувачам вносити зміни до свого сховища шляхом внесення нових комісій, внесення змін до існуючих, створення гілок, виконання локальних об'єднань та вилучення / переміщення до віддалених сховищ.

На відміну від gitk, git gui зосереджується на створенні комісій та конспектуванні одного файлу і не показує історію проекту. Однак він надає дії меню, щоб розпочати сеанс gitk зсередини git gui.

Як відомо, git gui працює у всіх популярних системах UNIX, Mac OS X та Windows (як у Cygwin, так і в MSYS). Наскільки це можливо, дотримуються конкретних вказівок для користувальницького інтерфейсу, що робить git gui досить рідним інтерфейсом для користувачів.

КОМАНДИ

звинувачувати

Запустіть програму перегляду звинувачення у вказаному файлі для даної версії (або робочого каталогу, якщо він не вказаний).

браузер

Запустіть браузер дерева, де відображаються всі файли у вказаній комісії. Файли, вибрані через браузер, відкриваються у переглядачі вини.

citool

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

версія

Показати поточно запущену версію git gui.


Це не працює для мене. Я можу натиснути зміни в заданому рядку, але це просто змінює подання для цього фіксації, і теперішній рядок відображається як this: але як я бачу попередню версію рядка і коли вона була додана?
BeeOnRope

Це один із випадків використання, з якого я знаю, де найкраще рішення
камбунгіологічний

17

Спираючись на попередню відповідь, цей однотонний лайнер повинен дати вам те, що ви шукаєте. Він відображає історію звинувачення в git для певного рядка певного файлу через останні 5 версій:

LINE=10 FILE=src/options.cpp REVS=5; for commit in $(git rev-list -n $REVS HEAD $FILE); do git blame -n -L$LINE,+1 $commit -- $FILE; done

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

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


5
Зауважте, що це остання редакція $ REVS, в якій змінився $ FILE, а не остання редакція $ REVS, в якій змінилася $ LINE.
Макс Нанасі

На яку відповідь ви звертаєтесь?
Flimm

Я вже не пам'ятаю. Можливо, я міг би краще підтвердити свою відповідь.
Буде Шеппард


11

Дуже унікальним рішенням цієї проблеми є використання git log:

git log -p -M - наступний --stat - шлях / до / ваш / файл

Як пояснив тут Андре


1
Я створив псевдонім, щоб використати це: git config --global alias.changes 'log -p -M --follow --stat --'і тоді я можу просто набратиgit changes path/to/your/file
Tizio Fittizio

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

10

Якщо ви використовуєте IDE JetBrains Idea (і похідні), ви можете вибрати кілька рядків, клацніть правою кнопкою миші контекстне меню, потім Git -> Показати історію для вибору. Ви побачите список комітетів, які впливали на вибрані рядки:

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


Це працювало краще, ніж інші відповіді для мене (використовуючи IntelliJ). Знадобився час, щоб завантажити всі зміни, але варто почекати.
Стів Чемберс

1

Спираючись на відповідь Вілла Шепарда, його висновок буде містити повторювані рядки для комітетів, де не було змін, тож ви можете відфільтрувати їх наступним чином (використовуючи цю відповідь )

LINE=1 FILE=a; for commit in $(git rev-list HEAD $FILE); do git blame -n -L$LINE,+1 $commit -- $FILE; done | sed '$!N; /^\(.*\)\n\1$/!P; D'

Зауважте, що я видалив аргумент REVS, і це повертається до кореневої комісії. Це пояснюється спостереженням Макса Нанасі вище.


1

Спираючись на відповідь DavidN, я хочу слідувати перейменованому файлу:

LINE=8 FILE=Info.plist; for commit in $(git log --format='%h%%' --name-only --follow -- $FILE | xargs echo | perl -pe 's/\%\s/,/g'); do hash=$(echo $commit | cut -f1 -d ','); fileMayRenamed=$(echo $commit | cut -f2 -d ','); git blame -n -L$LINE,+1 $hash -- $fileMayRenamed; done | sed '$!N; /^\(.*\)\n\1$/!P; D'

ref: чудово відобразити історію перейменування файлів у журналі git


1

Станом на Git 2.23 ви можете використовувати git blamin --ignore-rev

Для прикладу, наведеного у питанні, це було б:

git blame -L10,+1 src/options.cpp --ignore-rev fe25b6d

(проте це хитрі питання, тому що fe25b6d - це перша редакція файлу!)


0

Я використовую цей маленький сценарій башти, щоб переглянути історію звинувачення.

Перший параметр: файл, який потрібно подивитися

Наступні параметри: Перекладено на винуватця

#!/bin/bash
f=$1
shift
{ git log --pretty=format:%H -- "$f"; echo; } | {
  while read hash; do
    echo "--- $hash"
    git blame $@ $hash -- "$f" | sed 's/^/  /'
  done
}

Ви можете надати параметри вини, такі як -L 70, + 10, але краще використовувати регулярний пошук пошуку вини, оскільки номери рядків зазвичай "змінюються" з часом.


0

Грунтується на stangls «и відповідь , я ставлю цей сценарій в моїй PATH (навіть на Windows) , як мерзотника-БХ:

Це дозволяє мені шукати всі комісії, де було залучено слово:

git bh path/to/myfile myWord

Сценарій:

#!/bin/bash
f=$1
shift
csha=""
{ git log --pretty=format:%H -- "$f"; echo; } | {
  while read hash; do
    res=$(git blame -L"/$1/",+1 $hash -- "$f" 2>/dev/null | sed 's/^/  /')
    sha=${res%% (*}
    if [[ "${res}" != "" && "${csha}" != "${sha}" ]]; then
      echo "--- ${hash}"
      echo "${res}"
      csha="${sha}"
    fi
  done
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.