Git blame что это
Команда git blame это действительно полезная команда, чтобы найти того кто изменил определенную часть файла. Вы просто выполните ‘git blame [filename]’ и получите вывод всех данных файла включая sha значение последнего коммита, дату и автора каждой строки файла.
$ git blame sha1_file.c . 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 8) */ 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 9) #include "cache.h" 1f688557 (Junio C Hamano 2005-06-27 03:35:33 -0700 10) #include "delta.h" a733cb60 (Linus Torvalds 2005-06-28 14:21:02 -0700 11) #include "pack.h" 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 12) #include "blob.h" 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 13) #include "commit.h" 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 14) #include "tag.h" 8e440259 (Peter Eriksen 2006-04-02 14:44:09 +0200 15) #include "tree.h" f35a6d3b (Linus Torvalds 2007-04-09 21:20:29 -0700 16) #include "refs.h" 70f5d5d3 (Nicolas Pitre 2008-02-28 00:25:19 -0500 17) #include "pack-revindex.h"628522ec (Junio C Hamano 2007-12-29 02:05:47 -0800 18) #include "sha1-lookup.h" .
Часто полезно увидеть кто последним изменил файл, если в файле изменения ломают сборку приложения.
Вы также можете определить для этой команды начальную и конечную строки:
$>git blame -L 160,+10 sha1_file.c ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 160)> ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 161) 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 162)/* 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 163) * NOTE! This returns a statically allocate 790296fd (Jim Meyering 2008-01-03 15:18:07 +0100 164) * careful about using it. Do an "xstrdup() 0fcfd160 (Linus Torvalds 2005-04-18 13:04:43 -0700 165) * filename. ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 166) * ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 167) * Also note that this returns the location ace1534d (Junio C Hamano 2005-05-07 00:38:04 -0700 168) * SHA1 file can happen from any alternate d19938ab (Junio C Hamano 2005-05-09 17:57:56 -0700 169) * DB_ENVIRONMENT environment variable if i
This book is maintained by Scott Chacon, and hosting is donated by GitHub.
Please email me at schacon@gmail.com with patches, suggestions and comments.
Использование команды ‘git blame’
Команда git blame является неоценимым инструментом при работе с Git. Эта команда используется для отображения того, какая ревизия и автор последними внесли изменения в каждую строку файла. Это может быть особенно полезно при отладке или понимании структуры кода, особенно в больших проектах с множеством участников.
Практическое применение ‘git blame’
Рассмотрим практический пример использования git blame . Предположим, вы нашли странное поведение в коде и хотите понять, откуда это взялось. Команда git blame позволит вам просмотреть историю каждой строки файла и увидеть, кто внес последний коммит.
git blame myfile.txt
Результат выполнения этой команды будет включать номер ревизии, автора и дату для каждой строки кода. Это может дать вам контекст того, почему были сделаны определенные изменения.
Лучшие практики и дополнительные сведения
Хотя команда git blame может быть полезной для отладки и понимания кода, её важно использовать ответственно. Название команды может напоминать обвинение, но на самом деле она предназначена для предоставления истории и контекста кода, а не для назначения вины.
Более того, git blame может быть особенно полезен, если вы внедрите привычку формулирования качественных коммитов. Чем больше информации вы предоставляете в своих коммитах, тем более полезной становится история, которую вы можете получить с помощью ‘git blame’.
В завершение стоит отметить, что git blame это всего лишь один из многих полезных инструментов, доступных в Git для помощи в отладке и управлении кодом. Использование его в сочетании с другими командами, такими как git log и git diff , может значительно упростить процесс понимания истории кода.
A3.7 Приложение C: Команды Git — Отладка
В Git есть несколько команд, используемых для нахождения проблем в коде. Это команды для поиска места в истории, где проблема впервые проявилась и собственно виновника этой проблемы.
git bisect
Команда git bisect — это чрезвычайно полезная утилита для поиска коммита в котором впервые проявился баг или проблема с помощью автоматического бинарного поиска.
О ней упоминается только в разделе Бинарный поиск главы 7, где она полностью и раскрыта.
git blame
Команда git blame выводит перед каждой строкой файла SHA-1 коммита, последний раз менявшего эту строку и автора этого коммита. Это помогает в поисках человека, которому нужно задавать вопросы о проблемном куске кода.
Эта команда полностью разобрана в разделе Аннотация файла главы 7.
git grep
Команда git grep используется для поиска любой строки или регулярного выражения в любом из файлов вашего проекта, даже в более ранних его версиях.
Она полностью разобрана в разделе Команда git grep главы 7 и упоминается лишь там.
7.10 Инструменты Git — Обнаружение ошибок с помощью Git
Git предоставляет несколько инструментов, которые помогут вам найти и устранить проблемы в ваших проектах. Так как Git рассчитан на работу с проектом почти любого типа, эти инструменты имеют довольно обобщённые возможности, но часто они могут помочь вам отловить ошибку или её виновника.
Аннотация файла
Если вы обнаружили ошибку в вашем коде и хотите знать, когда она была добавлена и почему, то в большинстве случаев аннотация файла будет лучшим инструментом для этого. С помощью неё для любого файла можно увидеть, каким коммитом последний раз изменяли каждую из строк. Поэтому если вы видите, что некоторый метод в вашем коде работает неправильно, вы можете с помощью команды git blame снабдить файл аннотацией, и таким образом увидеть, когда каждая строка метода была изменена последний раз и кем.
В следующем примере используется git blame , чтобы определить, какой коммит и коммиттер отвечал за строки в Makefile ядра Linux верхнего уровня и, кроме того, использует параметр -L для ограничения вывода аннотации строками с 69 по 82 из этого файла:
$ git blame -L 69,82 Makefile b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 69) ifeq ("$(origin V)", "command line") b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 70) KBUILD_VERBOSE = $(V) ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) endif ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) ifndef KBUILD_VERBOSE ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) KBUILD_VERBOSE = 0 ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) endif ^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75) 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 76) ifeq ($(KBUILD_VERBOSE),1) 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 77) quiet = 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 78) Q = 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 79) else 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 80) quiet=quiet_ 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 81) Q = @ 066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 82) endif
Обратите внимание, что первое поле — это неполная SHA-1 сумма последнего коммита, который изменял соответствующую строку. Следующими двумя полями являются значения, извлечённые из этого коммита — имя автора и время создания коммита — таким образом, вы можете легко увидеть кто изменял строку и когда. После этого следуют номер строки и содержимое файла. Обратите внимание на строки со значением ^4832fe2 в поле коммита, так обозначаются те строки, которые были в первом коммите этого файла. Этот коммит был сделан, когда данный файл был впервые добавлен в проект и с тех пор эти строки не были изменены. Немного сбивает с толку то, что вы уже видели в Git, по крайней мере, три различных варианта использования символа ^ для изменения SHA-1 коммита, в данном случае этот символ имеет такое значение.
Другая отличная вещь в Git — это то, что он не отслеживает явно переименования файлов (пользователю не нужно явно указывать какой файл в какой был переименован). Он сохраняет снимки и уже после выполнения самого переименования неявно попытается выяснить, что было переименовано. Одна из интересных возможностей, вытекающих из этого — это то, что вы также можете попросить Git выявить перемещения кода всех других видов. Если передать опцию -C команде git blame , Git проанализирует аннотируемый файл и попытается выяснить откуда изначально появились фрагменты кода, если они, конечно же, были откуда-то скопированы. Например, предположим при реорганизации кода в файле GITServerHandler.m вы разнесли его по нескольким файлам, один из которых GITPackUpload.m . Вызывая git blame с опцией -C для файла GITPackUpload.m , вы можете увидеть откуда изначально появились разные фрагменты этого файла.
$ git blame -C -L 141,153 GITPackUpload.m f344f58d GITServerHandler.m (Scott 2009-01-04 141) f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC f344f58d GITServerHandler.m (Scott 2009-01-04 143) < 70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI ad11ac80 GITPackUpload.m (Scott 2009-03-24 145) ad11ac80 GITPackUpload.m (Scott 2009-03-24 146) NSString *parentSha; ad11ac80 GITPackUpload.m (Scott 2009-03-24 147) GITCommit *commit = [g ad11ac80 GITPackUpload.m (Scott 2009-03-24 148) ad11ac80 GITPackUpload.m (Scott 2009-03-24 149) //NSLog(@"GATHER COMMI ad11ac80 GITPackUpload.m (Scott 2009-03-24 150) 56ef2caf GITServerHandler.m (Scott 2009-01-05 151) if(commit) < 56ef2caf GITServerHandler.m (Scott 2009-01-05 152) [refDict setOb 56ef2caf GITServerHandler.m (Scott 2009-01-05 153)
Это, действительно, полезно. Обычно вы получаете в качестве изначального коммит, в котором вы скопировали код, так как это первый коммит, в котором вы обращаетесь к этим строкам в этом файле. Но в данном случае Git сообщает вам первый коммит, в котором эти строки были написаны, даже если это было сделано в другом файле.
Бинарный поиск
Аннотирование файла помогает, если вы знаете, где находится проблема и можете начать исследование с этого места. Если вы не знаете, что сломано, а с тех пор как код работал, были сделаны десятки или сотни коммитов, вы вероятно воспользуетесь командой git bisect . Эта команда выполняет бинарный поиск по истории коммитов для того, чтобы помочь вам как можно быстрее определить коммит, который создал проблему.
Допустим, вы только что развернули некоторую версию вашего кода в боевом окружении и теперь получаете отчёты о некоторой ошибке, которая не возникала в вашем разработческом окружении, и вы не можете представить, почему код ведет себя так. Вы возвращаетесь к вашему коду и выясняете, что можете воспроизвести проблему, но всё ещё не понимаете, что работает неверно. Вы можете воспользоваться бинарным поиском, чтобы выяснить это. Во-первых, выполните команду git bisect start для запуска процесса поиска, а затем используйте git bisect bad , чтобы сообщить Git, что текущий коммит сломан. Затем, используя git bisect good [good_commit] , вы должны указать, когда было последнее известное рабочее состояние:
$ git bisect start $ git bisect bad $ git bisect good v1.0 Bisecting: 6 revisions left to test after this [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] Error handling on repo
Git выяснил, что произошло около 12 коммитов между коммитом, который вы отметили как последний хороший коммит (v1.0), и текущим плохим коммитом, и выгрузил вам один из середины. В этот момент вы можете запустить ваши тесты, чтобы проверить присутствует ли проблема в этом коммите. Если это так, значит она была внесена до выгруженного промежуточного коммита, если нет, значит проблема была внесена после этого коммита. Пусть в данном коммите проблема не проявляется, вы сообщаете об этом Git с помощью git bisect good и продолжаете ваше путешествие:
$ git bisect good Bisecting: 3 revisions left to test after this [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] Secure this thing
Теперь вы оказались на другом коммите, расположенном посредине между только что протестированным и плохим коммитами. Вы снова выполняете ваши тесты, обнаруживаете, что текущий коммит сломан, и сообщаете об этом Git с помощью команды git bisect bad :
$ git bisect bad Bisecting: 1 revisions left to test after this [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] Drop exceptions table
Этот коммит хороший и теперь Git имеет всю необходимую информацию для определения того, где была внесена ошибка. Он сообщает вам SHA-1 первого плохого коммита и отображает некоторую информацию о коммите и файлах, которые были изменены в этом коммите, так, чтобы вы смогли разобраться что же случилось, что могло привнести эту ошибку:
$ git bisect good b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 Author: PJ Hyett Date: Tue Jan 27 14:48:32 2009 -0800 Secure this thing :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config
Когда вы закончили бинарный поиск, нужно выполнить git bisect reset для того, чтобы вернуть HEAD туда, где он был до начала поиска, иначе вы останетесь в, довольно, причудливом состоянии:
$ git bisect reset
Это мощный инструмент, который помогает вам за считанные минуты проверить сотни коммитов на возможность внесения ошибки. В действительности, если у вас есть скрипт, который будет возвращать 0 если проект находится в рабочем состоянии и любое другое число в обратном случае, то вы можете полностью автоматизировать git bisect . Сперва, вы снова сообщаете границы бинарного поиска, указывая известные плохие и хорошие коммиты. Вы можете сделать это, передавая их команде bisect start — первым аргументом известный плохой коммит, а вторым известный хороший коммит:
$ git bisect start HEAD v1.0 $ git bisect run test-error.sh
Это приведёт к автоматическому выполнению test-error.sh на каждый выгруженный коммит до тех пор, пока Git не найдёт первый сломанный коммит. Вы также можете использовать что-то вроде make или make tests , или что-то ещё, что у вас есть для запуска автоматизированных тестов.