Merge branch 'master' into mk/rename
authorJunio C Hamano <junkio@cox.net>
Thu, 10 Aug 2006 21:17:49 +0000 (14:17 -0700)
committerJunio C Hamano <junkio@cox.net>
Thu, 10 Aug 2006 21:17:49 +0000 (14:17 -0700)
* master:
git-verify-pack: no need to count errors
git-verify-pack: buffer overrun paranoia
git-verify-pack: free pack after use and a cleanup
git-verify-pack: get rid of while loop
git-verify-pack: insist on .idx extension
git-verify-pack: more careful path handling
git-verify-pack: show usage when no pack was specified
Add has_extension()
builtin-apply: remove unused increment
Fix git-diff A...B
combine-diff: use color
git-apply: applying a patch to make a symlink shorter.
allow diff.renamelimit to be set regardless of -M/-C
make --find-copies-harder imply -C
find_unique_abbrev() with len=0 should not abbreviate
check return value from diff_setup_done()
Fix tutorial-2.html
Documentation: git-status takes the same options as git-commit
Update git-init-db(1) and documentation of core.sharedRepository

19 files changed:
Documentation/config.txt
Documentation/git-init-db.txt
Documentation/git-status.txt
Documentation/tutorial-2.txt
builtin-apply.c
builtin-diff.c
combine-diff.c
diff.c
git-compat-util.h
help.c
http-fetch.c
index-pack.c
local-fetch.c
refs.c
revision.c
sha1_file.c
sha1_name.c
t/t4115-apply-symlink.sh [new file with mode: 0755]
verify-pack.c
index d89916bea77a0200b5fe45cf2da19c149cc2f05b..ce722a2db07e2a41cfdebc235538cf4ca2a170ad 100644 (file)
@@ -83,9 +83,12 @@ core.repositoryFormatVersion::
        version.
 
 core.sharedRepository::
-       If true, the repository is made shareable between several users
-       in a group (making sure all the files and objects are group-writable).
-       See gitlink:git-init-db[1]. False by default.
+       When 'group' (or 'true'), the repository is made shareable between
+       several users in a group (making sure all the files and objects are
+       group-writable). When 'all' (or 'world' or 'everybody'), the
+       repository will be readable by all users, additionally to being
+       group-shareable. When 'umask' (or 'false'), git will use permissions
+       reported by umask(2). See gitlink:git-init-db[1]. False by default.
 
 core.warnAmbiguousRefs::
        If true, git will warn you if the ref name you passed it is ambiguous
index 0a4fc14b97fe690f9546c5d6734dfaaa9d0d656f..63cd5dab3f82746816d6dc0b8eae32f2c9d930d4 100644 (file)
@@ -8,17 +8,47 @@ git-init-db - Creates an empty git repository
 
 SYNOPSIS
 --------
-'git-init-db' [--template=<template_directory>] [--shared]
+'git-init-db' [--template=<template_directory>] [--shared[=<permissions>]]
 
 
 OPTIONS
 -------
+
+--
+
 --template=<template_directory>::
-       Provide the directory from which templates will be used.
-       The default template directory is `/usr/share/git-core/templates`.
 
---shared::
-       Specify that the git repository is to be shared amongst several users.
+Provide the directory from which templates will be used.  The default template
+directory is `/usr/share/git-core/templates`.
+
+When specified, `<template_directory>` is used as the source of the template
+files rather than the default.  The template files include some directory
+structure, some suggested "exclude patterns", and copies of non-executing
+"hook" files.  The suggested patterns and hook files are all modifiable and
+extensible.
+
+--shared[={false|true|umask|group|all|world|everybody}]::
+
+Specify that the git repository is to be shared amongst several users.  This
+allows users belonging to the same group to push into that
+repository.  When specified, the config variable "core.sharedRepository" is
+set so that files and directories under `$GIT_DIR` are created with the
+requested permissions.  When not specified, git will use permissions reported
+by umask(2).
+
+The option can have the following values, defaulting to 'group' if no value
+is given:
+
+ - 'umask' (or 'false'): Use permissions reported by umask(2). The default,
+   when `--shared` is not specified.
+
+ - 'group' (or 'true'): Make the repository group-writable, (and g+sx, since
+   the git group may be not the primary group of all users).
+
+ - 'all' (or 'world' or 'everybody'): Same as 'group', but make the repository
+   readable by all users.
+
+--
 
 
 DESCRIPTION
