How are the commands git log -p
, git show
, and git diff
related and why would one be used over another?
Given a repo with the following 4 commits:
commitd - last commit
commitc
commitb
coomita - initial commit
What are the differences between the following git commands?:
git log -p commitb commitd
git show commitb commitd
git diff commitb commitd
git log -p commitd commitb
git show commitd commitb
git diff commitd commitb
git log -p commitb..commitd
git show commitb..commitd
git diff commitb..commitd
git log -p commitd..commitb
git show commitd..commitb
git diff commitd..commitb
git log -p commitb...commitd
git show commitb...commitd
git diff commitb...commitd
git log -p commitd...commitb
git show commitd...commitb
git diff commitd...commitb
git log A B
shows the history of both commitsA
andB
(basically generating a union set of each commits' history). Usually you wantgit log A..B
, which can also be written asgit log ^B A
(show everything reachable from A, but not (^
) from B). This range can also be empty (for instanceB..A
would be empty, since every commit reachable fromB
is also reachable fromA
). Therefore, you also get no output fromgit log
when used with the "wrong" arguments.git show
is a very versatile command and produces different output depending on its arguments. You can pass one or several commits and it will show you the commit information (authorship, timestamp, commit message, diff from previous commit). Commit ranges such asa..d
will be resolved and each commit is shown individually. You can also pass a path andgit show
will show you the file's contents. You can also specify a file at a certain revision with the syntaxcommit:path/to/file
. If you pass a directory,git show
will display the commit information of the last commit changing that directory.git diff
generally expects two trees or two files to compare. (It can also take no arguments and compare the index/staging area instead). A commit is automatically unwrapped into its corresponding tree (a tree object describes a certain state of the repository). The syntaxA..B
is silently resolved toA B
for the diff case and will show the changes required to get from commit/treeA
toB
The range
A...B
means "every commit reachable from A or B, but not from both".git log
it will show you those commits and it mostly only makes sense when used with diverged branches, i.e. "show every that's different between the two, but hide those commits which both branches have in common".git diff
this syntax is syntactic sugar forgit diff $(git merge-base A B) B
, i.e. "changes inB
since the history ofA
diverged.git show
you will simply get commit information for each single commit in that range.If anything's still unclear let me know in the comments.
Here's the output the repository you posted in your original question: