Reputation: 30206
I expected git show <commit>
and git diff <commit>^ <commit>
to show the all changes that took place in a given commit, but I see that their list of changes differs. (See example below.) What's the correct understanding of their function, then?
Yes, I've read the man pages
git show
For commits it shows the log message and textual diff. It also presents the
merge commit in a special format as produced by git diff-tree --cc.
git diff
git diff [--options] <commit> <commit> [--] [<path>...]
This is to view the changes between two arbitrary <commit>.
$ MY_COMMIT=7c95d118c9837f801f4e314732c593e25feba3b1
git show
and its output:$ git show --name-only $MY_COMMIT
commit 7c95d118c9837f801f4e314732c593e25feba3b1
Merge: 5f308b4 9ef9bd7
Author: Me <[email protected]>
Date: Thu Apr 23 14:14:58 2015 -0700
Merge branch 'develop' of github.com:pic-development/dataraptor into develop
Conflicts:
app/controllers/application_controller.rb
app/controllers/usage/staff_assignment_controller.rb
app/views/crm/connections/_show.html.erb
app/views/crm/task_builders/_task_builders.html.haml
spec/controllers/contacts_controller_spec.rb
spec/controllers/crm/connections_controller_spec.rb
app/controllers/application_controller.rb
app/controllers/usage/staff_assignment_controller.rb
app/views/crm/connections/_show.html.erb
git diff
and its output:$ git diff --name-only $MY_COMMIT^ $MY_COMMIT
app/assets/javascripts/application/quoting/ng-new-quote.js
app/assets/stylesheets/application-layout.css.scss
app/assets/stylesheets/application.css
app/controllers/application_controller.rb
app/controllers/crm/connections_controller.rb
app/controllers/usage/staff_assignment_controller.rb
app/models/crm/connection.rb
app/models/usage/permissions.rb
app/views/crm/connections/_show.html.erb
app/views/crm/task_builders/_task_builder.html.erb
app/views/layouts/application.html.erb
app/views/marketing/campaigns/_index.html.haml
app/views/marketing/campaigns/_task_builders.html.haml
app/views/shared/tab/_agency_management.html.erb
app/views/shared/tab/_contracts.html.erb
app/views/shared/tab/_help.html.erb
app/views/shared/tab/_marketing.html.erb
app/views/shared/tab/_my_account.html.erb
app/views/shared/tab/_reporting.html.erb
app/views/shared/tab/_sales_tools.html.erb
app/views/shared/tab/_system_management.html.erb
app/views/shared/tab/_underwriting_suitability.html.erb
app/views/usage/agent_field_sets/_new_submission_option.html.erb
app/views/usage/users/_personal.html.erb
vendor/assets/stylesheets/bootstrap-combined.min.css
vendor/assets/stylesheets/bootstrap.css
vendor/assets/stylesheets/pixel-admin.css
vendor/assets/stylesheets/themes.css
Upvotes: 2
Views: 118
Reputation: 488003
By default, for a merge commit, git show
produces (as the documentation says) a "combined diff". Using git diff
directly with only two of the three or more commits involved1 produces a regular (non-combined) diff.
The documentation on combined diffs is a bit buried, and for some reason this sentence:
Note that combined diff lists only files which were modified from all parents.
is in another section entirely. And, the section linked here refers to git diff
when you can't tell git diff
to look at all of the merge's parents simultaneously (you have to use git diff-tree
or git show
for that).
1A merge commit is one with at least two parents, so the three or more commits here are the commit you're git show
-ing, its first parent ($MY_COMMIT^1
), its second parent ($MY_COMMIT^2
), and any additional parents ($MY_COMMIT^3
, etc., for "octopus merges").
Upvotes: 0
Reputation: 37964
You are displaying the diff of a merge commit.
Consider an example with the following commits (F being the newest one), and you're doing a git show F
and a git diff F^ F
(which is effectively a git diff C F
).
A--B--C--F
\ /
D----E
git show
shows only the files that were changed in the merge commit itself. This may include files that had merge conflicts which were manually fixed. It will not show files that were modified in one of the merged branches (so B,C or D,E) and could be merged cleanly. To quote the man page (emphasis mine):
For commits [git show] shows the log message and textual diff. It also presents the merge commit in a special format as produced by git diff-tree --cc.
[git diff-tree --cc] further compresses the patch output by omitting uninteresting hunks whose the contents in the parents have only two variants and the merge result picks one of them without modification.
git diff <commit>^ <commit>
shows the diff of the merge commit's first parent and the merge commit. Since the merge commit contains all changes from both the first and second parent, you're effectively shown the diff of the entire branch (so in my example, commit D and E) that was merged in that commit.
Upvotes: 2