@@ -29,12 +59,6 @@ template files.
 An initial `HEAD` file that references the HEAD of the master branch
 is also created.
 
-If `--template=<template_directory>` is specified, `<template_directory>`
-is used as the source of the template files rather than the default.
-The template files include some directory structure, some suggested
-"exclude patterns", and copies of non-executing "hook" files.  The
-suggested patterns and hook files are all modifiable and extensible.
-
 If the `$GIT_DIR` environment variable is set then it specifies a path
 to use instead of `./.git` for the base of the repository.
 
@@ -42,11 +66,6 @@ If the object storage directory is specified via the `$GIT_OBJECT_DIRECTORY`
 environment variable then the sha1 directories are created underneath -
 otherwise the default `$GIT_DIR/objects` directory is used.
 
-A shared repository allows users belonging to the same group to push into that
-repository. When specifying `--shared` the config variable "core.sharedRepository" 
-is set to 'true' so that directories under `$GIT_DIR` are made group writable
-(and g+sx, since the git group may be not the primary group of all users).
-
 Running `git-init-db` in an existing repository is safe. It will not overwrite
 things that are already there. The primary reason for rerunning `git-init-db`
 is to pick up newly added templates.
index e446f4812e28c733baed21e1d82098252ffbfefc..ce7857e5a93c212c609b2ef0bef56c3c42ed841c 100644 (file)
@@ -8,7 +8,7 @@ git-status - Show working tree status
 
 SYNOPSIS
 --------
-'git-status'
+'git-status' <options>...
 
 DESCRIPTION
 -----------
@@ -23,6 +23,10 @@ If there is no path that is different between the index file and
 the current HEAD commit, the command exits with non-zero
 status.
 
+The command takes the same set of options as `git-commit`; it
+shows what would be committed if the same options are given to
+`git-commit`.
+
 
 OUTPUT
 ------
index 894ca5e06f26002f7dc5f2a16b713ca13e45886e..2f4fe1217a3cd6d9d958130ca5e03c68b027abc1 100644 (file)
@@ -244,6 +244,7 @@ $ git ls-files --stage
 $ git cat-file -t 513feba2
 blob
 $ git cat-file blob 513feba2
+hello world!
 hello world, again
 ------------------------------------------------
 
index f8c6763c7464a01ea81fae0665a7aef50809d031..be2c7152cd7ee8c8076cd4bbd5660dd2f85b0fd1 100644 (file)
@@ -1698,6 +1698,12 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
        desc.buffer = buf;
        if (apply_fragments(&desc, patch) < 0)
                return -1;
+
+       /* NUL terminate the result */
+       if (desc.alloc <= desc.size)
+               desc.buffer = xrealloc(desc.buffer, desc.size + 1);
+       desc.buffer[desc.size] = 0;
+
        patch->result = desc.buffer;
        patch->resultsize = desc.size;
 
@@ -2040,6 +2046,9 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
        int fd;
 
        if (S_ISLNK(mode))
+               /* Although buf:size is counted string, it also is NUL
+                * terminated.
+                */
                return symlink(buf, path);
        fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
        if (fd < 0)
index 1075855102fdb9d49f923edc4b62ddb75aa8027c..a090e298a55ef110a6fdd0e0dde54ea744a52f76 100644 (file)
@@ -253,7 +253,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
        argc = setup_revisions(argc, argv, &rev, NULL);
        if (!rev.diffopt.output_format) {
                rev.diffopt.output_format = DIFF_FORMAT_PATCH;
-               diff_setup_done(&rev.diffopt);
+               if (diff_setup_done(&rev.diffopt) < 0)
+                       die("diff_setup_done failed");
        }
 
        /* Do we have --cached and not have a pending object, then
@@ -348,6 +349,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                 * A and B.  We have ent[0] == merge-base, ent[1] == A,
                 * and ent[2] == B.  Show diff between the base and B.
                 */
