{"thread":{"id":"55722","subject":"[PATCH] revisions(7): clarify that most commands take a single revision range","startedAt":"2021-05-18T11:17:52Z","lastAt":"2021-05-21T19:19:25Z","messageCount":9,"participants":["Junio C Hamano","Bagas Sanjaya","Elijah Newren","Eric Sunshine","Felipe Contreras"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"424852","messageId":"xmqqv97g2svd.fsf@gitster.g","threadId":"55722","inReplyTo":null,"subject":"[PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-05-18T11:17:42Z","receivedAt":"2021-05-18T11:17:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sometimes new people are confused by how a revision \"range\" works,\nin that it is not a random collection of commits but a set of\ncommits that are all connected to each other, and most Git commands\nwork on a single such \"range\".\n\nGive an example to clarify it.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * So, here it is in a proper patch form, with an extended\n   description and illustration.\n\n Documentation/revisions.txt | 23 +++++++++++++++++++++++\n 1 file changed, 23 insertions(+)\n\ndiff --git a/Documentation/revisions.txt b/Documentation/revisions.txt\nindex d9169c062e..f5f17b65a1 100644\n--- a/Documentation/revisions.txt\n+++ b/Documentation/revisions.txt\n@@ -260,6 +260,9 @@ any of the given commits.\n A commit's reachable set is the commit itself and the commits in\n its ancestry chain.\n \n+There are several notations to specify a set of connected commits\n+(called a \"revision range\"), illustrated below.\n+\n \n Commit Exclusions\n ~~~~~~~~~~~~~~~~~\n@@ -294,6 +297,26 @@ is a shorthand for 'HEAD..origin' and asks \"What did the origin do since\n I forked from them?\"  Note that '..' would mean 'HEAD..HEAD' which is an\n empty range that is both reachable and unreachable from HEAD.\n \n+Commands that are specifically designed to take two distinct ranges\n+(e.g. \"git range-diff R1 R2\" to compare two ranges) do exist, but\n+they are exceptions.  Unless otherwise noted, all \"git\" commands\n+that operate on a set of commits work on a single revision range.\n+In other words, writing two \"two-dot range notation\" next to each\n+other, e.g.\n+\n+    $ git log A..B C..D\n+\n+does *not* specify two revision ranges for most commands.  Instead\n+it will name a single connected set of commits, i.e. those that are\n+reachable from either B or D but are reachable from neither A or C.\n+In a linear history like this:\n+\n+    ---A---B---o---o---C---D\n+\n+because A and B are reachable from C, the revision range specified\n+by these two dotted ranges is a single commit D.\n+\n+\n Other <rev>{caret} Parent Shorthand Notations\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n Three other shorthands exist, particularly useful for merge commits,\n-- \n2.32.0-rc0-111-g32b9632252\n\n"},{"id":"425020","messageId":"ab2d8b16-42db-9675-083a-efa7cfca6e4c@gmail.com","threadId":"55722","inReplyTo":"xmqqv97g2svd.fsf@gitster.g","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-05-20T02:27:26Z","receivedAt":"2021-05-20T02:27:31Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 18/05/21 18.17, Junio C Hamano wrote:\n> +Commands that are specifically designed to take two distinct ranges\n> +(e.g. \"git range-diff R1 R2\" to compare two ranges) do exist, but\n> +they are exceptions.  Unless otherwise noted, all \"git\" commands\n> +that operate on a set of commits work on a single revision range.\n> +In other words, writing two \"two-dot range notation\" next to each\n> +other, e.g.\n> +\n> +    $ git log A..B C..D\n> +\n> +does *not* specify two revision ranges for most commands.  Instead\n> +it will name a single connected set of commits, i.e. those that are\n> +reachable from either B or D but are reachable from neither A or C.\n> +In a linear history like this:\n> +\n> +    ---A---B---o---o---C---D\n> +\n\nSo \"git log A..B C..D\" is same as \"A..D\", right?\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"425032","messageId":"xmqqh7iyuhlp.fsf@gitster.g","threadId":"55722","inReplyTo":"ab2d8b16-42db-9675-083a-efa7cfca6e4c@gmail.com","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-05-20T04:58:10Z","receivedAt":"2021-05-20T04:58:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bagas Sanjaya <bagasdotme@gmail.com> writes:\n\n> On 18/05/21 18.17, Junio C Hamano wrote:\n>> ...\n>> +In other words, writing two \"two-dot range notation\" next to each\n>> +other, e.g.\n>> +\n>> +    $ git log A..B C..D\n>> +\n>> +does *not* specify two revision ranges for most commands.  Instead\n>> +it will name a single connected set of commits, i.e. those that are\n>> +reachable from either B or D but are reachable from neither A or C.\n>> +In a linear history like this:\n>> +\n>> +    ---A---B---o---o---C---D\n>> +\n>\n> So \"git log A..B C..D\" is same as \"A..D\", right?\n\nA..B C..D is equivalent to ^A ^C B D, and in order to be part of the\nset it represents, a commit must not be reachable from A, must not\nbe reachable from C, and must be reachable from B or D.\n\nIn the picture, A, B and two o's are all reachable from C, therefore\nare not part of the set A..B C..D represents.  Neither is C, as it\nis reachable from C.  That leaves only D in the resulting range.\n\nA..D is a set of connected five commits, B o o C D in the above\npicture.\n\nSo, no.\n\nThe confusion we often see goes more like \"The set A..B contains B\n(and nothing else), and C..D contains D (and nothing else), hence\n'git log A..B C..D' would show B and D\".  But that is not what\nhappens because \"git log\" (like most other commands) takes just a\n\"range\" that is \"A..B C..D\", which is a set of connected commits\neach of whose member is reachable from one of the \"positive\"\nendpoints (like B and D) and is not reachable from any of the\n\"negative\" endpoints (like A and C).\n\n\n"},{"id":"425033","messageId":"xmqqcztmuhem.fsf@gitster.g","threadId":"55722","inReplyTo":"xmqqh7iyuhlp.fsf@gitster.g","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-05-20T05:02:25Z","receivedAt":"2021-05-20T05:02:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Bagas Sanjaya <bagasdotme@gmail.com> writes:\n>\n>> On 18/05/21 18.17, Junio C Hamano wrote:\n>>> ...\n>>> +In other words, writing two \"two-dot range notation\" next to each\n>>> +other, e.g.\n>>> +\n>>> +    $ git log A..B C..D\n>>> +\n>>> +does *not* specify two revision ranges for most commands.  Instead\n>>> +it will name a single connected set of commits, i.e. those that are\n>>> +reachable from either B or D but are reachable from neither A or C.\n>>> +In a linear history like this:\n>>> +\n>>> +    ---A---B---o---o---C---D\n>>> +\n>>\n>> So \"git log A..B C..D\" is same as \"A..D\", right?\n>\n> A..B C..D is equivalent to ^A ^C B D, and in order to be part of the\n> set it represents, a commit must not be reachable from A, must not\n> be reachable from C, and must be reachable from B or D.\n>\n> In the picture, A, B and two o's are all reachable from C, therefore\n> are not part of the set A..B C..D represents.  Neither is C, as it\n> is reachable from C.  That leaves only D in the resulting range.\n>\n> A..D is a set of connected five commits, B o o C D in the above\n> picture.\n>\n> So, no.\n>\n> The confusion we often see goes more like \"The set A..B contains B\n> (and nothing else), and C..D contains D (and nothing else), hence\n> 'git log A..B C..D' would show B and D\".  But that is not what\n> happens because \"git log\" (like most other commands) takes just a\n> \"range\" that is \"A..B C..D\", which is a set of connected commits\n> each of whose member is reachable from one of the \"positive\"\n> endpoints (like B and D) and is not reachable from any of the\n> \"negative\" endpoints (like A and C).\n\nWell, apparently the proposed text may have failed to educate you\nabout what a \"revision range\" is and how it works, so it is not good\nenough, so I'll postpone merging the change down further and see if\nsomebody else can come up with a better description.\n\nThanks.\n"},{"id":"425035","messageId":"43f44eca-bf71-effa-29b0-cb2db41d581f@gmail.com","threadId":"55722","inReplyTo":"xmqqcztmuhem.fsf@gitster.g","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Bagas Sanjaya","fromEmail":"bagasdotme@gmail.com","sentAt":"2021-05-20T05:26:36Z","receivedAt":"2021-05-20T05:26:42Z","isPatch":true,"sender":{"key":"bagasdotme@gmail.com","avatar":"https://avatars.githubusercontent.com/u/40219486?v=4"},"body":"On 20/05/21 12.02, Junio C Hamano wrote:\n>> The confusion we often see goes more like \"The set A..B contains B\n>> (and nothing else), and C..D contains D (and nothing else), hence\n>> 'git log A..B C..D' would show B and D\".  But that is not what\n>> happens because \"git log\" (like most other commands) takes just a\n>> \"range\" that is \"A..B C..D\", which is a set of connected commits\n>> each of whose member is reachable from one of the \"positive\"\n>> endpoints (like B and D) and is not reachable from any of the\n>> \"negative\" endpoints (like A and C).\n> \n> Well, apparently the proposed text may have failed to educate you\n> about what a \"revision range\" is and how it works, so it is not good\n> enough, so I'll postpone merging the change down further and see if\n> somebody else can come up with a better description.\n> \n> Thanks.\n> \n\n From Pro Git book [1]:\n> The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another.\n> Say you want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with master..experiment — that means “all commits reachable from experiment that aren’t reachable from master.” \n> If, on the other hand, you want to see the opposite — all commits in master that aren’t in experiment — you can reverse the branch names. experiment..master shows you everything in master not reachable from experiment\n\nSo in the first case, git log master..experiment shows all commits that\nare only on experiment, while git log experiment..master shows all commits\nthat are only on master.\n\nThis above are often confused by most Git users, because they execute the\nlatter when they want semantics of the former.\n\nI CC'ed Scott Chacon because he wrote the description about revision\nrange in Pro Git book. Let's see what his opinions are.\n\n[1]: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection\n\n-- \nAn old man doll... just what I always wanted! - Clara\n"},{"id":"425130","messageId":"CABPp-BFhsw7jMZa9TcLSKz12=0H40froS-DTRXSvMR4q006Jyw@mail.gmail.com","threadId":"55722","inReplyTo":"ab2d8b16-42db-9675-083a-efa7cfca6e4c@gmail.com","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-05-20T16:40:33Z","receivedAt":"2021-05-20T16:40:46Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, May 19, 2021 at 7:28 PM Bagas Sanjaya <bagasdotme@gmail.com> wrote:\n>\n> On 18/05/21 18.17, Junio C Hamano wrote:\n> > +Commands that are specifically designed to take two distinct ranges\n> > +(e.g. \"git range-diff R1 R2\" to compare two ranges) do exist, but\n> > +they are exceptions.  Unless otherwise noted, all \"git\" commands\n> > +that operate on a set of commits work on a single revision range.\n> > +In other words, writing two \"two-dot range notation\" next to each\n> > +other, e.g.\n> > +\n> > +    $ git log A..B C..D\n> > +\n> > +does *not* specify two revision ranges for most commands.  Instead\n> > +it will name a single connected set of commits, i.e. those that are\n> > +reachable from either B or D but are reachable from neither A or C.\n> > +In a linear history like this:\n> > +\n> > +    ---A---B---o---o---C---D\n> > +\n\nWhy did you snip off the immediate next part of Junio's text which said:\n\n+because A and B are reachable from C, the revision range specified\n+by these two dotted ranges is a single commit D.\n\nIs this sentence hard to parse or confusing in some way?  I thought\nthis sentence would have made it pretty clear that the answer to this\nquestion:\n\n>\n> So \"git log A..B C..D\" is same as \"A..D\", right?\n\nwas 'no', so I'm curious if that particular final sentence's wording\ncould be improved.\n"},{"id":"425131","messageId":"CABPp-BEGtrb0QjhVff57=s8-8w1CCvw9N_mAm166pzyVDcL_7g@mail.gmail.com","threadId":"55722","inReplyTo":"xmqqcztmuhem.fsf@gitster.g","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2021-05-20T16:45:02Z","receivedAt":"2021-05-20T16:45:16Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Wed, May 19, 2021 at 10:03 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n> > Bagas Sanjaya <bagasdotme@gmail.com> writes:\n> >\n> >> On 18/05/21 18.17, Junio C Hamano wrote:\n> >>> ...\n> >>> +In other words, writing two \"two-dot range notation\" next to each\n> >>> +other, e.g.\n> >>> +\n> >>> +    $ git log A..B C..D\n> >>> +\n> >>> +does *not* specify two revision ranges for most commands.  Instead\n> >>> +it will name a single connected set of commits, i.e. those that are\n> >>> +reachable from either B or D but are reachable from neither A or C.\n> >>> +In a linear history like this:\n> >>> +\n> >>> +    ---A---B---o---o---C---D\n> >>> +\n> >>\n> >> So \"git log A..B C..D\" is same as \"A..D\", right?\n> >\n> > A..B C..D is equivalent to ^A ^C B D, and in order to be part of the\n> > set it represents, a commit must not be reachable from A, must not\n> > be reachable from C, and must be reachable from B or D.\n> >\n> > In the picture, A, B and two o's are all reachable from C, therefore\n> > are not part of the set A..B C..D represents.  Neither is C, as it\n> > is reachable from C.  That leaves only D in the resulting range.\n> >\n> > A..D is a set of connected five commits, B o o C D in the above\n> > picture.\n> >\n> > So, no.\n> >\n> > The confusion we often see goes more like \"The set A..B contains B\n> > (and nothing else), and C..D contains D (and nothing else), hence\n> > 'git log A..B C..D' would show B and D\".  But that is not what\n> > happens because \"git log\" (like most other commands) takes just a\n> > \"range\" that is \"A..B C..D\", which is a set of connected commits\n> > each of whose member is reachable from one of the \"positive\"\n> > endpoints (like B and D) and is not reachable from any of the\n> > \"negative\" endpoints (like A and C).\n>\n> Well, apparently the proposed text may have failed to educate you\n> about what a \"revision range\" is and how it works, so it is not good\n> enough, so I'll postpone merging the change down further and see if\n> somebody else can come up with a better description.\n>\n> Thanks.\n\nI think it's helpful and would have answered questions for users that\nI've had to manually explain to folks a few times, so while it may not\nbe optimal, I do think your description is an improvement to the docs.\nThat said, it can't hurt to see if we can find out what caused Bagas'\nconfusion and see if we can improve it, but I wouldn't hold it up\nindefinitely if no better wording comes along.\n"},{"id":"425133","messageId":"CAPig+cR_rNKoY385vp3ZyQ73O1HEbysLSCMpVCG=MT9ebSNiyA@mail.gmail.com","threadId":"55722","inReplyTo":"CABPp-BEGtrb0QjhVff57=s8-8w1CCvw9N_mAm166pzyVDcL_7g@mail.gmail.com","subject":"Re: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-05-20T16:53:23Z","receivedAt":"2021-05-20T16:53:36Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, May 20, 2021 at 12:45 PM Elijah Newren <newren@gmail.com> wrote:\n> On Wed, May 19, 2021 at 10:03 PM Junio C Hamano <gitster@pobox.com> wrote:\n> > Well, apparently the proposed text may have failed to educate you\n> > about what a \"revision range\" is and how it works, so it is not good\n> > enough, so I'll postpone merging the change down further and see if\n> > somebody else can come up with a better description.\n> >\n> > Thanks.\n>\n> I think it's helpful and would have answered questions for users that\n> I've had to manually explain to folks a few times, so while it may not\n> be optimal, I do think your description is an improvement to the docs.\n> That said, it can't hurt to see if we can find out what caused Bagas'\n> confusion and see if we can improve it, but I wouldn't hold it up\n> indefinitely if no better wording comes along.\n\nFor what it's worth, as a person who is far from being a\nrevision-range expert (and who doesn't typically think about them), I\nfound the proposed text illuminating and clearly written. I learned\nfrom it. So, I agree with Elijah[1] that it is a good improvement to\nhave (even if it's not perfect for every reader).\n\n[1]: Extended LInear Jump AHead\n"},{"id":"425233","messageId":"60a807b82f6aa_558062081c@natae.notmuch","threadId":"55722","inReplyTo":"xmqqv97g2svd.fsf@gitster.g","subject":"RE: [PATCH] revisions(7): clarify that most commands take a single revision range","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2021-05-21T19:19:20Z","receivedAt":"2021-05-21T19:19:25Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Junio C Hamano wrote:\n> +Commands that are specifically designed to take two distinct ranges\n> +(e.g. \"git range-diff R1 R2\" to compare two ranges) do exist, but\n> +they are exceptions.  Unless otherwise noted, all \"git\" commands\n\nNot sure why \"git\" is in quotes.\n\n> +that operate on a set of commits work on a single revision range.\n> +In other words, writing two \"two-dot range notation\" next to each\n> +other, e.g.\n> +\n> +    $ git log A..B C..D\n> +\n> +does *not* specify two revision ranges for most commands.  Instead\n> +it will name a single connected set of commits, i.e. those that are\n> +reachable from either B or D but are reachable from neither A or C.\n> +In a linear history like this:\n> +\n> +    ---A---B---o---o---C---D\n> +\n> +because A and B are reachable from C, the revision range specified\n> +by these two dotted ranges is a single commit D.\n\n  For example, if you have a linear history like this:\n\n    ---A---B---C---D---E---F\n\n  Doing A..F will retrieve 5 commits, and doing B..E will retrieve 3\n  commits, but doing A..F B..E will not retrieve 8 commits. Instead the\n  starting point A gets overriden by B, and the ending point of E by F,\n  effectively becoming B..F.\n\n  With more complex graphs the result is not so simple and might result\n  in two disconnected sets of commits, but that is considered a single\n  revision range.\n\n-- \nFelipe Contreras\n"}]}