How to change Git log date formats
Asked Answered
A

12

216

I am trying to display the last commit within Git, but I need the date in a special format.

I know that the log pretty format %ad respects the --date format, but the only --date format I can find is "short". I want to know the others, and whether I can create a custom one such as:

git -n 1 --date=**YYMMDDHHmm** --pretty=format:"Last committed item in this release was by %%an, %%aD, message: %%s(%%h)[%%d]"
Arterio answered 21/10, 2011 at 17:56 Comment(4)
I always find the official Linux Kernel Git documentation to be an excellent resource for these sorts of questions.Geraldine
Note: you now (Nov. 2014, Git 2.2) have --date=iso-strict: see my answer belowCarbazole
With git 2.7 (Q4 2015), you can ask to use the local timezone for any date format! See my answer below. It means that, in addition of --date=(relative|local|default|iso|iso-strict|rfc|short|raw), you will also have: --date=(relative-local|default-local|iso-local|iso-strict-local|rfc-local|short-local|raw-local)Carbazole
Related: How can one change the timestamp of an old commit in Git?Leveller
B
211

The others are (from 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).

There is no built-in way that I know of to create a custom format, but you can do some shell magic.

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

The first step here gets you a millisecond timestamp. You can change the second line to format that timestamp however you want. This example gives you something similar to --date=local, with a padded day.


And if you want permanent effect without typing this every time, try

git config log.date iso 

Or, for effect on all your git usage with this account

git config --global log.date iso
Baum answered 21/10, 2011 at 18:26 Comment(2)
And if you want permanent effect without typing this every time, try something like git config log.date iso or, for effect on all your git usage with this account git config --global log.date isoTravelled
You can use your own formats. see Ben Allred's answer. --format:<args> will pass <args> to strftime.Admixture
P
293

In addition to --date=(relative|local|default|iso|iso-strict|rfc|short|raw), as others have mentioned, you can also use a custom log date format with

--date=format:'%Y-%m-%d %H:%M:%S'       # committer's timezone
--date=format-local:'%Y-%m-%d %H:%M:%S' # current user's timezone

This outputs something like 2016-01-13 11:32:13.

NOTE: If you take a look at the commit linked to below, I believe you'll need at least Git v2.6.0-rc0 for this to work.

In a full command it would be something like:

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

I haven't been able to find this in documentation anywhere (if someone knows where to find it, please comment) so I originally found the placeholders by trial and error.

In my search for documentation on this I found a commit to Git itself that indicates the format is fed directly to strftime. Looking up strftime (here or here) the placeholders I found match the placeholders listed.

The placeholders include:

