Compare commits between 2 branches
IMO, the ideal tool showing the different commits between 2 branches need to
- list all the different commits E, D, B;
- mark the direction (which branch has the commit);
- have the output format which is highly readable and is even customizable.
Sometimes we want to know the symmetric difference in manner of commits NOT code lines of 2 branches before merging them. I noticed that there are some ways to do this but most of them are not ideal to me.
Here I list some ways and my comments. And provide my approach to do this. (Use my experimental repo as demo). The commits and the branches graph look like below:
A ------ C ------ E (branch:main)
\ |
·- B - C -- D (branch:feat)
Fig 1
IMO, the ideal tool showing the different commits between 2 branches need to
- list all the different commits E, D, B;
- mark the direction (which branch has the commit);
- have the output format which is highly readable and is even customizable.
1. git log
git log branch1..branch2
or git log branch1...branch2
Or an one-line way: git log --oneline branch1...branch2
Use git-log can list the commits on one branch and not on another branch. This is what exact we need. The parts I don’t like are:
-
If use double-dots, it only shows the incremental commits on the right-hand branch compared with the common ancestor, but not with the left-hand branch:
-
If use triple-dots, it does show all different commits but you cannot tell which branch does the different commit come from:
2. git show-branch
git show-branch branch1 branch2
git-show-branch is another very useful tool to list commits. The problem is it stops at the first common commit appearing at the 2 branches both.
The fig shows by default git-show-branch stops at commit [main^] Commit on main. , which is commit C in fig1 |
To show more commits, an option --more=x
need to be passed in but actually we are not able to know what’s a suitable value of x
.
The fig shows the expected result of all the 3 different commits but –more=5 is not always working |
3. git rev-list
git rev-list --oneline --left-right main...feat
This is almost the exptected one, if not considering the output formats. If we want to customize the format (like adding commiter name, date), the output can be a little bit messy to me:
A sample using --pretty=reference |
Another sample using customized formats |
Anyway it’s already good enough to show the different commits, and we could use sed
or other tools to make the output more readable.
In newer version of git, git-rev-list
provides option no-commit-header
with which the output can be cleaner.
4. a shell script or function
If we want everything under our control, the best way is to write a shell script.
I borrow the idea from Kim Briggs on Stackoverflow and add more customization in git log
and diff
part:
# Function to retrieve different commits between branches:
function gitbd() {
if ((2==$#)); then
alog=/tmp/gitbd_$(echo $1 | tr '/' '-').log
blog=/tmp/gitbd_$(echo $2 | tr '/' '-').log
git log --pretty="format:%h %as %s (%cn)" $1 > $alog
git log --pretty="format:%h %as %s (%cn)" $2 > $blog
colordiff -u $alog $blog | less
# vi -d $alog $blog
# diff -u $alog $blog
rm $alog $blog
fi
}
Add the function in your shell rc, then in command line, gitbd main feat
will give the different commits list, and colored in a very git
way, also shows the common commits around the different ones:
The format of each line can be customized by modifying git log
part of the function. The diff utility can be replaced with anything else you like.
Currently this function requires colordiff
, but you could choose vim
or just diff
if your diff
supports --color
.
Vim diff |