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(®ex, 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(®ex, p + 2, 0, NULL, 0);
> + matches = p && (negative ^ !regexec(®ex, 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
>