Czy istnieje sposób w git, aby uzyskać datę wypychania dla danego zatwierdzenia?

93

Zastanawiam się, czy istnieje sposób, aby wyświetlić datę wypychania związaną z każdym zatwierdzeniem w dzienniku git. Jeśli nie jest to możliwe, czy istnieje sposób, aby zobaczyć wszystkie zatwierdzenia pod pewnym naciskiem.

Piszę program, który musi śledzić zmiany w momencie ich wypychania. Ponieważ dziennik git jest uporządkowany według daty zatwierdzenia, a nie daty wypychania, nie mogę zobaczyć najnowszych zatwierdzeń, które są wypychane. Na przykład, jeśli użytkownik zatwierdza swoje lokalne repozytorium 2 dni przed wypchnięciem do głównego, to zatwierdzenie zostanie umieszczone za 2 dniami innych zatwierdzeń w dzienniku głównego repozytorium.

justkikuchi
źródło

Odpowiedzi:

77

Zebranie rozproszonych informacji i znalezienie najlepszej odpowiedzi na to pytanie zajęło mi niesamowicie dużo czasu, ale teraz wiem, że ją mam. W zaledwie dwóch wierszach, bez kodu i bez haków:

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

git reflog --date=local master

Nareszcie proste.

Ostrzeżenie: prawdopodobnie chcesz zastąpić domyślne wartości gc.reflogExpirei gc.reflogExpireUnreachable. Sprawdź git help reflogszczegóły i dowiedz się, jak i dlaczego to działa.

Dwie powyższe komendy muszą być uruchomione wewnątrz klona, ​​do którego pchasz . Jeśli nie jest to możliwe, przybliżenie polega na uruchomieniu w innym, trwałym klonie:

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

Nigdy nie usuwaj tego stałego klonu, bo stracisz daty.

Marsz
źródło
2
Dodam, że w moim przypadku musiałem zrobić git reflog --date=local origin/master(uwaga origin/), aby zobaczyć listę wypchnięć. W przeciwnym razie na liście znajdowały się tylko commits, checkouts i pulls (co też jest przydatne). Właściwie wskazała na to odpowiedź @ JonathanDay .
NIA
@NIA: origin / master poda tylko przybliżenie. Zaktualizowałem moją odpowiedź po Twoim komentarzu, czy to wyjaśnia?
MarcH
37

Git jest rozproszonym systemem kontroli wersji, więc musisz dokładnie zdefiniować, co rozumiesz przez „datę wypychania”. Na przykład załóżmy, że użytkownik A wypycha niektóre zatwierdzenia do repozytorium użytkownika B. Jakiś czas później użytkownik B wypycha te same zatwierdzenia do trzeciego repozytorium. Która data Cię interesuje?

Spekuluję, że masz współdzielone repozytorium i chcesz, aby użytkownicy tego współużytkowanego repozytorium mogli określić, kiedy coś zostało opublikowane w repozytorium. Jeśli to prawda, musisz zebrać te informacje w udostępnionym repozytorium.

Złe wiadomości

Niestety, nie ma możliwości dodania daty do komunikatów o zmianach. To zmieniłoby identyfikator zatwierdzenia (który jest skrótem SHA1 zawartości), powodując różnego rodzaju problemy.

Dobre wieści

Na szczęście Git ma (stosunkowo nową) funkcję o nazwie notatki . Ta funkcja umożliwia dołączanie dowolnego tekstu do zatwierdzeń, które git logmogą być wyświetlane. Notatki można edytować i udostępniać innym.

Możesz użyć funkcji notatek, aby dołączyć wiadomość „to zatwierdzenie otrzymano w dniu [data]” do każdego zatwierdzenia otrzymanego przez współdzielone repozytorium.

Zobacz git help notesszczegóły.

Jak zapisać datę

Oto podejście, które polecam:

  1. Zmodyfikuj punkt post-receivezaczepienia we współdzielonym repozytorium, aby przechodzić przez każde nowo osiągalne zatwierdzenie dla każdego zaktualizowanego odniesienia.
  2. Dla każdego zatwierdzenia dodaj coś w rodzaju „[użytkownik] z [repository_url] dodał to zatwierdzenie do [ref] dnia [data]” do notatki dotyczącej zatwierdzenia.

    Możesz użyć przypisu przypisanego do tego celu (np. refs/notes/received-on) Zamiast domyślnego refs/notes/commits. Zapobiegnie to konfliktom z notatkami utworzonymi do innych celów.

  3. Zmodyfikuj swój receivehaczyk, aby odmówić aktualizacji odniesienia do notatek (aby uniemożliwić użytkownikom przypadkowe lub celowe manipulowanie notatkami).
  4. Powiedz wszystkim użytkownikom, aby uruchomili następujące polecenia z poziomu ich drzewa roboczego:

    # 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/*'
    

    Ten krok jest konieczny, ponieważ Git domyślnie ignoruje niezwiązane z odgałęzieniami odniesienia bez tagów w nadrzędnych repozytoriach.

Powyższe zakłada, że ​​odniesienia są tylko zaawansowane, nigdy nie są usuwane ani aktualizowane na siłę. Prawdopodobnie będziesz chciał, aby post-receivehak dołączył również notatki „usunięto dnia [data]”, aby obsłużyć te przypadki.

