Re: [PATCH 0/3] Re: [PATCH] check-ref-format: require a repository for --branch
Jonathan Niederwrites: > Junio C Hamano wrote: >> Jonathan Nieder writes: > >>> Handles the nongit case in strbuf_check_branch_ref instead of >>> introducing a new check_branch_ref_format helper. >> >> I view that as a regression, actually. Don't we want a function >> that does not require a strbuf when asking a simple question: "I >> have a string, and I want to see if that is a valid name"? > > *shrug* I found the change easier to read, and it also sidesteps the > which-header question. It also ensures that other > strbuf_check_branch_ref callers are safe without having to audit them. Please ignore the above, which was merely an impression _without_ and before having received any patch to comment on ;-) Quite frankly, this is a Meh topic that won't have to hit even 'next' before the final. The color.ui=always thing has a lot more urgency, and this was merely what I did while waiting for others to react to that topic.
Re: [PATCH] check-ref-format: require a repository for --branch
Junio C Hamano wrote: > Jonathan Niederwrites: >> And in that spirit, I think the patch you replied with aims to go in >> the right direction, by providing the core functionality when in a >> repository while avoiding breaking such a script outside of one >> (though I do not understand it fully yet). > > Given that, is it safe for me to ignore this earlier one > >> For what it's worth, I don't agree with this repurposing of >> "check-ref-format --branch" at all. > > as reacting to the patch without reading what it does? On second reading, yes, I was reacting to the discussion leading up to the patch instead of the patch. The patch looks good. Sorry for the noise, Jonathan
Re: [PATCH] check-ref-format: require a repository for --branch
Junio C Hamano wrote: > Jonathan Niederwrites: >> And in that spirit, I think the patch you replied with aims to go in >> the right direction, by providing the core functionality when in a >> repository while avoiding breaking such a script outside of one >> (though I do not understand it fully yet). > > Given that, is it safe for me to ignore this earlier one > >> For what it's worth, I don't agree with this repurposing of >> "check-ref-format --branch" at all. > > as reacting to the patch without reading what it does? Are you saying I should have ignored the commit message? Recording future plans via the commit message is part of what the patch does, after all. >> Junio C Hamano wrote: >>>(e.g. a wrapper to "git >>> clone" that wants to verify the name it is going to give to the "-b" >>> option), and a check desired in such a context is different from >>> (and is stricter than) feeding refs/heads/$name to the same command >>> without the "--branch" option. >> >> Can you say more about this example? E.g. why is this hypothetical >> wrapper unable to rely on "git clone -b"'s own error handling? > > If I have to guess what you meant, perhaps the Porcelain wanted to > diagnose bad parameter that would be rejected _before_ letting clone > spend cycles and possibly network bandwidth? > > But this was my way of rephrasing an earlier example you used while > objecting to Peff's change [...] > so my answer to the question in the message I am directly responding > to would be "You tell me." ;-) Hm. Does the example in https://public-inbox.org/git/20171017070808.plddffhzdobye...@aiede.mtv.corp.google.com/ make it clearer? The goal of such a script is *not* error handling --- that is just a pleasant side-benefit. It is to be able to handle all branch specifiers from the user (and even a default branch that is not from the user) uniformly. Thanks, Jonathan
Re: [PATCH 0/3] Re: [PATCH] check-ref-format: require a repository for --branch
Junio C Hamano wrote: > Jonathan Niederwrites: >> Handles the nongit case in strbuf_check_branch_ref instead of >> introducing a new check_branch_ref_format helper. > > I view that as a regression, actually. Don't we want a function > that does not require a strbuf when asking a simple question: "I > have a string, and I want to see if that is a valid name"? *shrug* I found the change easier to read, and it also sidesteps the which-header question. It also ensures that other strbuf_check_branch_ref callers are safe without having to audit them. But feel free to tweak that back if you like, or I can tomorrow. Jonathan
Re: [PATCH 0/3] Re: [PATCH] check-ref-format: require a repository for --branch
Jonathan Niederwrites: > Handles the nongit case in strbuf_check_branch_ref instead of > introducing a new check_branch_ref_format helper. I view that as a regression, actually. Don't we want a function that does not require a strbuf when asking a simple question: "I have a string, and I want to see if that is a valid name"?
[PATCH 0/3] Re: [PATCH] check-ref-format: require a repository for --branch
Hi, Junio C Hamano wrote: > Subject: [PATCH] check-ref-format: --branch cannot grok @{-1} outside a > repository How about this? It is written to be more conservative than the patch I am replying to, but except for the commit message, it should be pretty much equivalent. [...] > --- a/builtin/check-ref-format.c > +++ b/builtin/check-ref-format.c > @@ -38,13 +38,22 @@ static char *collapse_slashes(const char *refname) > > static int check_ref_format_branch(const char *arg) > { > + int nongit, malformed; > struct strbuf sb = STRBUF_INIT; > - int nongit; > + const char *name = arg; > > setup_git_directory_gently(); > - if (strbuf_check_branch_ref(, arg)) > + > + if (!nongit) > + malformed = (strbuf_check_branch_ref(, arg) || > + !skip_prefix(sb.buf, "refs/heads/", )); > + else > + malformed = check_branch_ref_format(arg); Handles the nongit case in strbuf_check_branch_ref instead of introducing a new check_branch_ref_format helper. [...] > --- a/cache.h > +++ b/cache.h > @@ -1444,6 +1444,20 @@ extern int parse_oid_hex(const char *hex, struct > object_id *oid, const char **en > #define INTERPRET_BRANCH_HEAD (1<<2) > extern int interpret_branch_name(const char *str, int len, struct strbuf *, >unsigned allowed); > + > +/* > + * NEEDSWORK: declare strbuf_branchname() and strbuf_check_branch_ref() > + * here, not in strbuf.h > + */ As a result, it doesn't touch headers. I agree that these functions don't belong in strbuf.h (sorry for not updating the headers at the same time I moved their implementations) but suspect e.g. branch.h, revision.h, or some new header like revision-syntax.h would be a better place. [...] > --- a/strbuf.h > +++ b/strbuf.h > @@ -568,6 +568,12 @@ static inline void strbuf_complete_line(struct strbuf > *sb) > strbuf_complete(sb, '\n'); > } > > +/* > + * NEEDSWORK: the following two functions should not be in this file; > + * these are about refnames, and should be declared next to > + * interpret_branch_name() in cache.h > + */ Didn't touch headers. [...] > --- a/t/t1402-check-ref-format.sh > +++ b/t/t1402-check-ref-format.sh > @@ -161,6 +161,18 @@ test_expect_success 'check-ref-format --branch from > subdir' ' > test "$refname" = "$sha1" > ' > > +test_expect_success 'check-ref-format --branch @{-1} from non-repo' ' > + test_must_fail nongit git check-ref-format --branch @{-1} > +' Swapped test_must_fail and nongit to match existing tests. Junio C Hamano (3): check-ref-format --branch: do not expand @{...} outside repository check-ref-format --branch: strip refs/heads/ using skip_prefix check-ref-format doc: --branch validates and expands Documentation/git-check-ref-format.txt | 9 - builtin/check-ref-format.c | 6 -- sha1_name.c| 5 - t/t1402-check-ref-format.sh| 16 4 files changed, 32 insertions(+), 4 deletions(-)
Re: [PATCH] check-ref-format: require a repository for --branch
Jonathan Niederwrites: > And in that spirit, I think the patch you replied with aims to go in > the right direction, by providing the core functionality when in a > repository while avoiding breaking such a script outside of one > (though I do not understand it fully yet). Given that, is it safe for me to ignore this earlier one > For what it's worth, I don't agree with this repurposing of > "check-ref-format --branch" at all. as reacting to the patch without reading what it does? >>(e.g. a wrapper to "git >> clone" that wants to verify the name it is going to give to the "-b" >> option), and a check desired in such a context is different from >> (and is stricter than) feeding refs/heads/$name to the same command >> without the "--branch" option. > > Can you say more about this example? E.g. why is this hypothetical > wrapper unable to rely on "git clone -b"'s own error handling? If I have to guess what you meant, perhaps the Porcelain wanted to diagnose bad parameter that would be rejected _before_ letting clone spend cycles and possibly network bandwidth? But this was my way of rephrasing an earlier example you used while objecting to Peff's change For example, if you have a script with an $opt_branch variable that defaults to "master", it may do resolved_branch=$(git check-ref-format --branch "$opt_branch") even though it is in a mode that not going to have to use $resolved_branch and it is not running from a repository. so my answer to the question in the message I am directly responding to would be "You tell me." ;-) > --symbolic-full-name seems like a good fit. Do you remember why > check-ref-format was introduced instead? It really serves two purposes, and at this point, I do not think it really matters why it also does the @{-1} expansion as well as name validation. 604e0cb5 ("Documentation: describe check-ref-format --branch", 2009-10-12) happened 8 years ago, and since then it has been advertised long enough as if the 80% primary purpose of "c-r-f --branch" were to expand @{-1} to a branch name; even though the text hints that it also does the usual checks, by definition validation of the result of expanding @{-1} ought to succeed; after all that was the branch we _were_ on ;-).
Re: [PATCH] check-ref-format: require a repository for --branch
Junio C Hamanowrites: >> I don't think there is any need to prepare it upon my 4d03f955, >> though. I'd think it could simply replace it. > > Yeah, it ended up that way, it seems. Still it needs a bit of doc > updates to balance the description. So here is what I have now on 'pu'. Clearly not a 2.15 material yet. -- >8 -- Subject: [PATCH] check-ref-format: --branch cannot grok @{-1} outside a repository "git check-ref-format --branch $name" feature was originally introduced (and was advertised) as a way for scripts to take any end-user supplied string (like "master", "@{-1}" etc.) and see if that is usable when Git expects to see a branch name, and also obtain the concrete branch name that the at-mark magic expands to. When the user asks to interpret a branch name like "@{-1}", we have to dig the answer out of the HEAD reflog. We can obviously only do that if we have a repository, and indeed, running it outside a repository causes us to hit a BUG(). Let's disable the "expand @{-n}" half of the feature when it is run outside a repository, but keep the feature to check the syntax of a proposed branch name, as "git check-ref-format --branch $name" can be stricter than "git check-ref-format refs/heads/$name", and Porcelain scripts need to have a way to check a given name against the stricter rule. Helped-by: Jeff King Signed-off-by: Junio C Hamano --- Documentation/git-check-ref-format.txt | 9 - builtin/check-ref-format.c | 15 --- cache.h| 14 ++ sha1_name.c| 22 +++--- strbuf.h | 6 ++ t/t1402-check-ref-format.sh| 12 6 files changed, 71 insertions(+), 7 deletions(-) diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index 92777cef25..cf0a0b7df2 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -77,7 +77,14 @@ reference name expressions (see linkgit:gitrevisions[7]): . at-open-brace `@{` is used as a notation to access a reflog entry. -With the `--branch` option, it expands the ``previous branch syntax'' +With the `--branch` option, the command takes a name and checks if +it can be used as a valid branch name (e.g. when creating a new +branch). The rule `git check-ref-format --branch $name` implements +may be stricter than what `git check-ref-format refs/heads/$name` +says (e.g. a dash may appear at the beginning of a ref component, +but it is explicitly forbidden at the beginning of a branch name). +When run with `--branch` option in a repository, the input is first +expanded for the ``previous branch syntax'' `@{-n}`. For example, `@{-1}` is a way to refer the last branch you were on. This option should be used by porcelains to accept this syntax anywhere a branch name is expected, so they can act as if you diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index eac499450f..4e62852089 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -38,13 +38,22 @@ static char *collapse_slashes(const char *refname) static int check_ref_format_branch(const char *arg) { + int nongit, malformed; struct strbuf sb = STRBUF_INIT; - int nongit; + const char *name = arg; setup_git_directory_gently(); - if (strbuf_check_branch_ref(, arg)) + + if (!nongit) + malformed = (strbuf_check_branch_ref(, arg) || +!skip_prefix(sb.buf, "refs/heads/", )); + else + malformed = check_branch_ref_format(arg); + + if (malformed) die("'%s' is not a valid branch name", arg); - printf("%s\n", sb.buf + 11); + printf("%s\n", name); + strbuf_release(); return 0; } diff --git a/cache.h b/cache.h index 52b91f5b64..3815925122 100644 --- a/cache.h +++ b/cache.h @@ -1444,6 +1444,20 @@ extern int parse_oid_hex(const char *hex, struct object_id *oid, const char **en #define INTERPRET_BRANCH_HEAD (1<<2) extern int interpret_branch_name(const char *str, int len, struct strbuf *, unsigned allowed); + +/* + * NEEDSWORK: declare strbuf_branchname() and strbuf_check_branch_ref() + * here, not in strbuf.h + */ + +/* + * Check if a 'name' is suitable to be used as a branch name; this can + * be and is stricter than what check_refname_format() returns for a + * string that is a concatenation of "name" after "refs/heads/"; a + * name that begins with "-" is not allowed, for example. + */ +extern int check_branch_ref_format(const char *name); + extern int get_oid_mb(const char *str, struct object_id *oid); extern int validate_headref(const char *ref); diff --git a/sha1_name.c b/sha1_name.c index 5e2ec37b65..c95080258f 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1319,15
Re: [PATCH] check-ref-format: require a repository for --branch
Hi, Junio C Hamano wrote: > Things like @{-1} would not make any sense when the command is run > outside a repository, and the documentation is quite clear that it > is the primary reason why we added "--branch" option to the command, > i.e. > > With the `--branch` option, it expands the ``previous branch syntax'' > `@{-n}`. For example, `@{-1}` is a way to refer the last branch you > were on. This option should be used by porcelains to accept this > syntax anywhere a branch name is expected, so they can act as if you > typed the branch name. > > So I am tempted to take this patch to make sure that we won't gain > more people who abuse the command outside a repository. That seems very sensible on its face. My only worry is that a script that can be run both inside and outside a repository and does branch=$(git check-ref-format --branch "$user_supplied_branch_arg") currently works with user_supplied_branch_arg='master' and would stop working. If we have reason to believe that no such scripts exist, then this would be a good way to go, but I don't believe we can count on that. And in that spirit, I think the patch you replied with aims to go in the right direction, by providing the core functionality when in a repository while avoiding breaking such a script outside of one (though I do not understand it fully yet). > Having said that, there may still be a use case where a Porcelain > script wants a way to see if a $name it has is appropriate as a > branch name before it has a repository This seems like a different goal than "git check-ref-format --branch" was originally designed to fulfill (even though it fits well with the check-ref-format name and coincides with --branch behavior when in a repository). I think it's fine for us not to fulfill it. >(e.g. a wrapper to "git > clone" that wants to verify the name it is going to give to the "-b" > option), and a check desired in such a context is different from > (and is stricter than) feeding refs/heads/$name to the same command > without the "--branch" option. Can you say more about this example? E.g. why is this hypothetical wrapper unable to rely on "git clone -b"'s own error handling? > So I think the right endgame in the longer term is: > > - Find (or add if it doesn't exist) a way to recommend to Porcelain >scripts to use to expand an end-user generated string, and to map >it to a branch name (it may be "rev-parse --symbolic-full-name >$name"; I dunno). --symbolic-full-name seems like a good fit. Do you remember why check-ref-format was introduced instead? Was it just a matter of implementation simplicity, since --symbolic-full-name can handle a broader class of revision specifications like --remotes? The commit message to v1.6.3-rc0~29^2~4 (give Porcelain a way to grok branch shorthand, 2009-03-21) is appropriately apologetic but doesn't give more clues. > - Keep check-ref-format as (or revert it to be) a tool to "check". >This would involve split strbuf_check_branch_ref() into two: Without an example of where this tool would be used, if we consider "check-ref-format --branch" to be a mistake then I'd rather deprecate it with a goal of removing it completely. Ok, time to look in more detail. Thanks for your thoughtfulness, Jonathan
Re: [PATCH] check-ref-format: require a repository for --branch
On Tue, Oct 17, 2017 at 11:40:17AM +0900, Junio C Hamano wrote: > Kevin Daudtwrites: > > >> + setup_git_directory_gently(); > >> + > >> + if (!nongit) > >> + malformed = (strbuf_check_branch_ref(, arg) || > >> + !skip_prefix(sb.buf, "refs/heads/", )); > >> + else > >> + malformed = check_branch_ref_format(arg); > >> + > > > > Would it make sense to swap the logic and get rid of the double > > negative (!nongit)? > > I am trying to follow the pattern "handle the normal case that have > been supported forever first, and then handle new exception next", > so that it is easier to see that there is no behaviour change in the > normal case, so I do not think it makes it easier to see to swap the > if/else cases. Ok, thanks for your reasoning, makes sense. > > > >> + if (malformed) > >>die("'%s' is not a valid branch name", arg); > >> - printf("%s\n", sb.buf + 11); > >> + printf("%s\n", name); > >> + strbuf_release(); > >>return 0; > >> } > >>
Re: [PATCH] check-ref-format: require a repository for --branch
Jeff Kingwrites: > On Tue, Oct 17, 2017 at 10:22:31AM +0900, Junio C Hamano wrote: > >> > I like the state this puts us in, but there's one catch: we're >> > completely changing the meaning of "check-ref-format --branch", aren't >> > we? >> > >> > It is going from "this is how you resolve @{-1}" to "this is how you >> > check the validity of a potential branch name". Do we need to pick a >> > different name, and/or have a deprecation period? >> ... >> At least that is what I wanted to happen in the patch. > > Ah, OK, I did not read carefully enough then. I think that would be OK, > and probably close to what Jonathan was asking for. > > It leaves unresolved the fact that the resolving feature does not belong > in check-ref-format in the first place, but we can just accept that as a > historical wart. Yup, I actually was in favor of removing that and making it a "purely checking validity" feature, but given that it has been advertised in the documentation since 604e0cb5 ("Documentation: describe check-ref-format --branch", 2009-10-12), it is a bit too late to tell users that rev-parse is the right/kosher thing to do. > I don't think there is any need to prepare it upon my 4d03f955, > though. I'd think it could simply replace it. Yeah, it ended up that way, it seems. Still it needs a bit of doc updates to balance the description. Right now we stress on @{-n} resolution too much. Perhaps something like this? Documentation/git-check-ref-format.txt | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index 92777cef25..cf0a0b7df2 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -77,7 +77,14 @@ reference name expressions (see linkgit:gitrevisions[7]): . at-open-brace `@{` is used as a notation to access a reflog entry. -With the `--branch` option, it expands the ``previous branch syntax'' +With the `--branch` option, the command takes a name and checks if +it can be used as a valid branch name (e.g. when creating a new +branch). The rule `git check-ref-format --branch $name` implements +may be stricter than what `git check-ref-format refs/heads/$name` +says (e.g. a dash may appear at the beginning of a ref component, +but it is explicitly forbidden at the beginning of a branch name). +When run with `--branch` option in a repository, the input is first +expanded for the ``previous branch syntax'' `@{-n}`. For example, `@{-1}` is a way to refer the last branch you were on. This option should be used by porcelains to accept this syntax anywhere a branch name is expected, so they can act as if you
Re: [PATCH] check-ref-format: require a repository for --branch
On Tue, Oct 17, 2017 at 10:22:31AM +0900, Junio C Hamano wrote: > > I like the state this puts us in, but there's one catch: we're > > completely changing the meaning of "check-ref-format --branch", aren't > > we? > > > > It is going from "this is how you resolve @{-1}" to "this is how you > > check the validity of a potential branch name". Do we need to pick a > > different name, and/or have a deprecation period? > > That was not my intention. When used in a repository, it behaves > exactly the same as before, including @{-1} resolution part. And by > using strbuf_check_branch_ref(), it has always been checking the > validity of a potential branch name, even though it wasn't > advertised as such. The documentation needs to be updated, I would > think. > > When used outside a repository, @{-1} would not have worked anyway, > and @{-1} continues not to work, but the part that checks the > validity should continue to work. > > At least that is what I wanted to happen in the patch. Ah, OK, I did not read carefully enough then. I think that would be OK, and probably close to what Jonathan was asking for. It leaves unresolved the fact that the resolving feature does not belong in check-ref-format in the first place, but we can just accept that as a historical wart. I don't think there is any need to prepare it upon my 4d03f955, though. I'd think it could simply replace it. -Peff
Re: [PATCH] check-ref-format: require a repository for --branch
Kevin Daudtwrites: >> +setup_git_directory_gently(); >> + >> +if (!nongit) >> +malformed = (strbuf_check_branch_ref(, arg) || >> + !skip_prefix(sb.buf, "refs/heads/", )); >> +else >> +malformed = check_branch_ref_format(arg); >> + > > Would it make sense to swap the logic and get rid of the double > negative (!nongit)? I am trying to follow the pattern "handle the normal case that have been supported forever first, and then handle new exception next", so that it is easier to see that there is no behaviour change in the normal case, so I do not think it makes it easier to see to swap the if/else cases. > >> +if (malformed) >> die("'%s' is not a valid branch name", arg); >> -printf("%s\n", sb.buf + 11); >> +printf("%s\n", name); >> +strbuf_release(); >> return 0; >> } >>
Re: [PATCH] check-ref-format: require a repository for --branch
On Mon, Oct 16, 2017 at 07:45:46PM +0900, Junio C Hamano wrote: > Junio C Hamanowrites: > > [..] > > diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c > index 1e5f9835f0..4e62852089 100644 > --- a/builtin/check-ref-format.c > +++ b/builtin/check-ref-format.c > @@ -38,12 +38,22 @@ static char *collapse_slashes(const char *refname) > > static int check_ref_format_branch(const char *arg) > { > + int nongit, malformed; > struct strbuf sb = STRBUF_INIT; > + const char *name = arg; > > - setup_git_directory(); > - if (strbuf_check_branch_ref(, arg)) > + setup_git_directory_gently(); > + > + if (!nongit) > + malformed = (strbuf_check_branch_ref(, arg) || > + !skip_prefix(sb.buf, "refs/heads/", )); > + else > + malformed = check_branch_ref_format(arg); > + Would it make sense to swap the logic and get rid of the double negative (!nongit)? > + if (malformed) > die("'%s' is not a valid branch name", arg); > - printf("%s\n", sb.buf + 11); > + printf("%s\n", name); > + strbuf_release(); > return 0; > } >
Re: [PATCH] check-ref-format: require a repository for --branch
Jeff Kingwrites: > On Mon, Oct 16, 2017 at 07:45:46PM +0900, Junio C Hamano wrote: > >> > So I think the right endgame in the longer term is: >> > ... >> >> Here is to illustrate what I mean in a patch form. It resurrects >> the gentle setup, and uses a purely textual format check when we are >> outside the repository, while bypassing the @{magic} interpolation >> codepath that requires us to be in a repository. When we are in a >> repository, we operate the same way as before. > > I like the state this puts us in, but there's one catch: we're > completely changing the meaning of "check-ref-format --branch", aren't > we? > > It is going from "this is how you resolve @{-1}" to "this is how you > check the validity of a potential branch name". Do we need to pick a > different name, and/or have a deprecation period? That was not my intention. When used in a repository, it behaves exactly the same as before, including @{-1} resolution part. And by using strbuf_check_branch_ref(), it has always been checking the validity of a potential branch name, even though it wasn't advertised as such. The documentation needs to be updated, I would think. When used outside a repository, @{-1} would not have worked anyway, and @{-1} continues not to work, but the part that checks the validity should continue to work. At least that is what I wanted to happen in the patch.
Re: [PATCH] check-ref-format: require a repository for --branch
Jeff King wrote: > On Mon, Oct 16, 2017 at 07:45:46PM +0900, Junio C Hamano wrote: >> Here is to illustrate what I mean in a patch form. It resurrects >> the gentle setup, and uses a purely textual format check when we are >> outside the repository, while bypassing the @{magic} interpolation >> codepath that requires us to be in a repository. When we are in a >> repository, we operate the same way as before. > > I like the state this puts us in, but there's one catch: we're > completely changing the meaning of "check-ref-format --branch", aren't > we? > > It is going from "this is how you resolve @{-1}" to "this is how you > check the validity of a potential branch name". Do we need to pick a > different name, and/or have a deprecation period? Sorry to take so long on picking this up. I'll try to make an alternate patch today. For what it's worth, I don't agree with this repurposing of "check-ref-format --branch" at all. The old command already existed. No one asked for the new command. At most, we could get rid of the old command after a deprecation period. I don't understand at all why it's worth the confusion of changing its meaning. Thanks, Jonathan
Re: [PATCH] check-ref-format: require a repository for --branch
On Mon, Oct 16, 2017 at 07:45:46PM +0900, Junio C Hamano wrote: > > So I think the right endgame in the longer term is: > > ... > > Here is to illustrate what I mean in a patch form. It resurrects > the gentle setup, and uses a purely textual format check when we are > outside the repository, while bypassing the @{magic} interpolation > codepath that requires us to be in a repository. When we are in a > repository, we operate the same way as before. I like the state this puts us in, but there's one catch: we're completely changing the meaning of "check-ref-format --branch", aren't we? It is going from "this is how you resolve @{-1}" to "this is how you check the validity of a potential branch name". Do we need to pick a different name, and/or have a deprecation period? -Peff
Re: [PATCH] check-ref-format: require a repository for --branch
On Mon, Oct 16, 2017 at 03:44:08PM +0900, Junio C Hamano wrote: > I threw this topic in stalled category, hoping that one or the other > opinion eventually turns out to be more prevalent, but it didn't > seem to have happened X-<. I think it's sufficiently obscure that nobody really cares. I admit that _I_ don't actually care myself. We should fix the BUG(), obviously, but between the two I could live with it either way. Mostly I didn't want to go to the work to write the patch for the direction that I didn't think was right, and was hoping Jonathan would if he felt strongly about it. > So I think the right endgame in the longer term is: I won't quote the rest of your message because I agree with it completely, in terms of the endgame we'd like to see. I'll address a few specific comments on your followup patch. -Peff
Re: [PATCH] check-ref-format: require a repository for --branch
Junio C Hamanowrites: > Having said that, there may still be a use case where a Porcelain > script wants a way to see if a $name it has is appropriate as a > branch name before it has a repository (e.g. a wrapper to "git > clone" that wants to verify the name it is going to give to the "-b" > option), and a check desired in such a context is different from > (and is stricter than) feeding refs/heads/$name to the same command > without the "--branch" option. > > So I think the right endgame in the longer term is: > ... Here is to illustrate what I mean in a patch form. It resurrects the gentle setup, and uses a purely textual format check when we are outside the repository, while bypassing the @{magic} interpolation codepath that requires us to be in a repository. When we are in a repository, we operate the same way as before. Designed to be applied directly on top of 4d03f955 ("check-ref-format: require a repository for --branch", 2017-07-14), so it is missing the "'HEAD' is not a good branch name" I showed a few days ago. builtin/check-ref-format.c | 16 +--- cache.h | 14 ++ sha1_name.c | 22 +++--- strbuf.h| 6 ++ t/t1402-check-ref-format.sh | 10 +- 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index 1e5f9835f0..4e62852089 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -38,12 +38,22 @@ static char *collapse_slashes(const char *refname) static int check_ref_format_branch(const char *arg) { + int nongit, malformed; struct strbuf sb = STRBUF_INIT; + const char *name = arg; - setup_git_directory(); - if (strbuf_check_branch_ref(, arg)) + setup_git_directory_gently(); + + if (!nongit) + malformed = (strbuf_check_branch_ref(, arg) || +!skip_prefix(sb.buf, "refs/heads/", )); + else + malformed = check_branch_ref_format(arg); + + if (malformed) die("'%s' is not a valid branch name", arg); - printf("%s\n", sb.buf + 11); + printf("%s\n", name); + strbuf_release(); return 0; } diff --git a/cache.h b/cache.h index 52b91f5b64..3815925122 100644 --- a/cache.h +++ b/cache.h @@ -1444,6 +1444,20 @@ extern int parse_oid_hex(const char *hex, struct object_id *oid, const char **en #define INTERPRET_BRANCH_HEAD (1<<2) extern int interpret_branch_name(const char *str, int len, struct strbuf *, unsigned allowed); + +/* + * NEEDSWORK: declare strbuf_branchname() and strbuf_check_branch_ref() + * here, not in strbuf.h + */ + +/* + * Check if a 'name' is suitable to be used as a branch name; this can + * be and is stricter than what check_refname_format() returns for a + * string that is a concatenation of "name" after "refs/heads/"; a + * name that begins with "-" is not allowed, for example. + */ +extern int check_branch_ref_format(const char *name); + extern int get_oid_mb(const char *str, struct object_id *oid); extern int validate_headref(const char *ref); diff --git a/sha1_name.c b/sha1_name.c index 5e2ec37b65..c95080258f 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1319,15 +1319,31 @@ void strbuf_branchname(struct strbuf *sb, const char *name, unsigned allowed) strbuf_add(sb, name + used, len - used); } -int strbuf_check_branch_ref(struct strbuf *sb, const char *name) +static int strbuf_check_branch_ref_format(struct strbuf *sb) { - strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL); - if (name[0] == '-') + if (*sb->buf == '-') return -1; strbuf_splice(sb, 0, 0, "refs/heads/", 11); return check_refname_format(sb->buf, 0); } +int check_branch_ref_format(const char *name) +{ + struct strbuf sb = STRBUF_INIT; + int result; + + strbuf_addstr(, name); + result = strbuf_check_branch_ref_format(); + strbuf_release(); + return result; +} + +int strbuf_check_branch_ref(struct strbuf *sb, const char *name) +{ + strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL); + return strbuf_check_branch_ref_format(sb); +} + /* * This is like "get_sha1_basic()", except it allows "sha1 expressions", * notably "xyz^" for "parent of xyz" diff --git a/strbuf.h b/strbuf.h index d785258649..3da95685b2 100644 --- a/strbuf.h +++ b/strbuf.h @@ -568,6 +568,12 @@ static inline void strbuf_complete_line(struct strbuf *sb) strbuf_complete(sb, '\n'); } +/* + * NEEDSWORK: the following two functions should not be in this file; + * these are about refnames, and should be declared next to + * interpret_branch_name() in cache.h + */ + /* * Copy "name" to "sb", expanding any special @-marks as handled by * interpret_branch_name(). The result is a non-qualified branch name diff --git
Re: [PATCH] check-ref-format: require a repository for --branch
Jeff Kingwrites: > On Mon, Jul 17, 2017 at 10:27:09AM -0700, Jonathan Nieder wrote: >> ... >> I don't think it's right. Today I can do >> >> $ cd /tmp >> $ git check-ref-format --branch master >> master >> >> You might wonder why I'd ever do such a thing. But that's what "git >> check-ref-format --branch" is for --- it is for taking a >> argument and turning it into a branch name. For example, if you have >> a script with an $opt_branch variable that defaults to "master", it >> may do >> >> resolved_branch=$(git check-ref-format --branch "$opt_branch") >> >> even though it is in a mode that not going to have to use >> $resolved_branch and it is not running from a repository. > > I'm not sure I buy that. What does "turning it into a branch name" even > mean when you are not in a repository? Clearly @{-1} must fail. And > everything else is just going to output the exact input you provided. > So any script calling "check-ref-format --branch" outside of a repo > would be better off not calling it at all. I threw this topic in stalled category, hoping that one or the other opinion eventually turns out to be more prevalent, but it didn't seem to have happened X-<. Things like @{-1} would not make any sense when the command is run outside a repository, and the documentation is quite clear that it is the primary reason why we added "--branch" option to the command, i.e. With the `--branch` option, it expands the ``previous branch syntax'' `@{-n}`. For example, `@{-1}` is a way to refer the last branch you were on. This option should be used by porcelains to accept this syntax anywhere a branch name is expected, so they can act as if you typed the branch name. So I am tempted to take this patch to make sure that we won't gain more people who abuse the command outside a repository. Having said that, there may still be a use case where a Porcelain script wants a way to see if a $name it has is appropriate as a branch name before it has a repository (e.g. a wrapper to "git clone" that wants to verify the name it is going to give to the "-b" option), and a check desired in such a context is different from (and is stricter than) feeding refs/heads/$name to the same command without the "--branch" option. So I think the right endgame in the longer term is: - Find (or add if it doesn't exist) a way to recommend to Porcelain scripts to use to expand an end-user generated string, and to map it to a branch name (it may be "rev-parse --symbolic-full-name $name"; I dunno). - Keep check-ref-format as (or revert it to be) a tool to "check". This would involve split strbuf_check_branch_ref() into two: - one that does not do the @{-1} thing and is used ONLY for format validity check (including rejecting a name that begins with a dash, which is OK for a random ref but not acceptable as a branch name); - the other that does @{-1} thing before doing the above. and then making the code call the former, not the latter. The end result would be that check-ref-format becomes textual check only, and can be usable (agian) outside repository, with or without "--branch". As the current code does not allow us do that yet, I think it is safer to forbid use of --branch outside the repository for now, purely as a bugfix. [Footnote] *1* In a sense, @{-1} is not something the scripts need to check its validity of---it is the branch you came from, so by definition it must be with a good name. What the scripts want is instead see what the branch actually is, which is not what "check-ref-format" is about. a31dca03 ("check-ref-format --branch: give Porcelain a way to grok branch shorthand", 2009-03-21) says: The command may not be the best place to add this new feature, but $ git check-ref-format --branch "@{-1}" allows Porcelains to figure out what branch you were on before the last branch switching.
Re: [PATCH] check-ref-format: require a repository for --branch
Jeff Kingwrites: > I _do_ think it's a misfeature to put it in check-ref-format. It should > be part of rev-parse. Which admittedly is a kitchen sink, but this kind > of resolving is one of the main things it should be doing. And in fact > you can already do: > > git rev-parse --symbolic-full-name @{-1} > > But I stopped short of suggesting we remove the feature entirely. It > would obviously require a deprecation period. Yeah, I realize that "nonsense" was a bit too strong. I do agree that it was a misfeature to place in "check" ref-format, though. Thanks.
Re: [PATCH] check-ref-format: require a repository for --branch
On Thu, Aug 17, 2017 at 02:30:53PM -0700, Junio C Hamano wrote: > > I'm not sure I buy that. What does "turning it into a branch name" even > > mean when you are not in a repository? Clearly @{-1} must fail. And > > everything else is just going to output the exact input you provided. > > This "just going to output the exact input" is not entirely correct; > there is just one use case for it. > > "git check-ref-format --branch a..b" would fail with a helpful error > message, while the command run with "a.b" would tell you the name is > safe. Well, yes. It's checking the syntax, as well. But you don't need --branch for that. > Use of 'check-ref-format --branch "@{-1}"' *IS* a nonsense, whether > it is inside or outside a repository; it is OK to fail it outside a > repository and I would say it is even OK to fail it inside a > repository. After all "check-ref-format" is about checking if the > string is a sensible name to use. > > I think calling interpret_branch_name() in the codepath is a mistake > and we should instead report if "refs/heads/@{-1}" literally is a > valid refname we could create instead. I don't think it's nonsense. It's the reason the feature was added in the first place. See your own a31dca0393 (check-ref-format --branch: give Porcelain a way to grok branch shorthand, 2009-03-21). Without that interpretation, it does nothing that you could not equally well do as: git check-ref-format refs/heads/$name I _do_ think it's a misfeature to put it in check-ref-format. It should be part of rev-parse. Which admittedly is a kitchen sink, but this kind of resolving is one of the main things it should be doing. And in fact you can already do: git rev-parse --symbolic-full-name @{-1} But I stopped short of suggesting we remove the feature entirely. It would obviously require a deprecation period. -Peff
Re: [PATCH] check-ref-format: require a repository for --branch
Jeff Kingwrites: > On Mon, Jul 17, 2017 at 10:27:09AM -0700, Jonathan Nieder wrote: > >> > --- a/t/t1402-check-ref-format.sh >> > +++ b/t/t1402-check-ref-format.sh >> > @@ -161,6 +161,10 @@ test_expect_success 'check-ref-format --branch from >> > subdir' ' >> >test "$refname" = "$sha1" >> > ' >> > >> > +test_expect_success 'check-ref-format --branch from non-repo' ' >> > + test_must_fail nongit git check-ref-format --branch @{-1} >> > +' >> > + >> > valid_ref_normalized() { >> >prereq= >> >case $1 in >> >> I don't think it's right. Today I can do >> >> $ cd /tmp >> $ git check-ref-format --branch master >> master >> >> You might wonder why I'd ever do such a thing. But that's what "git >> check-ref-format --branch" is for --- it is for taking a >> argument and turning it into a branch name. For example, if you have >> a script with an $opt_branch variable that defaults to "master", it >> may do >> >> resolved_branch=$(git check-ref-format --branch "$opt_branch") >> >> even though it is in a mode that not going to have to use >> $resolved_branch and it is not running from a repository. > > I'm not sure I buy that. What does "turning it into a branch name" even > mean when you are not in a repository? Clearly @{-1} must fail. And > everything else is just going to output the exact input you provided. This "just going to output the exact input" is not entirely correct; there is just one use case for it. "git check-ref-format --branch a..b" would fail with a helpful error message, while the command run with "a.b" would tell you the name is safe. Use of 'check-ref-format --branch "@{-1}"' *IS* a nonsense, whether it is inside or outside a repository; it is OK to fail it outside a repository and I would say it is even OK to fail it inside a repository. After all "check-ref-format" is about checking if the string is a sensible name to use. I think calling interpret_branch_name() in the codepath is a mistake and we should instead report if "refs/heads/@{-1}" literally is a valid refname we could create instead.
Re: [PATCH] check-ref-format: require a repository for --branch
On Mon, Jul 17, 2017 at 11:18:43PM +0200, Marko Kungla wrote: > I guess that should only be about that it should not hit a (BUG). > In my case in the example I gave I scan trough the directories to > check repository status one of the tasks make use of check-ref-format. > Since it may hit directory which is not a git repository it should not > expose error (BUG) right. Right. The BUG should definitely be corrected. Between what Jonathan is suggesting and my patch, either would be fine for the case you described originally ("--branch @{-1}" would always fail in a non-repo). -Peff
Re: [PATCH] check-ref-format: require a repository for --branch
On Mon, Jul 17, 2017 at 10:27:09AM -0700, Jonathan Nieder wrote: > > --- a/t/t1402-check-ref-format.sh > > +++ b/t/t1402-check-ref-format.sh > > @@ -161,6 +161,10 @@ test_expect_success 'check-ref-format --branch from > > subdir' ' > > test "$refname" = "$sha1" > > ' > > > > +test_expect_success 'check-ref-format --branch from non-repo' ' > > + test_must_fail nongit git check-ref-format --branch @{-1} > > +' > > + > > valid_ref_normalized() { > > prereq= > > case $1 in > > I don't think it's right. Today I can do > > $ cd /tmp > $ git check-ref-format --branch master > master > > You might wonder why I'd ever do such a thing. But that's what "git > check-ref-format --branch" is for --- it is for taking a > argument and turning it into a branch name. For example, if you have > a script with an $opt_branch variable that defaults to "master", it > may do > > resolved_branch=$(git check-ref-format --branch "$opt_branch") > > even though it is in a mode that not going to have to use > $resolved_branch and it is not running from a repository. I'm not sure I buy that. What does "turning it into a branch name" even mean when you are not in a repository? Clearly @{-1} must fail. And everything else is just going to output the exact input you provided. So any script calling "check-ref-format --branch" outside of a repo would be better off not calling it at all. At best it does nothing, and at worst it's going to give a confusing error when $opt_branch is something like "@{-1}". A more compelling argument along these lines is something like: Accepting --branch outside of a repo is pointless, but it's something we've historically accepted. To avoid breaking existing scripts (even if they are doing something pointless), we'll continue to allow it. I'm not sure I buy _that_ line of reasoning either, but it at least makes sense to me (I just think it isn't worth the complexity of trying to audit the innards of interpret_branch_name()). -Peff
Re: [PATCH] check-ref-format: require a repository for --branch
I guess that should only be about that it should not hit a (BUG). In my case in the example I gave I scan trough the directories to check repository status one of the tasks make use of check-ref-format. Since it may hit directory which is not a git repository it should not expose error (BUG) right. On Mon, Jul 17, 2017 at 7:27 PM, Jonathan Niederwrote: > Hi, > > Jeff King wrote: >> On Fri, Jul 14, 2017 at 02:03:13PM -0400, Jeff King wrote: > >>> So I think the patch below is probably the right direction. >> >> And here it is with a real commit message, if this is what we want to >> do. > [...] >> --- a/t/t1402-check-ref-format.sh >> +++ b/t/t1402-check-ref-format.sh >> @@ -161,6 +161,10 @@ test_expect_success 'check-ref-format --branch from >> subdir' ' >> test "$refname" = "$sha1" >> ' >> >> +test_expect_success 'check-ref-format --branch from non-repo' ' >> + test_must_fail nongit git check-ref-format --branch @{-1} >> +' >> + >> valid_ref_normalized() { >> prereq= >> case $1 in > > I don't think it's right. Today I can do > > $ cd /tmp > $ git check-ref-format --branch master > master > > You might wonder why I'd ever do such a thing. But that's what "git > check-ref-format --branch" is for --- it is for taking a > argument and turning it into a branch name. For example, if you have > a script with an $opt_branch variable that defaults to "master", it > may do > > resolved_branch=$(git check-ref-format --branch "$opt_branch") > > even though it is in a mode that not going to have to use > $resolved_branch and it is not running from a repository. > > Thanks and hope that helps, > Jonathan -- Mail:marko.kun...@gmail.com Phone: +31 (0) 6 2546 0117
Re: [PATCH] check-ref-format: require a repository for --branch
Hi, Jeff King wrote: > On Fri, Jul 14, 2017 at 02:03:13PM -0400, Jeff King wrote: >> So I think the patch below is probably the right direction. > > And here it is with a real commit message, if this is what we want to > do. [...] > --- a/t/t1402-check-ref-format.sh > +++ b/t/t1402-check-ref-format.sh > @@ -161,6 +161,10 @@ test_expect_success 'check-ref-format --branch from > subdir' ' > test "$refname" = "$sha1" > ' > > +test_expect_success 'check-ref-format --branch from non-repo' ' > + test_must_fail nongit git check-ref-format --branch @{-1} > +' > + > valid_ref_normalized() { > prereq= > case $1 in I don't think it's right. Today I can do $ cd /tmp $ git check-ref-format --branch master master You might wonder why I'd ever do such a thing. But that's what "git check-ref-format --branch" is for --- it is for taking a argument and turning it into a branch name. For example, if you have a script with an $opt_branch variable that defaults to "master", it may do resolved_branch=$(git check-ref-format --branch "$opt_branch") even though it is in a mode that not going to have to use $resolved_branch and it is not running from a repository. Thanks and hope that helps, Jonathan