Jak zmienić formaty dat dziennika Git

150

Próbuję wyświetlić ostatnie zatwierdzenie w Git, ale potrzebuję daty w specjalnym formacie.

Wiem, że format dziennika jest dość %adzgodny z --dateformatem, ale jedyny --dateformat, jaki mogę znaleźć, jest „krótki”. Chcę poznać innych i czy mogę stworzyć niestandardowy, taki jak:

git -n 1 --date=**YYMMDDHHmm** --pretty=format:"Last committed item in this release was by %%an, %%aD, message: %%s(%%h)[%%d]"
ar3
źródło
1
Zawsze uważam, że oficjalna dokumentacja Linux Kernel Git jest doskonałym źródłem odpowiedzi na tego rodzaju pytania.
2
Uwaga: teraz (listopad 2014, Git 2.2) masz --date=iso-strict: zobacz moją odpowiedź poniżej
VonC
4
Dzięki git 2.7 (Q4 2015) możesz poprosić o użycie lokalnej strefy czasowej dla dowolnego formatu daty! Zobacz moją odpowiedź poniżej . Oznacza to, że oprócz tego --date=(relative|local|default|iso|iso-strict|rfc|short|raw)będziesz mieć również:--date=(relative-local|default-local|iso-local|iso-strict-local|rfc-local|short-local|raw-local)
VonC

Odpowiedzi:

167

Pozostali to (od git help log):

--date=(relative|local|default|iso|rfc|short|raw)
  Only takes effect for dates shown in human-readable format,
  such as when using "--pretty".  log.date config variable
  sets a default value for log command’s --date option.

--date=relative shows dates relative to the current time, e.g. "2 hours ago".

--date=local shows timestamps in user’s local timezone.

--date=iso (or --date=iso8601) shows timestamps in ISO 8601 format.

--date=rfc (or --date=rfc2822) shows timestamps in RFC 2822 format,
  often found in E-mail messages.

--date=short shows only date but not time, in YYYY-MM-DD format.

--date=raw shows the date in the internal raw git format %s %z format.

--date=default shows timestamps in the original timezone
  (either committer’s or author’s).

Nie znam żadnego wbudowanego sposobu tworzenia niestandardowego formatu, ale możesz zrobić trochę magii powłoki.

timestamp=`git log -n1 --format="%at"`
my_date=`perl -e "print scalar localtime ($timestamp)"`
git log -n1 --pretty=format:"Blah-blah $my_date"

W pierwszym kroku otrzymasz milisekundowy znacznik czasu. Możesz zmienić drugą linię, aby sformatować ten znacznik czasu w dowolny sposób. Ten przykład daje coś podobnego do --date=localwyściełanego dnia.


A jeśli chcesz uzyskać trwały efekt bez wpisywania tego za każdym razem, spróbuj

git config log.date iso 

Lub, aby mieć wpływ na całe wykorzystanie Git na tym koncie

git config --global log.date iso
dmedvinsky
źródło
15
A jeśli chcesz uzyskać trwały efekt bez wpisywania tego za każdym razem, spróbuj czegoś takiego jak git config log.date isolub, aby wpłynąć na całe wykorzystanie gita na tym konciegit config --global log.date iso
Stéphane Gourichon
12
Możesz użyć własnych formatów. zobacz odpowiedź Bena Allreda . --format:<args>przejdzie <args>do strftime.
Captain Man
190

Oprócz tego --date=(relative|local|default|iso|iso-strict|rfc|short|raw), jak wspominali inni, możesz również użyć niestandardowego formatu daty dziennika z

--date=format:'%Y-%m-%d %H:%M:%S'

To daje coś takiego 2016-01-13 11:32:13.

UWAGA: Jeśli spojrzysz na zmianę, do której link znajduje się poniżej, uważam, że będziesz potrzebować przynajmniej, Git v2.6.0-rc0aby to zadziałało.

W pełnym poleceniu byłoby to coś takiego:

git config --global alias.lg "log --graph --decorate 
-30 --all --date-order --date=format:'%Y-%m-%d %H:%M:%S' 
--pretty=format:'%C(cyan)%h%Creset %C(black bold)%ad%Creset%C(auto)%d %s'" 

