threads / patch / 54256

patch, 4 partssample hooks: become hash agnostic

Subject: [PATCH 0/4] sample hooks: become hash agnostic

## tl;dr

23 messages between Sep 18, 2020 and Sep 23, 2020. Diffs are folded; open one to read it.

replies: 22people: 7as markdown or json

Denton Liu· Sep 18, 2020, 11:19 UTC · lore

There are currently two hooks that have hardcoded 40 zeros as the null OID and, thus, are not hash-agnostic. Rewrite these to use the newly introduced `git rev-parse --null-oid` so that they become hash-agnostic.

Denton Liu (4):
  hooks--pre-push.sample: prefer $() for command substitution
  builtin/rev-parse: learn --null-oid
  hooks--pre-push.sample: use hash-agnostic null OID
  hooks--update.sample: use hash-agnostic null OID
 Documentation/git-rev-parse.txt  | 4 ++++
 builtin/rev-parse.c              | 4 ++++
 t/t1500-rev-parse.sh             | 6 ++++++
 templates/hooks--pre-push.sample | 8 ++++----
 templates/hooks--update.sample   | 2 +-
 5 files changed, 19 insertions(+), 5 deletions(-)
-- 
2.28.0.618.gf4bc123cb7
Denton Liu· Sep 18, 2020, 11:19 UTC · re: Denton Liu · lore

[PATCH 2/4] builtin/rev-parse: learn --null-oid

When a user needed the null OID for scripting purposes, it used to be very easy: hardcode 40 zeros. However, since Git started supporting SHA-256, this assumption became false which may break some scripts. Allow users to fix their broken scripts by providing users with a hash-agnostic method of obtaining the null OID.

Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 Documentation/git-rev-parse.txt | 4 ++++
 builtin/rev-parse.c             | 4 ++++
 t/t1500-rev-parse.sh            | 6 ++++++
 3 files changed, 14 insertions(+)
Show changes to 3 files +14 −0

Documentation/git-rev-parse.txt, builtin/rev-parse.c, t/t1500-rev-parse.sh

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 19b12b6d43..b370d425d7 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -285,6 +285,10 @@ print a message to stderr and exit with nonzero status.
 Other Options
 ~~~~~~~~~~~~~
 
+--null-oid::
+	Print the null OID (the OID containing all zeros). This OID is
+	used to represent a non-existent object.
+
 --since=datestring::
 --after=datestring::
 	Parse the date string, and output the corresponding
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index ed200c8af1..4e4ca99775 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -910,6 +910,10 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 				}
 				continue;
 			}
+			if (!strcmp(arg, "--null-oid")) {
+				puts(oid_to_hex(&null_oid));
+				continue;
+			}
 			if (skip_prefix(arg, "--since=", &arg)) {
 				show_datestring("--max-age=", arg);
 				continue;
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 408b97d5af..8c1bd543ef 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -185,4 +185,10 @@ test_expect_success 'showing the superproject correctly' '
 	test_cmp expect out
 '
 
+test_expect_success 'rev-parse --null-oid' '
+	echo "$(test_oid zero)" >expect &&
+	git rev-parse --null-oid >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
2.28.0.618.gf4bc123cb7
Taylor Blau· Sep 18, 2020, 14:11 UTC · re: Denton Liu · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

Hi Denton,
On Fri, Sep 18, 2020 at 04:19:03AM -0700, Denton Liu wrote:
Show 5 quoted lines
> When a user needed the null OID for scripting purposes, it used to be
> very easy: hardcode 40 zeros. However, since Git started supporting
> SHA-256, this assumption became false which may break some scripts.
> Allow users to fix their broken scripts by providing users with a
> hash-agnostic method of obtaining the null OID.

I have not been very involved in the hash transition, so please take my comments with a grain of salt (and if they are misplaced, feel free to ignore them).

This '--null-oid' thing makes me wonder exactly what it does. Yours gives a type-less object back, but what about scripts that want the OID of the empty blob or tree?

Would having something like '--null-oid[=<type>]' be useful for them? On the one hand, it seems like a thing that would be useful, but on the other, those aren't *the* null OID when 'type' is 'blob' or 'tree'. A more appropriate name in that case might be '--empty-oid=tree'.

So, that's an argument that '--null-oid' and '--empty-oid[=<type>]' should be two distinct things. I think I like that best. Do you have any thoughts about it?

Thanks, Taylor

Taylor Blau· Sep 18, 2020, 14:16 UTC · re: Taylor Blau · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On Fri, Sep 18, 2020 at 10:11:25AM -0400, Taylor Blau wrote:
Show 12 quoted lines
> Hi Denton,
>
> On Fri, Sep 18, 2020 at 04:19:03AM -0700, Denton Liu wrote:
> > When a user needed the null OID for scripting purposes, it used to be
> > very easy: hardcode 40 zeros. However, since Git started supporting
> > SHA-256, this assumption became false which may break some scripts.
> > Allow users to fix their broken scripts by providing users with a
> > hash-agnostic method of obtaining the null OID.
>
> I have not been very involved in the hash transition, so please take my
> comments with a grain of salt (and if they are misplaced, feel free to
> ignore them).

Same disclaimer above applies here, too ;-). There are a number of spots in the test suite that reference 'ZERO_OID', as well as OIDs for the empty tree and blob. Maybe the definition of those could be updated to use any new flags you do/don't introduce?

