Чи є в git спосіб отримати дату натискання для даного коміту?


92

Мені цікаво, чи є спосіб переглянути дату натискання, пов'язану з кожним комітом, у журналі git. Якщо це неможливо, чи є спосіб побачити всі коміти під певним натисканням.

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

Відповіді:


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] на [date]".

    Можливо, ви захочете використовувати замітку, призначену для цієї мети (наприклад 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

7
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

Здається, це працює для мене досить добре. Дата комітету (% cd) вводить в оману, оскільки це не обов'язково те саме, що дата натискання. Параметр --date = iso, однак видасть дату push / fetch .

Зверніть увагу: якщо ви отримали файл із джерела / майстра, він надрукує дату, коли ви його завантажили; НЕ дата, коли хтось інший натиснув фіксацію.

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

Бонус: Звичайно, ви можете зробити більш гарне форматування. Поки що мені подобається це кольорове кодування. Це трохи набирати текст, хоча. Це виведе SHA на червоний, переблокуйте селектор на блакитний, а переблокуйте на зелений.

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} (тягнути: вперед) JIRA-2542 вдосконалити звіт про тестування ", це означає, що тоді вміст мого відділення JIRA -2542 було об’єднано за походженням / майстром через швидкий термін у 2019-02-07 08:13:40?
Саймон

Привіт Саймоне, так. Ви виконали git-тягання на вашій гілці, і вона була об’єднана на origin / master за допомогою швидкої перемотки в той час.
ВК

Він працює лише над авторським сховищем. Якщо я клоную сховище, значення порожнє. Ви не можете бачити час натискання інших людей.
ramwin

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
Зауваживши, що перезапис origin/branchбуде відображати лише зміни, внесені на поточній машині, це надзвичайно корисно! Для повсякденного використання я не хочу реалізовувати жодні гачки, тому для простого запитання "Хм-м-м-м, коли я натиснув це коміт минулого тижня?" - це чудово працює.
NIA

4

Ви також можете переглянути час модифікації файлу об'єктного файлу фіксації в каталозі "objects" у сховищі git на самому сервері.


3

Чому git AuthorDate відрізняється від CommDate?

  • 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.