Nie udało mi się znaleźć tego w dokumentacji nigdzie (jeśli ktoś wie, gdzie to znaleźć, proszę o komentarz), więc pierwotnie znalazłem symbole zastępcze metodą prób i błędów.

Podczas moich poszukiwań dokumentacji na ten temat znalazłem zobowiązanie do samego Git które wskazuje, że format jest podawany bezpośrednio strftime. Wyszukiwanie strftime( tutaj lub tutaj ) symboli zastępczych, które znalazłem, pasuje do wymienionych symboli zastępczych.

Symbole zastępcze obejmują:

%a      Abbreviated weekday name
%A      Full weekday name
%b      Abbreviated month name
%B      Full month name
%c      Date and time representation appropriate for locale
%d      Day of month as decimal number (01 – 31)
%H      Hour in 24-hour format (00 – 23)
%I      Hour in 12-hour format (01 – 12)
%j      Day of year as decimal number (001 – 366)
%m      Month as decimal number (01 – 12)
%M      Minute as decimal number (00 – 59)
%p      Current locale's A.M./P.M. indicator for 12-hour clock
%S      Second as decimal number (00 – 59)
%U      Week of year as decimal number, with Sunday as first day of week (00 – 53)
%w      Weekday as decimal number (0 – 6; Sunday is 0)
%W      Week of year as decimal number, with Monday as first day of week (00 – 53)
%x      Date representation for current locale
%X      Time representation for current locale
%y      Year without century, as decimal number (00 – 99)
%Y      Year with century, as decimal number
%z, %Z  Either the time-zone name or time zone abbreviation, depending on registry settings
%%      Percent sign

W pełnym rozkazie byłoby to coś w rodzaju

git config --global alias.lg "log --graph --decorate -30 --all --date-order --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%C(cyan)%h%Creset %C(black bold)%ad%Creset%C(auto)%d %s'" 
Ben Allred
źródło
4
@Shiva: Sam niedawno natknąłem się na przypadek, w którym to nie zadziałało i może to być ta sama rzecz, na którą się natkniesz. Używałem maszyny parującej ze starszą wersją Gita. Kiedy zaktualizowałem Gita, zaczął działać niestandardowy format daty. Jeśli spojrzysz na zmianę, do której link znajduje się powyżej, myślę, że będziesz potrzebować przynajmniej wersji 2.6.0-rc0. Podany przykład jest dokładnie tym, czego używam. W pełnym rozkazie byłoby to coś w rodzajugit config --global alias.lg "log --graph --decorate -30 --all --date-order --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%C(cyan)%h%Creset %C(black bold)%ad%Creset%C(auto)%d %s'"
Ben Allred
1
Dzięki Ben! Wkleiłem Twoje polecenie bez zmian, uruchomiłem git lgi nadal otrzymuję następujący błąd. fatal: unknown date format format:%Y-%m-%d %H:%M:%S. Uruchamiam git w systemie Windows. Oto moja wersja gita. git version 1.9.5.msysgit.1. Więc czy muszę uaktualnić do nowszej wersji?
Shiva
Cześć Ben, byłem na starszej wersji. Zaktualizowałem do najnowszej i to działa. Więc zredagowałem twoją odpowiedź, aby była jaśniejsza (przeniosłem twój komentarz na górę), a także dałem ci +1! Dzięki!!
Shiva
To działa wspaniale! Używając prostego skryptu bash do eksportowania csv, mogę teraz mieć kolumny dla roku, miesiąca, tygodnia itp. Uwielbiam to.
Jamie Taylor
1
@EdRandall: Jeśli masz na myśli %X, ~~ Właśnie wypróbowałem to na moim komputerze i zdecydowanie sprawdzam czasy w mojej strefie czasowej. ~~ Hmm, teraz nie jestem pewien. Sklonowałem repozytorium od kogoś spoza mojej strefy czasowej i spróbowałem ponownie. Myślę, że po prostu otrzymuję formatowanie czasu przy użyciu bieżących ustawień regionalnych, ale z odciętą strefą czasową.
Ben Allred,
36

Po długim czasie szukania sposobu na git logwyświetlenie daty w formacie, YYYY-MM-DDktóry by działał less, wymyśliłem następujący format:

%ad%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08

wraz z przełącznikiem --date=iso .