+               ent[1] = ent[2];
                return builtin_diff_tree(&rev, argc, argv, ent);
        }
        else
index 919112bba9271a8e3903b06946cf91036411f1a4..ba8baca0ab9f2c3c48b4678108d4a62c1f9f8fd9 100644 (file)
@@ -497,11 +497,17 @@ static void show_parent_lno(struct sline *sline, unsigned long l0, unsigned long
        printf(" -%lu,%lu", l0, l1-l0);
 }
 
-static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
+static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent,
+                      int use_color)
 {
        unsigned long mark = (1UL<<num_parent);
        int i;
        unsigned long lno = 0;
+       const char *c_frag = diff_get_color(use_color, DIFF_FRAGINFO);
+       const char *c_new = diff_get_color(use_color, DIFF_FILE_NEW);
+       const char *c_old = diff_get_color(use_color, DIFF_FILE_OLD);
+       const char *c_plain = diff_get_color(use_color, DIFF_PLAIN);
+       const char *c_reset = diff_get_color(use_color, DIFF_RESET);
 
        if (!cnt)
                return; /* result deleted */
@@ -522,12 +528,13 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
                rlines = hunk_end - lno;
                if (cnt < hunk_end)
                        rlines--; /* pointing at the last delete hunk */
+               fputs(c_frag, stdout);
                for (i = 0; i <= num_parent; i++) putchar(combine_marker);
                for (i = 0; i < num_parent; i++)
                        show_parent_lno(sline, lno, hunk_end, i);
                printf(" +%lu,%lu ", lno+1, rlines);
                for (i = 0; i <= num_parent; i++) putchar(combine_marker);
-               putchar('\n');
+               printf("%s\n", c_reset);
                while (lno < hunk_end) {
                        struct lline *ll;
                        int j;
@@ -535,18 +542,23 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
                        sl = &sline[lno++];
                        ll = sl->lost_head;
                        while (ll) {
+                               fputs(c_old, stdout);
                                for (j = 0; j < num_parent; j++) {
                                        if (ll->parent_map & (1UL<<j))
                                                putchar('-');
                                        else
                                                putchar(' ');
                                }
-                               puts(ll->line);
+                               printf("%s%s\n", ll->line, c_reset);
                                ll = ll->next;
                        }
                        if (cnt < lno)
                                break;
                        p_mask = 1;
+                       if (!(sl->flag & (mark-1)))
+                               fputs(c_plain, stdout);
+                       else
+                               fputs(c_new, stdout);
                        for (j = 0; j < num_parent; j++) {
                                if (p_mask & sl->flag)
                                        putchar('+');
@@ -554,7 +566,7 @@ static void dump_sline(struct sline *sline, unsigned long cnt, int num_parent)
                                        putchar(' ');
                                p_mask <<= 1;
                        }
-                       printf("%.*s\n", sl->len, sl->bol);
+                       printf("%.*s%s\n", sl->len, sl->bol, c_reset);
                }
        }
 }
@@ -586,14 +598,15 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt,
        sline->p_lno[i] = sline->p_lno[j];
 }
 
-static void dump_quoted_path(const char *prefix, const char *path)
+static void dump_quoted_path(const char *prefix, const char *path,
+                            const char *c_meta, const char *c_reset)
 {
-       fputs(prefix, stdout);
+       printf("%s%s", c_meta, prefix);
        if (quote_c_style(path, NULL, NULL, 0))
                quote_c_style(path, NULL, stdout, 0);
        else
                printf("%s", path);
-       putchar('\n');
+       printf("%s\n", c_reset);
 }
 
 static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
