Виноват - предыдущие коммиты?

Можно ли увидеть, кто редактировал конкретную строку перед коммитом, о котором сообщает 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? И кто его редактировал перед этим коммитом?

12 ответов

Решение
git blame -L10,+1 fe25b6d^ -- src/options.cpp

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

Вы можете использовать git log -L для просмотра эволюции ряда линий.

Например:

git log -L 15,23:filename.txt

означает "проследить эволюцию строк с 15 по 23 в файле с именем filename.txt".

Амбер ответ правильный, но я нашел его неясным; Синтаксис:

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

Обратите внимание -- используется для отделения дерева sha1 от относительных путей к файлам. 1

Например:

git blame master -- index.html

Полная благодарность Amber за знание всех вещей!:)

Вы можете проверить:

git gui blame <filename>

Дает вам хорошее графическое отображение изменений, таких как "git blame", но с кликабельными ссылками на строку, чтобы перейти к более ранним коммитам. Наведите указатель мыши на ссылки, чтобы получить всплывающее окно с подробной информацией о коммите. Не мои кредиты... нашел это здесь:

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

git gui графический интерфейс Tcl/Tc для git Без каких-либо других параметров он запускает довольно простое, но полезное графическое приложение для фиксации файлов, фрагментов или даже отдельных строк и других подобных команд, таких как изменение, возврат, нажатие... Это часть пакета git stock. На окнах это включено в установщик. На Debian - я не знаю о других * nix системах - он должен быть установлен отдельно:

apt-get install git-gui

Из документов:

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

ОПИСАНИЕ

Графический пользовательский интерфейс на основе Tcl/Tk для Git. git gui фокусируется на том, чтобы позволить пользователям вносить изменения в свой репозиторий, делая новые коммиты, внося поправки в существующие, создавая ветви, выполняя локальные слияния и извлекая / отправляя в удаленные репозитории.

В отличие от gitk, git gui фокусируется на генерации коммитов и аннотации к одному файлу и не отображает историю проекта. Однако он предоставляет действия меню для запуска сеанса gitk из git gui.

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

КОМАНДЫ

вина

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

браузер

Запустите древовидный браузер, показывающий все файлы в указанном коммите. Файлы, выбранные через браузер, открываются в программе просмотра виновных.

citool

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

версия

Показать текущую версию git gui.

Уникальным решением этой проблемы является использование git log:

git log -p -M --follow --stat - путь / к / вашему / файлу

Как объяснил Андре здесь

Основываясь на предыдущем ответе, эта однострочная команда bash должна дать вам то, что вы ищете. Он отображает историю мерзавца за конкретную строку определенного файла, за последние 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

В выходных данных этой команды вы можете увидеть, как изменяется содержимое строки или даже может отображаться номер строки для конкретного коммита.

Это часто указывает на то, что строка была добавлена ​​впервые, после этой конкретной фиксации. Это также может указывать на то, что строка была перемещена из другой части файла.

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

Есть также recursive-blame, Может быть установлен с

npm install -g recursive-blame

Начиная с Git 2.23 вы можете использовать git blame --ignore-rev

Для примера, приведенного в вопросе, это будет:

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

(однако это вопрос с подвохом, потому что fe25b6d - первая редакция файла!)

Основываясь на ответе Уилла Шепарда, его вывод будет включать дубликаты строк для коммитов, в которых не было изменений, поэтому вы можете отфильтровать их следующим образом (используя этот ответ)

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, и это восходит к корневой фиксации. Это связано с наблюдением Макса Нанаси выше.

stangls на stangls, я поместил этот скрипт в свой PATH (даже в Windows) как git-bh:

Это позволяет мне искать все коммиты, в которых было задействовано слово:

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
}

Основываясь на ответе 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 log

Я написал ublameИнструмент python, который возвращает наивную историю коммитов файла, которые повлияли на данный поисковый запрос, вы найдете более подробную информацию на странице þroject.

Я использую этот маленький скрипт bash, чтобы посмотреть историю обвинений.

Первый параметр: файл для просмотра

Последующие параметры: передано, чтобы свалить вину

#!/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, но лучше использовать поиск по регулярным выражениям в git-винах, потому что номера строк обычно "меняются" с течением времени.

Другие вопросы по тегам