linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Bob Peterson <rpeterso@redhat.com>
Cc: cluster-devel <cluster-devel@redhat.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: GFS2: Pull request (merge window)
Date: Fri, 5 May 2017 14:07:53 -0700	[thread overview]
Message-ID: <CA+55aFwRFrFeFkt1uJpsbBKwhzSVhuSwPkzvxOeUoR_J3YM2xw@mail.gmail.com> (raw)
In-Reply-To: <1070215647.4566044.1494016107082.JavaMail.zimbra@redhat.com>

On Fri, May 5, 2017 at 1:28 PM, Bob Peterson <rpeterso@redhat.com> wrote:
>
> I asked around, but nobody could tell me what went wrong. Strangely,
> this command:
>
> git log --oneline --right-only origin/master...FETCH_HEAD --stat
>
> doesn't show this, but this one does:
>
> git diff --stat --right-only origin/master...FETCH_HEAD

So the fundamental difference between "git log" and "git diff" is that
one is a "ser operation" on the commits in question, and the other is
fundamentally a "operation between two endpoints".

And that's why "git log" will always show the "right" thing - because
even in the presense of complex history, there's no ambiguity about
which commits are part of the new set, and which are in the old set.
So "git log" just does a set difference, and shows the commits in one
set but not the other.

But "git diff", because it is fundamentally about two particular
points in history, can have a hard time once you have complex history:
what are the two points?

In particular, what "git diff origin/master...FETCH_HEAD" means is really:

 - find the common point (git calls it "merge base" because the common
point is also used for merging) between the two commits (origin/master
and FETCH_HEAD)

 - do the diff from that common point to the end result (FETCH_HEAD)

and for linear history that is all very obvious and unambiguous.

But once you have non-linear history, and particularly once you have
back-merges (ie you're not just merging work that is uniquely your own
from multiple of your *own* branches, but you're also doing merges of
upstream code), the notion of that "common case" is no longer
unambiguous. There is not necessarily any *one* common base, there can
be multiple points in history that are common between the two
branches, but are distinct points of history (ie one is not an
ancestor of another).

And since a diff is fundamentally about just two end-points ("what are
the differences between these two points in the history"), "git diff"
fundamentally cannot handle that case without help.

So "git diff" will pick the first of the merge bases it finds, and
just use that. Which even in the presense of more complex history will
often work by luck, but more often just means that you'll see
differences that aren't all from your tree, but some of them came from
the *other* common point(s).

For example, after doing the pull, I can then do:

    git merge-base --all HEAD^ HEAD^2

to see the merge bases of the merge in HEAD. In this case, because of
your back-merge, there's two of them (with more complex history, there
can be more still):

  f9fe1c12d126 rhashtable: Add rhashtable_lookup_get_insert_fast
  69eea5a4ab9c Merge branch 'for-linus' of git://git.kernel.dk/linux-block

and because "git diff" will just pick the first one, you will
basically have done

    git diff f9fe1c12d126..FETCH_HEAD

and if you then look at the *set* of changes (with "git log" of that
range), you'll see why that diff also ends up containing those block
changes (because they came on from that other merge base: commit
69eea5a4ab9c that had that linux-block merge).

Now, doing a *merge* in git will take _all_ of those merge bases into
account, and do something *much* more complicated than just a two-way
diff. It will internally first create a single merge base (by
recursively merging up all the other merge bases into a new internal
commit), and then using that single merge base it will then do a
normal three-way merge of the two branches.

"git diff' doesn't do that kind of complicated operation, and although
it *could* do that merge base recursive merging dance, the problem
would be what to do about conflicts (which "git merge" obviously can
also have, but with git merge you have that whole manual conflict
resolution case).

So once you have complex history that isn't just about merging your
own local changes from other local branches, you'll start hitting this
situation.

Visualizing the history with "gitk" for those cases is often a great
way to see why there's no single point that can be diffed against.

But once you *do* have that kind of complex history, you're also
expected to have the expertise to handle it:

> So I created a temporary local branch and used git merge to
> generate a correct diffstat.

That's the correct thing to do. Hopefully the above explains *why*
it's the correct thing to do.

