Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Mon, 25 Jun 2012 18:21:33 +0000 (11:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 25 Jun 2012 18:21:33 +0000 (11:21 -0700)
* maint:
git-submodule.sh: fix filename in comment.
git-add--interactive.perl: Remove two unused variables

24 files changed:
Documentation/RelNotes/1.7.12.txt [new file with mode: 0644]
Documentation/git-clone.txt
GIT-VERSION-GEN
Makefile
RelNotes
builtin.h
builtin/add.c
builtin/clone.c
builtin/help.c
builtin/log.c
builtin/ls-files.c
bundle.c
dir.c
dir.h
git-request-pull.sh
git.c
help.c
http.c
t/t1304-default-acl.sh
t/t5701-clone-local.sh
unpack-trees.c
unpack-trees.h
version.c [new file with mode: 0644]
version.h [new file with mode: 0644]
diff --git a/Documentation/RelNotes/1.7.12.txt b/Documentation/RelNotes/1.7.12.txt
new file mode 100644 (file)
index 0000000..117f4b1
--- /dev/null
@@ -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).
index 6e22522c4f7e97dbab42b3cbb5b538cdea3b4d74..c1ddd4c2cc78e078a0849fc8fb82f8de0aa7fc9b 100644 (file)
@@ -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
index a7570decfb6f5331f7dc2e2e1fb29f5d1151489d..fde74a68d541fbe58585ece72149faa90c3fe5c0 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.11.1
+DEF_VER=v1.7.11.GIT
 
 LF='
 '
index 4592f1f2ee82a656c9dfd2fcf9132e4fd132bc67..f62ca2aebb28758ea164b65dab7dff19ddd4c3e0 100644 (file)
--- 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
index ceedb902ca9fb8c9ee58b7c06348eaf767f715bc..19bb2ebbe687d9ded1a5c82d28d4410de1e2f19f 120000 (symlink)
--- 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
index 338f540e39af7093b39668a3bed16158a4483566..dea1643fafe09e795b309545067c29806896d041 100644 (file)
--- 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[];
 
index b79336d712b4c71cc2f026b0e9f42ea0bcebfc6f..87446cf92a686ed69717c85a6b38302f59351460 100644 (file)
@@ -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();
index a4d8d25ee319c2bbcfe5b450468cfb41d3fcd0d6..7f3b9823ce4e2ff911acca4d1632e7310e8e0aeb 100644 (file)
@@ -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."));
 
index 43d3c84449a57ec7028acb663d4ab4bea134c97e..8f9cd60548c122d8a6f03e0b388f0b6508a3f354 100644 (file)
 #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])) {
index 906dca475af0ed51d499cce4a7c0a34f038c5810..4f1b42a685ff76a64e7c8386007ca450c5032cb1 100644 (file)
@@ -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;
index 7cff175745d680d9cde24280e569b4f513d28673..31b3f2d9006e0f5703ca9fb37bea247012581c0e 100644 (file)
@@ -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);
 }
 
 /*
index 8d31b98f58b9e9bf156615130ec80684f788fcaa..8d12816b9d0bc682ed9c019a7a5d5cec4b859171 100644 (file)
--- 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 ed1510fbc808f4c9799eb84a3c38030b7565f3bc..2c02b312b77f3363c234bdc66faaeafd5899586d 100644 (file)
--- 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 58b6fc7c86df1bd5ac6f072672027a1474732ac6..6c73e4151de8374d35427358cde50b506a2d7de9 100644 (file)
--- 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);
index e6438e24c7c787b55428a48eca9461d772db7ee6..d566015975d317683c89bfcfde93ae998efd1058 100755 (executable)
@@ -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 (<STDIN>) {
                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 d232de92e496bd5750015edce22d3b67f236b605..4da3db522ac37ed8695593d3e3cc0bb87e0574f4 100644 (file)
--- 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 6012c07b735a541659cd75e2334563aeb933bfcb..662349dd56fd31d2ea2635657887640f43ce947c 100644 (file)
--- 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 5cb87f16f25fe3d32e2594c8c6325d562eddc9ca..b61ac85d4b19a0b9121c5b19f2b9c731bbb238d4 100644 (file)
--- 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);
index 2b962cfda70d998e9c2799cf8fc720b330cd118a..79045abb5171691246167a42eec6bf18fbeb0b76 100755 (executable)
@@ -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
index c6feca44e3677c416bfe4841fda5205b2133f7bc..7ff6e0e16cbeb014c1ea551392a63beca2dbc386 100755 (executable)
@@ -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
index ad40109432971b8b26f107a84b02aeb405e8daf9..33a581924e11167dc546bdf97c8d49460b43674e 100644 (file)
@@ -1023,6 +1023,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
                        o->el = &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.
index 5e432f576eb2304a63510a61a71182e11f777092..ec74a9f19a47c39de61def9709da6d4d6f1dcbdb 100644 (file)
@@ -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 (file)
index 0000000..f98d5a6
--- /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 (file)
index 0000000..fd9cdd6
--- /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 */