{"thread":{"id":"50561","subject":"how does one interpret \"git diff <commit> ^<commit>\"","startedAt":"2019-02-22T13:22:18Z","lastAt":"2019-02-22T15:31:02Z","messageCount":3,"participants":["Robert P. J. Day","Ævar Arnfjörð Bjarmason","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"369910","messageId":"alpine.LFD.2.21.1902220816010.6353@localhost.localdomain","threadId":"50561","inReplyTo":null,"subject":"how does one interpret \"git diff <commit> ^<commit>\"","fromName":"Robert P. J. Day","fromEmail":"rpjday@crashcourse.ca","sentAt":"2019-02-22T13:22:12Z","receivedAt":"2019-02-22T13:22:18Z","isPatch":false,"sender":{"key":"rpjday@crashcourse.ca","avatar":"https://avatars.githubusercontent.com/u/226084077?v=4"},"body":"\n  was perusing the git FAQ and ran across this:\n\n  How do I obtain a list of files which have changed in a given commit?\n\n     $ git diff --name-only <commit>^!\n\n\nafter playing with \"git rev-parse\", i figured out that the above was\nequivalent to (using kernel \"v4.19\" tag as an example):\n\n$ git diff v4.19 ^v4.19^\ndiff --git a/Makefile b/Makefile\nindex bf3786e4ffec..69fa5c0310d8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2,8 +2,8 @@\n VERSION = 4\n PATCHLEVEL = 19\n SUBLEVEL = 0\n-EXTRAVERSION = -rc8\n-NAME = Merciless Moray\n+EXTRAVERSION =\n+NAME = \"People's Front\"\n\n # *DOCUMENTATION*\n # To see a list of typical targets execute \"make help\"\n$\n\n  but i get exactly the same output if i reverse the arguments:\n\n$ git diff ^v4.19^ v4.19\ndiff --git a/Makefile b/Makefile\nindex bf3786e4ffec..69fa5c0310d8 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2,8 +2,8 @@\n VERSION = 4\n PATCHLEVEL = 19\n SUBLEVEL = 0\n-EXTRAVERSION = -rc8\n-NAME = Merciless Moray\n+EXTRAVERSION =\n+NAME = \"People's Front\"\n\n # *DOCUMENTATION*\n # To see a list of typical targets execute \"make help\"\n\n  so i'm confused as to how to \"git diff\" interprets and processes\nthose two arguments, as \"v4.19\" is, of course, a reference to a\nspecific commit, but \"^v4.19^\" appears to define all those commits not\nreachable from \"v4.19^\". how should one read this?\n\nrday\n\n-- \n\n========================================================================\nRobert P. J. Day                                 Ottawa, Ontario, CANADA\n                  http://crashcourse.ca/dokuwiki\n\nTwitter:                                       http://twitter.com/rpjday\nLinkedIn:                               http://ca.linkedin.com/in/rpjday\n========================================================================\n"},{"id":"369912","messageId":"874l8v6ht3.fsf@evledraar.gmail.com","threadId":"50561","inReplyTo":"alpine.LFD.2.21.1902220816010.6353@localhost.localdomain","subject":"Re: how does one interpret \"git diff <commit> ^<commit>\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2019-02-22T14:04:08Z","receivedAt":"2019-02-22T14:04:15Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Fri, Feb 22 2019, Robert P. J. Day wrote:\n\n>   was perusing the git FAQ and ran across this:\n>\n>   How do I obtain a list of files which have changed in a given commit?\n>\n>      $ git diff --name-only <commit>^!\n>\n>\n> after playing with \"git rev-parse\", i figured out that the above was\n> equivalent to (using kernel \"v4.19\" tag as an example):\n>\n> $ git diff v4.19 ^v4.19^\n> diff --git a/Makefile b/Makefile\n> index bf3786e4ffec..69fa5c0310d8 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -2,8 +2,8 @@\n>  VERSION = 4\n>  PATCHLEVEL = 19\n>  SUBLEVEL = 0\n> -EXTRAVERSION = -rc8\n> -NAME = Merciless Moray\n> +EXTRAVERSION =\n> +NAME = \"People's Front\"\n>\n>  # *DOCUMENTATION*\n>  # To see a list of typical targets execute \"make help\"\n> $\n>\n>   but i get exactly the same output if i reverse the arguments:\n>\n> $ git diff ^v4.19^ v4.19\n> diff --git a/Makefile b/Makefile\n> index bf3786e4ffec..69fa5c0310d8 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -2,8 +2,8 @@\n>  VERSION = 4\n>  PATCHLEVEL = 19\n>  SUBLEVEL = 0\n> -EXTRAVERSION = -rc8\n> -NAME = Merciless Moray\n> +EXTRAVERSION =\n> +NAME = \"People's Front\"\n>\n>  # *DOCUMENTATION*\n>  # To see a list of typical targets execute \"make help\"\n>\n>   so i'm confused as to how to \"git diff\" interprets and processes\n> those two arguments, as \"v4.19\" is, of course, a reference to a\n> specific commit, but \"^v4.19^\" appears to define all those commits not\n> reachable from \"v4.19^\". how should one read this?\n\nI'm not sure if it answers your question, but search for \"Jon Loeliger\"\nin \"man git-rev-parse\". It shows an example of a graph and what the ^REV\nsyntax means.\n\n^v4.19^ looks cutsey, but just means:\n\n    first_parent_of_v4.19_is_X = v4.19^\n    not_reachable_from_X = ^$first_parent_of_v4.19_is_X\n"},{"id":"369930","messageId":"xmqq1s3zsuvi.fsf@gitster-ct.c.googlers.com","threadId":"50561","inReplyTo":"alpine.LFD.2.21.1902220816010.6353@localhost.localdomain","subject":"Re: how does one interpret \"git diff <commit> ^<commit>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-02-22T15:30:57Z","receivedAt":"2019-02-22T15:31:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Robert P. J. Day\" <rpjday@crashcourse.ca> writes:\n\n>   was perusing the git FAQ and ran across this:\n>\n>   How do I obtain a list of files which have changed in a given commit?\n>\n>      $ git diff --name-only <commit>^!\n>\n>\n> after playing with \"git rev-parse\", i figured out that the above was\n> equivalent to (using kernel \"v4.19\" tag as an example):\n>\n> $ git diff v4.19 ^v4.19^\n\nA \"rev\" argument on the command line can have two (and a half but\nthat one does not come into picture in this discussion) polarity.\nNormal and negative.  Negative revs are written with \"^\" prefix (not\nto be confused with \"^\" suffix which means \"the first parent of),\nand normal revs are written without \"^\" prefix.\n\nThere are some short-hands like <rev>^!, but they expand to\ncombination of the normal and negative rev arguments at the bottom.\nThe one you used, \"rev^!\", on the command line expands to \"rev --not\nrev^1 rev^2... --not\" for all its parents.  Here \"--not\" means\n\"treat all revs that follow have opposite polarity than they are\nwritten until you see the next \"--not\".  For a non-merge commit,\nthat's equivalent to \"rev --not rev^\", which in turn is \"rev ^rev^.\n\nNow these normal and negative revs are often used for specifying\nranges to revision walking operations (think: \"git log\" etc.)  When\nused to specify revision range, the set of commits a range specifies\nis anything reachable from any one or more of normal revs, excluding\nthe ones reachable from any one or more of negative revs.  So \"git\nlog v4.18..v4.19\", which is a short-hand for \"git log ^v4.18 v4.19\"\n(because A..B is a short-hand that expands to \"^A B\"), i.e. list all\ncommits that are reachable from v4.19, but I am not interested in\nthe ones that are reachable from v4.18.\n\n\"git diff\" is about comparing two endpoints, so these normal and\nnegative revs are used differently.  With one negative and one\nnormal rev, you can tell \"compare negative with normal to produce\na patch that takes the tree of the negative one to the tree of the\nnormal one\".\n\nSo with \"git diff v4.19^!\", aka \"git diff ^v4.19^ v4.19\" (as v4.19\nis not a merge), you are asking\n\n\tgit diff v4.19^..v4.19\n\nwhich is equivalent to asking\n\n\tgit diff v4.19^ v4.19\n\nwhich is \"give me difference to bring the tree of the first parent\nof v4.19 to that of v4.19\".\n\nFor interactive use to see \"What happend at v4.19?\", it is much\neasier to type \"git show v4.19\" than \"git diff v4.19^!\", though.\n"}]}