@@ -699,18 +712,22 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
 
        if (show_hunks || mode_differs || working_tree_file) {
                const char *abb;
+               int use_color = opt->color_diff;
+               const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
+               const char *c_reset = diff_get_color(use_color, DIFF_RESET);
 
                if (rev->loginfo)
                        show_log(rev, opt->msg_sep);
-               dump_quoted_path(dense ? "diff --cc " : "diff --combined ", elem->path);
-               printf("index ");
+               dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
+                                elem->path, c_meta, c_reset);
+               printf("%sindex ", c_meta);
                for (i = 0; i < num_parent; i++) {
                        abb = find_unique_abbrev(elem->parent[i].sha1,
                                                 abbrev);
                        printf("%s%s", i ? "," : "", abb);
                }
                abb = find_unique_abbrev(elem->sha1, abbrev);
-               printf("..%s\n", abb);
+               printf("..%s%s\n", abb, c_reset);
 
                if (mode_differs) {
                        int added = !!elem->mode;
@@ -719,10 +736,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
                                    DIFF_STATUS_ADDED)
                                        added = 0;
                        if (added)
-                               printf("new file mode %06o", elem->mode);
+                               printf("%snew file mode %06o",
+                                      c_meta, elem->mode);
                        else {
                                if (!elem->mode)
-                                       printf("deleted file ");
+                                       printf("%sdeleted file ", c_meta);
                                printf("mode ");
                                for (i = 0; i < num_parent; i++) {
                                        printf("%s%06o", i ? "," : "",
@@ -731,11 +749,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
                                if (elem->mode)
                                        printf("..%06o", elem->mode);
                        }
-                       putchar('\n');
+                       printf("%s\n", c_reset);
                }
-               dump_quoted_path("--- a/", elem->path);
-               dump_quoted_path("+++ b/", elem->path);
-               dump_sline(sline, cnt, num_parent);
+               dump_quoted_path("--- a/", elem->path, c_meta, c_reset);
+               dump_quoted_path("+++ b/", elem->path, c_meta, c_reset);
+               dump_sline(sline, cnt, num_parent, opt->color_diff);
        }
        free(result);
 
