Есть ли способ в git получить дату отправки для данного коммита?

93

Мне интересно, есть ли способ просмотреть дату push, связанную с каждой фиксацией, в журнале git. Если это невозможно, есть ли способ увидеть все коммиты под определенным толчком.

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

Justkikuchi
источник

Ответы:

77

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

# required for a bare repo
git config core.logAllRefUpdates true

git reflog --date=local master

Наконец-то просто.

Предупреждение: вы, вероятно, захотите изменить значения по умолчанию gc.reflogExpireи gc.reflogExpireUnreachable. Узнайте git help reflogподробности и поймите, как и почему это работает.

Две приведенные выше команды должны выполняться внутри клона, на который вы нажимаете . Если это невозможно, то приближение должно выполняться в другом постоянном клоне:

git fetch               origin        # often and *regularly*
git reflog --date=local origin/master

Никогда не удаляйте этот постоянный клон, иначе вы потеряете даты.

Март
источник
2
Я хотел бы добавить, что в моем случае мне пришлось сделать git reflog --date=local origin/master(примечание origin/), чтобы увидеть список нажатий. В противном случае в списке были только фиксации, проверки и извлечения (что тоже полезно). Собственно, на это мне указал ответ @JonathanDay .
NIA
@NIA: origin / master даст вам только приблизительное представление. Я обновил свой ответ после вашего комментария, проясняет ли это?
MarcH
37

Git - это распределенная система контроля версий, поэтому вы должны четко определить, что вы подразумеваете под «датой отправки». Например, предположим, что пользователь A отправляет некоторые коммиты в репозиторий пользователя B. Некоторое время спустя пользователь B отправляет те же коммиты в третий репозиторий. Какая дата вас интересует?

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

Плохие новости

К сожалению, нет возможности добавить дату в сообщения фиксации. Это изменит идентификатор фиксации (который является хешем содержимого SHA1), что вызовет всевозможные проблемы.

Хорошие новости

К счастью, в Git есть (относительно новая) функция под названием заметки . Эта функция позволяет прикреплять к коммитам произвольный текст, который git logможет отображаться. Заметки можно редактировать и делиться ими с другими.

Вы можете использовать функцию примечаний, чтобы прикрепить сообщение «эта фиксация была получена [дата]» к каждой фиксации по мере ее получения в общий репозиторий.

Подробнее git help notesсм.

Как записать дату

Вот подход, который я рекомендую:

  1. Измените post-receiveловушку в вашем общем репозитории, чтобы просматривать каждую новую доступную фиксацию для каждой обновленной ссылки.
  2. Для каждой фиксации добавьте что-то вроде «[пользователь] из [repository_url] добавил эту фиксацию в [ref] on [date]» в примечании к фиксации.

    Вы можете использовать примечания ref, посвященные этой цели (например refs/notes/received-on), вместо значения по умолчанию refs/notes/commits. Это предотвратит конфликты с заметками, созданными для других целей.

  3. Измените receiveловушку, чтобы запретить обновление ссылки на заметки (чтобы пользователи не случайно или намеренно не повредили заметки).
  4. Скажите всем пользователям, чтобы они запускали следующие команды из своего рабочего дерева:

    # Fetch all notes from the shared repository.
    # Assumes the shared repository remote is named 'origin'.
    git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*'
    
    # Show all notes from the shared repository when running 'git log'
    git config --add notes.displayRef 'refs/remote-notes/origin/*'
    

    Этот шаг необходим, поскольку Git по умолчанию игнорирует ссылки без веток и тегов в вышестоящих репозиториях.

Вышеупомянутое предполагает, что ссылки только расширяются, никогда не удаляются и не обновляются принудительно. Вы, вероятно, захотите, чтобы post-receiveловушка также добавляла примечания «удалено [дата]» для обработки этих случаев.

Ричард Хансен
источник
Я использовал вашу идею в своем блоге mnaoumov.wordpress.com/2013/01/31/git-get-push-date
mnaoumov
8
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

Мне кажется, это очень хорошо работает. Дата коммиттера (% cd) вводит в заблуждение, потому что она не обязательно совпадает с датой отправки. Однако опция --date = iso выводит дату push / fetch .

