Почему Git GUI продолжает называть меня Jon Skeet? - PullRequest
0 голосов
/ 22 декабря 2018

В шутку я назвал учетную запись пользователя моего ноутбука Джона Скита.Я настроил параметры для каждого репозитория так, чтобы они называли меня wizzwizz4, но когда я просматриваю свои коммиты, я вижу это:

Author: Jon Skeet <jon@myLaptop>  2018-12-21 22:07:11
Committer: wizzwizz4 <wizzwizz4@users.noreply.github.com>  2018-12-21 22:12:07
Parent: 39c31f5aebe43cdddbe00432207e4bb2cc6a777e (Initial commit)
Branches: master
Follows: 
Precedes: 

Почему он продолжает это делать, когда мои настройки репозитория четко указывают мои намерения?Я не хочу, чтобы Джон получил кредит на мой код!Фиксация из командной строки дает ожидаемый результат.

1 Ответ

0 голосов
/ 22 декабря 2018

Есть несколько способов, которые могут произойти.Прежде чем мы доберемся до них всех, нам нужно будет предоставить соответствующую справочную информациюТакже стоит подчеркнуть ключевой элемент: Никакие данные в любом существующем коммите не могут быть изменены, даже один бит. Пока коммит 39c31f5aebe43cdddbe00432207e4bb2cc6a777e существует в вашем репозитории, он будет по-прежнему иметь ту же информацию,(Обратите внимание, что это родительский коммита, который вы показали. Вы не показали фактический хэш-идентификатор самого коммита, поэтому я не смог использовать его.)

Вочень специфический случай Git-GUI (git-gui.sh, который я никогда не использую), он выглядит из source , как будто есть особенность, где использование «исправить» читает HEAD фиксирует информацию об авторе и копирует ее.Обычно должен делать это, когда вы выбираете «внесение поправок» (что, как отмечено выше и ниже, является ложью белого), а не должно делать это, когда не вносятся поправки.В отличие от командной строки git commit, похоже, нет ручки Git-GUI, чтобы внести изменения, не сохраняя автора.Если он случайно применяет автора, сохраняющего все новые коммиты, это просто ошибка.

Подробнее читайте дальше.

Фон

Каждый коммитимеет некоторые метаданные , связанные с ним.В необработанном объекте фиксации есть две соответствующие строки метаданных, которые называются author и committer .Эти два, как правило, но не обязательно, одинаковы, как можно видеть из различных коммитов в Git-репозитории для самого Git.Например:

$ git cat-file -p 5d826e972970a784bd7a7bdf587512510097b8c7
tree c790c47fe551d5ed812cfefdac243eb972c1fde3
parent b5796d9a3263b26a8ef32eeca76b3c1d62fcedc5
author Junio C Hamano <gitster pobox.com> 1544328981 +0900
committer Junio C Hamano <gitster pobox.com> 1544328981 +0900

Git 2.20

Signed-off-by: Junio C Hamano <gitster pobox.com>

(я заменил @ на , чтобы, возможно, сократить сбор спама).Но:

$ git cat-file -p 6fcbad87d476d7281832af843dd448c94673fbfc
tree aa05bc7af6e92f3db5d5d738adf0d0b1b3dd23b6
parent b00bf1c9a8dd5009d5102aef7af9e2b886b1e5ad
author Johannes Sixt <j6t kdbg.org> 1543858489 +0100
committer Junio C Hamano <gitster pobox.com> 1543891852 +0900

rebase docs: fix incorrect format of [... snip]

Обратите внимание, что на самом деле в каждом из двух полей есть три части: полное имя, адрес электронной почты ви timestamp-with-zone-offset.

Когда вы делаете новый коммит, используя git commit, Git обычно устанавливает и автора, и коммиттера в те же три строки .Но многие команды Git копируют некоторые существующие коммиты в новую улучшенную замену.Новый коммит, по определению, имеет новый и другой хэш-идентификатор, но предназначен для использования вместо старого.В этих случаях Git обычно сохраняет исходную информацию author и устанавливает вас (и сейчас) как committer .

Для справки: автор-сохраняющее коммит-копированиекоманды git commit с опциями --amend или -c / -C;git cherry-pickgit rebase.Команда git am предназначена для превращения отправленных по электронной почте исправлений в коммиты: она принимает в качестве входных данных что-то отличное от commit , поэтому мы можем сказать, что это сохраняет автора, но затем мы должны определить, что мы подразумеваем автор .В этом случае git am угадывает информацию об авторстве, анализируя сообщение в формате почтового ящика.