I'd be just as happy if that were to occur in a different series than this, since I don't want to hold you up by adding a bunch of new things to your list.

In either case, I think '--zero-oid' makes more sense than '--null-oid' (and it matches the tests that are already written). The pair '--zero-oid' and '--empty-oid=<type>' make sense to me.

Thanks, Taylor

Junio C Hamano· Sep 18, 2020, 18:16 UTC · re: Taylor Blau · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

Taylor Blau <me@ttaylorr.com> writes:
> In either case, I think '--zero-oid' makes more sense than '--null-oid'
> (and it matches the tests that are already written). The pair
> '--zero-oid' and '--empty-oid=<type>' make sense to me.

I am not sure rev-parse should even know about "empty-oid". An end user or a script who wants to learn what name an empty blob has can and should ask "git hash-object -t blob --stdin </dev/null".

I can buy --zero-oid might be handy, but don't see a pressing need if it is merely to support our test suite and sample hooks. Instead, something like

  ZERO_OID=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
should suffice, no?
Take this as a mild indifference, not as a strong rejection.
Taylor Blau· Sep 18, 2020, 18:21 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On Fri, Sep 18, 2020 at 11:16:54AM -0700, Junio C Hamano wrote:
Show 9 quoted lines
> Taylor Blau <me@ttaylorr.com> writes:
>
> > In either case, I think '--zero-oid' makes more sense than '--null-oid'
> > (and it matches the tests that are already written). The pair
> > '--zero-oid' and '--empty-oid=<type>' make sense to me.
>
> I am not sure rev-parse should even know about "empty-oid".  An end
> user or a script who wants to learn what name an empty blob has can
> and should ask "git hash-object -t blob --stdin </dev/null".

Yeah, my uncertainty ("should this be '--empty-oid' or '--null-oid'?") is probably a good indication (to me, at least) that the option shouldn't even exist.

Show 7 quoted lines
> I can buy --zero-oid might be handy, but don't see a pressing need
> if it is merely to support our test suite and sample hooks.
> Instead, something like
>
>   ZERO_OID=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
>
> should suffice, no?
Absolutely.
> Take this as a mild indifference, not as a strong rejection.

For what it's worth, I'm probably as indifferent as you. I would be slightly less so if there was evidence of lots of out-of-tree scripts that care about these special OIDs, but I haven't looked too far.

Thanks, Taylor