Обратите внимание: если вы получили его из origin / master, он напечатает дату, которую вы его получили; НЕ дата, когда кто-то еще нажал на коммит.

 - %h:  abrev. hash
 - %gd: human readable reflog selector
 - %gs: reflog subject
 - %s:  subject/commit message

Бонус: вы, конечно, можете сделать более красивое форматирование. Пока мне нравится эта цветовая кодировка. Хотя печатать это немного. Это выведет SHA на красный цвет, селектор reflog - на голубой, а reflog - на зеленый.

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso
ВК
источник
Привет, VC, означает ли это, что если вывод команды "reflog show origin / master --pretty = '% Cred% h% Creset -% C (желтый)% gd% Creset% Cblue (% gs)% Creset% s' - -date = iso "is" da4c192cd -origin / master @ {2019-02-07 08:13:40 +0100} (pull: fast-forward) JIRA-2542 Enhanced Test Report ", это означает, что содержимое моей ветки JIRA -2542 был слит на origin / master через fast-froward в 07.02.2019, 08:13:40?
Саймон
Привет, Саймон, да. Вы сделали git pull для своей ветки, и в то время она была объединена в origin / master с помощью быстрой перемотки вперед.
VC
Работает только на авторском репозитории. Если я клонирую репозиторий, значение будет пустым. Вы не можете видеть время толчка других людей.
Рамвин
6

Взгляните на git reflog show master. Возможно, это не тот формат, который вам нужен, но он должен указать вам правильное направление.

Другая идея - запустить сценарий внутри push-хука.

Карл Билефельдт
источник
Я думал о том, чтобы запустить толкатель, но, похоже, это должно быть последнее усилие. С крючком кажется, что каждый пользователь должен иметь этот крючок в каждом из своих репозиториев. Не могли бы вы рассказать подробнее о git reflog show master? Я хочу иметь возможность просматривать дату отправки отдельных коммитов каждого пользователя.
Justkikuchi
git reflog показывает порядок изменений в любом репо, в котором вы его запускаете. Я не уверен, есть ли прямой способ получить дату, но в .git/logs/refs/heads/masterнем отображается временная метка.
Karl Bielefeldt
3
Что касается крючков, там получить крючки , которые работают на компьютере , вы нажимаете на . Поскольку нажатие актуально только относительно определенного репо, я предполагаю, что у вас есть определенное «благословенное» репо, на котором вы хотите его запустить. То же самое и git reflogв этом отношении.
Karl Bielefeldt
5

Этот ответ относительно проверки журнала ссылок на пульте дистанционного управления может помочь ( https://stackoverflow.com/a/8791295/336905 ), предоставив вам информацию о том, какая ветка была отправлена, даже если она не показывает, какие коммиты были отправлены, но вы может взаимно коррелировать, найдя следующий толчок после локальной даты фиксации. Не надежно, но удобно, если вы еще не реализовали отличные заметки от @RichardHansen, опубликованные ранее.

Джонатан Дэй
источник
1
Обратите внимание, что reflog of origin/branchбудет отображать только изменения, сделанные на текущей машине, это чрезвычайно полезно! Для повседневного использования я не хочу реализовывать какие-либо хуки, поэтому на простой вопрос «Хммм, когда я подтолкнул эту фиксацию на прошлой неделе?» - отлично работает.
NIA
4

Вы также можете посмотреть время изменения файла объектного файла фиксации в каталоге «objects» в репозитории git на самом сервере.

Богатый
источник
3

Почему git AuthorDate отличается от CommitDate?

  • AuthorDate когда коммит был впервые создан.
  • CommitDate - это время последнего изменения фиксации (например, перебазирования).

Вы можете получить их с параметрами --prettyформатирования:

       o    %cd: committer date
       o    %cD: committer date, RFC2822 style
       o    %cr: committer date, relative
       o    %ct: committer date, UNIX timestamp
       o    %ci: committer date, ISO 8601 format

Итак, если вы и другие разработчики делаете это git rebaseраньше git push, у вас будет дата фиксации позже, чем дата автора .

Эта команда показывает дату фиксации: git log --pretty=fuller

днозай
источник
1

Думаю, вы можете использовать следующую нотацию для получения даты отправки: git log -g --date = local

Паш PGH
источник