%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
Proxy answered 13/1, 2016 at 23:4 Comment(18)
@Shiva: I ran into a case myself recently where it didn't work and it may be the same thing you're running into. I was using a pairing machine with an older version of Git. When I updated Git the custom date format started working. If you take a look at the commit linked to above, I believe you'll need at least v2.6.0-rc0. The example given is exactly what I use. In a full command it would be something like 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'"Proxy
Thanks Ben! I pasted your command as-is and ran the git lg and I still get the following error. fatal: unknown date format format:%Y-%m-%d %H:%M:%S. I am running git on windows. Here's my git version. git version 1.9.5.msysgit.1. So do I have to upgrade to the newer version?Lauricelaurie
Hi Ben, I was on the older version. I upgraded to latest and this works. So I edited your answer to make it clearer (moved your comment to the top) and also +1-ed you! Thanks!!Lauricelaurie
This works a treat! Using a simple bash script to export a csv, now I can i have columns for year, month, week etc. Love it.Frazzled
Offering this complete example (so I can find it again later): git log -1 --pretty="format:blah-%ad" --date="format:%Y-%m-%d-%H-%M-%S" which as of this writing emits this output: blah-2016-09-14-15-17-55. And for reference my git --version is git version 2.6.0Bolduc
Does 'time representation for current locale' mean that the time is normalised and displayed in terms of the viewer's timezone? Or is the viewer expected to add the timezone offset on by themselves (something which is surely the job of a computer!)Dingman
@EdRandall: If you're referring to %X, ~~I just tried it on my machine and definitely getting times in my time zone.~~ Hmm, now I'm not sure. I cloned a repo from someone not in my time zone and tried again. I think I'm just getting the time formatted using the current locale settings but with the time zone lopped off.Proxy
These abbreviations don't work for me in git for-each-ref. Only long field-names I found here and there in stack overflow answers (things like "committerdate" etc. Also, the --date is not supported by git for-each-ref. Can someone shed a little light on this? I'm using git 2.10.1Quinquennium
how can I put --date=format:'%Y-%m-%d %H:%M:%S' into .gitconfig ?Hendrika
@MartinVegter You can use date = format:%Y-%m-%d %H:%M:%S under the [log] section.Raviv
fatal: Invalid object name '%H'..Disperse
~~I'm running into the same issue as @Disperse - Is this perhaps a BSD strftime issue?~~ @Disperse apparently this happens if we try to use it as params on an alias that doesn't respect quotes in the input. e.g., It works correctly if I use it in a call to log itself ( rather than my lol alias for git log --format=oneline $@ #) git log --pretty=oneline --walk-reflogs --date=default --date=format:'%Y-%m-%d %I:%M:%S %p'Dorn
I noticed that date format causes Segmentation fault in older git versions, so --date=iso will do a good job instead of --date="format:%Y-%m-%d-%H-%M-%S". See following git issue for more details: github.com/git-for-windows/git/issues/3624Gervais
Can we use a custom format and local dates? Something like --date=local:format:"%y-%m-%d %H:%M:%S? I want custom time formats, but it's annoying if I have to sacrifice getting to see a consistent time for all times. Frankly, even just seeing everything in UTC would be acceptable since at least then they would still be consistent and nothing would appear out of order (e.g. when someone 5 timezones away makes a commit 1 hour after me, and it shows up as them making it 4 hours prior to mine).Saskatchewan
Should have googled more thoroughly 🤦‍♂️ For anyone else also looking for formatted local times, you can use --date=format-local:"%Y-%m-%d...". In fact, any of the date options supports the -local suffix 😄 iso-local, rfc-local, etc... Taken from https://mcmap.net/q/14134/-retrieving-git-log-in-yyyy-mm-dd-format-in-local-time-zoneSaskatchewan
Thanks @ShaunMitchell! Added that to the main content. (And updating my own aliases. :-))Proxy
Well I googled for 2 hours before finding this. Why is this not part of the git documentation I wonder. Anyway, if anyone - like me - searched for git for-each-ref --format syntax, it is basically the same. For instance: git for-each-ref --format=%(creatordate:format:%Y-%m-%d %H:$M)Wingover
in CMD: git -v git version 2.39.3.windows.1 git log "--pretty=format:%cd.%h.%f" "--date=format:%Y-%m-%d____%H-%M-%S" background.js ----Why v2.39.3 is also available.Salzman
B
211

The others are (from 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).

There is no built-in way that I know of to create a custom format, but you can do some shell magic.

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

The first step here gets you a millisecond timestamp. You can change the second line to format that timestamp however you want. This example gives you something similar to --date=local, with a padded day.


And if you want permanent effect without typing this every time, try

git config log.date iso 

Or, for effect on all your git usage with this account

git config --global log.date iso
Baum answered 21/10, 2011 at 18:26 Comment(2)
And if you want permanent effect without typing this every time, try something like git config log.date iso or, for effect on all your git usage with this account git config --global log.date isoTravelled
You can use your own formats. see Ben Allred's answer. --format:<args> will pass <args> to strftime.Admixture
K
39

After a long time looking for a way to get git log output the date in the format YYYY-MM-DD in a way that would work in less, I came up with the following format:

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

along with the switch --date=iso.

This will print the date in ISO format (a long one), and then print 14 times the backspace character (0x08), which, in my terminal, effectively removes everything after the YYYY-MM-DD part. For example:

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

This gives something like:

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

What I did was create an alias named l with some tweaks on the format above. It shows the commit graph to the left, then the commit's hash, followed by the date, the shortnames, the refnames and the subject. The alias is as follows (in ~/.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'
Khz answered 24/5, 2013 at 13:20 Comment(6)
This works very well for me. Using 6 of %x08 removes exactly the trailing timezone for me.Fairway
What about --date=short shows only date but not time, in YYYY-MM-DD format.Reserved
In zsh and bash this shows you output on the terminal, but if you pipe it into anything, the "backspaced" data is still there. This means things like | sort | uniq don't work.Dupery
You could use cut -d" " -f1,4- to get rid of the unwanted date portions. Then | sort | uniq will work just fine.Borderer
This is ridiculous and awesome at the same time. I'm using %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) to get the format 2015-01-19 11:27 (11 days). +1Cithara
now this answer https://mcmap.net/q/13969/-how-to-change-git-log-date-formats is more suitable (since Git v2.6.0-rc0)Deluca
C
37