brian m. carlson· Sep 18, 2020, 21:26 UTC · re: Taylor Blau · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On 2020-09-18 at 14:11:25, Taylor Blau wrote:
Show 25 quoted lines
> Hi Denton,
> 
> On Fri, Sep 18, 2020 at 04:19:03AM -0700, Denton Liu wrote:
> > When a user needed the null OID for scripting purposes, it used to be
> > very easy: hardcode 40 zeros. However, since Git started supporting
> > SHA-256, this assumption became false which may break some scripts.
> > Allow users to fix their broken scripts by providing users with a
> > hash-agnostic method of obtaining the null OID.
> 
> I have not been very involved in the hash transition, so please take my
> comments with a grain of salt (and if they are misplaced, feel free to
> ignore them).
> 
> This '--null-oid' thing makes me wonder exactly what it does. Yours
> gives a type-less object back, but what about scripts that want the OID
> of the empty blob or tree?
> 
> Would having something like '--null-oid[=<type>]' be useful for them? On
> the one hand, it seems like a thing that would be useful, but on the
> other, those aren't *the* null OID when 'type' is 'blob' or 'tree'. A
> more appropriate name in that case might be '--empty-oid=tree'.
> 
> So, that's an argument that '--null-oid' and '--empty-oid[=<type>]'
> should be two distinct things. I think I like that best. Do you have any
> thoughts about it?

So I definitely want to distinguish between the null (all-zeros) OID and the OID of an empty object, and I think using "null" and "empty" are fine.

What I typically do when I write shell scripts, and which may obviate the need for this patch is turn this:

  [ "$oid" = 0000000000000000000000000000000000000000 ]
into this:
  echo "$oid" | grep -qsE '^0+$'

This is slightly less efficient, but it's also backwards compatible with older Git version assuming you have a POSIX grep.

If you still want this option, then that's fine, but please make --null-oid take the same arguments as --show-object-format (and default to the same value). Git will soon learn about writing SHA-1 while storing in SHA-256, and it makes everyone's life better if we can plan for the future by making it understand these options now.

I'm not sure we need an empty tree and empty blob object, because it's pretty easy to write these:

  git hash-object -t tree /dev/null
  git hash-object -t blob /dev/null
That's what I've done in some of the transition code at least.
-- 
brian m. carlson: Houston, Texas, US
Chris Torek· Sep 20, 2020, 04:25 UTC · re: brian m. carlson · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On Fri, Sep 18, 2020 at 2:34 PM brian m. carlson <sandals@crustytoothpaste.net> wrote:

> So I definitely want to distinguish between the null (all-zeros) OID and
> the OID of an empty object, and I think using "null" and "empty" are
> fine.
(I like this myself)
Show 11 quoted lines
> What I typically do when I write shell scripts, and which may obviate
> the need for this patch is turn this:
>
>   [ "$oid" = 0000000000000000000000000000000000000000 ]
>
> into this:
>
>   echo "$oid" | grep -qsE '^0+$'
>
> This is slightly less efficient, but it's also backwards compatible
> with older Git version assuming you have a POSIX grep.

