--- /dev/null
+From d64db36be81b970bfc9f9d7bae854819e267d6a0 Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ijackson@chiark.greenend.org.uk>
+Date: Fri, 4 Nov 2016 17:23:42 +0000
+Subject: [PATCH 1/5] check-ref-format: Refactor out check_one_ref_format
+
+We are going to want to reuse this. No functional change right now.
+
+It currently has a hidden memory leak if --normalize is used.
+
+Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
+---
+ builtin/check-ref-format.c | 26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
+index eac4994..4d56caa 100644
+--- a/builtin/check-ref-format.c
++++ b/builtin/check-ref-format.c
+@@ -48,12 +48,22 @@ static int check_ref_format_branch(const char *arg)
+ return 0;
+ }
+
++static int normalize = 0;
++static int flags = 0;
++
++static int check_one_ref_format(const char *refname)
++{
++ if (normalize)
++ refname = collapse_slashes(refname);
++ if (check_refname_format(refname, flags))
++ return 1;
++ if (normalize)
++ printf("%s\n", refname);
++}
++
+ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ {
+ int i;
+- int normalize = 0;
+- int flags = 0;
+- const char *refname;
+
+ if (argc == 2 && !strcmp(argv[1], "-h"))
+ usage(builtin_check_ref_format_usage);
+@@ -76,13 +86,5 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ if (! (i == argc - 1))
+ usage(builtin_check_ref_format_usage);
+
+- refname = argv[i];
+- if (normalize)
+- refname = collapse_slashes(refname);
+- if (check_refname_format(refname, flags))
+- return 1;
+- if (normalize)
+- printf("%s\n", refname);
+-
+- return 0;
++ return check_one_ref_format(argv[i]);
+ }
+--
+2.10.1
+
--- /dev/null
+From 3caa32b73e206378ad870276cc5feb73b6cf54bb Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ijackson@chiark.greenend.org.uk>
+Date: Fri, 4 Nov 2016 17:45:38 +0000
+Subject: [PATCH 2/5] check-ref-format: Refactor to make --branch code more
+ common
+
+We are going to want to permit other options with --branch.
+
+So, replace the special case with just an entry for --branch in the
+parser for ordinary options, and check for option compatibility at the
+end.
+
+No overall functional change.
+
+Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
+---
+ builtin/check-ref-format.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
+index 4d56caa..f12c19c 100644
+--- a/builtin/check-ref-format.c
++++ b/builtin/check-ref-format.c
+@@ -49,13 +49,19 @@ static int check_ref_format_branch(const char *arg)
+ }
+
+ static int normalize = 0;
++static int check_branch = 0;
+ static int flags = 0;
+
+ static int check_one_ref_format(const char *refname)
+ {
++ int got;
++
+ if (normalize)
+ refname = collapse_slashes(refname);
+- if (check_refname_format(refname, flags))
++ got = check_branch
++ ? check_ref_format_branch(refname)
++ : check_refname_format(refname, flags);
++ if (got)
+ return 1;
+ if (normalize)
+ printf("%s\n", refname);
+@@ -68,9 +74,6 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ if (argc == 2 && !strcmp(argv[1], "-h"))
+ usage(builtin_check_ref_format_usage);
+
+- if (argc == 3 && !strcmp(argv[1], "--branch"))
+- return check_ref_format_branch(argv[2]);
+-
+ for (i = 1; i < argc && argv[i][0] == '-'; i++) {
+ if (!strcmp(argv[i], "--normalize") || !strcmp(argv[i], "--print"))
+ normalize = 1;
+@@ -80,9 +83,15 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ flags &= ~REFNAME_ALLOW_ONELEVEL;
+ else if (!strcmp(argv[i], "--refspec-pattern"))
+ flags |= REFNAME_REFSPEC_PATTERN;
++ else if (!strcmp(argv[i], "--branch"))
++ check_branch = 1;
+ else
+ usage(builtin_check_ref_format_usage);
+ }
++
++ if (check_branch && (flags || normalize))
++ usage(builtin_check_ref_format_usage);
++
+ if (! (i == argc - 1))
+ usage(builtin_check_ref_format_usage);
+
+--
+2.10.1
+
--- /dev/null
+From 983c936a996dba2da91358be7e0b1e2a4481741a Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ijackson@chiark.greenend.org.uk>
+Date: Fri, 4 Nov 2016 17:26:18 +0000
+Subject: [PATCH 3/5] check-ref-format: Abolish leak of collapsed refname
+
+collapse_slashes always returns a value from xmallocz.
+
+Right now this leak is not very interesting, since we only call
+check_one_ref_format once.
+
+Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
+---
+ builtin/check-ref-format.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
+index f12c19c..020ebe8 100644
+--- a/builtin/check-ref-format.c
++++ b/builtin/check-ref-format.c
+@@ -63,8 +63,10 @@ static int check_one_ref_format(const char *refname)
+ : check_refname_format(refname, flags);
+ if (got)
+ return 1;
+- if (normalize)
++ if (normalize) {
+ printf("%s\n", refname);
++ free((void*)refname);
++ }
+ }
+
+ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+--
+2.10.1
+
--- /dev/null
+From 5f0a31143d8e1c3740e81ad948c8ae670a322dcc Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ijackson@chiark.greenend.org.uk>
+Date: Fri, 4 Nov 2016 17:40:49 +0000
+Subject: [PATCH 4/5] check-ref-format: New --report-errors option
+
+Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
+---
+ Documentation/git-check-ref-format.txt | 8 ++++++--
+ builtin/check-ref-format.c | 10 ++++++++--
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
+index 8611a99..e9a2657 100644
+--- a/Documentation/git-check-ref-format.txt
++++ b/Documentation/git-check-ref-format.txt
+@@ -8,10 +8,10 @@ git-check-ref-format - Ensures that a reference name is well formed
+ SYNOPSIS
+ --------
+ [verse]
+-'git check-ref-format' [--normalize]
++'git check-ref-format' [--report-errors] [--normalize]
+ [--[no-]allow-onelevel] [--refspec-pattern]
+ <refname>
+-'git check-ref-format' --branch <branchname-shorthand>
++'git check-ref-format' [--report-errors] --branch <branchname-shorthand>
+
+ DESCRIPTION
+ -----------
+@@ -105,6 +105,10 @@ OPTIONS
+ with a status of 0. (`--print` is a deprecated way to spell
+ `--normalize`.)
+
++--report-errors::
++ If any ref does not check OK, print a message to stderr.
++ (By default, git check-ref-format is silent.)
++
+
+ EXAMPLES
+ --------
+diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
+index 020ebe8..559d5c2 100644
+--- a/builtin/check-ref-format.c
++++ b/builtin/check-ref-format.c
+@@ -9,7 +9,7 @@
+
+ static const char builtin_check_ref_format_usage[] =
+ "git check-ref-format [--normalize] [<options>] <refname>\n"
+-" or: git check-ref-format --branch <branchname-shorthand>";
++" or: git check-ref-format [<options>] --branch <branchname-shorthand>";
+
+ /*
+ * Return a copy of refname but with leading slashes removed and runs
+@@ -51,6 +51,7 @@ static int check_ref_format_branch(const char *arg)
+ static int normalize = 0;
+ static int check_branch = 0;
+ static int flags = 0;
++static int report_errors = 0;
+
+ static int check_one_ref_format(const char *refname)
+ {
+@@ -61,8 +62,11 @@ static int check_one_ref_format(const char *refname)
+ got = check_branch
+ ? check_ref_format_branch(refname)
+ : check_refname_format(refname, flags);
+- if (got)
++ if (got) {
++ if (report_errors)
++ fprintf(stderr, "bad ref format: %s\n", refname);
+ return 1;
++ }
+ if (normalize) {
+ printf("%s\n", refname);
+ free((void*)refname);
+@@ -87,6 +91,8 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ flags |= REFNAME_REFSPEC_PATTERN;
+ else if (!strcmp(argv[i], "--branch"))
+ check_branch = 1;
++ else if (!strcmp(argv[i], "--report-errors"))
++ report_errors = 1;
+ else
+ usage(builtin_check_ref_format_usage);
+ }
+--
+2.10.1
+
--- /dev/null
+From f22917e0bd9347ed547e124738083d5b6889da0a Mon Sep 17 00:00:00 2001
+From: Ian Jackson <ijackson@chiark.greenend.org.uk>
+Date: Fri, 4 Nov 2016 17:41:15 +0000
+Subject: [PATCH 5/5] check-ref-format: New --stdin option
+
+Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
+---
+ Documentation/git-check-ref-format.txt | 10 ++++++++--
+ builtin/check-ref-format.c | 34 +++++++++++++++++++++++++++++++---
+ 2 files changed, 39 insertions(+), 5 deletions(-)
+
+diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt
+index e9a2657..5a213ce 100644
+--- a/Documentation/git-check-ref-format.txt
++++ b/Documentation/git-check-ref-format.txt
+@@ -10,8 +10,9 @@ SYNOPSIS
+ [verse]
+ 'git check-ref-format' [--report-errors] [--normalize]
+ [--[no-]allow-onelevel] [--refspec-pattern]
+- <refname>
+-'git check-ref-format' [--report-errors] --branch <branchname-shorthand>
++ <refname> | --stdin
++'git check-ref-format' [--report-errors] --branch
++ <branchname-shorthand> | --stdin
+
+ DESCRIPTION
+ -----------
+@@ -109,6 +110,11 @@ OPTIONS
+ If any ref does not check OK, print a message to stderr.
+ (By default, git check-ref-format is silent.)
+
++--stdin::
++ Instead of checking on ref supplied on the command line,
++ read refs, one per line, from stdin. The exit status is
++ 0 if all the refs were OK.
++
+
+ EXAMPLES
+ --------
+diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
+index 559d5c2..87f52fa 100644
+--- a/builtin/check-ref-format.c
++++ b/builtin/check-ref-format.c
+@@ -76,6 +76,7 @@ static int check_one_ref_format(const char *refname)
+ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ {
+ int i;
++ int use_stdin = 0;
+
+ if (argc == 2 && !strcmp(argv[1], "-h"))
+ usage(builtin_check_ref_format_usage);
+@@ -93,6 +94,8 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ check_branch = 1;
+ else if (!strcmp(argv[i], "--report-errors"))
+ report_errors = 1;
++ else if (!strcmp(argv[i], "--stdin"))
++ use_stdin = 1;
+ else
+ usage(builtin_check_ref_format_usage);
+ }
+@@ -100,8 +103,33 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
+ if (check_branch && (flags || normalize))
+ usage(builtin_check_ref_format_usage);
+
+- if (! (i == argc - 1))
+- usage(builtin_check_ref_format_usage);
++ if (!use_stdin) {
++ if (! (i == argc - 1))
++ usage(builtin_check_ref_format_usage);
++
++ return check_one_ref_format(argv[i]);
++ } else {
++ char buffer[2048];
++ int worst = 0;
+
+- return check_one_ref_format(argv[i]);
++ if (! (i == argc))
++ usage(builtin_check_ref_format_usage);
++
++ while (fgets(buffer, sizeof(buffer), stdin)) {
++ char *newline = strchr(buffer, '\n');
++ if (!newline) {
++ fprintf(stderr, "%s --stdin: missing final newline or line too long\n", *argv);
++ exit(127);
++ }
++ *newline = 0;
++ int got = check_one_ref_format(buffer);
++ if (got > worst)
++ worst = got;
++ }
++ if (!feof(stdin)) {
++ perror("reading from stdin");
++ exit(127);
++ }
++ return worst;
++ }
+ }
+--
+2.10.1
+
+++ /dev/null
-#!/bin/bash
-set -e
-set -o pipefail
-
-cpus='0 1'
-
-uid=`id -u`
-cd /var/run/user/$uid
-mkdir -p version-charset-test
-cd version-charset-test
-
-stunt=stunt$1
-rm -rf $stunt
-mkdir $stunt
-cd $stunt
-
-for cpu in $cpus; do
- mkdir c$cpu
- (cd c$cpu
- git init -q)
-done
-
-#exec 3<&0 </dev/null
-
-#git commit --allow-empty -m 'Test object'
-#head=`git rev-parse HEAD`
-
-#exec <&3 3<&-
-
-perl -we '
- use strict;
-
- our $file;
- our $count;
- our $batch=0;
- our $total=0;
- our @tasks;
-
- my @freecpus = qw('"$cpus"');
-
- print STDERR "check using cpus @freecpus\n";
-
- sub await_task () {
- my ($pid, $cpu, $oldbatch) = @{ shift @tasks };
- waitpid $pid, 0 == $pid or die $!;
- die "$oldbatch $?" if $?;
- unlink "b$oldbatch" or die "$oldbatch $!";
-# print STDERR "check completed $oldbatch [$pid] #$cpu\n";
- push @freecpus, $cpu;
- }
-
- sub complete_batch () {
- return unless $file;
-
- close $file or die $!;
-
-# print STDERR "check closing $batch ($count)\n";
-
- await_task unless @freecpus;
-
- my $cpu = shift @freecpus;
-
- my $pid = fork // die $!;
- if (!$pid) {
- close STDIN;
-# seek STDIN,0,1;
-# flush STDIN;
- open STDIN, "<", "b$batch" or die $batch;
- chdir "c$cpu" or die "$cpu $!";
- exec qw(eatmydata git update-ref --stdin);
- die $!;
- }
-# print STDERR "check spawned $batch ($count) [$pid] #$cpu\n";
- push @tasks, [ $pid, $cpu, $batch ];
- $batch++;
- $file = undef;
- $total += $count;
- $count = 0;
- }
-
- while (<>) {
-#print STDERR ">$_<\n";
- $file ||= new IO::File "b$batch", ">" or die $!;
- chomp;
- print $file "delete refs/tags/$_\n" or die $!;
- $count++ < 1000 or complete_batch;
- }
-#print STDERR "FOO\n";
- STDIN->error and die $!;
- complete_batch();
- await_task while @tasks;
- print STDERR "check exiting (total=$total)\n";
-'
./generate $cpu/$ncpus "$@" | \
../dpkg/src/dpkg --filter-valid-versions | \
./escape | \
- ./check $cpu
+ perl -pe 's#^#refs/tags/#' | \
+ ../git/git-check-ref-format --report-errors --stdin
echo >&2 "cpu $cpu ok"
) &
pids+=( $! )
done
+set +e
+ok=true
for pid in ${pids[*]}; do
- wait $pid
+ wait $pid || ok=false
done
+set -e
+
+$ok || echo >&2 'BAD'
+
+$ok
echo '*** OK EVERYTHING IS FINE ***'