threads / patch / 30960

patchImprove revisions.txt

Subject: [PATCH] Improve revisions.txt

## tl;dr

9 messages between Jul 5, 2012 and Jul 23, 2012. Diffs are folded; open one to read it.

replies: 8people: 2as markdown or json

Max Horn· Jul 5, 2012, 16:45 UTC · lore

One section talked about <name> when only <refname> was defined. And the description for r1^! was incorrect, talking about "parents" (which I understand as meaning direct parent commits), when really all ancestors were meant. Finally I added a few more examples (in particular one for "B..C") that helped me understand the whole thing.

Signed-off-by: Max Horn <max@quendi.de>
---
 Documentation/revisions.txt |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)
Show changes to Documentation/revisions.txt +12 −8
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 1725661..b452265 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -24,22 +24,22 @@ blobs contained in a commit.
   object referenced by 'refs/heads/master'.  If you
   happen to have both 'heads/master' and 'tags/master', you can
   explicitly say 'heads/master' to tell git which one you mean.
-  When ambiguous, a '<name>' is disambiguated by taking the
+  When ambiguous, a '<refname>' is disambiguated by taking the
   first match in the following rules:
 
-  . If '$GIT_DIR/<name>' exists, that is what you mean (this is usually
+  . If '$GIT_DIR/<refname>' exists, that is what you mean (this is usually
     useful only for 'HEAD', 'FETCH_HEAD', 'ORIG_HEAD', 'MERGE_HEAD'
     and 'CHERRY_PICK_HEAD');
 
-  . otherwise, 'refs/<name>' if it exists;
+  . otherwise, 'refs/<refname>' if it exists;
 
   . otherwise, 'refs/tags/<refname>' if it exists;
 
-  . otherwise, 'refs/heads/<name>' if it exists;
+  . otherwise, 'refs/heads/<refname>' if it exists;
 
-  . otherwise, 'refs/remotes/<name>' if it exists;
+  . otherwise, 'refs/remotes/<refname>' if it exists;
 
-  . otherwise, 'refs/remotes/<name>/HEAD' if it exists.
+  . otherwise, 'refs/remotes/<refname>/HEAD' if it exists.
 +
 'HEAD' names the commit on which you based the changes in the working tree.
 'FETCH_HEAD' records the branch which you fetched from a remote repository
@@ -215,8 +215,9 @@ It is the set of commits that are reachable from either one of
 
 Two other shorthands for naming a set that is formed by a commit
 and its parent commits exist.  The 'r1{caret}@' notation means all
-parents of 'r1'.  'r1{caret}!' includes commit 'r1' but excludes
-all of its parents.
+commits reachable from 'r1' except for 'r1' itself, i.e. all ancestors
+of 'r1' are included. In contrast to this, 'r1{caret}!' includes commit
+'r1' but excludes all of its ancestors.
 
 Here are a handful of examples:
 
@@ -224,7 +225,10 @@ Here are a handful of examples:
    D F              G H I J D F
    ^G D             H D
    ^D B             E I J F B
+   B..C             C
    B...C            G H D E B C
    ^D B C           E I J F B C
+   C                I J F C
    C^@              I J F
+   B^! C            B C
    F^! D            G H D F
-- 
1.7.7.5 (Apple Git-26)
Junio C Hamano· Jul 5, 2012, 18:06 UTC · re: Max Horn · lore

Re: [PATCH] Improve revisions.txt

Max Horn <max@quendi.de> writes:
> One section talked about <name> when only <refname> was defined.
Thanks.  This is a definite improvement.
> And the description for r1^! was incorrect, talking about "parents"
> (which I understand as meaning direct parent commits),
> when really all ancestors were meant.

What makes ^! exclude "all ancestors" is that you fed it to rev-list or log. r1^! really means "mark r1 as interesting, but mark its direct parents as uninteresting". r1^@ means "r1's direct parents are interesting". For example, "git show -s r1^@" will show the direct parents of r1 but not its ancestors.

While there is nothing wrong in the updated descriptin per-se (because it is about "specifying ranges", aka "feeding these to rev-list or log, here is what happens"), I am torn about this part of the patch. Perhaps ^! and ^@ may also deserve to be described as a way to give individual revisions (not "specifying ranges")?

I dunno.
Show 14 quoted lines
> Finally I added a few more examples (in particular one for "B..C")
> that helped me understand the whole thing.
> ...
> @@ -224,7 +225,10 @@ Here are a handful of examples:
>     D F              G H I J D F
>     ^G D             H D
>     ^D B             E I J F B
> +   B..C             C
>     B...C            G H D E B C
>     ^D B C           E I J F B C
> +   C                I J F C
>     C^@              I J F
> +   B^! C            B C
>     F^! D            G H D F
Max Horn· Jul 6, 2012, 00:01 UTC · re: Junio C Hamano · lore

[PATCH 1/2] Make <refname> documentation more consistent.

Formerly, the documentation for <refname> would occasionally say <name> instead of <refname>. Now it uniformly uses <refname>.

Signed-off-by: Max Horn <max@quendi.de>
---
 Documentation/revisions.txt | 12 ++++++------
 1 Datei geändert, 6 Zeilen hinzugefügt(+), 6 Zeilen entfernt(-)
Show changes to Documentation/revisions.txt +6 −6
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index 1725661..f4f6f28 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -24,22 +24,22 @@ blobs contained in a commit.
   object referenced by 'refs/heads/master'.  If you
   happen to have both 'heads/master' and 'tags/master', you can
   explicitly say 'heads/master' to tell git which one you mean.
-  When ambiguous, a '<name>' is disambiguated by taking the
+  When ambiguous, a '<refname>' is disambiguated by taking the
   first match in the following rules:
 
-  . If '$GIT_DIR/<name>' exists, that is what you mean (this is usually
+  . If '$GIT_DIR/<refname>' exists, that is what you mean (this is usually
     useful only for 'HEAD', 'FETCH_HEAD', 'ORIG_HEAD', 'MERGE_HEAD'
     and 'CHERRY_PICK_HEAD');
 
-  . otherwise, 'refs/<name>' if it exists;
+  . otherwise, 'refs/<refname>' if it exists;
 
   . otherwise, 'refs/tags/<refname>' if it exists;
 
-  . otherwise, 'refs/heads/<name>' if it exists;
+  . otherwise, 'refs/heads/<refname>' if it exists;
 
-  . otherwise, 'refs/remotes/<name>' if it exists;
+  . otherwise, 'refs/remotes/<refname>' if it exists;
 
-  . otherwise, 'refs/remotes/<name>/HEAD' if it exists.
+  . otherwise, 'refs/remotes/<refname>/HEAD' if it exists.
 +
 'HEAD' names the commit on which you based the changes in the working tree.
 'FETCH_HEAD' records the branch which you fetched from a remote repository
-- 
1.7.11.1.145.g4722b29.dirty
Max Horn· Jul 6, 2012, 00:01 UTC · re: Max Horn · lore

[PATCH 2/2] Document rev^! and rev^@ as revision specifiers

Previously, the rev^! and rev^@ syntax were only described in the SPECIFYING RANGES section of revisions.txt, making it a bit harder to find information about it. Moreover, that description was slightly confusing as it described the technical definition of rev^! and rev^@ without making it completely clear what the end effect was. This patch attempts to address this by adding dedicate entries for rev^! and rev^@ in the SPECIFYING REVISIONS section, rewording the existing explanation, and adding two select additional examples.

Finally, it also adds an example for the B..C range syntax, to help illustrate how it differs from B...C.

Signed-off-by: Max Horn <max@quendi.de>
---
 Documentation/revisions.txt | 24 +++++++++++++++++++++---
 1 Datei geändert, 21 Zeilen hinzugefügt(+), 3 Zeilen entfernt(-)
Show changes to Documentation/revisions.txt +21 −3
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index f4f6f28..2784298 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -128,6 +128,20 @@ the '$GIT_DIR/refs' directory or from the '$GIT_DIR/packed-refs' file.
   it returns the youngest matching commit which is reachable from
   the '<rev>' before '{caret}'.
 
+'<rev>{caret}@', e.g. 'HEAD{caret}@'::
+  A suffix '{caret}' followed by an at sign
+  means all parents of '<rev>'.
+  This is somewhat different from the other specifiers in this
+  section in that it may refer to multiple commits at once.
+  See also the next section on SPECIFYING RANGES.
+
+'<rev>{caret}!', e.g. 'HEAD{caret}!'::
+  A suffix '{caret}' followed by an exclamation mark
+  means commit '<rev>' but forces all of its parents to be excluded. For
+  commands that deal with a single revision, this is the same as '<rev>".
+  Hence it is primarily used with commands expecting commit ranges.
+  See also the next section on SPECIFYING RANGES.
+
 ':/<text>', e.g. ':/fix nasty bug'::
   A colon, followed by a slash, followed by a text, names
   a commit whose commit message matches the specified regular expression.
@@ -214,9 +228,10 @@ It is the set of commits that are reachable from either one of
 'r1' or 'r2' but not from both.
 
 Two other shorthands for naming a set that is formed by a commit
-and its parent commits exist.  The 'r1{caret}@' notation means all
-parents of 'r1'.  'r1{caret}!' includes commit 'r1' but excludes
-all of its parents.
+and its parent commits exist.  Recall that 'r1{caret}@' means all
+parents of 'r1'. When specifying ranges, this effectively includes
+all ancestors of 'r1' but excludes 'r1' itself. In contrast to this,
+'r1{caret}!' includes commit 'r1' but excludes all of its ancestors.
 
 Here are a handful of examples:
 
@@ -224,7 +239,10 @@ Here are a handful of examples:
    D F              G H I J D F
    ^G D             H D
    ^D B             E I J F B
+   B..C             C
    B...C            G H D E B C
    ^D B C           E I J F B C
+   C                I J F C
    C^@              I J F
+   C^!              C
    F^! D            G H D F
-- 
1.7.11.1.145.g4722b29.dirty
Junio C Hamano· Jul 6, 2012, 07:21 UTC · re: Max Horn · lore

Re: [PATCH 2/2] Document rev^! and rev^@ as revision specifiers

Max Horn <max@quendi.de> writes:
Show 6 quoted lines
> +'<rev>{caret}@', e.g. 'HEAD{caret}@'::
> +  A suffix '{caret}' followed by an at sign
> +  means all parents of '<rev>'.
> +  This is somewhat different from the other specifiers in this
> +  section in that it may refer to multiple commits at once.
> +  See also the next section on SPECIFYING RANGES.
Looks good.
> +'<rev>{caret}!', e.g. 'HEAD{caret}!'::
> +  A suffix '{caret}' followed by an exclamation mark
> +  means commit '<rev>' but forces all of its parents to be excluded. For
> +  commands that deal with a single revision, this is the same as '<rev>".

Is this sentence correct? "git commit -C 'HEAD^!'" might be a command that expects a single revision, but I do not think it is the same as "git commit -C HEAD".

> +  Hence it is primarily used with commands expecting commit ranges.
That is correct.
Max Horn· Jul 6, 2012, 09:00 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/2] Document rev^! and rev^@ as revision specifiers

Am 06.07.2012 um 09:21 schrieb Junio C Hamano <gitster@pobox.com>:
Show 20 quoted lines
> Max Horn <max@quendi.de> writes:
> 
>> +'<rev>{caret}@', e.g. 'HEAD{caret}@'::
>> +  A suffix '{caret}' followed by an at sign
>> +  means all parents of '<rev>'.
>> +  This is somewhat different from the other specifiers in this
>> +  section in that it may refer to multiple commits at once.
>> +  See also the next section on SPECIFYING RANGES.
> 
> Looks good.
> 
> 
>> +'<rev>{caret}!', e.g. 'HEAD{caret}!'::
>> +  A suffix '{caret}' followed by an exclamation mark
>> +  means commit '<rev>' but forces all of its parents to be excluded. For
>> +  commands that deal with a single revision, this is the same as '<rev>".
> 
> Is this sentence correct?  "git commit -C 'HEAD^!'" might be a
> command that expects a single revision, but I do not think it is the
> same as "git commit -C HEAD".
Ignoring the exact words I used for the moment, what I meant is that these two commands should be functionally equivalent. Aren't they? If not, I obviously misunderstand something, and would like to learn more, and add a better explanation.
If they are equivalent in the sense that the end results are indistinguishable,, and you just dislike the (indeed inaccurate) choice of words, how about replacing "is the same as" by "is [functionally] equivalent".

Thank you very much for your reviews, Max

Show 5 quoted lines
> 
>> +  Hence it is primarily used with commands expecting commit ranges.
> 
> That is correct.
> 
Junio C Hamano· Jul 6, 2012, 19:18 UTC · re: Max Horn · lore

Re: [PATCH 2/2] Document rev^! and rev^@ as revision specifiers

Max Horn <max@quendi.de> writes:
Show 10 quoted lines
>>> +'<rev>{caret}!', e.g. 'HEAD{caret}!'::
>>> +  A suffix '{caret}' followed by an exclamation mark
>>> +  means commit '<rev>' but forces all of its parents to be excluded. For
>>> +  commands that deal with a single revision, this is the same as '<rev>".
>> 
>> Is this sentence correct?  "git commit -C 'HEAD^!'" might be a
>> command that expects a single revision, but I do not think it is the
>> same as "git commit -C HEAD".
>
> Ignoring the exact words I used for the moment, what I meant is that these two commands should be functionally equivalent. Aren't they?

No. When a single commit is wanted HEAD^! shouldn't be used, and they cannot be functionally equivalent. I haven't tried but I think "commit -C HEAD^!" would give you a syntax error.

Max Horn· Jul 9, 2012, 15:02 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/2] Document rev^! and rev^@ as revision specifiers

