'Visualizing branch topology in Git
I'm playing with Git in isolation on my own machine, and I find it difficult to maintain a mental model of all my branches and commits. I know I can do a git log to see the commit history from where I am, but is there a way to see the entire branch topography, something like these ASCII maps that seem to be used everywhere for explaining branches?
.-A---M---N---O---P
/ / / / /
I B C D E
\ / / / /
`-------------'
It just feels like someone coming along and trying to pick up my repository would have difficulty working out exactly what was going on.
I guess I'm influenced by AccuRev's stream browser...
Solution 1:[1]
I have 3 aliases (and 4 alias-aliases for quick usage) that I normally throw in my ~/.gitconfig file:
[alias]
lg = lg1
lg1 = lg1-specific --all
lg2 = lg2-specific --all
lg3 = lg3-specific --all
lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
lg2-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
lg3-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(auto)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'
git lg/git lg1 looks like this:

git lg2 looks like this:

and git lg3 looks like this:

It should be noted that this isn't meant as a end-all-be-all solution— it's a template for you to change, add to and fix up to your liking. If you want to use these, my recommendation is to:
- Add them to your
.gitconfig, - Customize to your liking (different color choices, different line arrangements for the 2- and 3-line versions, etc.),
- And then save a copy to a Gist or other code snippet tool so you can copy & paste it into
.gitconfigs in the future (or alternatively version control your dotfiles, of course).
Note: Answer copied from and improved upon the answer at stackoverflow.com/questions/1057564/pretty-git-branch-graphs since it's far more appropriate here than it was there. Left the copy on the other question for historical reasons— it's closed now, and the answer's referenced by a bunch of other answers.
Solution 2:[2]
I usually use
git log --graph --full-history --all --pretty=format:"%h%x09%d%x20%s"
With colors (if your shell is Bash):
git log --graph --full-history --all --color \
--pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s"
This will print text-based representation like this:
* 040cc7c (HEAD, master) Manual is NOT built by default
* a29ceb7 Removed offensive binary file that was compiled on my machine and was hence incompatible with other machines.
| * 901c7dd (cvc3) cvc3 now configured before building
| * d9e8b5e More sane Yices SMT solver caller
| | * 5b98a10 (nullvars) All uninitialized variables get zero inits
| |/
| * 1cad874 CFLAGS for cvc3 to work successfully
| * 1579581 Merge branch 'llvm-inv' into cvc3
| |\
| | * a9a246b nostaticalias option
| | * 73b91cc Comment about aliases.
| | * 001b20a Prints number of iteration and node.
| |/
|/|
| * 39d2638 Included header files to cvc3 sources
| * 266023b Added cvc3 to blast infrastructure.
| * ac9eb10 Initial sources of cvc3-1.5
|/
* d642f88 Option -aliasstat, by default stats are suppressed
(You could just use git log --format=oneline, but it will tie commit messages to numbers, which looks less pretty IMHO).
To make a shortcut for this command, you may want to edit your ~/.gitconfig file:
[alias]
gr = log --graph --full-history --all --color --pretty=tformat:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s%x20%x1b[33m(%an)%x1b[0m"
However, as Sodel the Vociferous notes in the comments, such long formatting command is hard to memorize. Usually, it's not a problem as you may put it into the ~/.gitconfig file. However, if you sometimes have to log in to a remote machine where you can't modify the config file, you could use a more simple but faster to type version:
git log --graph --oneline
Solution 3:[3]
To any of these recipes (based on git log or gitk), you can add --simplify-by-decoration to collapse the uninteresting linear parts of the history. This makes much more of the topology visible at once. I can now understand large histories that would be incomprehensible without this option!
I felt the need to post this because it doesn't seem to be as well-known as it should be. It doesn't appear in most of the Stack Overflow questions about visualizing history, and it took me quite a bit of searching to find--even after I knew I wanted it! I finally found it in this Debian bug report. The first mention on Stack Overflow seems to be this answer by Antoine Pelisse.
Solution 4:[4]
Solution 5:[5]
Take a look at GitKraken - a cross-platform GUI that shows topology in a lucid way.
Here's a quick video tutorial on some advanced features.
Note: registration is required.
Solution 6:[6]
99.999% of my time is looking at history by git lg and the 0.001% is by git log.
I just want to share two log aliases that might be useful (configure from .gitconfig):
[Alias]
lg = log --graph --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short
hist = log --graph --full-history --all --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short
git lgwill see the current branch history.git histwill see the whole branch history.
Solution 7:[7]
I like, with git log, to do:
git log --graph --oneline --branches
(also with --all, for viewing remote branches as well)
Works with recent Git releases: introduced since 1.6.3 (Thu, 7 May 2009)
"
--pretty=<style>" option to the log family of commands can now be spelled as "--format=<style>".
In addition,--format=%formatstringis a short-hand for--pretty=tformat:%formatstring."
--oneline" is a synonym for "--pretty=oneline --abbrev-commit".
PS D:\git\tests\finalRepo> git log --graph --oneline --branches --all
* 4919b68 a second bug10 fix
* 3469e13 a first bug10 fix
* dbcc7aa a first legacy evolution
| * 55aac85 another main evol
| | * 47e6ee1 a second bug10 fix
| | * 8183707 a first bug10 fix
| |/
| * e727105 a second evol for 2.0
| * 473d44e a main evol
|/
* b68c1f5 first evol, for making 1.0
You can also limit the span of the log display (number of commits):
PS D:\git\tests\finalRepo> git log --graph --oneline --branches --all -5
* 4919b68 a second bug10 fix
* 3469e13 a first bug10 fix
* dbcc7aa a first legacy evolution
| * 55aac85 another main evol
| | * 47e6ee1 a second bug10 fix
(show only the last 5 commits)
What I do not like about the current selected solution is:
git log --graph
It displayed way too much info (when I want only to look at a quick summary):
PS D:\git\tests\finalRepo> git log --graph
* commit 4919b681db93df82ead7ba6190eca6a49a9d82e7
| Author: VonC <[email protected]>
| Date: Sat Nov 14 13:42:20 2009 +0100
|
| a second bug10 fix
|
* commit 3469e13f8d0fadeac5fcb6f388aca69497fd08a9
| Author: VonC <[email protected]>
| Date: Sat Nov 14 13:41:50 2009 +0100
|
| a first bug10 fix
|
gitk is great, but forces me to leave the shell session for another window, whereas displaying the last n commits quickly is often enough.
Solution 8:[8]
Gitg is a great tool for Linux, similar to Gitx for OS X. Just run 'gitg' on the command line from somewhere inside your repository's tree structure (same with gitx).
Solution 9:[9]
A nice web based tool is ungit. It runs on any platform that Node.js and Git supports. There is a video of how it works for those that find that sort of things easier than reading...

Solution 10:[10]
I found git-big-picture quite useful.
It creates pretty 2D graphs using dot/Graphviz instead of the rather linear, "one-dimensional" views gitk and friends produce. With the -i option it shows the branch points and merge commits, but leaves out everything in-between.
Solution 11:[11]
Have a look at BranchMaster.
I wrote it to visualize a complex branch structure, by collapsing all commits between them to a single line. The numbers indicates the number of commits.

Solution 12:[12]
There is also Tig. It doesn't fold branches like "BranchMaster", but...
It is fast, runs in the terminal.
Because it is so quick (+ keyboard control) you get a great UX. It is almost like my "ls" for directories containing Git repositories.
It has the usual shortcuts, / to search, etc.

(PS: It is the terminal in the background of this screenshot. It looks better nowadays, but my computer refuses to take a screenshot, sorry)
(PPS: I use GitKraken as well, and it has really clear visualisations, but it's much heavier than Tig)
Solution 13:[13]
For Mac users, check out (no pun intended) the free, open source tool GitUp.
I like the way the graphs are displayed. It's clearer than some of the other tools I've seen.
The project is at GitHub.
Solution 14:[14]
Giggle draws really nice graphs.
Solution 15:[15]
TortoiseGit has a tool called "Revision Graph". If you're on Windows it's as easy as right clicking on your repository ? Tortoise Git ? Revision Graph.
Solution 16:[16]
I found this blog post which shows a concise way:
git log --oneline --abbrev-commit --all --graph --decorate --color
I usually create an alias for the above command:
alias gl='git log --oneline --abbrev-commit --all --graph --decorate --color'
And simply just use gl.
You can also add the alias to the Git configuration. Open file ~/.gitconfig and add the following line to the [alias] section:
[alias]
lg = log --oneline --abbrev-commit --all --graph --decorate --color
And use it like this:
git lg
Sample output:
Solution 17:[17]
I use the following aliases.
[alias]
lol = log --graph --decorate --pretty=oneline --abbrev-commit
lola = log --graph --decorate --pretty=oneline --abbrev-commit --all
It has more info in the color scheme than aliases that I saw above. It also seems to be quite common, so you might have a chance of it existing in other's environment or being able to mention it in conversation without having to explain it.
With screenshots and a full description in Git lola.
Solution 18:[18]
For those using the VSCode text editor, consider the Git History Extension by D. Jayamanne:
Solution 19:[19]
I have this git log alias in ~/.gitconfig to view the graph history:
[alias]
l = log --all --graph --pretty=format:'%C(auto)%h%C(auto)%d %s %C(dim white)(%aN, %ar)'
With the alias in place, git l will show something like this:
In Git 2.12+ you can even customize the line colors of the graph using the log.graphColors configuration option.
As for the logs' format, it's similar to --oneline, with the addition of the author name (respecting .mailmap) and the relative author date. Note that the %C(auto) syntax, which tells Git to use the default colors for commit hash, etc. is supported in Git >= 1.8.3.
Solution 20:[20]
Gitx is also a fantastic visualization tool if you happen to be on OS X.
Solution 21:[21]
I'm using the Visual Studio Code editor, and I found myself very pleased with the Git Graph extension of it, made by mhutchie. (And I'm not alone, there are 1 million users of the extension!).
If you happened to like the editor, then just go to the extension tab (the cubicles on the left middle) and type in "Git Graph" and install
To use it, go to the Git control tab and press View Git Graph button
Solution 22:[22]
Another git log command. This one with fixed-width columns:
git log --graph --pretty=format:"%x09%h | %<(10,trunc)%cd |%<(25,trunc)%d | %s" --date=short
Sample output:
Solution 23:[23]
My personal favorite alias, via .gitconfig, is:
graph = log --graph --color --all --pretty=format:"%C(yellow)%H%C(green)%d%C(reset)%n%x20%cd%n%x20%cn%x20(%ce)%n%x20%s%n"
You can test directly from the command line like this:
git log --graph --color --all --pretty=format:"%C(yellow)%H%C(green)%d%C(reset)%n%x20%cd%n%x20%cn%x20(%ce)%n%x20%s%n"
Sample output:
Solution 24:[24]
Check out SmartGit. It very much reminds me of the TortoiseHg branch visualization and it's free for non-commercial use.
Solution 25:[25]
I found it incredible that among the many answers it is not mentioned Gitviz, available for Window/Linux/Mac
In addition to providing a 2-D view of the branches and commit, it listens your git commands and it modify by itself the graph.
Solution 26:[26]
The most rated answers are showing git log commands as favorite solutions.
If you need a tablelike, say column-like output, you can use your awesome git log commands with slight modifications and some limitations with the .gitconfig alias.tably snippet below.
Modifications:
- you have to use
%><(<N>[,ltrunc|mtrunc|trunc])before every commit placeholder - add a unique delimiter as column separator
- add
--coloroption for colored output
Limitations:
you can place the CPU graph at every column as long as you do not use non-empty newlines
%n...the last commit placeholder of any newline can be used without
%><(<N>[,trunc])if extra characters are needed for decoration like
(committer:,<and>)in...%C(dim white)(committer: %cn% <%ce>)%C(reset)...to get a tablelike output they must be written directly before and after the commit placeholder
...%C(dim white)%<(25,trunc)(committer: %cn%<(25,trunc) <%ce>)%C(reset)...if the
--format=format:option is not the last one close it with%C(reset)as mostly donecompared to normal
git logoutput this one is slow, but nice
Example taken from this site:
thompson1 = log --all --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
will be with ^ as delimiter and without added characters
thompson1-new = log --all --graph --color --abbrev-commit --decorate --format=format:'^%C(bold blue)%<(7,trunc)%h%C(reset)^%C(bold green)%<(21,trunc)%ar%C(reset)^%C(white)%<(40,trunc)%s%C(reset)^%C(dim white)%<(25,trunc)%an%C(reset)^%C(auto)%d%C(reset)'
which compares like
Or with moving the graph to column 5:
To achieve this, add the following to your .gitconfig file and call your log alias with
git tably YourLogAlias:
[color "decorate"]
HEAD = bold blink italic 196
branch = 214
tag = bold 222
[alias]
# delimiter used as column seperator
delim = ^
# example thompson1
thompson1 = log --all --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
# modified thompson1 example
thompson1-new = log --all --graph --color --abbrev-commit --decorate --format=format:'^%C(bold blue)%<(7,trunc)%h%C(reset)^%C(bold green)%<(21,trunc)%ar%C(reset)^%C(white)%<(40,trunc)%s%C(reset)^%C(dim white)%<(25,trunc)%an%C(reset)^%C(auto)%d%C(reset)'
# set a column for the graph
thompson1-new-col = 1
tably = !bash -c '" \
declare -A col_length; \
delim=$(git config alias.delim); \
git_log_cmd=$(git config alias.$1); \
git_tre_col=${2:-$(git config alias.$1-col)}; \
\
i=0; \
n=0; \
while IFS= read -r line; do \
((n++)); \
while read -d\"$delim\" -r col_info;do \
((i++)); \
[[ -z \"$col_info\" ]] && col_length[\"$n:$i\"]=${col_length[\"${last[$i]:-1}:$i\"]} && ((i--)) && continue; \
[[ $i -gt ${i_max:-0} ]] && i_max=$i; \
col_length[\"$n:$i\"]=$(grep -Eo \"\\([0-9]*,[lm]*trunc\\)\" <<< \"$col_info\" | grep -Eo \"[0-9]*\" | head -n 1); \
[[ -n \"${col_length[\"$n:$i\"]}\" ]] && last[$i]=$n; \
chars_extra=$(grep -Eo \"\\trunc\\).*\" <<< \"$col_info\"); \
chars_extra=${chars_extra#trunc)}; \
chars_begin=${chars_extra%%\\%*}; \
chars_extra=${chars_extra#*\\%}; \
case \" ad aD ae aE ai aI al aL an aN ar as at b B cd cD ce cE ci cI cl cL cn cN cr \
cs ct d D e f G? gd gD ge gE GF GG GK gn gN GP gs GS GT h H N p P s S t T \" in \
*\" ${chars_extra:0:2} \"*) \
chars_extra=${chars_extra:2}; \
chars_after=${chars_extra%%\\%*}; \
;; \
*\" ${chars_extra:0:1} \"*) \
chars_extra=${chars_extra:1}; \
chars_after=${chars_extra%%\\%*}; \
;; \
*) \
echo \"No Placeholder found. Probably no tablelike output.\"; \
continue; \
;; \
esac ; \
if [[ -n \"$chars_begin$chars_after\" ]];then \
len_extra=$(echo \"$chars_begin$chars_after\" | wc -m); \
col_length["$n:$i"]=$((${col_length["$n:$i"]}+$len_extra-1)); \
fi; \
\
done <<< \"${line#*=format:}$delim\"; \
i=1; \
done <<< \"$(echo -e \"${git_log_cmd//\\%n/\\\\n}\")\"; \
\
while IFS= read -r graph;do \
chars_count=$(sed -nl1000 \"l\" <<< \"$graph\" | grep -Eo \"\\\\\\\\\\\\\\\\|\\||\\/|\\ |\\*|_\" | wc -l); \
[[ ${chars_count:-0} -gt ${col_length["1:1"]:-0} ]] && col_length["1:1"]=$chars_count; \
done < <([[ -n \"$(grep -F graph <<< \"$git_log_cmd\")\" ]] && git log --all --graph --pretty=format:\" \" && echo); \
\
l=0; \
while IFS= read -r line;do \
c=0; \
((l++)); \
[[ $l -gt $n ]] && l=1; \
while IFS= read -d\"$delim\" -r col_content;do \
((c++)); \
if [[ $c -eq 1 ]];then \
[[ -n \"$(grep -F \"*\" <<< \"$col_content\")\" ]] || l=2; \
chars=$(sed -nl1000 \"l\" <<< \"$col_content\" | grep -Eo \"\\\\\\\\\\\\\\\\|\\||\\/|\\ |\\*|_\" | wc -l); \
whitespaces=$((${col_length["1:1"]}-$chars)); \
whitespaces=$(seq -s\" \" $whitespaces|tr -d \"[:digit:]\"); \
col_content[1]=\"${col_content[1]}$col_content$whitespaces\n\"; \
else \
col_content[$c]=\"${col_content[$c]}$(printf \"%-${col_length[\"$l:$c\"]}s\" \"${col_content:-\"\"}\")\n\"; \
fi; \
done <<< \"$line$delim\"; \
for ((k=$c+1;k<=$i_max;k++));do \
empty_content=\"$(printf \"%-${col_length[\"$l:$k\"]:-${col_length[\"${last[$k]:-1}:$k\"]:-0}}s\" \"\")\"; \
col_content[$k]=\"${col_content[$k]}$empty_content\n\"; \
done; \
done < <(git $1 && echo); \
\
while read col_num;do \
if [[ -z \"$cont_all\" ]];then \
cont_all=${col_content[$col_num]}; \
else \
cont_all=$(paste -d\" \" <(echo -e \"$cont_all\") <(echo -e \"${col_content[$col_num]}\")); \
fi; \
done <<< $(seq 2 1 ${git_tre_col:-1};seq 1;seq $((${git_tre_col:-1}+1)) 1 $i_max); \
echo -e \"$cont_all\"; \
"' "git-tably"
This is more or less only a part of my answer https://stackoverflow.com/a/61487052/8006273 where you can find deeper explanations, but nicely fits to this question here too.
If there are problems with your git log commands leave a comment.
Solution 27:[27]
I want to share my compact preset for git log command:
(green is my default console color)
It's designed to be as compact and table-like as possible (without adding any excess spaces) while still being informative and easy to read. This is basically a compact version of medium format Git uses by default.
Features:
- Fixed item positions;
- Default colors of commit hash and ref names;
- Commit author date is in local time zone;
- Commit message is wrapped at 128 characters and indented;
- Extended commit message is also shown (if any) with any trailing newlines removed.
You can add it into your config file using these commands:
(note that they will change the date format for all git log formats!)
$ git config --global log.date 'format-local:%d %b %Y %H:%M'
$ git config --global pretty.compact '%C(auto)%h %C(cyan)%<(17,trunc)%an%C(auto) %D%n %C(cyan)%ad%C(auto) %w(128,0,26)%s%w(0,0,26)%+b%-(trailers:key=FAKE)'
... and then use it like so (with --graph, --all or any other options):
$ git log --graph --pretty=compact
If you'd also like to make it default you can do so with this command:
$ git config --global format.pretty compact
Or if you like aliases:
$ git config --global alias.logc "log --date=format-local:'%d %b %Y %H:%M' --pretty='%C(auto)%h %C(cyan)%<(17,trunc)%an%C(auto) %D%n %C(cyan)%ad%C(auto) %w(128,0,26)%s%w(0,0,26)%+b%-(trailers:key=FAKE)'"
If you'd like to make any changes, see the PRETTY FORMATS section of git log reference.
Solution 28:[28]
On Windows there is a very useful tool you can use: Git Extensions. It's a GUI tool and makes Git operations very easy.
Also it's open sourced.
Solution 29:[29]
I've tried --simplify-by-decoration but all my merges are not shown. So I instead just prune off lines with no "\" and "/" symbols at the headers, while always keeping lines with "(" indicating branches immediately after that. When showing branch history I'm in general uninterested in commit comments, so I remove them too. I end up with the following shell alias.
gbh () {
git log --graph --oneline --decorate "$@" | grep '^[^0-9a-f]*[\\/][^0-9a-f]*\( [0-9a-f]\|$\)\|^[^0-9a-f]*[0-9a-f]*\ (' | sed -e 's/).*/)/'
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
















