diff options
-rw-r--r-- | Documentation/config.txt | 9 | ||||
-rw-r--r-- | Documentation/git-init-db.txt | 51 | ||||
-rw-r--r-- | Documentation/git-status.txt | 6 | ||||
-rw-r--r-- | Documentation/tutorial-2.txt | 1 | ||||
-rw-r--r-- | builtin-apply.c | 9 | ||||
-rw-r--r-- | builtin-diff.c | 4 | ||||
-rw-r--r-- | combine-diff.c | 50 | ||||
-rw-r--r-- | diff.c | 6 | ||||
-rw-r--r-- | git-compat-util.h | 6 | ||||
-rw-r--r-- | help.c | 2 | ||||
-rw-r--r-- | http-fetch.c | 2 | ||||
-rw-r--r-- | index-pack.c | 2 | ||||
-rw-r--r-- | local-fetch.c | 4 | ||||
-rw-r--r-- | refs.c | 2 | ||||
-rw-r--r-- | revision.c | 3 | ||||
-rw-r--r-- | sha1_file.c | 2 | ||||
-rw-r--r-- | sha1_name.c | 2 | ||||
-rwxr-xr-x | t/t4115-apply-symlink.sh | 49 | ||||
-rw-r--r-- | verify-pack.c | 75 |
19 files changed, 208 insertions, 77 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=<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. 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' <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 ------ 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 ------------------------------------------------ diff --git a/builtin-apply.c b/builtin-apply.c index f8c6763c74..be2c7152cd 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -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) diff --git a/builtin-diff.c b/builtin-diff.c index 1075855102..a090e298a5 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 @@ -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 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<<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); @@ -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 | 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 @@ -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/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); @@ -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/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; } 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/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]; 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 diff --git a/verify-pack.c b/verify-pack.c index c99db9dd79..f440a39678 100644 --- a/verify-pack.c +++ b/verify-pack.c @@ -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; } |