Note that a lot of `grep`s do not have `-q` and/or `-s` so the portable variant of this is `grep '^0+$' >/dev/null` (you only need the `2>&1` part if you're concerned about bad input files or an error on a pipe or something).

Show 7 quoted lines
> I'm not sure we need an empty tree and empty blob object, because it's
> pretty easy to write these:
>
>   git hash-object -t tree /dev/null
>   git hash-object -t blob /dev/null
>
> That's what I've done in some of the transition code at least.

That's what's recommended in my 2012 stackoverflow Q&A, too. The use of `/dev/null` directly here is perhaps unsatisfactory on old Windows systems, though...?

Chris
brian m. carlson· Sep 20, 2020, 18:58 UTC · re: Chris Torek · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On 2020-09-20 at 04:25:33, Chris Torek wrote:
Show 18 quoted lines
> On Fri, Sep 18, 2020 at 2:34 PM brian m. carlson
> <sandals@crustytoothpaste.net> wrote:
> > What I typically do when I write shell scripts, and which may obviate
> > the need for this patch is turn this:
> >
> >   [ "$oid" = 0000000000000000000000000000000000000000 ]
> >
> > into this:
> >
> >   echo "$oid" | grep -qsE '^0+$'
> >
> > This is slightly less efficient, but it's also backwards compatible
> > with older Git version assuming you have a POSIX grep.
> 
> Note that a lot of `grep`s do not have `-q` and/or `-s` so the
> portable variant of this is `grep '^0+$' >/dev/null` (you only need
> the `2>&1` part if you're concerned about bad input files or
> an error on a pipe or something).

If we're looking for best compatibility here, then using egrep and /dev/null is best, I agree. I personally use the POSIX version because it's been that way since at least 2001 and I don't have a problem with requiring compliance with a 19-year-old standard. But for Git, we should definitely do whatever we do in the testsuite if we use this approach, since presumably that works everywhere.

As Andreas pointed out, there are ways to avoid the external process that we could stuff in a shell function. I'm not picky.

Show 11 quoted lines
> > I'm not sure we need an empty tree and empty blob object, because it's
> > pretty easy to write these:
> >
> >   git hash-object -t tree /dev/null
> >   git hash-object -t blob /dev/null
> >
> > That's what I've done in some of the transition code at least.
> 
> That's what's recommended in my 2012 stackoverflow Q&A, too.
> The use of `/dev/null` directly here is perhaps unsatisfactory on
> old Windows systems, though...?

I believe all modern versions of Git for Windows provide /dev/null via the shell, since it's required for a lot of things to work, so I'm not worried about this case. It is definitely good to think about Windows, though.

-- 
brian m. carlson: Houston, Texas, US
Taylor Blau· Sep 20, 2020, 15:35 UTC · re: brian m. carlson · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On Fri, Sep 18, 2020 at 09:26:09PM +0000, brian m. carlson wrote:
Show 11 quoted lines
> What I typically do when I write shell scripts, and which may obviate
> the need for this patch is turn this:
>
>   [ "$oid" = 0000000000000000000000000000000000000000 ]
>
> into this:
>
>   echo "$oid" | grep -qsE '^0+$'
>
> This is slightly less efficient, but it's also backwards compatible
> with older Git version assuming you have a POSIX grep.

Yeah, I mostly just have no idea how common this is in the wild. If many scripts care about the null OID, then a '--null-oid' makes sense to me. But if it's only a few, then it does not.

Show 5 quoted lines
> If you still want this option, then that's fine, but please make
> --null-oid take the same arguments as --show-object-format (and default
> to the same value).  Git will soon learn about writing SHA-1 while
> storing in SHA-256, and it makes everyone's life better if we can plan
> for the future by making it understand these options now.
Agreed.
Show 7 quoted lines
> I'm not sure we need an empty tree and empty blob object, because it's
> pretty easy to write these:
>
>   git hash-object -t tree /dev/null
>   git hash-object -t blob /dev/null
>
> That's what I've done in some of the transition code at least.

I could go either way. This for some reason seems more common to me, so I wouldn't mind making it easier for callers, but I don't care so much because what you already wrote is easy enough as-is.

> --
> brian m. carlson: Houston, Texas, US

Thanks, Taylor

Andreas Schwab· Sep 20, 2020, 16:03 UTC · re: brian m. carlson · lore

Re: [PATCH 2/4] builtin/rev-parse: learn --null-oid

On Sep 18 2020, brian m. carlson wrote:
Show 11 quoted lines
> What I typically do when I write shell scripts, and which may obviate
> the need for this patch is turn this:
>
>   [ "$oid" = 0000000000000000000000000000000000000000 ]
>
> into this:
>
>   echo "$oid" | grep -qsE '^0+$'
>
> This is slightly less efficient, but it's also backwards compatible
> with older Git version assuming you have a POSIX grep.
You can also use
  case $oid in *[1-9a-f]*) ... ;; *) ... ;; esac
which doesn't need an external process.
Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."
Denton Liu· Sep 18, 2020, 11:19 UTC · re: Denton Liu · lore

[PATCH 1/4] hooks--pre-push.sample: prefer $() for command substitution

The preferred form for a command substitution is $() over ``. Use this form for the command substitution in the sample hook.

Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 templates/hooks--pre-push.sample | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Show changes to templates/hooks--pre-push.sample +1 −1
diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
index 6187dbf439..64b5707553 100755
--- a/templates/hooks--pre-push.sample
+++ b/templates/hooks--pre-push.sample
@@ -41,7 +41,7 @@ do
 		fi
 
 		# Check for WIP commit