Spowoduje to wydrukowanie daty w formacie ISO (długiej), a następnie 14-krotność znaku cofnięcia (0x08), który w moim terminalu skutecznie usuwa wszystko po części RRRR-MM-DD. Na przykład:

git log --date=iso --pretty=format:'%ad%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%aN %s'

To daje coś takiego:

2013-05-24 bruno This is the message of the latest commit.
2013-05-22 bruno This is an older commit.
...

To, co zrobiłem, to utworzenie aliasu o nazwie lz kilkoma poprawkami w powyższym formacie. Pokazuje wykres zatwierdzenia po lewej stronie, następnie hash zatwierdzenia, a następnie datę, nazwy skrócone, nazwy refnames i temat. Alias ​​jest następujący (w ~ / .gitconfig):

[alias]
        l = log --date-order --date=iso --graph --full-history --all --pretty=format:'%x08%x09%C(red)%h %C(cyan)%ad%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08 %C(bold blue)%aN%C(reset)%C(bold yellow)%d %C(reset)%s'
Bruno Reis
źródło
2
U mnie to działa bardzo dobrze. Użycie 6 z% x08 usuwa dokładnie końcową strefę czasową dla mnie.
Penghe Geng
7
A co z--date=short shows only date but not time, in YYYY-MM-DD format.
Paaske
3
W zsh i bash pokazuje to wyjście na terminalu, ale jeśli potokujesz to do czegoś, dane "cofnięte" nadal tam są. Oznacza to, że rzeczy takie jak | sort | uniqnie działają.
chmac
5
To jest jednocześnie śmieszne i niesamowite. Używam, %C(bold cyan)%ai%x08%x08%x08%x08%x08%x08%x08%x08%x08%C(reset) %C(bold green)(%ar%x08%x08%x08%x08)%C(reset)aby uzyskać format 2015-01-19 11:27 (11 days). +1
naught101
2
teraz ta odpowiedź stackoverflow.com/a/34778736/907576 jest bardziej odpowiednia (od Git v2.6.0-rc0)
radistao
25

Możesz użyć opcji obcinania pola, aby uniknąć tak wielu %x08znaków. Na przykład:

git log --pretty='format:%h %s%n\t%<(12,trunc)%ci%x08%x08, %an <%ae>'

jest równa:

git log --pretty='format:%h %s%n\t%ci%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08%x08, %an <%ae>'

I trochę łagodniejszy dla oczu.

Jeszcze lepiej, w tym konkretnym przykładzie użycie %cdbędzie honorować --date=<format>, więc jeśli chcesz YYYY-MM-DD, możesz to zrobić %<i %x08całkowicie uniknąć :

git log --date=short --pretty='format:%h %s%n\t%cd, %an <%ae>'

Właśnie zauważyłem, że jest to trochę okrągłe w stosunku do oryginalnego postu, ale zostawię to na wypadek, gdyby inni przybyli tutaj z tymi samymi parametrami wyszukiwania, co ja.

dvhart
źródło
23

Potrzebowałem tego samego i zauważyłem, że działa dla mnie:

git log -n1 --pretty='format:%cd' --date=format:'%Y-%m-%d %H:%M:%S'

--date=formatFormatuje wyjście datę którym --prettymówi co wydrukować.

lac_dev
źródło
2
To nie działa na mnie. Otrzymuję „nieznany format daty”
Ray
jaką masz wersję gita?
lac_dev
Zaktualizowano za pomocą medium.com/@katopz/how-to-upgrade-git-ff00ea12be18
amatorski barista
git log --pretty=format:"%h%x09%cd%x09%s" --date=format:'%Y-%m-%d %H:%M:%S %p'
amatorski barista,
@amateurbarista, który nie pokazuje ostatniego zatwierdzenia, przeczytaj żądanie. ar3 próbuje pokazać ostatnie zatwierdzenie, a nie kilka ostatnich.
lac_dev
16

Pamiętaj o date=isoformacie „ ”: nie jest to dokładnie ISO 8601 .
Zobacz zatwierdzenie „ 466fb67 ” z Beat Bolli ( bbolli) , dla Git 2.2.0 (listopad 2014)

ładny: podaj ścisły format daty ISO 8601

