Merge branch 'mg/maint-tag-rfc1991'
authorJunio C Hamano <gitster@pobox.com>
Wed, 8 Dec 2010 19:24:13 +0000 (11:24 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 Dec 2010 19:24:13 +0000 (11:24 -0800)
* mg/maint-tag-rfc1991:
tag: recognize rfc1991 signatures
tag: factor out sig detection for tag display
tag: factor out sig detection for body edits
verify-tag: factor out signature detection
t/t7004-tag: test handling of rfc1991 signatures

1  2 
builtin/tag.c
builtin/verify-tag.c
t/t7004-tag.sh
diff --combined builtin/tag.c
index d1d7d8701db23dfa0db0fb3457f57826b7012d41,617a58f0583049716c7b73577ac6df0e132bebea..aa1f87d47a3e4bdaa2ca3711c9dfc495fc2247e0
@@@ -29,8 -29,6 +29,6 @@@ struct tag_filter 
        struct commit_list *with_commit;
  };
  
- #define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
  static int show_reference(const char *refname, const unsigned char *sha1,
                          int flag, void *cb_data)
  {
@@@ -70,9 -68,9 +68,9 @@@
                        return 0;
                }
                /* only take up to "lines" lines, and strip the signature */
+               size = parse_signature(buf, size);
                for (i = 0, sp += 2;
-                               i < filter->lines && sp < buf + size &&
-                               prefixcmp(sp, PGP_SIGNATURE "\n");
+                               i < filter->lines && sp < buf + size;
                                i++) {
                        if (i)
                                printf("\n    ");
@@@ -242,8 -240,7 +240,7 @@@ static void write_tag_body(int fd, cons
  {
        unsigned long size;
        enum object_type type;
-       char *buf, *sp, *eob;
-       size_t len;
+       char *buf, *sp;
  
        buf = read_sha1_file(sha1, &type, &size);
        if (!buf)
                return;
        }
        sp += 2; /* skip the 2 LFs */
-       eob = strstr(sp, "\n" PGP_SIGNATURE "\n");
-       if (eob)
-               len = eob - sp;
-       else
-               len = buf + size - sp;
-       write_or_die(fd, sp, len);
+       write_or_die(fd, sp, parse_signature(sp, buf + size - sp));
  
        free(buf);
  }
@@@ -390,7 -382,7 +382,7 @@@ int cmd_tag(int argc, const char **argv
                OPT_BOOLEAN('s', NULL, &sign, "annotated and GPG-signed tag"),
                OPT_STRING('u', NULL, &keyid, "key-id",
                                        "use another key to sign the tag"),
 -              OPT_BOOLEAN('f', "force", &force, "replace the tag if exists"),
 +              OPT__FORCE(&force, "replace the tag if exists"),
  
                OPT_GROUP("Tag listing options"),
                {
diff --combined builtin/verify-tag.c
index 8136dba7a1a43bf90cd213a30a7f1a57a1248ac3,86cac6d715dbc29b3586e84ea28f4083ddb2a1b8..313476604967bb2962350c82d45ffad04eab09e1
@@@ -17,13 -17,11 +17,11 @@@ static const char * const verify_tag_us
                NULL
  };
  
- #define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
  static int run_gpg_verify(const char *buf, unsigned long size, int verbose)
  {
        struct child_process gpg;
        const char *args_gpg[] = {"gpg", "--verify", "FILE", "-", NULL};
-       char path[PATH_MAX], *eol;
+       char path[PATH_MAX];
        size_t len;
        int fd, ret;
  
        close(fd);
  
        /* find the length without signature */
-       len = 0;
-       while (len < size && prefixcmp(buf + len, PGP_SIGNATURE)) {
-               eol = memchr(buf + len, '\n', size - len);
-               len += eol ? eol - (buf + len) + 1 : size - len;
-       }
+       len = parse_signature(buf, size);
        if (verbose)
                write_in_full(1, buf, len);
  
@@@ -93,7 -87,7 +87,7 @@@ int cmd_verify_tag(int argc, const cha
  {
        int i = 1, verbose = 0, had_error = 0;
        const struct option verify_tag_options[] = {
 -              OPT__VERBOSE(&verbose),
 +              OPT__VERBOSE(&verbose, "print tag contents"),
                OPT_END()
        };
  
diff --combined t/t7004-tag.sh
index f160af3ccc8714700218efcd3b38c216ff7bab43,6841c23c0a276934928aed65aef4a55cb55370e1..3e7baaf89f9bada46fc084e568544ce9df833594
@@@ -1030,6 -1030,72 +1030,72 @@@ test_expect_success GPG 
        test_cmp expect actual
  '
  
+ # usage with rfc1991 signatures
+ echo "rfc1991" > gpghome/gpg.conf
+ get_tag_header rfc1991-signed-tag $commit commit $time >expect
+ echo "RFC1991 signed tag" >>expect
+ echo '-----BEGIN PGP MESSAGE-----' >>expect
+ test_expect_success GPG \
+       'creating a signed tag with rfc1991' '
+       git tag -s -m "RFC1991 signed tag" rfc1991-signed-tag $commit &&
+       get_tag_msg rfc1991-signed-tag >actual &&
+       test_cmp expect actual
+ '
+ cat >fakeeditor <<'EOF'
+ #!/bin/sh
+ cp "$1" actual
+ EOF
+ chmod +x fakeeditor
+ test_expect_success GPG \
+       'reediting a signed tag body omits signature' '
+       echo "RFC1991 signed tag" >expect &&
+       GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&
+       test_cmp expect actual
+ '
+ test_expect_success GPG \
+       'verifying rfc1991 signature' '
+       git tag -v rfc1991-signed-tag
+ '
+ test_expect_success GPG \
+       'list tag with rfc1991 signature' '
+       echo "rfc1991-signed-tag RFC1991 signed tag" >expect &&
+       git tag -l -n1 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n2 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n999 rfc1991-signed-tag >actual &&
+       test_cmp expect actual
+ '
+ rm -f gpghome/gpg.conf
+ test_expect_success GPG \
+       'verifying rfc1991 signature without --rfc1991' '
+       git tag -v rfc1991-signed-tag
+ '
+ test_expect_success GPG \
+       'list tag with rfc1991 signature without --rfc1991' '
+       echo "rfc1991-signed-tag RFC1991 signed tag" >expect &&
+       git tag -l -n1 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n2 rfc1991-signed-tag >actual &&
+       test_cmp expect actual &&
+       git tag -l -n999 rfc1991-signed-tag >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success GPG \
+       'reediting a signed tag body omits signature' '
+       echo "RFC1991 signed tag" >expect &&
+       GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit &&
+       test_cmp expect actual
+ '
  # try to sign with bad user.signingkey
  git config user.signingkey BobTheMouse
  test_expect_success GPG \
@@@ -1051,23 -1117,13 +1117,23 @@@ test_expect_success 
  
  test_expect_success \
        'message in editor has initial comment' '
 -      GIT_EDITOR=cat git tag -a initial-comment > actual
 +      ! (GIT_EDITOR=cat git tag -a initial-comment > actual)
 +'
 +
 +test_expect_success \
 +      'message in editor has initial comment: first line' '
        # check the first line --- should be empty
 -      first=$(sed -e 1q <actual) &&
 -      test -z "$first" &&
 +      echo >first.expect &&
 +      sed -e 1q <actual >first.actual &&
 +      test_cmp first.expect first.actual
 +'
 +
 +test_expect_success \
 +      'message in editor has initial comment: remainder' '
        # remove commented lines from the remainder -- should be empty
 -      rest=$(sed -e 1d -e '/^#/d' <actual) &&
 -      test -z "$rest"
 +      >rest.expect
 +      sed -e 1d -e '/^#/d' <actual >rest.actual &&
 +      test_cmp rest.expect rest.actual
  '
  
  get_tag_header reuse $commit commit $time >expect
@@@ -1107,7 -1163,7 +1173,7 @@@ hash1=$(git rev-parse HEAD
  test_expect_success 'creating second commit and tag' '
        echo foo-2.0 >foo &&
        git add foo &&
 -      git commit -m second
 +      git commit -m second &&
        git tag v2.0
  '
  
  EOF
  
  test_expect_success 'checking that first commit is in all tags (hash)' "
 -      git tag -l --contains $hash1 v* >actual
 +      git tag -l --contains $hash1 v* >actual &&
        test_cmp expected actual
  "
  
  # other ways of specifying the commit
  test_expect_success 'checking that first commit is in all tags (tag)' "
 -      git tag -l --contains v1.0 v* >actual
 +      git tag -l --contains v1.0 v* >actual &&
        test_cmp expected actual
  "
  
  test_expect_success 'checking that first commit is in all tags (relative)' "
 -      git tag -l --contains HEAD~2 v* >actual
 +      git tag -l --contains HEAD~2 v* >actual &&
        test_cmp expected actual
  "
  
@@@ -1152,7 -1208,7 +1218,7 @@@ v2.
  EOF
  
  test_expect_success 'checking that second commit only has one tag' "
 -      git tag -l --contains $hash2 v* >actual
 +      git tag -l --contains $hash2 v* >actual &&
        test_cmp expected actual
  "
  
@@@ -1161,7 -1217,7 +1227,7 @@@ cat > expected <<EO
  EOF
  
  test_expect_success 'checking that third commit has no tags' "
 -      git tag -l --contains $hash3 v* >actual
 +      git tag -l --contains $hash3 v* >actual &&
        test_cmp expected actual
  "
  
@@@ -1171,7 -1227,7 +1237,7 @@@ test_expect_success 'creating simple br
        git branch stable v2.0 &&
          git checkout stable &&
        echo foo-3.0 > foo &&
 -      git commit foo -m fourth
 +      git commit foo -m fourth &&
        git tag v3.0
  '
  
@@@ -1182,7 -1238,7 +1248,7 @@@ v3.
  EOF
  
  test_expect_success 'checking that branch head only has one tag' "
 -      git tag -l --contains $hash4 v* >actual
 +      git tag -l --contains $hash4 v* >actual &&
        test_cmp expected actual
  "
  
@@@ -1196,7 -1252,7 +1262,7 @@@ v4.
  EOF
  
  test_expect_success 'checking that original branch head has one tag now' "
 -      git tag -l --contains $hash3 v* >actual
 +      git tag -l --contains $hash3 v* >actual &&
        test_cmp expected actual
  "
  
  EOF
  
  test_expect_success 'checking that initial commit is in all tags' "
 -      git tag -l --contains $hash1 v* >actual
 +      git tag -l --contains $hash1 v* >actual &&
        test_cmp expected actual
  "
  
  # mixing modes and options:
  
  test_expect_success 'mixing incompatibles modes and options is forbidden' '
 -      test_must_fail git tag -a
 -      test_must_fail git tag -l -v
 -      test_must_fail git tag -n 100
 -      test_must_fail git tag -l -m msg
 -      test_must_fail git tag -l -F some file
 +      test_must_fail git tag -a &&
 +      test_must_fail git tag -l -v &&
 +      test_must_fail git tag -n 100 &&
 +      test_must_fail git tag -l -m msg &&
 +      test_must_fail git tag -l -F some file &&
        test_must_fail git tag -v -s
  '