> 
On 06.07.2012, at 21:18, Junio C Hamano wrote:
Show 17 quoted lines
> Max Horn <max@quendi.de> writes:
> 
>>>> +'<rev>{caret}!', e.g. 'HEAD{caret}!'::
>>>> +  A suffix '{caret}' followed by an exclamation mark
>>>> +  means commit '<rev>' but forces all of its parents to be excluded. For
>>>> +  commands that deal with a single revision, this is the same as '<rev>".
>>> 
>>> Is this sentence correct?  "git commit -C 'HEAD^!'" might be a
>>> command that expects a single revision, but I do not think it is the
>>> same as "git commit -C HEAD".
>> 
>> Ignoring the exact words I used for the moment, what I meant is that these two commands should be functionally equivalent. Aren't they?
> 
> No.  When a single commit is wanted HEAD^! shouldn't be used, and
> they cannot be functionally equivalent.  I haven't tried but I think
> "commit -C HEAD^!"  would give you a syntax error.
> 
Indeed, it says
 fatal: could not lookup commit HEAD^!
I'll iterate over this once more.

Cheers, Max

Junio C Hamano· Jul 23, 2012, 19:27 UTC · re: Max Horn · lore

Re: [PATCH 2/2] Document rev^! and rev^@ as revision specifiers

