From: Junio C Hamano Date: Mon, 25 Jun 2012 18:21:33 +0000 (-0700) Subject: Merge branch 'maint' X-Git-Tag: v1.7.12-rc0~89 X-Git-Url: https://www.git.lorimer.id.au/gitweb.git/diff_plain/8df9be792b1a8cc349a7a9f321be7c36c2a2a18d?hp=4c8a9db6f7dd9e10b5ce9bfbcd5faa82a8c86ce3 Merge branch 'maint' * maint: git-submodule.sh: fix filename in comment. git-add--interactive.perl: Remove two unused variables --- diff --git a/Documentation/RelNotes/1.7.12.txt b/Documentation/RelNotes/1.7.12.txt new file mode 100644 index 0000000000..117f4b1904 --- /dev/null +++ b/Documentation/RelNotes/1.7.12.txt @@ -0,0 +1,55 @@ +Git v1.7.12 Release Notes +========================= + +Updates since v1.7.11 +--------------------- + +UI, Workflows & Features + + * "git help" used to always default to "man" format even on platforms + where "man" viewer is not widely available. + + * "git clone --local $path" started its life as an experiment to + optionally use link/copy when cloning a repository on the disk, but + we didn't deprecate it after we made the option a no-op to always + use the optimization. The command learned "--no-local" option to + turn this off, as a more explicit alternative over use of file:// + URL. + + * git native protocol agents learned to show software version over + the wire, so that the server log can be examined to see the vintage + distribution of clients. + + +Foreign Interface + + +Performance and Internal Implementation (please report possible regressions) + + * Some tests showed false failures caused by a bug in ecryptofs. + + +Also contains minor documentation updates and code clean-ups. + + +Fixes since v1.7.11 +------------------- + +Unless otherwise noted, all the fixes since v1.7.11 in the maintenance +releases are contained in this release (see release notes to them for +details). + +* Running "git bundle verify" on a bundle that records a complete + history said "it requires these 0 commits". + (merge 8c3710f jc/bundle-complete-notice later to maint). + +* "git ls-files --exclude=t -i" did not consider anything under t/ as + excluded, as it did not pay attention to exclusion of leading paths + while walking the index. Other two users of excluded() are also + updated. + (merge 0d316f0 jc/ls-files-i-dir later to maint). + +* "git request-pull $url dev" when the tip of "dev" branch was tagged + with "ext4-for-linus" used the contents from the tag in the output + but still asked the "dev" branch to be pulled, not the tag. + (merge 682853e jc/request-pull-match-tagname later to maint). diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 6e22522c4f..c1ddd4c2cc 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -46,13 +46,18 @@ OPTIONS mechanism and clones the repository by making a copy of HEAD and everything under objects and refs directories. The files under `.git/objects/` directory are hardlinked - to save space when possible. This is now the default when - the source repository is specified with `/path/to/repo` - syntax, so it essentially is a no-op option. To force - copying instead of hardlinking (which may be desirable - if you are trying to make a back-up of your repository), - but still avoid the usual "git aware" transport - mechanism, `--no-hardlinks` can be used. + to save space when possible. ++ +If the repository is specified as a local path (e.g., `/path/to/repo`), +this is the default, and --local is essentially a no-op. If the +repository is specified as a URL, then this flag is ignored (and we +never use the local optimizations). Specifying `--no-local` will +override the default when `/path/to/repo` is given, using the regular +git transport instead. ++ +To force copying instead of hardlinking (which may be desirable if you +are trying to make a back-up of your repository), but still avoid the +usual "git aware" transport mechanism, `--no-hardlinks` can be used. --no-hardlinks:: Optimize the cloning process from a repository on a diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index a7570decfb..fde74a68d5 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.7.11.1 +DEF_VER=v1.7.11.GIT LF=' ' diff --git a/Makefile b/Makefile index 4592f1f2ee..f62ca2aebb 100644 --- a/Makefile +++ b/Makefile @@ -296,6 +296,13 @@ all:: # the diff algorithm. It gives a nice speedup if your processor has # fast unaligned word loads. Does NOT work on big-endian systems! # Enabled by default on x86_64. +# +# Define GIT_USER_AGENT if you want to change how git identifies itself during +# network interactions. The default is "git/$(GIT_VERSION)". +# +# Define DEFAULT_HELP_FORMAT to "man", "info" or "html" +# (defaults to "man") if you want to have a different default when +# "git help" is called without a parameter specifying the format. GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN @@ -799,6 +806,7 @@ LIB_OBJS += usage.o LIB_OBJS += userdiff.o LIB_OBJS += utf8.o LIB_OBJS += varint.o +LIB_OBJS += version.o LIB_OBJS += walker.o LIB_OBJS += wrapper.o LIB_OBJS += write_or_die.o @@ -904,6 +912,8 @@ BUILTIN_OBJS += builtin/write-tree.o GITLIBS = $(LIB_FILE) $(XDIFF_LIB) EXTLIBS = +GIT_USER_AGENT = git/$(GIT_VERSION) + # # Platform specific tweaks # @@ -1236,6 +1246,7 @@ ifeq ($(uname_S),Windows) BLK_SHA1 = YesPlease NO_POSIX_GOODIES = UnfortunatelyYes NATIVE_CRLF = YesPlease + DEFAULT_HELP_FORMAT = html CC = compat/vcbuild/scripts/clink.pl AR = compat/vcbuild/scripts/lib.pl @@ -1915,6 +1926,15 @@ SHELL_PATH_CQ_SQ = $(subst ','\'',$(SHELL_PATH_CQ)) BASIC_CFLAGS += -DSHELL_PATH='$(SHELL_PATH_CQ_SQ)' endif +GIT_USER_AGENT_SQ = $(subst ','\'',$(GIT_USER_AGENT)) +GIT_USER_AGENT_CQ = "$(subst ",\",$(subst \,\\,$(GIT_USER_AGENT)))" +GIT_USER_AGENT_CQ_SQ = $(subst ','\'',$(GIT_USER_AGENT_CQ)) +BASIC_CFLAGS += -DGIT_USER_AGENT='$(GIT_USER_AGENT_CQ_SQ)' + +ifdef DEFAULT_HELP_FORMAT +BASIC_CFLAGS += -DDEFAULT_HELP_FORMAT='"$(DEFAULT_HELP_FORMAT)"' +endif + ALL_CFLAGS += $(BASIC_CFLAGS) ALL_LDFLAGS += $(BASIC_LDFLAGS) @@ -1962,7 +1982,7 @@ strip: $(PROGRAMS) git$X $(STRIP) $(STRIP_OPTS) $(PROGRAMS) git$X git.o: common-cmds.h -git.sp git.s git.o: EXTRA_CPPFLAGS = -DGIT_VERSION='"$(GIT_VERSION)"' \ +git.sp git.s git.o: EXTRA_CPPFLAGS = \ '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ '-DGIT_MAN_PATH="$(mandir_SQ)"' \ '-DGIT_INFO_PATH="$(infodir_SQ)"' @@ -1979,6 +1999,9 @@ builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ '-DGIT_MAN_PATH="$(mandir_SQ)"' \ '-DGIT_INFO_PATH="$(infodir_SQ)"' +version.sp version.s version.o: EXTRA_CPPFLAGS = \ + '-DGIT_VERSION="$(GIT_VERSION)"' + $(BUILT_INS): git$X $(QUIET_BUILT_IN)$(RM) $@ && \ ln git$X $@ 2>/dev/null || \ @@ -1996,6 +2019,7 @@ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's|@@DIFF@@|$(DIFF_SQ)|' \ -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + -e 's|@@GIT_USER_AGENT@@|$(GIT_USER_AGENT_SQ)|g' \ -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \ -e 's/@@NO_CURL@@/$(NO_CURL)/g' \ -e 's/@@USE_GETTEXT_SCHEME@@/$(USE_GETTEXT_SCHEME)/g' \ @@ -2089,7 +2113,7 @@ configure: configure.ac $(RM) $<+ # These can record GIT_VERSION -git.o git.spec http.o \ +version.o git.spec \ $(patsubst %.sh,%,$(SCRIPT_SH)) \ $(patsubst %.perl,%,$(SCRIPT_PERL)) \ : GIT-VERSION-FILE @@ -2259,9 +2283,6 @@ attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \ gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \ -DGIT_LOCALE_PATH='"$(localedir_SQ)"' -http.sp http.s http.o: EXTRA_CPPFLAGS = \ - -DGIT_HTTP_USER_AGENT='"git/$(GIT_VERSION)"' - ifdef NO_EXPAT http-walker.sp http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT endif diff --git a/RelNotes b/RelNotes index ceedb902ca..19bb2ebbe6 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/1.7.11.1.txt \ No newline at end of file +Documentation/RelNotes/1.7.12.txt \ No newline at end of file diff --git a/builtin.h b/builtin.h index 338f540e39..dea1643faf 100644 --- a/builtin.h +++ b/builtin.h @@ -9,7 +9,6 @@ #define DEFAULT_MERGE_LOG_LEN 20 -extern const char git_version_string[]; extern const char git_usage_string[]; extern const char git_more_info_string[]; diff --git a/builtin/add.c b/builtin/add.c index b79336d712..87446cf92a 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -443,6 +443,9 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (pathspec) { int i; + struct path_exclude_check check; + + path_exclude_check_init(&check, &dir); if (!seen) seen = find_used_pathspec(pathspec); for (i = 0; pathspec[i]; i++) { @@ -450,7 +453,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) && !file_exists(pathspec[i])) { if (ignore_missing) { int dtype = DT_UNKNOWN; - if (excluded(&dir, pathspec[i], &dtype)) + if (path_excluded(&check, pathspec[i], -1, &dtype)) dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); } else die(_("pathspec '%s' did not match any files"), @@ -458,6 +461,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) } } free(seen); + path_exclude_check_clear(&check); } plug_bulk_checkin(); diff --git a/builtin/clone.c b/builtin/clone.c index a4d8d25ee3..7f3b9823ce 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -38,7 +38,7 @@ static const char * const builtin_clone_usage[] = { }; static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1; -static int option_local, option_no_hardlinks, option_shared, option_recursive; +static int option_local = -1, option_no_hardlinks, option_shared, option_recursive; static char *option_template, *option_depth; static char *option_origin = NULL; static char *option_branch = NULL; @@ -70,8 +70,8 @@ static struct option builtin_clone_options[] = { PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, OPT_BOOLEAN(0, "mirror", &option_mirror, "create a mirror repository (implies bare)"), - OPT_BOOLEAN('l', "local", &option_local, - "to clone from a local repository"), + OPT_BOOL('l', "local", &option_local, + "to clone from a local repository"), OPT_BOOLEAN(0, "no-hardlinks", &option_no_hardlinks, "don't use local hardlinks, always copy"), OPT_BOOLEAN('s', "shared", &option_shared, @@ -342,7 +342,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, if (!option_no_hardlinks) { if (!link(src->buf, dest->buf)) continue; - if (option_local) + if (option_local > 0) die_errno(_("failed to create link '%s'"), dest->buf); option_no_hardlinks = 1; } @@ -668,7 +668,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) die(_("repository '%s' does not exist"), repo_name); else repo = repo_name; - is_local = path && !is_bundle; + is_local = option_local != 0 && path && !is_bundle; if (is_local && option_depth) warning(_("--depth is ignored in local clones; use file:// instead.")); diff --git a/builtin/help.c b/builtin/help.c index 43d3c84449..8f9cd60548 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -12,6 +12,10 @@ #include "column.h" #include "help.h" +#ifndef DEFAULT_HELP_FORMAT +#define DEFAULT_HELP_FORMAT "man" +#endif + static struct man_viewer_list { struct man_viewer_list *next; char name[FLEX_ARRAY]; @@ -447,6 +451,8 @@ int cmd_help(int argc, const char **argv, const char *prefix) if (parsed_help_format != HELP_FORMAT_NONE) help_format = parsed_help_format; + if (help_format == HELP_FORMAT_NONE) + help_format = parse_help_format(DEFAULT_HELP_FORMAT); alias = alias_lookup(argv[0]); if (alias && !is_git_command(argv[0])) { diff --git a/builtin/log.c b/builtin/log.c index 906dca475a..4f1b42a685 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -21,6 +21,7 @@ #include "parse-options.h" #include "branch.h" #include "streaming.h" +#include "version.h" /* Set a default date-time format for git log ("log.date" config variable) */ static const char *default_date_mode = NULL; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 7cff175745..31b3f2d900 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -200,9 +200,19 @@ static void show_ru_info(void) } } +static int ce_excluded(struct path_exclude_check *check, struct cache_entry *ce) +{ + int dtype = ce_to_dtype(ce); + return path_excluded(check, ce->name, ce_namelen(ce), &dtype); +} + static void show_files(struct dir_struct *dir) { int i; + struct path_exclude_check check; + + if ((dir->flags & DIR_SHOW_IGNORED)) + path_exclude_check_init(&check, dir); /* For cached/deleted files we don't need to even do the readdir */ if (show_others || show_killed) { @@ -215,9 +225,8 @@ static void show_files(struct dir_struct *dir) if (show_cached | show_stage) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; - int dtype = ce_to_dtype(ce); - if (dir->flags & DIR_SHOW_IGNORED && - !excluded(dir, ce->name, &dtype)) + if ((dir->flags & DIR_SHOW_IGNORED) && + !ce_excluded(&check, ce)) continue; if (show_unmerged && !ce_stage(ce)) continue; @@ -232,9 +241,8 @@ static void show_files(struct dir_struct *dir) struct cache_entry *ce = active_cache[i]; struct stat st; int err; - int dtype = ce_to_dtype(ce); - if (dir->flags & DIR_SHOW_IGNORED && - !excluded(dir, ce->name, &dtype)) + if ((dir->flags & DIR_SHOW_IGNORED) && + !ce_excluded(&check, ce)) continue; if (ce->ce_flags & CE_UPDATE) continue; @@ -247,6 +255,9 @@ static void show_files(struct dir_struct *dir) show_ce_entry(tag_modified, ce); } } + + if ((dir->flags & DIR_SHOW_IGNORED)) + path_exclude_check_clear(&check); } /* diff --git a/bundle.c b/bundle.c index 8d31b98f58..8d12816b9d 100644 --- a/bundle.c +++ b/bundle.c @@ -188,12 +188,16 @@ int verify_bundle(struct bundle_header *header, int verbose) r->nr), r->nr); list_refs(r, 0, NULL); - r = &header->prerequisites; - printf_ln(Q_("The bundle requires this ref", - "The bundle requires these %d refs", - r->nr), - r->nr); - list_refs(r, 0, NULL); + if (!r->nr) { + printf_ln(_("The bundle records a complete history.")); + } else { + r = &header->prerequisites; + printf_ln(Q_("The bundle requires this ref", + "The bundle requires these %d refs", + r->nr), + r->nr); + list_refs(r, 0, NULL); + } } return ret; } diff --git a/dir.c b/dir.c index ed1510fbc8..2c02b312b7 100644 --- a/dir.c +++ b/dir.c @@ -553,7 +553,7 @@ int excluded_from_list(const char *pathname, return -1; /* undecided */ } -int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) +static int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) { int pathlen = strlen(pathname); int st; @@ -573,6 +573,64 @@ int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) return 0; } +void path_exclude_check_init(struct path_exclude_check *check, + struct dir_struct *dir) +{ + check->dir = dir; + strbuf_init(&check->path, 256); +} + +void path_exclude_check_clear(struct path_exclude_check *check) +{ + strbuf_release(&check->path); +} + +/* + * Is this name excluded? This is for a caller like show_files() that + * do not honor directory hierarchy and iterate through paths that are + * possibly in an ignored directory. + * + * A path to a directory known to be excluded is left in check->path to + * optimize for repeated checks for files in the same excluded directory. + */ +int path_excluded(struct path_exclude_check *check, + const char *name, int namelen, int *dtype) +{ + int i; + struct strbuf *path = &check->path; + + /* + * we allow the caller to pass namelen as an optimization; it + * must match the length of the name, as we eventually call + * excluded() on the whole name string. + */ + if (namelen < 0) + namelen = strlen(name); + + if (path->len && + path->len <= namelen && + !memcmp(name, path->buf, path->len) && + (!name[path->len] || name[path->len] == '/')) + return 1; + + strbuf_setlen(path, 0); + for (i = 0; name[i]; i++) { + int ch = name[i]; + + if (ch == '/') { + int dt = DT_DIR; + if (excluded(check->dir, path->buf, &dt)) + return 1; + } + strbuf_addch(path, ch); + } + + /* An entry in the index; cannot be a directory with subentries */ + strbuf_setlen(path, 0); + + return excluded(check->dir, name, dtype); +} + static struct dir_entry *dir_entry_new(const char *pathname, int len) { struct dir_entry *ent; diff --git a/dir.h b/dir.h index 58b6fc7c86..6c73e4151d 100644 --- a/dir.h +++ b/dir.h @@ -1,6 +1,8 @@ #ifndef DIR_H #define DIR_H +#include "strbuf.h" + struct dir_entry { unsigned int len; char name[FLEX_ARRAY]; /* more */ @@ -76,8 +78,22 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const extern int excluded_from_list(const char *pathname, int pathlen, const char *basename, int *dtype, struct exclude_list *el); -extern int excluded(struct dir_struct *, const char *, int *); struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len); + +/* + * The excluded() API is meant for callers that check each level of leading + * directory hierarchies with excluded() to avoid recursing into excluded + * directories. Callers that do not do so should use this API instead. + */ +struct path_exclude_check { + struct dir_struct *dir; + struct strbuf path; +}; +extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *); +extern void path_exclude_check_clear(struct path_exclude_check *); +extern int path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype); + + extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); diff --git a/git-request-pull.sh b/git-request-pull.sh index e6438e24c7..d566015975 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -57,9 +57,13 @@ headrev=$(git rev-parse --verify "$head"^0) || exit merge_base=$(git merge-base $baserev $headrev) || die "fatal: No commits in common between $base and $head" -# $head is the token given from the command line. If a ref with that -# name exists at the remote and their values match, we should use it. -# Otherwise find a ref that matches $headrev. +# $head is the token given from the command line, and $tag_name, if +# exists, is the tag we are going to show the commit information for. +# If that tag exists at the remote and it points at the commit, use it. +# Otherwise, if a branch with the same name as $head exists at the remote +# and their values match, use that instead. +# +# Otherwise find a random ref that matches $headrev. find_matching_ref=' sub abbr { my $ref = shift; @@ -70,24 +74,29 @@ find_matching_ref=' } } - my ($exact, $found); + my ($tagged, $branch, $found); while () { my ($sha1, $ref, $deref) = /^(\S+)\s+(\S+?)(\^\{\})?$/; next unless ($sha1 eq $ARGV[1]); $found = abbr($ref); + if ($deref && $ref eq "tags/$ARGV[2]") { + $tagged = $found; + last; + } if ($ref =~ m|/\Q$ARGV[0]\E$|) { $exact = $found; - last; } } - if ($exact) { + if ($tagged) { + print "$tagged\n"; + } elsif ($exact) { print "$exact\n"; } elsif ($found) { print "$found\n"; } ' -ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev") +ref=$(git ls-remote "$url" | perl -e "$find_matching_ref" "$head" "$headrev" "$tag_name") url=$(git ls-remote --get-url "$url") @@ -114,6 +123,12 @@ fi && if test -n "$tag_name" then + if test -z "$ref" || test "$ref" != "tags/$tag_name" + then + echo >&2 "warn: You locally have $tag_name but it does not (yet)" + echo >&2 "warn: appear to be at $url" + echo >&2 "warn: Do you want to push it there, perhaps?" + fi git cat-file tag "$tag_name" | sed -n -e '1,/^$/d' -e '/^-----BEGIN PGP /q' -e p echo diff --git a/git.c b/git.c index d232de92e4..4da3db522a 100644 --- a/git.c +++ b/git.c @@ -256,8 +256,6 @@ static int handle_alias(int *argcp, const char ***argv) return ret; } -const char git_version_string[] = GIT_VERSION; - #define RUN_SETUP (1<<0) #define RUN_SETUP_GENTLY (1<<1) #define USE_PAGER (1<<2) diff --git a/help.c b/help.c index 6012c07b73..662349dd56 100644 --- a/help.c +++ b/help.c @@ -6,6 +6,7 @@ #include "common-cmds.h" #include "string-list.h" #include "column.h" +#include "version.h" void add_cmdname(struct cmdnames *cmds, const char *name, int len) { diff --git a/http.c b/http.c index 5cb87f16f2..b61ac85d4b 100644 --- a/http.c +++ b/http.c @@ -4,6 +4,7 @@ #include "run-command.h" #include "url.h" #include "credential.h" +#include "version.h" int active_requests; int http_is_verbose; @@ -299,7 +300,7 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_VERBOSE, 1); curl_easy_setopt(result, CURLOPT_USERAGENT, - user_agent ? user_agent : GIT_HTTP_USER_AGENT); + user_agent ? user_agent : git_user_agent()); if (curl_ftp_no_epsv) curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0); diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh index 2b962cfda7..79045abb51 100755 --- a/t/t1304-default-acl.sh +++ b/t/t1304-default-acl.sh @@ -14,16 +14,15 @@ umask 077 # We need an arbitrary other user give permission to using ACLs. root # is a good candidate: exists on all unices, and it has permission # anyway, so we don't create a security hole running the testsuite. - -setfacl_out="$(setfacl -m u:root:rwx . 2>&1)" -setfacl_ret=$? - -if test $setfacl_ret != 0 -then - say "Unable to use setfacl (output: '$setfacl_out'; return code: '$setfacl_ret')" -else - test_set_prereq SETFACL -fi +test_expect_success 'checking for a working acl setup' ' + if setfacl -m d:m:rwx -m u:root:rwx . && + getfacl . | grep user:root:rwx && + touch should-have-readable-acl && + getfacl should-have-readable-acl | egrep "mask::?rw-" + then + test_set_prereq SETFACL + fi +' if test -z "$LOGNAME" then diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index c6feca44e3..7ff6e0e16c 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -124,4 +124,14 @@ test_expect_success 'cloning non-git directory fails' ' test_must_fail git clone not-a-git-repo not-a-git-repo-clone ' +test_expect_success 'cloning file:// does not hardlink' ' + git clone --bare file://"$(pwd)"/a non-local && + ! repo_is_hardlinked non-local +' + +test_expect_success 'cloning a local path with --no-local does not hardlink' ' + git clone --bare --no-local a force-nonlocal && + ! repo_is_hardlinked force-nonlocal +' + test_done diff --git a/unpack-trees.c b/unpack-trees.c index ad40109432..33a581924e 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1023,6 +1023,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options o->el = ⪙ } + if (o->dir) { + o->path_exclude_check = xmalloc(sizeof(struct path_exclude_check)); + path_exclude_check_init(o->path_exclude_check, o->dir); + } memset(&o->result, 0, sizeof(o->result)); o->result.initialized = 1; o->result.timestamp.sec = o->src_index->timestamp.sec; @@ -1148,6 +1152,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options done: free_excludes(&el); + if (o->path_exclude_check) { + path_exclude_check_clear(o->path_exclude_check); + free(o->path_exclude_check); + } return ret; return_failed: @@ -1363,7 +1371,8 @@ static int check_ok_to_remove(const char *name, int len, int dtype, if (ignore_case && icase_exists(o, name, len, st)) return 0; - if (o->dir && excluded(o->dir, name, &dtype)) + if (o->dir && + path_excluded(o->path_exclude_check, name, -1, &dtype)) /* * ce->name is explicitly excluded, so it is Ok to * overwrite it. diff --git a/unpack-trees.h b/unpack-trees.h index 5e432f576e..ec74a9f19a 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -52,6 +52,7 @@ struct unpack_trees_options { const char *prefix; int cache_bottom; struct dir_struct *dir; + struct path_exclude_check *path_exclude_check; struct pathspec *pathspec; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_ERROR_TYPES]; diff --git a/version.c b/version.c new file mode 100644 index 0000000000..f98d5a654d --- /dev/null +++ b/version.c @@ -0,0 +1,17 @@ +#include "git-compat-util.h" +#include "version.h" + +const char git_version_string[] = GIT_VERSION; + +const char *git_user_agent(void) +{ + static const char *agent = NULL; + + if (!agent) { + agent = getenv("GIT_USER_AGENT"); + if (!agent) + agent = GIT_USER_AGENT; + } + + return agent; +} diff --git a/version.h b/version.h new file mode 100644 index 0000000000..fd9cdd6316 --- /dev/null +++ b/version.h @@ -0,0 +1,8 @@ +#ifndef VERSION_H +#define VERSION_H + +extern const char git_version_string[]; + +const char *git_user_agent(void); + +#endif /* VERSION_H */