Pull to refresh

Итак, вы думаете, что знаете Git? Часть первая: старый добрый Git

Level of difficultyEasy
Reading time4 min
Views16K
Original author: Scott Chacon

Автор оригинала Скотт Чакон — сооснователь GitHub и основатель нового клиента GitButler. Этот клиент ставит во главу угла рабочий процесс и удобство разработки, в том числе код-ревью, и не является просто очередной обёрткой над CLI git.


В первом посте из этой короткой серии по Git я хотел начать с вещей, уже существующих какое-то время. При этом кажется, что многие люди о них не знают или не умеют ими пользоваться. В них нет ничего нового, но я нахожу их полезными и, возможно, не совсем освещёнными. Я просто хочу рассказать о:






Условная конфигурация


Многие из вас, вероятно, знают, что в Git есть маленькое классное хранилище «ключ-значение», вызываемое командой git config. Его значения, которые подставляются при выполнении различных команд, Git проверяет в трёх местах.


Наверное, каждого пользователя Git при первой настройке попросили запустить что-то такое:


git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

Команда добавляет значение user.name в файл ~/.gitconfig. Но также есть другие опции:


  • --system, которой, возможно, никто не пользовался. Она записывает значение в общесистемный конфигурационный файл [прим. перев. — речь идёт о $(prefix)/etc/gitconfig];
  • --local — по умолчанию. Она записывает значение в .git/config любого проекта, где вы находитесь прямо сейчас.

В поиске значения Git смотрит в таком порядке:


  • локальное;
  • глобальное;
  • системное.

Однако есть секретное четвёртое место, которое Git может посмотреть. Если вы добавите в свою глобальную конфигурацию что-то примерно такое:


[includeIf "gitdir:~/projects/oss"]
    path = ~/.gitconfig-oss

Git поищет значение в ~/.gitconfig-oss, только если проект, с которым вы сейчас работаете, находится в ~/projects/oss.


Итак, у вас могли бы быть:


  • каталог work со значениями, относящимися к конкретной работе (адрес электронной почты в компании, ключ GPG-подписи и т. д.);
  • каталог oss со значениями для проектов с открытым исходным кодом и  т.  д.

Но gitdir — не единственный фильтр:


  • через onbranch как включающий фильтр можно указать определённые названия ветки;
  • через hasconfig: remote.*.url можно включать файлы конфигурации, только если у текущего проекта есть удалённый сервер с определёнными URL.

Так что ставьте лайк, если у вас есть ключи для GitHub.org или что-то в этом роде. Подробности читайте в документации.


git blame и git log с диапазонами строк


Есть пара интересных опций git blame, о которых большинство людей не знают, а в существующих GUI они почти не реализованы.


Одна из них -L — диапазон строк. Если вы запускаете git blame в CLI, часто вы просто просматриваете весь файл и находите ту часть, которую ищете. Но если вы хотите отобразить только подраздел файла, то можно задать диапазон строк, например git blame -L 28,43 путь/к/файлу:



git blame -L


Чтобы дать Git шаблон для поиска начала блока и выполнить git blame только для этого блока, можно воспользоваться синтаксисом :. Так, в той же ситуации я могу получить такой же вывод, выполнив git blame -L : 'class LocalFile' gitbutler-ui/src/lib/vbranches/types.ts. Вместо 'class LocalFile' можно подставить имя функции или что-то ещё.


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


Например, git log -L28,43:gitbutler-ui/src/lib/vbranches/types.ts даст вам что-то вроде этого:



Вместо упорядочивания по строкам, опция -L как будто собирает все коммиты git blame, а затем показывает коммиты с кодом, в каждом из которых менялся заданный блок. В основном это те же данные, но в другом формате, больше похожем на рассказ, как этот код собирался воедино.


git blame с отслеживанием


Одна на самом деле не очень хорошая штука в работе с blame через GUI заключается в том, что CLI обладает гораздо более мощными инструментами, чтобы найти что-то ближе к реальной истории, стоящей за вашим кодом. Есть много ситуаций, где это действительно ценно.


Первая — игнорирование изменений пробелов. Некоторые GUI игнорируют их, но не все. Если вы просто пойдёте и внедрите файл prettierrc — бах, теперь вы владелец тонны строк кода. С опцией git blame -w эти типы изменений пробельных символов игнорируются.


Другая отличная опция, которая отслеживает перемещение кода между файлами в коммите, — это-C. Когда вы выполните рефакторинг функции из одного файла в другой, обычная команда git blame просто покажет вас как автора нового файла, но опция -C отследит движение кода и покажет последнего, кто изменил строки.


Любые из этих данных могут оказаться тем, что вы ищете, но я бы сказал, чаще всего возникает последняя ситуация. Если вы хотите, чтобы Git старался ещё усерднее (ищете движение в нескольких или во всех коммитах), то можете указать опцию -C до трёх раз.


Кроме того, ваш GUI не делает этого (скорее всего, я не могу говорить обо всех). Давайте посмотрим на вывод git blame из предыдущего примера в GitLens VS Code:



git blame в плагине VS Code GitLens


Ок, выглядит хорошо. Большую часть этого кода, кажется, написал Кирил. Теперь давайте посмотрим на тот же блок с git blame -w -C -C -C:



git blame -C -C -C


Git следовал за этим куском кода от файла к файлу в течение нескольких переименований.


Кроме того, Кирил на самом деле владеет всего несколькими строками, большие его куски на самом деле написал Маттиас. Если захочется разузнать о них, гораздо лучше спросить Маттиаса, а не Кирила, как предполагает наш GUI.


git diff по словам вместо строк


Это невероятно вторично, а в некоторых графических интерфейсах есть приятные версии. Я нахожу GitHub лучше того, что собираюсь показать, ведь он аккуратно выполняет команду в GUI и в CLI. Но если вы запускаете git diff в CLI для строки с небольшим изменением, то можете изменить формат Git по умолчанию на слова, а не на строки, опцией--word-diff:



нормальный, построчный git diff



особенно крутой git diff --word-diff


Память о разрешении конфликта


Наконец, если вы часто выполняете git rebase или git cherry-pick и сталкиваетесь с одним и тем же конфликтом чаще одного раза, то можно включить функцию запоминания и разрешения конфликта. Если Git дважды и более раз увидит один и тот же конфликт, то решит его автоматически.


Эту функцию можно легко включить настройкой конфигурации rerere.enabled. Далее можно попросить Git настроить для вас автоматический стейджинг через rerere.autoUpdate:


git config --global rerere.enabled true
git config --global rerere.autoUpdate true


Git навсегда запомнил конфликт


Затем, в следующий раз, когда вы столкнётесь с конфликтом, который решали раньше, — магия!

автоматическое исправление


Что дальше?


Опять же, всё это уже давно есть в Git, но если вы чего-то не знали, то теперь знаете. Далее — новые штуки в Git.




P.S. Ссылка на видео-версию от domix32

Tags:
Hubs:
If this publication inspired you and you want to support the author, do not hesitate to click on the button
Total votes 22: ↑21 and ↓1+23
Comments6

Articles