Механизмы для каждого поля

Существует одна базовая команда Git, git commit-tree, другаяКоманды либо используют, либо встроены в них.Это фактически создает объект фиксации, который содержит вышеуказанные метаданные.Могут потребоваться различные директивы для индивидуальной настройки каждого поля.Если для какого-либо поля установлено , а не , git commit-tree может принимать откуда-то значение по умолчанию.

Поскольку для каждого из авторов есть шесть частей - имя, адрес электронной почты и отметка времении коммиттер - есть шесть мест, чтобы получить конкретные директивы, и много мест - не шесть в этот раз! - чтобы получить значения по умолчанию.Однако сначала давайте перечислим первичные шесть.

Вместо того, чтобы принимать параметры командной строки, git commit-tree берет эти шесть элементов из переменных среды , как описано в документации :

GIT_AUTHOR_NAME
GIT_AUTHOR_EMAIL
GIT_AUTHOR_DATE
GIT_COMMITTER_NAME
GIT_COMMITTER_EMAIL
GIT_COMMITTER_DATE

Если вы установите любую или все этих переменных, то будет установлено значение, которое войдет в все последующие новые коммиты (до тех пор, пока вы не сбросите переменные или ваш сеанс с этой средой не истечет, сбросив переменные).

Если нет, то в документации сказано:

В случае, если (некоторые из) эти переменные среды не установлены, информация берется из элементов конфигурации user.name и user.email или, если не присутствует, переменной среды EMAIL, или, если она не установлена, системного пользователяимя и имя хоста, используемые для исходящей почты (взяты из /etc/mailname и возвращаются к полному имени хоста, когда этот файл не существует).

Это немного лживая ложь, так какфактический путь к коду зависит от параметров времени компиляции, поэтому разные установки Git могут иметь разные индивидуальные настройки по умолчанию.Но общая общая идея верна: Git сначала будет использовать ваши настройки user.name и user.email как для автора, так и для коммиттера, если вы не переопределили одно или оба с различными переменными окружения.

По умолчаниювременная метка, конечно, просто представление вашего компьютера о текущем времени.Относительно новый параметр user.useConfigOnly говорит современному Git не догадываться при user.name и / или user.email.В более старых версиях Git Git не угадывал: если бы они не были установлены, git commit-tree и git commit просто потерпели бы ошибку с сообщением об ошибке, сообщая, что он не знал, кто вы.

The git commit команда переднего конца также принимает --author и --date в качестве аргументов.Эти аргументы могут указывать имя пользователя, адрес электронной почты и / или метку времени для использования в новом коммите;git commit эффективно реализует их, устанавливая на время операции фиксации переменные GIT_AUTHOR_*.

При использовании внешнего интерфейса git commit с флагом --amend, который, несмотря на его имя,на самом деле не изменяет коммит;он просто создает новый, чтобы использовать вместо текущего, со всеми вытекающими отсюда последствиями - флаг --reset-author указывает внешнему интерфейсу не сохранять информацию об авторе исходного коммита.

Заключение

Если новые коммиты получают неверного автора, а правильный коммиттер должен иметь место:

  • ВыИспользуешь --author.Стоп!

  • В вашей среде установлены GIT_AUTHOR_NAME и GIT_AUTHOR_EMAIL.Прекратите устанавливать их!

Если у вас есть какой-либо существующий коммит, и вы пытаетесь заменить его новым и улучшенным коммитом через git commit --amend, но он сохраняет настройки автора, простодобавить --reset-author.Конечно, это работает только из командной строки.Если вы используете что-то еще, выясните, есть ли у него аналогичная опция.

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

Коммиты, которые находятся на верхушке их ветви, а не на каких-либо другихветку, довольно легко поменять, используя git commit --amend.Дальнейшие коммиты в истории более трудны: вы можете использовать интерактивную перебазировку, или git replace, или, в особо уродливых случаях, git filter-branch, чтобы поменять их местами (иногда комбинируя эти приемы).Любое «изменение» на более старый коммит обязательно распространяется по всем его потомкам по дизайну, 1 , так что такого рода изменения могут быть весьма разрушительными.Однако, если она «меняется» - заменяет, действительно, историю, которую никто еще не видел, она достаточно безопасна.


1 Непосредственные потомки «плохого» коммитасодержит идентификатор родительского хэша плохого коммита.Следовательно, чтобы дети могли ссылаться на замену, мы должны заменить детей тоже .Это означает, что мы должны затем заменить их потомков и т. Д. По линии, вплоть до кончиков коммитов каждой затронутой ветви.

...