Richard Hansen
źródło
Skorzystałem z twojego pomysłu na moim blogu mnaoumov.wordpress.com/2013/01/31/git-get-push-date
mnaoumov
8
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

Wydaje mi się, że to działa całkiem nieźle. Data inicjatora (% cd) jest myląca, ponieważ niekoniecznie jest taka sama jak data wypychania. Jednak opcja --date = iso wyświetli datę wypychania / pobierania .

Uwaga, jeśli pobrałeś z pochodzenia / wzorca, wydrukuje datę pobrania; NIE data, kiedy ktoś inny wprowadził zobowiązanie.

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

Bonus: możesz oczywiście zrobić ładniejsze formatowanie. Jak dotąd podoba mi się to kodowanie kolorami. Jednak jest to trochę za dużo do pisania. Spowoduje to wyjście SHA na kolor czerwony, selektor reflog na cyjan i reflog na kolor zielony.

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso
VC
źródło
Cześć VC, czy to oznacza, że ​​jeśli wynik polecenia "reflog show origin / master --pretty = '% Cred% h% Creset -% C (żółty)% gd% Creset% Cblue (% gs)% Creset% s' - -date = iso "is" da4c192cd -origin / master @ {2019-02-07 08:13:40 +0100} (pull: fast-forward) JIRA-2542 ulepsz raport z testu ", oznacza to zawartość mojej gałęzi JIRA -2542 został scalony na origin / master poprzez szybki przegląd o 2019-02-07 08:13:40?
Simon,
Cześć Simon, tak. Wykonałeś git pull na swojej gałęzi i została ona w tym czasie połączona na źródle / master za pomocą szybkiego przewijania do przodu.
VC,
Działa tylko w repozytorium autora. Jeśli sklonuję repozytorium, wartość jest pusta. Nie widać czasu pchania innych osób.
ramwin
6

Spójrz na git reflog show master. Prawdopodobnie nie jest to dokładny format, który chcesz, ale powinien wskazywać właściwy kierunek.

Innym pomysłem jest uruchomienie skryptu wewnątrz haka push.

Karl Bielefeldt
źródło
Myślałem o uruchomieniu haka, ale wygląda na to, że powinien to być ostatni wysiłek. Wydaje się, że w przypadku haka każdy użytkownik musiałby go mieć w każdym z repozytoriów. Czy możesz być bardziej szczegółowy na temat git reflog show master? Chcę mieć możliwość przeglądania dat wypychania poszczególnych zatwierdzeń każdego użytkownika.
justkikuchi
git reflog pokazuje kolejność zmian w dowolnym repozytorium, w którym je uruchomisz. Nie jestem pewien, czy istnieje bezpośredni sposób na uzyskanie daty, ale .git/logs/refs/heads/masterpokazuje on znacznik czasu.
Karl Bielefeldt
3
Co do haków, istnieją otrzymać haki, które działają na maszyny, którą popchnąć do . Ponieważ pushowanie jest istotne tylko w odniesieniu do konkretnego repozytorium, zakładam, że masz pewne „błogosławione” repozytorium, na którym chcesz je uruchomić. To samo dotyczy git reflogtej sprawy.
Karl Bielefeldt
5

Ta odpowiedź dotycząca sprawdzenia reflogu na pilocie może pomóc ( https://stackoverflow.com/a/8791295/336905 ), podając informacje o tym, która gałąź została przepchnięta nawet przez nią, nie pokazuje, które zatwierdzenia zostały wysłane, ale ty może przeprowadzić korelację krzyżową, znajdując następne wypychanie po dacie lokalnego zatwierdzenia. Nie jest niezawodny, ale przydatny, jeśli nie wdrożyłeś jeszcze doskonałej sugestii dotyczącej notatek z @RichardHansen opublikowanej wcześniej

Jonathan Day
źródło
1
Z uwagą, że reflog of origin/branchpokaże tylko zmiany dokonane na bieżącej maszynie, jest to niezwykle przydatne! Do codziennego użytku nie chcę wprowadzać żadnych haczyków, więc dla prostego pytania „Hmmm, kiedy w zeszłym tygodniu naciskałem na to zatwierdzenie?” - działa świetnie.
NIA
4

Możesz również spojrzeć na czas modyfikacji pliku obiektu zatwierdzania w katalogu "objects" w repozytorium git na samym serwerze.

Bogaty
źródło
3

Dlaczego git AuthorDate różni się od CommitDate?

  • AuthorDate to moment, w którym zatwierdzenie zostało utworzone po raz pierwszy.
  • CommitDate to data ostatniej modyfikacji zatwierdzenia (np. rebase).

Możesz je uzyskać z --prettyopcjami formatowania:

       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

Tak więc, jeśli ty i inni programiści robiliście to git rebasewcześniej git push, w końcu data zatwierdzenia będzie późniejsza niż data autora .

To polecenie pokazuje datę zatwierdzenia: git log --pretty=fuller

dnozay
źródło
1

Myślę, że możesz użyć następnej notacji, aby uzyskać datę wypychania: git log -g --date = local

Pashh PGH
źródło