-		commit=`git rev-list -n 1 --grep '^WIP' "$range"`
+		commit="$(git rev-list -n 1 --grep '^WIP' "$range")"
 		if [ -n "$commit" ]
 		then
 			echo >&2 "Found WIP commit in $local_ref, not pushing"
-- 
2.28.0.618.gf4bc123cb7
Eric Sunshine· Sep 18, 2020, 16:57 UTC · re: Denton Liu · lore

Re: [PATCH 1/4] hooks--pre-push.sample: prefer $() for command substitution

On Fri, Sep 18, 2020 at 7:19 AM Denton Liu <liu.denton@gmail.com> wrote:
Show 9 quoted lines
> The preferred form for a command substitution is $() over ``. Use this
> form for the command substitution in the sample hook.
>
> Signed-off-by: Denton Liu <liu.denton@gmail.com>
> ---
> diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
> @@ -41,7 +41,7 @@ do
> -               commit=`git rev-list -n 1 --grep '^WIP' "$range"`
> +               commit="$(git rev-list -n 1 --grep '^WIP' "$range")"
The double quotes around $(...) are unnecessary and just add noise.
>                 if [ -n "$commit" ]

If you're looking for style fixes, then this would be another candidate (using 'test' instead of '[').

Denton Liu· Sep 18, 2020, 11:19 UTC · re: Denton Liu · lore

[PATCH 3/4] hooks--pre-push.sample: use hash-agnostic null OID

The pre-push sample hook has the null OID hardcoded as 40 zeros. However, with the introduction of SHA-256 support, this assumption no longer holds true. Replace the hardcoded $z40 with a call to `git rev-parse --null-oid` so the sample hook becomes hash-agnostic.

Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 templates/hooks--pre-push.sample | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
Show changes to templates/hooks--pre-push.sample +3 −3
diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
index 64b5707553..b3bc5276bf 100755
--- a/templates/hooks--pre-push.sample
+++ b/templates/hooks--pre-push.sample
@@ -22,16 +22,16 @@
 remote="$1"
 url="$2"
 
-z40=0000000000000000000000000000000000000000
+null_oid="$(git rev-parse --null-oid)"
 
 while read local_ref local_sha remote_ref remote_sha
 do
-	if [ "$local_sha" = $z40 ]
+	if [ "$local_sha" = "$null_oid" ]
 	then
 		# Handle delete
 		:
 	else
-		if [ "$remote_sha" = $z40 ]
+		if [ "$remote_sha" = "$null_oid" ]
 		then
 			# New branch, examine all commits
 			range="$local_sha"
-- 
2.28.0.618.gf4bc123cb7
Eric Sunshine· Sep 18, 2020, 17:06 UTC · re: Denton Liu · lore

Re: [PATCH 3/4] hooks--pre-push.sample: use hash-agnostic null OID

On Fri, Sep 18, 2020 at 7:19 AM Denton Liu <liu.denton@gmail.com> wrote:
Show 15 quoted lines
> The pre-push sample hook has the null OID hardcoded as 40 zeros.
> However, with the introduction of SHA-256 support, this assumption no
> longer holds true. Replace the hardcoded $z40 with a call to
> `git rev-parse --null-oid` so the sample hook becomes hash-agnostic.
>
> Signed-off-by: Denton Liu <liu.denton@gmail.com>
> ---
> diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
> @@ -22,16 +22,16 @@
> +null_oid="$(git rev-parse --null-oid)"
>
>  while read local_ref local_sha remote_ref remote_sha
>  do
> -       if [ "$local_sha" = $z40 ]
> +       if [ "$local_sha" = "$null_oid" ]

Seeing this made me wonder if, rather than introducing a --null-oid option (or --zero-oid per Taylor's suggestion), it would make more sense to answer the question more directly. For instance:

    if test rev-parse --is-null-oid "$local_sha"
    then
        ...

Or, if following Taylor's suggestion, you would add --is-zero-oid, --is-empty-blob, --is-empty-tree.

On the other hand, as this is used in a loop, being able to ask for the null (or zero) OID just once before the loop does make sense, so maybe the --is-*-oid forms are less practical.

By the way, if you're cleaning up the sample scripts to make them hash-agnostic, then it would also make sense to s/sha/oid/.

Denton Liu· Sep 18, 2020, 11:19 UTC · re: Denton Liu · lore

[PATCH 4/4] hooks--update.sample: use hash-agnostic null OID

The update sample hook has the null OID hardcoded as 40 zeros. However, with the introduction of SHA-256 support, this assumption no longer holds true. Replace the hardcoded $z40 with a call to `git rev-parse --null-oid` so the sample hook becomes hash-agnostic.

Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 templates/hooks--update.sample | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Show changes to templates/hooks--update.sample +1 −1
diff --git a/templates/hooks--update.sample b/templates/hooks--update.sample
index 5014c4b31c..5316362af5 100755
--- a/templates/hooks--update.sample
+++ b/templates/hooks--update.sample
@@ -60,7 +60,7 @@ esac
 
 # --- Check types
 # if $newrev is 0000...0000, it's a commit to delete a ref.
-zero="0000000000000000000000000000000000000000"
+zero="$(git rev-list --null-oid)"
 if [ "$newrev" = "$zero" ]; then
 	newrev_type=delete
 else
-- 
2.28.0.618.gf4bc123cb7
Eric Sunshine· Sep 18, 2020, 17:08 UTC · re: Denton Liu · lore

Re: [PATCH 4/4] hooks--update.sample: use hash-agnostic null OID

On Fri, Sep 18, 2020 at 7:19 AM Denton Liu <liu.denton@gmail.com> wrote:
Show 11 quoted lines
> The update sample hook has the null OID hardcoded as 40 zeros. However,
> with the introduction of SHA-256 support, this assumption no longer
> holds true. Replace the hardcoded $z40 with a call to
> `git rev-parse --null-oid` so the sample hook becomes hash-agnostic.
>
> Signed-off-by: Denton Liu <liu.denton@gmail.com>
> ---
> diff --git a/templates/hooks--update.sample b/templates/hooks--update.sample
> @@ -60,7 +60,7 @@ esac
> -zero="0000000000000000000000000000000000000000"
> +zero="$(git rev-list --null-oid)"
Definitely want a s/rev-list/rev-parse/ here.
brian m. carlson· Sep 18, 2020, 21:35 UTC · re: Denton Liu · lore

Re: [PATCH 0/4] sample hooks: become hash agnostic

On 2020-09-18 at 11:19:01, Denton Liu wrote:
> There are currently two hooks that have hardcoded 40 zeros as the null
> OID and, thus, are not hash-agnostic. Rewrite these to use the newly
> introduced `git rev-parse --null-oid` so that they become hash-agnostic.

I've looked over this series and I fully agree that the scripts should be hash agnostic. I offered an alternative which you may find simpler and more appealing (or not), but with the constraint that if we add --null-oid, it should accept an argument, I have no comments beyond what other folks have added.

-- 
brian m. carlson: Houston, Texas, US
Denton Liu· Sep 23, 2020, 09:38 UTC · re: Denton Liu · lore

[PATCH v2 0/3] sample hooks: become hash agnostic

There are currently two hooks that have hardcoded 40 zeros as the null OID and, thus, are not hash-agnostic. Rewrite these to get the zero OID using

	git hash-object --stdin </dev/null | tr '[0-9a-f]' '0'
so that the zero OID is hash-agnostic.

This was initially done by introducing `git rev-parse --null-oid` to get the zero OID but that seems like overkill. From a cursory search of Github, the only instances of the zero OID being used come from clones of the git.git repository (tests and sample hooks). Since we don't want to introduce an option that no one will use, don't go this route and just do the easiest thing.

If in the future, someone decides that `git rev-parse --zero-oid` is useful, they can also adjust these hooks accordingly.

Changes since v1:
* Don't implement `git rev-parse --null-oid`
Denton Liu (3):
  hooks--pre-push.sample: modernize script
  hooks--pre-push.sample: use hash-agnostic zero OID
  hooks--update.sample: use hash-agnostic zero OID
 templates/hooks--pre-push.sample | 18 +++++++++---------
 templates/hooks--update.sample   |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)
Range-diff against v1:
1:  ed1ade7328 < -:  ---------- hooks--pre-push.sample: prefer $() for command substitution
2:  004f2e4c92 < -:  ---------- builtin/rev-parse: learn --null-oid
3:  9d6c2951ab < -:  ---------- hooks--pre-push.sample: use hash-agnostic null OID
-:  ---------- > 1:  95dd0b19ba hooks--pre-push.sample: modernize script
-:  ---------- > 2:  afb460d9fd hooks--pre-push.sample: use hash-agnostic zero OID
4:  42d2829889 ! 3:  784135549f hooks--update.sample: use hash-agnostic null OID
    @@ Metadata
     Author: Denton Liu <liu.denton@gmail.com>
     
      ## Commit message ##
    -    hooks--update.sample: use hash-agnostic null OID
    +    hooks--update.sample: use hash-agnostic zero OID
     
    -    The update sample hook has the null OID hardcoded as 40 zeros. However,
    +    The update sample hook has the zero OID hardcoded as 40 zeros. However,
         with the introduction of SHA-256 support, this assumption no longer
         holds true. Replace the hardcoded $z40 with a call to
    -    `git rev-parse --null-oid` so the sample hook becomes hash-agnostic.
    +
    +            git hash-object --stdin </dev/null | tr '[0-9a-f]' '0'
    +
    +    so the sample hook becomes hash-agnostic.
     
      ## templates/hooks--update.sample ##
     @@ templates/hooks--update.sample: esac
    @@ templates/hooks--update.sample: esac
      # --- Check types
      # if $newrev is 0000...0000, it's a commit to delete a ref.
     -zero="0000000000000000000000000000000000000000"
    -+zero="$(git rev-list --null-oid)"
    ++zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
      if [ "$newrev" = "$zero" ]; then
      	newrev_type=delete
      else
-- 
2.28.0.760.g8d73e04208
Denton Liu· Sep 23, 2020, 09:38 UTC · re: Denton Liu · lore

[PATCH v2 1/3] hooks--pre-push.sample: modernize script

The preferred form for a command substitution is $() over ``. Use this form for the command substitution in the sample hook.

The preferred form for conditional tests is to use `test` over []. Replace [] with `test`.

Finally, replace all instances of "sha" with "oid".
Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 templates/hooks--pre-push.sample | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
Show changes to templates/hooks--pre-push.sample +8 −8
diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
index 6187dbf439..d0f30190ac 100755
--- a/templates/hooks--pre-push.sample
+++ b/templates/hooks--pre-push.sample
@@ -14,7 +14,7 @@
 # Information about the commits which are being pushed is supplied as lines to
 # the standard input in the form:
 #
-#   <local ref> <local sha1> <remote ref> <remote sha1>
+#   <local ref> <local oid> <remote ref> <remote oid>
 #
 # This sample shows how to prevent push of commits where the log message starts
 # with "WIP" (work in progress).
@@ -24,25 +24,25 @@ url="$2"
 
 z40=0000000000000000000000000000000000000000
 
-while read local_ref local_sha remote_ref remote_sha
+while read local_ref local_oid remote_ref remote_oid
 do
-	if [ "$local_sha" = $z40 ]
+	if test "$local_oid" = $z40
 	then
 		# Handle delete
 		:
 	else
-		if [ "$remote_sha" = $z40 ]
+		if test "$remote_oid" = $z40
 		then
 			# New branch, examine all commits
-			range="$local_sha"
+			range="$local_oid"
 		else
 			# Update to existing branch, examine new commits
-			range="$remote_sha..$local_sha"
+			range="$remote_oid..$local_oid"
 		fi
 
 		# Check for WIP commit
-		commit=`git rev-list -n 1 --grep '^WIP' "$range"`
-		if [ -n "$commit" ]
+		commit=$(git rev-list -n 1 --grep '^WIP' "$range")
+		if test -n "$commit"
 		then
 			echo >&2 "Found WIP commit in $local_ref, not pushing"
 			exit 1
-- 
2.28.0.760.g8d73e04208
Denton Liu· Sep 23, 2020, 09:38 UTC · re: Denton Liu · lore

[PATCH v2 3/3] hooks--update.sample: use hash-agnostic zero OID

The update sample hook has the zero OID hardcoded as 40 zeros. However, with the introduction of SHA-256 support, this assumption no longer holds true. Replace the hardcoded $z40 with a call to

	git hash-object --stdin </dev/null | tr '[0-9a-f]' '0'
so the sample hook becomes hash-agnostic.
Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 templates/hooks--update.sample | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Show changes to templates/hooks--update.sample +1 −1
diff --git a/templates/hooks--update.sample b/templates/hooks--update.sample
index 5014c4b31c..c4d426bc6e 100755
--- a/templates/hooks--update.sample
+++ b/templates/hooks--update.sample
@@ -60,7 +60,7 @@ esac
 
 # --- Check types
 # if $newrev is 0000...0000, it's a commit to delete a ref.
-zero="0000000000000000000000000000000000000000"
+zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
 if [ "$newrev" = "$zero" ]; then
 	newrev_type=delete
 else
-- 
2.28.0.760.g8d73e04208
Denton Liu· Sep 23, 2020, 09:38 UTC · re: Denton Liu · lore

[PATCH v2 2/3] hooks--pre-push.sample: use hash-agnostic zero OID

The pre-push sample hook has the zero OID hardcoded as 40 zeros. However, with the introduction of SHA-256 support, this assumption no longer holds true. Replace the hardcoded $z40 with a call to

	git hash-object --stdin </dev/null | tr '[0-9a-f]' '0'
so the sample hook becomes hash-agnostic.
Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
 templates/hooks--pre-push.sample | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
Show changes to templates/hooks--pre-push.sample +3 −3
diff --git a/templates/hooks--pre-push.sample b/templates/hooks--pre-push.sample
index d0f30190ac..4ce688d32b 100755
--- a/templates/hooks--pre-push.sample
+++ b/templates/hooks--pre-push.sample
@@ -22,16 +22,16 @@
 remote="$1"
 url="$2"
 
-z40=0000000000000000000000000000000000000000
+zero=$(git hash-object --stdin </dev/null | tr '[0-9a-f]' '0')
 
 while read local_ref local_oid remote_ref remote_oid
 do
-	if test "$local_oid" = $z40
+	if test "$local_oid" = "$zero"
 	then
 		# Handle delete
 		:
 	else
-		if test "$remote_oid" = $z40
+		if test "$remote_oid" = "$zero"
 		then
 			# New branch, examine all commits
 			range="$local_oid"
-- 
2.28.0.760.g8d73e04208
Junio C Hamano· Sep 23, 2020, 16:34 UTC · re: Denton Liu · lore

Re: [PATCH v2 0/3] sample hooks: become hash agnostic

Denton Liu <liu.denton@gmail.com> writes:
Show 12 quoted lines
> There are currently two hooks that have hardcoded 40 zeros as the null
> OID and, thus, are not hash-agnostic. Rewrite these to get the zero OID using
>
> 	git hash-object --stdin </dev/null | tr '[0-9a-f]' '0'
>
> so that the zero OID is hash-agnostic.
>
> This was initially done by introducing `git rev-parse --null-oid` to get the
> zero OID but that seems like overkill. From a cursory search of Github, the
> only instances of the zero OID being used come from clones of the git.git
> repository (tests and sample hooks). Since we don't want to introduce an option
> that no one will use, don't go this route and just do the easiest thing.
Patches 2&3/3 look quite sensible.

Patch 1/3 is a borderline Meh, as we do not need to force _our_ coding convention to the end-users, even though we do do so on ourselves. But let's take it to make things more consistent.

Thanks.

← back to recent threads