Git log tabular formatting

GitBashScripting

Git Problem Overview


I have a simple alias to display few last commits:

log --pretty=format:'%h %an %s' -10

How can I make the results to be displayed in columns, like this:

898e8789 Author1             Commit message here
803e8759 Other Author name   Commit message here

Git Solutions


Solution 1 - Git

In Git 1.8.3 and later, there is native support for this in the pretty format, using the %<(N) syntax to format the next placeholder as N columns wide:

$ git log --pretty=format:'%h %<(20)%an %s' -10

For versions before 1.8.3, the previous version of this answer, retained below, should work.

Here's a solution in Bash using read to parse the log lines back apart, and printf to print them out, with a fixed width field for the authors name so the columns will stay lined up. It assumes that | will never appear in the author's name; you can choose another delimiter if you think that might be a problem.

git log --pretty=format:'%h|%an|%s' -10 | 
  while IFS='|' read hash author message
  do 
    printf '%s %-20s %s\n' "$hash" "$author" "$message"
  done

You can create this as an alias using:

[alias]
    mylog = "!git log --pretty=format:'%h|%an|%s' -10 | while IFS='|' read hash author message; do printf '%s %-20s %s\n' \"$hash\" \"$author\" \"$message\"; done"

I'm sure you could do this in fewer characters using awk but as the saying goes,

> Whenever faced with a problem, some people say “Lets use AWK.” Now, they have two problems.

Of course, having said that, I had to figure out how to do it in awk which is a bit shorter:

git ... | awk -F '|' '{ printf "%s %-20s %s\n", $1, $2, $3 }'

Solution 2 - Git

You can also do:

git log --pretty=format:'%h %<(20)%an %s' -10

No need for shell magic or post processing with awk, column etc.

Solution 3 - Git

The following command will print the log in a tabular form

git log --pretty=format:'%h|%an|%s' -10 | column -t -s '|'

the column command "columnates" the output, using the "|" as field separator, it will find out the optimal column width given the input, so it would work well even if you have more fields.

On Linux it will work ok as long as you don't use colors, the Linux implementation doesn't handle well the ANSI escape codes.

But in Mac OS X, it will handle colors and you can use any unicode character as field delimiter. I use ∑ since I'm pretty sure it won't occur by chance on the commit text. | is a bad choice because it could appear in the commit description and also if you use --graph --decorate --all it will appear as part of the symbols used to draw the graph

Solution 4 - Git

In order to get truly tabular format you need to also truncate usernames that are longer than e.g. 20 characters:

git log --pretty=format:'%h %<(20,trunc)%an %s' -10

Additionally, if you're outputting to the terminal, you may want to prevent line overflows by either truncating the commit message field:

git log --pretty=format:'%h %<(20,trunc)%an %<(39,trunc)%s' -10

or wrapping the lines and indenting any overflowing lines to align:

git log --pretty=format:'%w(79, 0, 29)%h %<(20,trunc)%an %s' -10

EDIT: The above example hard-codes the terminal width to be 79 characters. On POSIX systems you can use tput cols to return the width:

git log --pretty=format:'%w(`tput cols`, 0, 29)%h %<(20,trunc)%an %s' -10

or

git log --pretty=format:'%w($((`tput cols`-1)), 0, 29)%h %<(20,trunc)%an %s' -10

Unfortunately these last two break git alias so it will require a terminal alias (unless you really love typing).

Solution 5 - Git

How to add a tab?

What you are looking for is:

%x09

Here is an example
git log --pretty=format:"%C(magenta)%h %C(cyan)%C(bold)%ad%Creset %C(cyan)%cr%Creset%x09 | %s %C(green)%Creset" --date=short

I wanted the relative date to be tabbed bc it was not a fixed length, this way all columns line up (for anything less than a year ago). Wanted to make it line up all of the time, but this is as far as I got before I ran out of time (ironically).

Hope this helps!

If you have suggestions to improve this answer for the relative year case (not just grepping out the year) happy to hear them too, feel free to edit this answer to add them if you know how to do it.

Edit:

I decided to try out the %<(n) syntax suggested by another person too, I found that it is too short if you have anything over 9 years bc 10 years is one more digit using %<(20) which was suggested. Instead I suggest %<(23)

git log --pretty=format:"%C(magenta) %h %C(cyan)%C(bold)%ad%Creset %<(23) %C(cyan)%cr%Creset %s%C(green)%Creset" --date=short`

Unless the project is over 100 years old it will line up great. But if you want it to work for that you just add 1 making it %<(24)

Solution 6 - Git

The problem with the tabular format is the fact that you might run out of space ...

The following one is my personal best compromise between the essential stuff to display:

  • who
  • did what
  • and when
  • to be able to dig more by the commit hash for the how

so:

  git log --pretty --format='%h %aI %<(15)%an ::: %s'

or

 git log --pretty --format='%h %cI %<(15)%an ::: %s'

if you want to get the commiter time and not the author time

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontakeshinView Question on Stackoverflow
Solution 1 - GitBrian CampbellView Answer on Stackoverflow
Solution 2 - GitJesseView Answer on Stackoverflow
Solution 3 - GitRubenLagunaView Answer on Stackoverflow
Solution 4 - GitinsysionView Answer on Stackoverflow
Solution 5 - GitjasonleonhardView Answer on Stackoverflow
Solution 6 - GitYordan GeorgievView Answer on Stackoverflow