Format daty „ISO” Gita nie jest tak naprawdę zgodny ze standardem ISO 8601 ze względu na niewielkie różnice i nie może być analizowany przez parsery tylko ISO 8601, np. Te z łańcuchów narzędzi XML.

Dane wyjściowe z „ --date=iso” różnią się od ISO 8601 w następujący sposób:

  • spacja zamiast ogranicznika Tdaty / godziny
  • przestrzeń między czasem a strefą czasową
  • brak dwukropka między godzinami i minutami strefy czasowej

Dodaj ścisły format daty ISO 8601 do wyświetlania dat osoby zatwierdzającej i autora.
Użyj specyfikatorów formatu „ %aI” i „ %cI” i dodaj nazwy formatów daty „ --date=iso-strict” lub „ --date=iso8601-strict”.

Zobacz ten wątek do dyskusji.

VonC
źródło
11
date -d @$(git log -n1 --format="%at") +%Y%m%d%H%M

Pamiętaj, że spowoduje to konwersję na lokalną strefę czasową, jeśli ma to znaczenie dla twojego przypadku użycia.

Gepard
źródło
Dzięki.
Poprawiłem
5

Git 2.7 (Q4 2015) zostanie wprowadzony -localjako instrukcja.
Oznacza to, że oprócz:

--date=(relative|local|default|iso|iso-strict|rfc|short|raw)

będziesz mieć również:

--date=(default-local|iso-local|iso-strict-local|rfc-local|short-local)

-localPrzyrostek nie może być stosowany z rawlub relative. Odniesienie .

Możesz teraz poprosić o dowolny format daty, korzystając z lokalnej strefy czasowej . Widzieć

Zobacz commit add00ba , commit 547ed71 (03 września 2015) autor: Jeff King ( peff) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu 7b09c45 , 05 października 2015)

W szczególności ostatni z powyższych (commit add00ba) wspomina:

date: robić "local ” prostopadle do formatu daty:

Większość naszych " --date" trybów dotyczy formatu daty: które elementy pokazujemy iw jakiej kolejności.
Ale „ --date=local” jest trochę dziwaczny. Oznacza to „pokaż datę w normalnym formacie, ale używając lokalnej strefy czasowej”.
Strefa czasowa, której używamy, jest ortogonalna w stosunku do rzeczywistego formatu i nie ma powodu, dla którego nie moglibyśmy mieć „zlokalizowanego iso8601” itp.

Ta poprawka dodaje " local" pole boolowskie do " struct date_mode" i usuwa DATE_LOCALelement z date_mode_typewyliczenia (teraz jest to tylko DATE_NORMALplus local=1).
Nowa funkcja jest dostępna dla użytkowników poprzez dodanie „ -local” do dowolnego trybu daty (np. „ iso-local”), A my zachowujemy „ local” jako alias dla „ default-local” w celu zapewnienia zgodności wstecznej.

VonC
źródło
2
Muszę zauważyć, że format-localdziała też! Więc jest to bardzo idealne połączenie mocy między ulubionym formatem i lokalnym.
acgtyrant
5

Opcja formatu %aibyła tym, czego chciałem:

%ai: data autora, format podobny do ISO 8601

--format="%ai"
ThorSummoner
źródło
5

Potrzebuję daty w specjalnym formacie.

W Git 2.21 (Q1 2019) wprowadzono nowy format " --date=human" daty, który zmienia dane wyjściowe w zależności od tego, jak bardzo czas jest od aktualnego czasu .

" --date=auto" może być użyty do użycia tego nowego formatu, gdy wyjście jest kierowane na pager lub terminal, a poza tym format domyślny.

Zobacz commit 110a6a1 , commit b841d4f (29 stycznia 2019) i commit 038a878 , commit 2fd7c22 (21 stycznia 2019) autorstwa Stephena P. Smitha (``) .
Zobacz commit acdd377 (18 stycznia 2019) autorstwa Linusa Torvaldsa ( torvalds) .
(Połączone przez Junio ​​C Hamano - gitster- w zatwierdzeniu ecbe1be , 07 lutego 2019 r.)

Dodaj dokumentację dotyczącą formatu daty „ludzkiej”

Wyświetlaj informacje o dacie i godzinie w formacie podobnym do tego, jak ludzie zapisują daty w innych kontekstach.
Jeśli rok nie jest określony, czytelnik wnioskuje, że podana data jest w bieżącym roku .