I needed the same thing and found the following working for me:

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

The --date=format formats the date output where the --pretty tells what to print.

Cronin answered 6/9, 2016 at 0:49 Comment(5)
This doesn't work for me. I get "unknown date format"Chirm
which version of git do you have?Cronin
Updated using medium.com/@katopz/how-to-upgrade-git-ff00ea12be18Arianism
git log --pretty=format:"%h%x09%cd%x09%s" --date=format:'%Y-%m-%d %H:%M:%S %p'Arianism
@amateurbarista that doesn't show the last commit, read the request. ar3 is trying to show the last commit, not the last few commits.Cronin
R
26

You can use the field truncation option to avoid quite so many %x08 characters. For example:

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

is equivalent to:

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>'

And quite a bit easier on the eyes.

Better still, for this particular example, using %cd will honor the --date=<format>, so if you want YYYY-MM-DD, you can do this and avoid %< and %x08 entirely:

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

I just noticed this was a bit circular with respect to the original post but I'll leave it in case others arrived here with the same search parameters I did.

Ruinous answered 24/9, 2013 at 16:25 Comment(1)
At first I thought you meant that <(##,trunc) could replace all uses of delete (%x08) but I see that (if I understand right) some cases with variable length fields still benefit. E.g., adding four deletes to remove " ago" from a relative date.Slumber
C
19

2014 : Be aware of the "date=iso" format: it isn't exactly ISO 8601.
See commit "466fb67" from Beat Bolli (bbolli), for Git 2.2.0 (November 2014)

pretty: provide a strict ISO 8601 date format

Git's "ISO" date format does not really conform to the ISO 8601 standard due to small differences, and it cannot be parsed by ISO 8601-only parsers, e.g. those of XML toolchains.

The output from "--date=iso" deviates from ISO 8601 in these ways:

  • a space instead of the T date/time delimiter
  • a space between time and time zone
  • no colon between hours and minutes of the time zone

Add a strict ISO 8601 date format for displaying committer and author dates.
Use the '%aI' and '%cI' format specifiers and add '--date=iso-strict' or '--date=iso8601-strict' date format names.

See this thread for discussion.


With Git 2.45 (Q2 2024), batch 10, the output format for dates "iso-strict" has been tweaked to show a time in the Zulu timezone with "Z" suffix, instead of "+00:00".

See commit 69e2bee (13 Mar 2024) by Beat Bolli (bbolli).
(Merged by Junio C Hamano -- gitster -- in commit 1f49f75, 21 Mar 2024)

date: make "iso-strict" conforming for the UTC timezone

Reported-by: Michael Osipov
Signed-off-by: Beat Bolli

ISO 8601-1:2020-12 specifies that a zero timezone offset must be denoted with a "Z" suffix instead of the numeric "+00:00".
Add the correponding special case to show_date() and a new test.

Changing an established output format which might be depended on by scripts is always problematic, but here we choose to adhere more closely to the published standard.

2016-06-15T14:13:20Z
Carbazole answered 16/11, 2014 at 20:20 Comment(0)
L
13
date -d @$(git log -n1 --format="%at") +%Y%m%d%H%M

Note that this will convert to your local timezone, in case that matters for your use case.

Losse answered 12/4, 2014 at 3:47 Comment(1)
Thanks. I tweaked it with %ctParticiaparticipant
C
9

Git 2.7 (Q4 2015) will introduce -local as an instruction.
It means that, in addition to:

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

you will also have:

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

The -local suffix cannot be used with raw or relative. Reference.

You now can ask for any date format using the local timezone. See

See commit add00ba, commit 547ed71 (03 Sep 2015) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit 7b09c45, 05 Oct 2015)

In particular, the last from above (commit add00ba) mentions:

date: make "local" orthogonal to date format:

Most of our "--date" modes are about the format of the date: which items we show and in what order.
But "--date=local" is a bit of an oddball. It means "show the date in the normal format, but using the local timezone".
The timezone we use is orthogonal to the actual format, and there is no reason we could not have "localized iso8601", etc.