(Although to be honest, I also am pretty used to parsing the wrong
diffs, and people sometimes just send me the garbage diffstat and say
"I don't know what happened", and I'll figure it out and can still
validate that the garbage diffstat they sent me is what I too get if I
do just a silly "git diff" without taking merge bases into account).

           Linus

  reply	other threads:[~2017-05-05 21:08 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <909713995.4565875.1494016018520.JavaMail.zimbra@redhat.com>
2017-05-05 20:28 ` GFS2: Pull request (merge window) Bob Peterson
2017-05-05 21:07   ` Linus Torvalds [this message]
     [not found] <2063498114.10752149.1552067836491.JavaMail.zimbra@redhat.com>
2019-03-08 17:58 ` Bob Peterson
     [not found] <180051537.56890898.1545229879645.JavaMail.zimbra@redhat.com>
2018-12-19 14:31 ` Bob Peterson
     [not found] <1929897739.23623737.1540322729596.JavaMail.zimbra@redhat.com>
2018-10-23 19:26 ` Bob Peterson
2018-10-24 16:35   ` Linus Torvalds
2018-10-24 16:41     ` Bob Peterson
     [not found] <1772901878.39899227.1528134744434.JavaMail.zimbra@redhat.com>
2018-06-04 17:53 ` Bob Peterson
     [not found] <242799785.15741010.1522776740239.JavaMail.zimbra@redhat.com>
2018-04-03 17:32 ` Bob Peterson
     [not found] <2035999397.5567269.1517410350526.JavaMail.zimbra@redhat.com>
2018-01-31 14:54 ` Bob Peterson
     [not found] <800692691.31850756.1510678641181.JavaMail.zimbra@redhat.com>
2017-11-14 16:57 ` Bob Peterson
2017-11-14 17:17   ` Bob Peterson
     [not found] <1332965725.6958432.1504544624096.JavaMail.zimbra@redhat.com>
2017-09-04 17:05 ` Bob Peterson
     [not found] <2018468119.28735933.1499259957760.JavaMail.zimbra@redhat.com>
2017-07-05 13:08 ` Bob Peterson
     [not found] <1526627784.3659456.1493822813354.JavaMail.zimbra@redhat.com>
2017-05-03 16:41 ` Bob Peterson
     [not found] <468087826.25173671.1487684421990.JavaMail.zimbra@redhat.com>
2017-02-21 13:41 ` Bob Peterson
     [not found] <603920106.687778.1475513554626.JavaMail.zimbra@redhat.com>
2016-10-03 16:55 ` Bob Peterson
     [not found] <404724578.17300814.1469208769730.JavaMail.zimbra@redhat.com>
2016-07-22 17:33 ` Bob Peterson
     [not found] <2074855986.8621406.1463772170266.JavaMail.zimbra@redhat.com>
2016-05-20 19:23 ` Bob Peterson
     [not found] <2094757318.39162844.1458219077321.JavaMail.zimbra@redhat.com>
2016-03-17 12:51 ` Bob Peterson
     [not found] <1243871936.8427302.1452623511952.JavaMail.zimbra@redhat.com>
2016-01-12 18:34 ` Bob Peterson
     [not found] <337313427.7367463.1447086799887.JavaMail.zimbra@redhat.com>
2015-11-09 16:45 ` Bob Peterson
     [not found] <987432592.26261269.1441889826020.JavaMail.zimbra@redhat.com>
2015-09-10 13:19 ` Bob Peterson
     [not found] <1946368926.25134466.1435330524247.JavaMail.zimbra@redhat.com>
2015-06-26 14:56 ` Bob Peterson
     [not found] <1305736412.15685734.1429033600005.JavaMail.zimbra@redhat.com>
2015-04-14 17:47 ` Bob Peterson
2015-04-14 23:16   ` Linus Torvalds
2015-04-15  7:34     ` Steven Whitehouse
2015-04-14 23:19   ` Linus Torvalds
2015-04-15 12:09     ` Bob Peterson
2015-02-10 11:04 Steven Whitehouse
  -- strict thread matches above, loose matches on Subject: below --
2014-12-08 18:26 Steven Whitehouse
2014-10-08 19:25 Steven Whitehouse
2014-06-04  9:33 Steven Whitehouse
2014-04-01 23:15 Steven Whitehouse
2014-04-04 21:52 ` Linus Torvalds
2014-04-07  9:31   ` Steven Whitehouse
2014-01-20 19:15 Steven Whitehouse
2013-11-05 15:39 Steven Whitehouse
2013-09-09  9:22 Steven Whitehouse
2013-07-01 15:20 Steven Whitehouse
2013-04-29 11:08 Steven Whitehouse
2013-02-19 16:38 Steven Whitehouse
2012-12-11 10:39 Steven Whitehouse
2012-09-13 13:42 GFS2: Pull request (fixes) Steven Whitehouse
2012-10-01  9:09 ` GFS2: Pull request (merge window) Steven Whitehouse
2012-07-23 14:59 Steven Whitehouse
2012-08-03  1:22 ` Linus Torvalds
2012-08-03 10:18   ` Steven Whitehouse
2012-08-03 16:16     ` Linus Torvalds
2012-05-21  8:17 Steven Whitehouse
2012-03-20 16:10 Steven Whitehouse
2012-01-06 12:09 Steven Whitehouse
2011-10-25  8:41 Steven Whitehouse
2011-07-22 12:08 Steven Whitehouse
2011-05-20  8:14 Steven Whitehouse
2011-03-16 13:55 Steven Whitehouse
2011-01-05 10:22 Steven Whitehouse
2010-10-21  9:43 Steven Whitehouse
2010-08-03  9:06 Steven Whitehouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CA+55aFwRFrFeFkt1uJpsbBKwhzSVhuSwPkzvxOeUoR_J3YM2xw@mail.gmail.com \
    --to=torvalds@linux-foundation.org \
    --cc=cluster-devel@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rpeterso@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).