From d5dc6a76d49367cddc015e01d2e9aa22e64d7e28 Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Wed, 9 Aug 2006 02:26:23 +0200 Subject: [PATCH 01/19] Update git-init-db(1) and documentation of core.sharedRepository Combine option descriptions in git-init-db(1). Reflect the changes to additionally allow all users to read the created git repository. Signed-off-by: Jonas Fonseca Signed-off-by: Junio C Hamano --- Documentation/config.txt | 9 ++++-- Documentation/git-init-db.txt | 53 ++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index d89916bea7..ce722a2db0 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -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 diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt index 0a4fc14b97..63cd5dab3f 100644 --- a/Documentation/git-init-db.txt +++ b/Documentation/git-init-db.txt @@ -8,17 +8,47 @@ git-init-db - Creates an empty git repository SYNOPSIS -------- -'git-init-db' [--template=] [--shared] +'git-init-db' [--template=] [--shared[=]] OPTIONS ------- ---template=:: - 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. +-- + +--template=:: + +Provide the directory from which templates will be used. The default template +directory is `/usr/share/git-core/templates`. + +When specified, `` 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=` is specified, `` -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. From fb6ff943de33dccc3f43541ed4ae4b71abddac8b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 7 Aug 2006 22:41:32 -0700 Subject: [PATCH 02/19] Documentation: git-status takes the same options as git-commit Signed-off-by: Junio C Hamano --- Documentation/git-status.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index e446f4812e..ce7857e5a9 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -8,7 +8,7 @@ git-status - Show working tree status SYNOPSIS -------- -'git-status' +'git-status' ... 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 ------ From 1d17c25c38a6b98d20b7bbe789b45996fd84d672 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 00:57:01 -0700 Subject: [PATCH 03/19] Fix tutorial-2.html Honza Pazdziora noticed that one example did not match reality. Signed-off-by: Junio C Hamano --- Documentation/tutorial-2.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/tutorial-2.txt b/Documentation/tutorial-2.txt index 894ca5e06f..2f4fe1217a 100644 --- a/Documentation/tutorial-2.txt +++ b/Documentation/tutorial-2.txt @@ -244,6 +244,7 @@ $ git ls-files --stage $ git cat-file -t 513feba2 blob $ git cat-file blob 513feba2 +hello world! hello world, again ------------------------------------------------ From 72ee96c0f1861fcdb9eaf39e78d86888437a27a9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 12:45:27 -0700 Subject: [PATCH 04/19] check return value from diff_setup_done() Signed-off-by: Junio C Hamano --- builtin-diff.c | 3 ++- revision.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin-diff.c b/builtin-diff.c index 1075855102..dd9886c6e8 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -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 diff --git a/revision.c b/revision.c index a58257ad80..5a91d06b98 100644 --- a/revision.c +++ b/revision.c @@ -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; } From 02c5cba2007856465710aa37cd41b404372ab95b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 13:17:04 -0700 Subject: [PATCH 05/19] find_unique_abbrev() with len=0 should not abbreviate Signed-off-by: Junio C Hamano --- sha1_name.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sha1_name.c b/sha1_name.c index 5fe8e5d4bf..c5a05faeb6 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -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]; From 03b9d560bed6029f43968ad3f09a8f9c015b20e0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 13:17:19 -0700 Subject: [PATCH 06/19] make --find-copies-harder imply -C Signed-off-by: Junio C Hamano --- diff.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/diff.c b/diff.c index 895c137655..02a409d964 100644 --- a/diff.c +++ b/diff.c @@ -1515,9 +1515,10 @@ 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)) + if (options->find_copies_harder) + options->detect_rename = DIFF_DETECT_COPY; + + if ((0 <= options->rename_limit && !options->detect_rename) return -1; if (options->output_format & (DIFF_FORMAT_NAME | From 943d5b73e2adf3cd0d3f72c9a06c75681a4ea3ca Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 14:05:23 -0700 Subject: [PATCH 07/19] allow diff.renamelimit to be set regardless of -M/-C Signed-off-by: Junio C Hamano --- diff.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/diff.c b/diff.c index 02a409d964..b3b1781a9c 100644 --- a/diff.c +++ b/diff.c @@ -1518,9 +1518,6 @@ int diff_setup_done(struct diff_options *options) if (options->find_copies_harder) options->detect_rename = DIFF_DETECT_COPY; - if ((0 <= options->rename_limit && !options->detect_rename) - return -1; - if (options->output_format & (DIFF_FORMAT_NAME | DIFF_FORMAT_NAME_STATUS | DIFF_FORMAT_CHECKDIFF | From 2c71810b90d122abdcc57fc3cb62174d16e77b58 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 9 Aug 2006 22:47:25 -0700 Subject: [PATCH 08/19] git-apply: applying a patch to make a symlink shorter. The internal representation of the result is counted string (i.e. char *buf and ulong size), which is fine for writing out to regular file, but throwing the buf at symlink(2) was a no-no. Reported by Willy Tarreau. Signed-off-by: Junio C Hamano --- builtin-apply.c | 11 +++++++++ t/t4115-apply-symlink.sh | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100755 t/t4115-apply-symlink.sh diff --git a/builtin-apply.c b/builtin-apply.c index f8c6763c74..c15987386b 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1698,6 +1698,14 @@ 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.alloc++; + } + desc.buffer[desc.size] = 0; + patch->result = desc.buffer; patch->resultsize = desc.size; @@ -2040,6 +2048,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) diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh new file mode 100755 index 0000000000..d5f2cfb186 --- /dev/null +++ b/t/t4115-apply-symlink.sh @@ -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 From 567a03d14cb624b0edc76be9cffda11edac2bea3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 10 Aug 2006 00:30:33 -0700 Subject: [PATCH 09/19] combine-diff: use color Using the same mechanism as the regular diffs, color combined diff output. Signed-off-by: Junio C Hamano --- combine-diff.c | 50 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/combine-diff.c b/combine-diff.c index 919112bba9..ba8baca0ab 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -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<lost_head; while (ll) { + fputs(c_old, stdout); for (j = 0; j < num_parent; j++) { if (ll->parent_map & (1UL<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); From 306ea2df03322ac8c29f4eb5a968acb7ef3c8f72 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 10 Aug 2006 00:50:15 -0700 Subject: [PATCH 10/19] Fix git-diff A...B Commit 9919f41 meant to make git-diff A...B to (usually) mean "git-diff `git-merge-base A B` B", but it got the parameters wrong and ended up showing "git-diff `git-merge-base A B` A" by mistake. Signed-off-by: Junio C Hamano --- builtin-diff.c | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin-diff.c b/builtin-diff.c index dd9886c6e8..a090e298a5 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -349,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 From 242abf106c6929028c2dc916504879885cd64d4d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 10 Aug 2006 00:56:40 -0700 Subject: [PATCH 11/19] builtin-apply: remove unused increment We do not use desc.alloc after assigning desc.buffer to patch->result; do not bother to increment it. Signed-off-by: Junio C Hamano --- builtin-apply.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index c15987386b..be2c7152cd 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1700,10 +1700,8 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry * return -1; /* NUL terminate the result */ - if (desc.alloc <= desc.size) { + if (desc.alloc <= desc.size) desc.buffer = xrealloc(desc.buffer, desc.size + 1); - desc.alloc++; - } desc.buffer[desc.size] = 0; patch->result = desc.buffer; From 83a2b841d6b90e6f4b797df40ed3a105364574b6 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:30 +0200 Subject: [PATCH 12/19] Add has_extension() The little helper has_extension() documents through its name what we are trying to do and makes sure we don't forget the underrun check. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-help.c | 2 +- git-compat-util.h | 6 ++++++ http-fetch.c | 2 +- index-pack.c | 2 +- local-fetch.c | 4 ++-- refs.c | 2 +- sha1_file.c | 2 +- verify-pack.c | 2 +- 8 files changed, 14 insertions(+), 8 deletions(-) diff --git a/builtin-help.c b/builtin-help.c index fb731cc934..7a7f7759e5 100644 --- a/builtin-help.c +++ b/builtin-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) diff --git a/git-compat-util.h b/git-compat-util.h index 3bcf5b13f2..dd92093652 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -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/http-fetch.c b/http-fetch.c index 36af3e5b94..6ea39f0589 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -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); } diff --git a/index-pack.c b/index-pack.c index b39953dc69..a91e39ecd6 100644 --- a/index-pack.c +++ b/index-pack.c @@ -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); diff --git a/local-fetch.c b/local-fetch.c index 4bf86fbbe2..b6ec170c01 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -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 02850b6908..b01835f634 100644 --- 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) diff --git a/sha1_file.c b/sha1_file.c index 43bc2ea0cf..a1bb01ca35 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -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? */ diff --git a/verify-pack.c b/verify-pack.c index c99db9dd79..ef00204ad4 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -10,7 +10,7 @@ static int verify_one_pack(char *arg, int verbose) /* Should name foo.idx, but foo.pack may be named; * convert it to foo.idx */ - if (!strcmp(arg + len - 5, ".pack")) { + if (has_extension(arg, len, ".pack")) { strcpy(arg + len - 5, ".idx"); len--; } From 6f05b57da8e82c471ea6765da67e813d496ed278 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:31 +0200 Subject: [PATCH 13/19] git-verify-pack: show usage when no pack was specified Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/verify-pack.c b/verify-pack.c index ef00204ad4..7201596bf9 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -34,6 +34,7 @@ int main(int ac, char **av) int errs = 0; int verbose = 0; int no_more_options = 0; + int nothing_done = 1; while (1 < ac) { char path[PATH_MAX]; @@ -50,8 +51,13 @@ int main(int ac, char **av) strcpy(path, av[1]); if (verify_one_pack(path, verbose)) errs++; + nothing_done = 0; } ac--; av++; } + + if (nothing_done) + usage(verify_pack_usage); + return !!errs; } From ae9c86f2b6c89a3a0991209dae51086f884959c0 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:32 +0200 Subject: [PATCH 14/19] git-verify-pack: more careful path handling Use strlcpy() to copy the filename into a buffer and complain if it doesn't fit. Also move the path buffer into verify_one_pack(); it is used only there. Now we can const'ify the first argument of this function. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 7201596bf9..77b3d282da 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -1,11 +1,16 @@ #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); + char arg[PATH_MAX]; + int len; struct packed_git *g; - + + len = strlcpy(arg, path, PATH_MAX); + if (len >= PATH_MAX) + return error("name too long: %s", path); + while (1) { /* Should name foo.idx, but foo.pack may be named; * convert it to foo.idx @@ -37,8 +42,6 @@ int main(int ac, char **av) 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; @@ -48,8 +51,7 @@ int main(int ac, char **av) usage(verify_pack_usage); } else { - strcpy(path, av[1]); - if (verify_one_pack(path, verbose)) + if (verify_one_pack(av[1], verbose)) errs++; nothing_done = 0; } From 68f4c78b95b9d119d8888b40b0a93b93a39b2f26 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:33 +0200 Subject: [PATCH 15/19] git-verify-pack: insist on .idx extension git-verify-pack can be called with a filename without .idx extension. add_packed_git() on the other hand depends on its presence. So instead of trying to call it with whatever the user gave us check for that extension and add it if it's missing. That means that you can't name your index file "blah" and your pack file ".pack" anymore ("git-verify-pack blah" currently works in that case). I think this regression is a good change. ;-) Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 77b3d282da..002b711617 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -18,13 +18,12 @@ static int verify_one_pack(const char *path, int verbose) 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; } - /* Should name foo.idx now */ - if ((g = add_packed_git(arg, len, 1))) - break; - /* No? did you name just foo? */ - strcpy(arg + len, ".idx"); - len += 4; if ((g = add_packed_git(arg, len, 1))) break; return error("packfile %s not found.", arg); From fc5fc50980958f742a9f3d79fb7a64f02e87877a Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:34 +0200 Subject: [PATCH 16/19] git-verify-pack: get rid of while loop Get rid of that while loop which was apparently used as a way to avoid goto's (why?). It's easy now because there is only one break left at the end of it. Also make the comment clearer. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 002b711617..c7293140f6 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -11,23 +11,23 @@ static int verify_one_pack(const char *path, int verbose) if (len >= PATH_MAX) return error("name too long: %s", path); - while (1) { - /* Should name foo.idx, but foo.pack may be named; - * convert it to foo.idx - */ - 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); + /* + * 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))) + return error("packfile %s not found.", arg); + return verify_pack(g, verbose); } From d0d619c8c50b90fbbd6a7e0994fde073341bf92b Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:35 +0200 Subject: [PATCH 17/19] git-verify-pack: free pack after use and a cleanup Plug memory leak in verify_one_pack() by freeing the struct packed_git we got from add_packed_git(). Also rename g to pack and pull an assignment out of an if statement while we're at it. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index c7293140f6..78d789c62d 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -5,7 +5,8 @@ static int verify_one_pack(const char *path, int verbose) { char arg[PATH_MAX]; int len; - struct packed_git *g; + struct packed_git *pack; + int err; len = strlcpy(arg, path, PATH_MAX); if (len >= PATH_MAX) @@ -25,10 +26,14 @@ static int verify_one_pack(const char *path, int verbose) len += 4; } - if (!(g = add_packed_git(arg, len, 1))) + pack = add_packed_git(arg, len, 1); + if (!pack) return error("packfile %s not found.", arg); - return verify_pack(g, verbose); + err = verify_pack(pack, verbose); + free(pack); + + return err; } static const char verify_pack_usage[] = "git-verify-pack [-v] ..."; From f711ab5470cd1da7fdafa3b7b5e39015dcfca5ce Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:36 +0200 Subject: [PATCH 18/19] git-verify-pack: buffer overrun paranoia Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/verify-pack.c b/verify-pack.c index 78d789c62d..99c352ee3a 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -26,6 +26,15 @@ static int verify_one_pack(const char *path, int verbose) len += 4; } + /* + * 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); From 0eaf22f4c4bba89457e733264e71343368712793 Mon Sep 17 00:00:00 2001 From: Rene Scharfe Date: Thu, 10 Aug 2006 17:02:37 +0200 Subject: [PATCH 19/19] git-verify-pack: no need to count errors Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- verify-pack.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/verify-pack.c b/verify-pack.c index 99c352ee3a..f440a39678 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -49,7 +49,7 @@ static const char verify_pack_usage[] = "git-verify-pack [-v] ..."; int main(int ac, char **av) { - int errs = 0; + int err = 0; int verbose = 0; int no_more_options = 0; int nothing_done = 1; @@ -65,7 +65,7 @@ int main(int ac, char **av) } else { if (verify_one_pack(av[1], verbose)) - errs++; + err = 1; nothing_done = 0; } ac--; av++; @@ -74,5 +74,5 @@ int main(int ac, char **av) if (nothing_done) usage(verify_pack_usage); - return !!errs; + return err; }