diff --git a/diff.c b/diff.c
index 895c1376559cc2aaa1e6c25361a9a6b831c9a18a..b3b1781a9cac05457e42691970c93b6e1501f68c 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1515,10 +1515,8 @@ void diff_setup(struct diff_options *options)
 
 int diff_setup_done(struct diff_options *options)
 {
-       if ((options->find_copies_harder &&
-            options->detect_rename != DIFF_DETECT_COPY) ||
-           (0 <= options->rename_limit && !options->detect_rename))
-               return -1;
+       if (options->find_copies_harder)
+               options->detect_rename = DIFF_DETECT_COPY;
 
        if (options->output_format & (DIFF_FORMAT_NAME |
                                      DIFF_FORMAT_NAME_STATUS |
index 3bcf5b13f2c7bab387b02bd3075629a9d14c5feb..dd9209365253971c70db772929fb4541f1c609b2 100644 (file)
@@ -139,6 +139,12 @@ static inline ssize_t xwrite(int fd, const void *buf, size_t len)
        }
 }
 
+static inline int has_extension(const char *filename, int len, const char *ext)
+{
+       int extlen = strlen(ext);
+       return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
+}
+
 /* Sane ctype - no locale, and works with signed chars */
 #undef isspace
 #undef isdigit
diff --git a/help.c b/help.c
index fb731cc9345e197e710aea611e9519f1e04e0ab8..7a7f7759e592208b4604b6987bce8be46c936882 100644 (file)
--- a/help.c
+++ b/help.c
@@ -140,7 +140,7 @@ static void list_commands(const char *exec_path, const char *pattern)
                        continue;
 
                entlen = strlen(de->d_name);
-               if (4 < entlen && !strcmp(de->d_name + entlen - 4, ".exe"))
+               if (has_extension(de->d_name, entlen, ".exe"))
                        entlen -= 4;
 
                if (longest < entlen)
index 36af3e5b94bb87f8d452aac99c27cba0097abf13..6ea39f0589e74767be31eed87d2248370108b5f7 100644 (file)
@@ -870,7 +870,7 @@ static void process_ls_pack(struct remote_ls_ctx *ls)
 
        if (strlen(ls->dentry_name) == 63 &&
            !strncmp(ls->dentry_name, "objects/pack/pack-", 18) &&
-           !strncmp(ls->dentry_name+58, ".pack", 5)) {
+           has_extension(ls->dentry_name, 63, ".pack")) {
                get_sha1_hex(ls->dentry_name + 18, sha1);
                setup_index(ls->repo, sha1);
        }
index b39953dc698aae25f79caa9553e13bca6cd4e986..a91e39ecd6469c04da92391bdb24e5a05691b617 100644 (file)
@@ -447,7 +447,7 @@ int main(int argc, char **argv)
                usage(index_pack_usage);
        if (!index_name) {
                int len = strlen(pack_name);
-               if (len < 5 || strcmp(pack_name + len - 5, ".pack"))
+               if (!has_extension(pack_name, len, ".pack"))
                        die("packfile name '%s' does not end with '.pack'",
                            pack_name);
                index_name_buf = xmalloc(len);
index 4bf86fbbe2703514cd3ab39fd9c81accac662aaf..b6ec170c015661ec602a6c2bd2b2f10754dbbd9c 100644 (file)
@@ -43,8 +43,8 @@ static int setup_indices(void)
                return -1;
        while ((de = readdir(dir)) != NULL) {
                int namelen = strlen(de->d_name);
-               if (namelen != 50 || 
-                   strcmp(de->d_name + namelen - 5, ".pack"))
+               if (namelen != 50 ||
+                   !has_extension(de->d_name, namelen, ".pack"))
                        continue;
                get_sha1_hex(de->d_name + 5, sha1);
                setup_index(sha1);
diff --git a/refs.c b/refs.c
index 02850b69083f793becacc59a0da97a8f69367e4e..b01835f634603f2f89c188bd56aae6fb45983ba3 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -147,7 +147,7 @@ static int do_for_each_ref(const char *base, int (*fn)(const char *path, const u
                        namelen = strlen(de->d_name);
                        if (namelen > 255)
                                continue;
-                       if (namelen>5 && !strcmp(de->d_name+namelen-5,".lock"))
+                       if (has_extension(de->d_name, namelen, ".lock"))
                                continue;
                        memcpy(path + baselen, de->d_name, namelen+1);
                        if (stat(git_path("%s", path), &st) < 0)
index a58257ad8037f7009c69ee0502c3669756bb3987..5a91d06b980d710e30a80c353a636ca1ca6b9a55 100644 (file)
@@ -936,7 +936,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                        revs->diffopt.output_format = DIFF_FORMAT_PATCH;
        }
        revs->diffopt.abbrev = revs->abbrev;
-       diff_setup_done(&revs->diffopt);
+       if (diff_setup_done(&revs->diffopt) < 0)
+               die("diff_setup_done failed");
 
        return left;
 }
index 43bc2ea0cf039bb9fd02c8313981e85bd7398d33..a1bb01ca3569279318333f8088ade35614167612 100644 (file)
@@ -590,7 +590,7 @@ static void prepare_packed_git_one(char *objdir, int local)
                int namelen = strlen(de->d_name);
                struct packed_git *p;
 
-               if (strcmp(de->d_name + namelen - 4, ".idx"))
+               if (!has_extension(de->d_name, namelen, ".idx"))
                        continue;
 
                /* we have .idx.  Is it a file we can map? */
index 5fe8e5d4bf25d79c3fa76610d1617ee07c1f1e2c..c5a05faeb6b2bac74f4c5e06c5e397dc103bb190 100644 (file)
@@ -193,7 +193,7 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)
 
        is_null = !memcmp(sha1, null_sha1, 20);
        memcpy(hex, sha1_to_hex(sha1), 40);
-       if (len == 40)
+       if (len == 40 || !len)
                return hex;
        while (len < 40) {
                unsigned char sha1_ret[20];
diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh
new file mode 100755 (executable)
index 0000000..d5f2cfb
--- /dev/null
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='git-apply symlinks and partial files
+
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       ln -s path1/path2/path3/path4/path5 link1 &&
+       git add link? &&
+       git commit -m initial &&
+
+       git branch side &&
+
+       rm -f link? &&
+
+       ln -s htap6 link1 &&
+       git update-index link? &&
+       git commit -m second &&
+
+       git diff-tree -p HEAD^ HEAD >patch  &&
+       git apply --stat --summary patch
+
+'
+
+test_expect_success 'apply symlink patch' '
+
+       git checkout side &&
+       git apply patch &&
+       git diff-files -p >patched &&
+       diff -u patch patched
+
+'
+
+test_expect_success 'apply --index symlink patch' '
+
+       git checkout -f side &&
+       git apply --index patch &&
+       git diff-index --cached -p HEAD >patched &&
+       diff -u patch patched
+
+'
+
+test_done
index c99db9dd79315dff4ac19c79b35275cd02397e60..f440a39678b23ebb9d58115f0481875add21e981 100644 (file)
@@ -1,43 +1,60 @@
 #include "cache.h"
 #include "pack.h"
 
-static int verify_one_pack(char *arg, int verbose)
+static int verify_one_pack(const char *path, int verbose)
 {
-       int len = strlen(arg);
-       struct packed_git *g;
-       
-       while (1) {
-               /* Should name foo.idx, but foo.pack may be named;
-                * convert it to foo.idx
-                */
-               if (!strcmp(arg + len - 5, ".pack")) {
-                       strcpy(arg + len - 5, ".idx");
-                       len--;
-               }
-               /* Should name foo.idx now */
-               if ((g = add_packed_git(arg, len, 1)))
-                       break;
-               /* No?  did you name just foo? */
+       char arg[PATH_MAX];
+       int len;
+       struct packed_git *pack;
+       int err;
+
+       len = strlcpy(arg, path, PATH_MAX);
+       if (len >= PATH_MAX)
+               return error("name too long: %s", path);
+
+       /*
+        * In addition to "foo.idx" we accept "foo.pack" and "foo";
+        * normalize these forms to "foo.idx" for add_packed_git().
+        */
+       if (has_extension(arg, len, ".pack")) {
+               strcpy(arg + len - 5, ".idx");
+               len--;
+       } else if (!has_extension(arg, len, ".idx")) {
+               if (len + 4 >= PATH_MAX)
+                       return error("name too long: %s.idx", arg);
                strcpy(arg + len, ".idx");
                len += 4;
-               if ((g = add_packed_git(arg, len, 1)))
-                       break;
-               return error("packfile %s not found.", arg);
        }
-       return verify_pack(g, verbose);
+
+       /*
+        * add_packed_git() uses our buffer (containing "foo.idx") to
+        * build the pack filename ("foo.pack").  Make sure it fits.
+        */
+       if (len + 1 >= PATH_MAX) {
+               arg[len - 4] = '\0';
+               return error("name too long: %s.pack", arg);
+       }
+
+       pack = add_packed_git(arg, len, 1);
+       if (!pack)
+               return error("packfile %s not found.", arg);
+
+       err = verify_pack(pack, verbose);
+       free(pack);
+
+       return err;
 }
 
 static const char verify_pack_usage[] = "git-verify-pack [-v] <pack>...";
 
 int main(int ac, char **av)
 {
-       int errs = 0;
+       int err = 0;
        int verbose = 0;
        int no_more_options = 0;
+       int nothing_done = 1;
 
        while (1 < ac) {
-               char path[PATH_MAX];
-
                if (!no_more_options && av[1][0] == '-') {
                        if (!strcmp("-v", av[1]))
                                verbose = 1;
@@ -47,11 +64,15 @@ int main(int ac, char **av)
                                usage(verify_pack_usage);
                }
                else {
-                       strcpy(path, av[1]);
-                       if (verify_one_pack(path, verbose))
-                               errs++;
+                       if (verify_one_pack(av[1], verbose))
+                               err = 1;
+                       nothing_done = 0;
                }
                ac--; av++;
        }
-       return !!errs;
+
+       if (nothing_done)
+               usage(verify_pack_usage);
+
+       return err;
 }