Max Horn <max@quendi.de> writes:
Show 26 quoted lines
>> 
> On 06.07.2012, at 21:18, Junio C Hamano wrote:
>
>> Max Horn <max@quendi.de> writes:
>> 
>>>>> +'<rev>{caret}!', e.g. 'HEAD{caret}!'::
>>>>> +  A suffix '{caret}' followed by an exclamation mark
>>>>> +  means commit '<rev>' but forces all of its parents to be excluded. For
>>>>> +  commands that deal with a single revision, this is the same as '<rev>".
>>>> 
>>>> Is this sentence correct?  "git commit -C 'HEAD^!'" might be a
>>>> command that expects a single revision, but I do not think it is the
>>>> same as "git commit -C HEAD".
>>> 
>>> Ignoring the exact words I used for the moment, what I meant is
>>> that these two commands should be functionally
>>> equivalent. Aren't they?
>> 
>> No.  When a single commit is wanted HEAD^! shouldn't be used, and
>> they cannot be functionally equivalent.  I haven't tried but I think
>> "commit -C HEAD^!"  would give you a syntax error.
>
> Indeed, it says
>  fatal: could not lookup commit HEAD^!
>
> I'll iterate over this once more.
Let's do this instead.
-- >8 --
Subject: Enumerate revision range specifiers in the documentation

