git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH V3 2/2] object name: introduce '^{/!-<negative pattern>}' notation

From
Philip Oakley <philipoakley@iee.org>
Date
Jan 11, 2016, 17:59 UTC
Message-ID
<ED12DDDA0C004D23BDDB14973C675800@PhilipOakley>
In-Reply-To
<1452392583-2708-1-git-send-email-ischis2@cox.net>
From: "Stephen P. Smith" <ischis2@cox.net>
> From: Will Palmer <wmpalmer@gmail.com>
>
> To name a commit, you can now say

perhaps s|say|use the :/!-<negative pattern> regex style, and consequentially, say|

Should the patch subject line also be updated to reflect the change?
Show 172 quoted lines
>
>    $ git rev-parse HEAD^{/!-foo}
>
> and it will return the hash of the first commit reachable from HEAD,
> whose commit message does not contain "foo". This is the opposite of the
> existing <rev>^{/<pattern>} syntax.
>
> The specific use-case this is intended for is to perform an operation,
> excluding the most-recent commits containing a particular marker. For
> example, if you tend to make "work in progress" commits, with messages
> beginning with "WIP", you work, then it could be useful to diff against
> "the most recent commit which was not a WIP commit". That sort of thing
> now possible, via commands such as:
>
>    $ git diff @^{/!-^WIP}
>
> The leader '/!-', rather than simply '/!', to denote a negative match,
> is chosen to leave room for additional modifiers in the future.
>
> Signed-off-by: Will Palmer <wmpalmer@gmail.com>
> Signed-off-by: Stephen P. Smith <ischis2@cox.net>
> ---
>
> Notes:
>    Moved modref branch from 2/2 to the 1/2 patch as discussed in [1] and
>    [2].
>
>    [1] http://article.gmane.org/gmane.comp.version-control.git/271071
>    [2] http://article.gmane.org/gmane.comp.version-control.git/283573
>
> Documentation/revisions.txt | 11 ++++++-----
> sha1_name.c                 | 20 +++++++++++++++-----
> t/t1511-rev-parse-caret.sh  | 31 ++++++++++++++++++++++++++++++-
> 3 files changed, 51 insertions(+), 11 deletions(-)
>
> diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
> index d85e303..0c84d4f 100644
> --- a/Documentation/revisions.txt
> +++ b/Documentation/revisions.txt
> @@ -176,11 +176,12 @@ existing tag object.
>   A colon, followed by a slash, followed by a text, names
>   a commit whose commit message matches the specified regular expression.
>   This name returns the youngest matching commit which is
> -  reachable from any ref.  If the commit message starts with a
> -  '!' you have to repeat that;  the special sequence ':/!',
> -  followed by something else than '!', is reserved for now.
> -  The regular expression can match any part of the commit message. To
> -  match messages starting with a string, one can use e.g. ':/^foo'.
> +  reachable from any ref. The regular expression can match any part of 
> the
> +  commit message. To match messages starting with a string, one can use
> +  e.g. ':/^foo'. The special sequence ':/!' is reserved for modifiers to 
> what
> +  is matched. ':/!-foo' performs a negative match, while ':/!!foo' 
> matches a
> +  literal '!' character, followed by 'foo'. Any other sequence beginning 
> with
> +  ':/!' is reserved for now.
>
> '<rev>:<path>', e.g. 'HEAD:README', ':README', 'master:./README'::
>   A suffix ':' followed by a path names the blob or tree
> diff --git a/sha1_name.c b/sha1_name.c
> index 892db21..a2c5303 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -848,8 +848,12 @@ static int get_sha1_1(const char *name, int len, 
> unsigned char *sha1, unsigned l
>  * through history and returning the first commit whose message starts
>  * the given regular expression.
>  *
> - * For future extension, ':/!' is reserved. If you want to match a 
> message
> - * beginning with a '!', you have to repeat the exclamation mark.
> + * For negative-matching, prefix the pattern-part with '!-', like: 
> ':/!-WIP'.
> + *
> + * For a literal '!' character at the beginning of a pattern, you have to 
> repeat
> + * that, like: ':/!!foo'
> + *
> + * For future extension, all other sequences beginning with ':/!' are 
> reserved.
>  */
>
> /* Remember to update object flag allocation in object.h */
> @@ -878,12 +882,18 @@ static int get_sha1_oneline(const char *prefix, 
> unsigned char *sha1,
> {
>  struct commit_list *backup = NULL, *l;
>  int found = 0;
> + int negative = 0;
>  regex_t regex;
>
>  if (prefix[0] == '!') {
> - if (prefix[1] != '!')
> - die ("Invalid search pattern: %s", prefix);
>  prefix++;
> +
> + if (prefix[0] == '-') {
> + prefix++;
> + negative = 1;
> + } else if (prefix[0] != '!') {
> + die ("Invalid search pattern: %s", prefix);
> + }
>  }
>
>  if (regcomp(&regex, prefix, REG_EXTENDED))
> @@ -903,7 +913,7 @@ static int get_sha1_oneline(const char *prefix, 
> unsigned char *sha1,
>  continue;
>  buf = get_commit_buffer(commit, NULL);
>  p = strstr(buf, "\n\n");
> - matches = p && !regexec(&regex, p + 2, 0, NULL, 0);
> + matches = p && (negative ^ !regexec(&regex, p + 2, 0, NULL, 0));
>  unuse_commit_buffer(commit, buf);
>
>  if (matches) {
> diff --git a/t/t1511-rev-parse-caret.sh b/t/t1511-rev-parse-caret.sh
> index b2f90be..8a5983f 100755
> --- a/t/t1511-rev-parse-caret.sh
> +++ b/t/t1511-rev-parse-caret.sh
> @@ -26,7 +26,10 @@ test_expect_success 'setup' '
>  git branch expref &&
>  echo changed >>a-blob &&
>  git add -u &&
> - git commit -m Changed
> + git commit -m Changed &&
> + echo changed-again >>a-blob &&
> + git add -u &&
> + git commit -m Changed-again
> '
>
> test_expect_success 'ref^{non-existent}' '
> @@ -99,4 +102,30 @@ test_expect_success 'ref^{/!!Exp}' '
>  test_cmp expected actual
> '
>
> +test_expect_success 'ref^{/!-}' '
> + test_must_fail git rev-parse master^{/!-}
> +'
> +
> +test_expect_success 'ref^{/!-.}' '
> + test_must_fail git rev-parse master^{/!-.}
> +'
> +
> +test_expect_success 'ref^{/!-non-existent}' '
> + git rev-parse master >expected &&
> + git rev-parse master^{/!-non-existent} >actual &&
> + test_cmp expected actual
> +'
> +
> +test_expect_success 'ref^{/!-Changed}' '
> + git rev-parse expref >expected &&
> + git rev-parse master^{/!-Changed} >actual &&
> + test_cmp expected actual
> +'
> +
> +test_expect_success 'ref^{/!-!Exp}' '
> + git rev-parse modref >expected &&
> + git rev-parse expref^{/!-!Exp} >actual &&
> + test_cmp expected actual
> +'
> +
> test_done
> -- 
> 2.7.0-rc2
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
Previous: Stephen P. SmithNext: Stephen P. Smith
Message 12 of 26 in “specify commit by negative pattern”
  1. 0/2 specify commit by negative patternWill Palmer, Jun 6, 2015
  2. 1/2 test for '!' handling in rev-parse's named commitsWill Palmer, Jun 6, 2015
  3. 2/2 object name: introduce '^{/!-<negative pattern>}' notationWill Palmer, Jun 6, 2015
  4. Junio C HamanoJun 8, 2015
  5. Will PalmerJun 9, 2015
  6. Junio C HamanoOct 28, 2015
  7. Stephen SmithJan 8, 2016
  8. Junio C HamanoJan 8, 2016
  9. 0/2 specify commit by negative patternStephen P. Smith, Jan 10, 2016
  10. 1/2 test for '!' handling in rev-parse's named commitsStephen P. Smith, Jan 10, 2016
  11. 2/2 object name: introduce '^{/!-<negative pattern>}' notationStephen P. Smith, Jan 10, 2016
  12. Philip OakleyJan 11, 2016
  13. 0/2 specify commit by negative patternStephen P. Smith, Jan 13, 2016
  14. 1/2 test for '!' handling in rev-parse's named commitsStephen P. Smith, Jan 13, 2016
  15. 2/2 object name: introduce '^{/!-<negative pattern>}' notationStephen P. Smith, Jan 13, 2016
  16. Junio C HamanoJan 13, 2016
  17. 2/2 object name: introduce '^{/!-<negative pattern>}' notationStephen P. Smith, Jan 31, 2016
  18. Junio C HamanoFeb 1, 2016
  19. Philip OakleyJan 10, 2016
  20. 0/2 specify commit by negative patternStephen P. Smith, Jan 11, 2016
  21. Philip OakleyJan 11, 2016
  22. Stephen & Linda SmithJan 10, 2016
  23. Philip OakleyJan 10, 2016
  24. Stephen & Linda SmithJan 9, 2016
  25. Duy NguyenJan 9, 2016
  26. Junio C HamanoJan 11, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.