This patch adds a "local" boolean field to "struct date_mode", and drops the DATE_LOCAL element from the date_mode_type enum (it's now just DATE_NORMAL plus local=1).
The new feature is accessible to users by adding "-local" to any date mode (e.g., "iso-local"), and we retain "local" as an alias for "default-local" for backwards compatibility.

Carbazole answered 7/10, 2015 at 10:45 Comment(1)
I must note that the format-local works too! So it is very perfect that merge the power between the favorite format and local.Hekking
C
9

I need the date in a special format.

With Git 2.21 (Q1 2019), a new date format "--date=human" that morphs its output depending on how far the time is from the current time has been introduced.

"--date=auto" can be used to use this new format when the output is going to the pager or to the terminal and otherwise the default format.

See commit 110a6a1, commit b841d4f (29 Jan 2019), and commit 038a878, commit 2fd7c22 (21 Jan 2019) by Stephen P. Smith (``).
See commit acdd377 (18 Jan 2019) by Linus Torvalds (torvalds).
(Merged by Junio C Hamano -- gitster -- in commit ecbe1be, 07 Feb 2019)

Add 'human' date format documentation

Display date and time information in a format similar to how people write dates in other contexts.
If the year isn't specified then, the reader infers the date is given is in the current year.

By not displaying the redundant information, the reader concentrates on the information that is different.
The patch reports relative dates based on information inferred from the date on the machine running the git command at the time the command is executed.

While the format is more useful to humans by dropping inferred information, there is nothing that makes it actually human.
If the 'relative' date format wasn't already implemented, then using 'relative' would have been appropriate.

Add human date format tests.

When using human several fields are suppressed depending on the time difference between the reference date and the local computer date.

  • In cases where the difference is less than a year, the year field is suppressed.
  • If the time is less than a day; the month and year is suppressed.
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

Replace the proposed 'auto' mode with 'auto:'

In addition to adding the 'human' format, the patch added the auto keyword which could be used in the config file as an alternate way to specify the human format. Removing 'auto' cleans up the 'human' format interface.

Added the ability to specify mode 'foo' if the pager is being used by using auto:foo syntax.
Therefore, 'auto:human' date mode defaults to human if we're using the pager.
So you can do:

git config --add log.date auto:human

and your "git log" commands will show the human-legible format unless you're scripting things.


Git 2.24 (Q4 2019) simplified the code.

See commit 47b27c9, commit 29f4332 (12 Sep 2019) by Stephen P. Smith (``).
(Merged by Junio C Hamano -- gitster -- in commit 36d2fca, 07 Oct 2019)

Quit passing 'now' to date code

Commit b841d4f (Add human format to test-tool, 2019-01-28, Git v2.21.0-rc0) added a get_time() function which allows $GIT_TEST_DATE_NOW in the environment to override the current time.
So we no longer need to interpret that variable in cmd__date().

Therefore, we can stop passing the "now" parameter down through the date functions, since nobody uses them.
Note that we do need to make sure all of the previous callers that took a "now" parameter are correctly using get_time().


With Git 2.32 (Q2 2021), "git log --format=..."(man) placeholders learned %ah/%ch placeholders to request the --date=human output.

See commit b722d45 (25 Apr 2021) by ZheNing Hu (adlternative).
(Merged by Junio C Hamano -- gitster -- in commit f16a466, 07 May 2021)

pretty: provide human date format

Signed-off-by: ZheNing Hu

Add the placeholders %ah and %ch to format author date and committer date, like --date=human does, which provides more humanity date output.

pretty-formats now includes in its man page:

'%ah':: author date, human style (like the --date=human option of git rev-list)

pretty-formats now includes in its man page:

'%ch':: committer date, human style (like the --date=human option of git rev-list)

Carbazole answered 23/2, 2019 at 21:5 Comment(0)
C
5

The format option %ai was what I wanted:

%ai: author date, ISO 8601-like format

--format="%ai"
Cyruscyst answered 29/4, 2015 at 20:50 Comment(0)
S
4

Use Bash and the date command to convert from an ISO-like format to the one you want. I wanted an org-mode date format (and list item), so I did this:

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

And the result is for example:

+ [2015-09-13 Sun 22:44] 2b0ad02e6cec Merge pull request #72 from 3b/bug-1474631
Selfsustaining answered 18/9, 2015 at 18:47 Comment(0)
U
3
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]"
Underthecounter answered 24/10, 2012 at 21:37 Comment(1)
Care to elaborate? Also, your answer already has an author field and history. no need to sign it.Graecize

© 2022 - 2024 — McMap. All rights reserved.