It was a bit hard to learn how <rev>^@, <rev>^! and various other forms of range specification are used, because they were discussed mostly in the prose part of the documentation, unlike various forms of extended SHA-1 expressions that are listed in enumerated list.

Also add a few more examples showing use of <rev>, <rev>..<rev> and <rev>^! forms, stolen from a patch by Max Horn.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/revisions.txt | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
Show changes to Documentation/revisions.txt +31 −0
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index f4f6f28..6506ec6 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -218,13 +218,44 @@ and its parent commits exist.  The 'r1{caret}@' notation means all
 parents of 'r1'.  'r1{caret}!' includes commit 'r1' but excludes
 all of its parents.
 
+To summarize:
+
+'<rev>'::
+	Include commits that are reachable from (i.e. ancestors of)
+	<rev>.
+
+'{caret}<rev>'::
+	Exclude commits that are reachable from (i.e. ancestors of)
+	<rev>.
+
+'<rev1>..<rev2>'::
+	Include commits that are reachable from <rev2> but exclude
+	those that are reachable from <rev1>.
+
+'<rev1>...<rev2>'::
+	Include commits that are reachable from either <rev1> or
+	<rev2> but exclude those that are reachable from both.
+
+'<rev>{caret}@', e.g. 'HEAD{caret}@'::
+  A suffix '{caret}' followed by an at sign is the same as listing
+  all parents of '<rev>' (meaning, include anything reachable from
+  its parents, but not the commit itself).
+
+'<rev>{caret}!', e.g. 'HEAD{caret}!'::
+  A suffix '{caret}' followed by an exclamation mark is the same
+  as giving commit '<rev>' and then all its parents prefixed with
+  '{caret}' to exclude them (and their ancestors).
+
 Here are a handful of examples:
 
    D                G H D
    D F              G H I J D F
    ^G D             H D
    ^D B             E I J F B
+   B..C             C
    B...C            G H D E B C
    ^D B C           E I J F B C
+   C                I J F C
    C^@              I J F
+   C^!              C
    F^! D            G H D F

← back to recent threads