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...
This question is related to
git
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=%formatstring
is 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.
Nobody mentioned 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 has really clear visualisations, but it's much heavier than tig
)
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/).*/)/'
}
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
I found "git-big-picture" quite useful: https://github.com/esc/git-big-picture
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.
For Mac users, checkout (no pun intended) the free, open source tool GitUp: http://gitup.co/
I like the way the graphs are displayed, it's clearer than some of the other tools I've seen.
The project is here: https://github.com/git-up/GitUp
Tortoise Git has a tool called "Revision Graph". If you're on Windows it's as easy as right click on your repo --> Tortoise Git --> Revision Graph.
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.
Have a look at BranchMaster.
I wrote it to visualize complex branch structure, by collapsing all commits between them to a single line. The numbers indicates the number of commits.
Giggle draws really nice graphs.
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"
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 lg
will see the current branch history.git hist
will see the whole branch history.Git official site enlisted some third party platform specific GUI tools. Hit here git GUI Tools for Linux Platform
I have used gitg
and GitKraken
for linux platform. Both good to understand the commit tree
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:
.gitconfig
,.gitconfig
s 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.
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.
can we make it more complicated?
How about simple git log --all --decorate --oneline --graph (remember A Dog = --All --Decorate --Oneline --Graph)
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.
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.
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).
For those using the VSCode text editor, consider the Git History Extension by D. Jayamanne:
Gitk
sometime painful for me to read.
Motivate me to write GitVersionTree.
Check out SmartGit
. It very much reminds me of the TortoiseHg branch visualization and it's free for non-commercial use.
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 simple just use gl
.
You can also add the alias to the git config . Open ~/.gitconfig
and add the following line to the [alias]
[alias]
lg = log --oneline --abbrev-commit --all --graph --decorate --color
and use it like this: git lg
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 here: http://blog.kfish.org/2010/04/git-lola.html
The most rated answers 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:
%><(<N>[,ltrunc|mtrunc|trunc])
before every commit placeholder--color
option for colored outputLimitations:
%n...
%><(<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 done
compared to normal git log output 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 graph to column 5
To achieve this add the following to your .gitconfig 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.
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
Gitx is also a fantastic visualization tool if you happen to be on OS X.
Source: Stackoverflow.com