Nie wyświetlając zbędnych informacji, czytelnik koncentruje się na informacjach, które są inne .
Poprawka podaje względne daty na podstawie informacji wywnioskowanych z daty na komputerze, na którym uruchomiono gitpolecenie w momencie wykonania polecenia.

Chociaż format jest bardziej przydatny dla ludzi, pomijając wywnioskowane informacje, nic nie czyni go tak naprawdę ludzkim.
Gdyby relativeformat daty „ ” nie był jeszcze zaimplementowany, użycie „ relative” byłoby właściwe.

Dodaj humantesty formatu daty.

W przypadku korzystania z humankilku pól są pomijane w zależności od różnicy czasu między datą odniesienia a datą z komputera lokalnego.

  • W przypadkach, gdy różnica jest mniejsza niż rok, pole roku jest pomijane.
  • Jeśli czas jest krótszy niż jeden dzień; miesiąc i rok są pomijane.
check_date_format_human 18000       "5 hours ago"       #  5 hours ago
check_date_format_human 432000      "Tue Aug 25 19:20"  #  5 days ago
check_date_format_human 1728000     "Mon Aug 10 19:20"  #  3 weeks ago
check_date_format_human 13000000    "Thu Apr 2 08:13"   #  5 months ago
check_date_format_human 31449600    "Aug 31 2008"       # 12 months ago
check_date_format_human 37500000    "Jun 22 2008"       #  1 year, 2 months ago
check_date_format_human 55188000    "Dec 1 2007"        #  1 year, 9 months ago
check_date_format_human 630000000   "Sep 13 1989"       # 20 years ago

## Zamień proponowany autotryb „ auto:” na „ ”

Oprócz dodania humanformatu „ ”, łatka dodała autosłowo kluczowe, które może być użyte w pliku konfiguracyjnym jako alternatywny sposób określenia formatu ludzkiego. Usunięcie „auto” czyści humaninterfejs formatu „ ”.

Dodano możliwość określenia trybu „ foo”, jeśli pager jest używany przy użyciu auto:fooskładni.
Dlatego auto:humantryb daty „ ” jest domyślny, humanjeśli używamy pagera.
Możesz więc:

git config --add log.date auto:human

a Twoje git logpolecenia „ ” pokażą format czytelny dla człowieka, chyba że tworzysz skrypty.


Git 2.24 (Q4 2019) uprościł kod.

Zobacz commit 47b27c9 , commit 29f4332 (12 września 2019) autorstwa Stephena P. Smitha (``) .
(Scalone przez Junio ​​C Hamano - gitster- w zatwierdzeniu 36d2fca , 07 października 2019)

Przestań przekazywać „teraz” do kodu daty

Commit b841d4f (Add humanformat to test-tool, 2019-01-28, Git v2.21.0-rc0) dodał get_time()funkcję, która pozwala $GIT_TEST_DATE_NOWw środowisku zastąpić bieżący czas.
Nie musimy więc już interpretować tej zmiennej w cmd__date().

Dlatego możemy przestać " now" przekazywać parametr w dół przez funkcje daty, ponieważ nikt ich nie używa.
Zauważ, że musimy się upewnić, że wszystkie poprzednie wywołania, które przyjęły nowparametr " ", używają poprawnie get_time().

VonC
źródło
2
git log -n1 --format="Last committed item in this release was by %an, `git log -n1 --format=%at | awk '{print strftime("%y%m%d%H%M",$1)}'`, message: %s (%h) [%d]"
webb
źródło
Możesz rozwinąć temat? Twoja odpowiedź ma już pole autora i historię. nie trzeba go podpisywać.
Kissaki
2

Użyj Bash i polecenia daty, aby przekonwertować z formatu podobnego do ISO na taki, który chcesz. Chciałem mieć format daty w trybie organizacyjnym (i element listy), więc zrobiłem to:

echo + [$(date -d "$(git log --pretty=format:%ai -1)" +"%Y-%m-%d %a %H:%M")] \
    $(git log --pretty=format:"%h %s" --abbrev=12 -1)

A wynik to na przykład:

+ [2015-09-13 Sun 22:44] 2b0ad02e6cec Merge pull request #72 from 3b/bug-1474631
Liam
źródło