Merge branch 'sn/complete-bash-wo-process-subst'
authorJunio C Hamano <gitster@pobox.com>
Thu, 27 Oct 2011 19:04:28 +0000 (12:04 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 27 Oct 2011 19:04:28 +0000 (12:04 -0700)
* sn/complete-bash-wo-process-subst:
completion: fix issue with process substitution not working on Git for Windows

21 files changed:
Documentation/RelNotes/1.7.8.txt
Documentation/gitweb.conf.txt
builtin/clone.c
builtin/fetch.c
builtin/grep.c
builtin/remote.c
contrib/mw-to-git/git-remote-mediawiki
git-submodule.sh
gitweb/INSTALL
gitweb/Makefile
gitweb/gitweb.perl
perl/Git.pm
read-cache.c
remote.c
remote.h
t/gitweb-lib.sh
t/t5510-fetch.sh
t/t7511-status-index.sh [new file with mode: 0755]
t/t9700-perl-git.sh
t/t9700/test.pl
templates/hooks--pre-commit.sample
index d7b2c76c03a9983f64e92b418ea74b508ccb8b13..3045245aa6fa507dc9f1cf6b51b73bc7581151d2 100644 (file)
@@ -96,6 +96,9 @@ Updates since v1.7.7
  * "git stash" learned "--include-untracked" option to stash away
    untracked/ignored cruft from the working tree.
 
+ * "git submodule clone" does not leak an error message to the UI
+   level unnecessarily anymore.
+
  * "git submodule update" learned to honor "none" as the value for
    submodule.<name>.update to specify that the named submodule should
    not be checked out by default.
@@ -113,6 +116,9 @@ Updates since v1.7.7
  * "gitweb" leaked unescaped control characters from syntax hiliter
    outputs.
 
+ * "gitweb" can be told to give custom string at the end of the HTML
+   HEAD element.
+
  * "gitweb" now has its own manual pages.
 
 
@@ -150,6 +156,10 @@ included in this release.
    with too many refs were unnecessarily slow.
    (merge 17d68a54d jp/get-ref-dir-unsorted later to maint).
 
+ * "git fetch --prune" was unsafe when used with refspecs from the
+   command line.
+   (merge e8c1e6c cn/fetch-prune later to maint).
+
  * Report from "git commit" on untracked files was confused under
    core.ignorecase option.
    (merge 2548183b jk/name-hash-dirent later to maint).
@@ -198,9 +208,15 @@ included in this release.
    of a blob, when JavaScript actions are enabled.
    (merge 2b07ff3ff ps/gitweb-js-with-lineno later to maint).
 
+ * The logic to filter out forked projects in the project list in
+   "gitweb" was broken for some time.
+   (merge 53c632f jm/maint-gitweb-filter-forks-fix later to maint).
+
+
+
 ---
 exec >/var/tmp/1
-O=v1.7.7-485-g9ee3d37
+O=v1.7.7.1-453-g0b26d1e
 echo O=$(git describe --always master)
 git log --first-parent --oneline --reverse ^$O master
 echo
index 4ca3e27dc97b81f73215391569f62d52550e33c1..7aba497b74540499f45ca135bc094ecdffff240a 100644 (file)
@@ -364,6 +364,11 @@ $site_name::
 +
 Can be set using the `GITWEB_SITENAME` at build time.  Unset by default.
 
+$site_html_head_string::
+       HTML snippet to be included in the <head> section of each page.
+       Can be set using `GITWEB_SITE_HTML_HEAD_STRING` at build time.
+       No default value.
+
 $site_header::
        Name of a file with HTML to be included at the top of each page.
        Relative to the directory containing the 'gitweb.cgi' script.
index 488f48e9a571fa9b958cd95b92808b44f4541982..efe8b6cce5a9f2ae40c6f69755debecfb6b501ca 100644 (file)
@@ -577,9 +577,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
        if (0 <= option_verbosity) {
                if (option_bare)
-                       printf(_("Cloning into bare repository %s...\n"), dir);
+                       printf(_("Cloning into bare repository '%s'...\n"), dir);
                else
-                       printf(_("Cloning into %s...\n"), dir);
+                       printf(_("Cloning into '%s'...\n"), dir);
        }
        init_db(option_template, INIT_DB_QUIET);
        write_config(&option_config);
index 1adf6c176f31b2ece263bc1f07eee8c7e0b40098..91731b909aeb22bf8d4e366b8b92281ac0f9ac0c 100644 (file)
@@ -510,10 +510,10 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
        return ret;
 }
 
-static int prune_refs(struct transport *transport, struct ref *ref_map)
+static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map)
 {
        int result = 0;
-       struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
+       struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
        const char *dangling_msg = dry_run
                ? _("   (%s will become dangling)\n")
                : _("   (%s has become dangling)\n");
@@ -704,8 +704,31 @@ static int do_fetch(struct transport *transport,
                free_refs(ref_map);
                return 1;
        }
-       if (prune)
-               prune_refs(transport, ref_map);
+       if (prune) {
+               /* If --tags was specified, pretend the user gave us the canonical tags refspec */
+               if (tags == TAGS_SET) {
+                       const char *tags_str = "refs/tags/*:refs/tags/*";
+                       struct refspec *tags_refspec, *refspec;
+
+                       /* Copy the refspec and add the tags to it */
+                       refspec = xcalloc(ref_count + 1, sizeof(struct refspec));
+                       tags_refspec = parse_fetch_refspec(1, &tags_str);
+                       memcpy(refspec, refs, ref_count * sizeof(struct refspec));
+                       memcpy(&refspec[ref_count], tags_refspec, sizeof(struct refspec));
+                       ref_count++;
+
+                       prune_refs(refspec, ref_count, ref_map);
+
+                       ref_count--;
+                       /* The rest of the strings belong to fetch_one */
+                       free_refspec(1, tags_refspec);
+                       free(refspec);
+               } else if (ref_count) {
+                       prune_refs(refs, ref_count, ref_map);
+               } else {
+                       prune_refs(transport->remote->fetch, transport->remote->fetch_refspec_nr, ref_map);
+               }
+       }
        free_refs(ref_map);
 
        /* if neither --no-tags nor --tags was specified, do automated tag
@@ -888,7 +911,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
        atexit(unlock_pack);
        refspec = parse_fetch_refspec(ref_nr, refs);
        exit_code = do_fetch(transport, refspec, ref_nr);
-       free(refspec);
+       free_refspec(ref_nr, refspec);
        transport_disconnect(transport);
        transport = NULL;
        return exit_code;
index 7d0779f6cfd60149379f957941ebef18aef735ab..3d7329d78c6e3ec31ed8ce03b8928c9ed24afb9e 100644 (file)
@@ -74,13 +74,32 @@ static int all_work_added;
 /* This lock protects all the variables above. */
 static pthread_mutex_t grep_mutex;
 
+static inline void grep_lock(void)
+{
+       if (use_threads)
+               pthread_mutex_lock(&grep_mutex);
+}
+
+static inline void grep_unlock(void)
+{
+       if (use_threads)
+               pthread_mutex_unlock(&grep_mutex);
+}
+
 /* Used to serialize calls to read_sha1_file. */
 static pthread_mutex_t read_sha1_mutex;
 
-#define grep_lock() pthread_mutex_lock(&grep_mutex)
-#define grep_unlock() pthread_mutex_unlock(&grep_mutex)
-#define read_sha1_lock() pthread_mutex_lock(&read_sha1_mutex)
-#define read_sha1_unlock() pthread_mutex_unlock(&read_sha1_mutex)
+static inline void read_sha1_lock(void)
+{
+       if (use_threads)
+               pthread_mutex_lock(&read_sha1_mutex);
+}
+
+static inline void read_sha1_unlock(void)
+{
+       if (use_threads)
+               pthread_mutex_unlock(&read_sha1_mutex);
+}
 
 /* Signalled when a new work_item is added to todo. */
 static pthread_cond_t cond_add;
@@ -354,13 +373,9 @@ static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type
 {
        void *data;
 
-       if (use_threads) {
-               read_sha1_lock();
-               data = read_sha1_file(sha1, type, size);
-               read_sha1_unlock();
-       } else {
-               data = read_sha1_file(sha1, type, size);
-       }
+       read_sha1_lock();
+       data = read_sha1_file(sha1, type, size);
+       read_sha1_unlock();
        return data;
 }
 
index 44eb8795cd654fa2fce97b9999e6611dd74bf479..733514979969f69ad45448a67d981b621bbee146 100644 (file)
@@ -349,7 +349,8 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
                else
                        string_list_append(&states->tracked, abbrev_branch(ref->name));
        }
-       stale_refs = get_stale_heads(states->remote, fetch_map);
+       stale_refs = get_stale_heads(states->remote->fetch,
+                                    states->remote->fetch_refspec_nr, fetch_map);
        for (ref = stale_refs; ref; ref = ref->next) {
                struct string_list_item *item =
                        string_list_append(&states->stale, abbrev_branch(ref->name));
index 0b32d18eaa963492bfb7fb1bb4437763db7b70c3..c18bfa1f1515a8edb27c2d468a2982860a561939 100755 (executable)
@@ -109,6 +109,10 @@ $dumb_push = ($dumb_push eq "true");
 
 my $wiki_name = $url;
 $wiki_name =~ s/[^\/]*:\/\///;
+# If URL is like http://user:password@example.com/, we clearly don't
+# want the password in $wiki_name. While we're there, also remove user
+# and '@' sign, to avoid author like MWUser@HTTPUser@host.com
+$wiki_name =~ s/^.*@//;
 
 # Commands parser
 my $entry;
index 928a62f626fe7ff1db8239713d94ff9aa25158eb..3adab9363563e80e4ceb2c7fb5c3ab91ac1ef505 100755 (executable)
@@ -104,9 +104,9 @@ module_name()
        re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
        name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
                sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
-       test -z "$name" &&
-       die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$path'")"
-       echo "$name"
+       test -z "$name" &&
+       die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$path'")"
+       echo "$name"
 }
 
 #
@@ -130,7 +130,7 @@ module_clone()
 
        gitdir=
        gitdir_base=
-       name=$(module_name "$path")
+       name=$(module_name "$path" 2>/dev/null)
        base_path=$(dirname "$path")
 
        gitdir=$(git rev-parse --git-dir)
index d134ffe4c75fcc303631cdac15c1bed011c45fd1..6d4540679731bdfd33af61635c59b798b19a8888 100644 (file)
@@ -130,6 +130,8 @@ You can specify the following configuration variables when building GIT:
    Points to an .html file which is included on the gitweb project
    overview page ('projects_list' view), if it exists.  Relative to
    gitweb.cgi script.  [Default: indextext.html]
+ * GITWEB_SITE_HTML_HEAD_STRING
+   html snippet to include in the <head> section of each page. [No default]
  * GITWEB_SITE_HEADER
    Filename of html text to include at top of each page.  Relative to
    gitweb.cgi script.  [No default]
index 1c85b5fda8bc994e0ecd249e11e8f2331098bea9..cd194d057f9231ed77f57f05b22a226cd1210f6d 100644 (file)
@@ -34,6 +34,7 @@ GITWEB_CSS = static/gitweb.css
 GITWEB_LOGO = static/git-logo.png
 GITWEB_FAVICON = static/git-favicon.png
 GITWEB_JS = static/gitweb.js
+GITWEB_SITE_HTML_HEAD_STRING =
 GITWEB_SITE_HEADER =
 GITWEB_SITE_FOOTER =
 HIGHLIGHT_BIN = highlight
@@ -144,6 +145,7 @@ GITWEB_REPLACE = \
        -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
        -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
        -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \
+       -e 's|++GITWEB_SITE_HTML_HEAD_STRING++|$(GITWEB_SITE_HTML_HEAD_STRING)|g' \
        -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
        -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \
        -e 's|++HIGHLIGHT_BIN++|$(HIGHLIGHT_BIN)|g'
@@ -185,7 +187,9 @@ install: all
 ### Cleaning rules
 
 clean:
-       $(RM) gitweb.cgi static/gitweb.min.js static/gitweb.min.css GITWEB-BUILD-OPTIONS
+       $(RM) gitweb.cgi static/gitweb.js \
+               static/gitweb.min.js static/gitweb.min.css \
+               GITWEB-BUILD-OPTIONS
 
 .PHONY: all clean install test test-installed .FORCE-GIT-VERSION-FILE FORCE
 
index 85d64b244dead86132de8a2a980cfbfc27c86494..4f0c3bd90c7f90dad1674f50999da534c33c0261 100755 (executable)
@@ -85,6 +85,8 @@ sub evaluate_uri {
 our $site_name = "++GITWEB_SITENAME++"
                  || ($ENV{'SERVER_NAME'} || "Untitled") . " Git";
 
+# html snippet to include in the <head> section of each page
+our $site_html_head_string = "++GITWEB_SITE_HTML_HEAD_STRING++";
 # filename of html text to include at top of each page
 our $site_header = "++GITWEB_SITE_HEADER++";
 # html text to include at home page
@@ -2886,7 +2888,7 @@ sub filter_forks_from_projects_list {
                $path =~ s/\.git$//;      # forks of 'repo.git' are in 'repo/' directory
                next if ($path =~ m!/$!); # skip non-bare repositories, e.g. 'repo/.git'
                next unless ($path);      # skip '.git' repository: tests, git-instaweb
-               next unless (-d $path);   # containing directory exists
+               next unless (-d "$projectroot/$path"); # containing directory exists
                $pr->{'forks'} = [];      # there can be 0 or more forks of project
 
                # add to trie
@@ -3879,6 +3881,11 @@ sub git_header_html {
                print "<base href=\"".esc_url($base_url)."\" />\n";
        }
        print_header_links($status);
+
+       if (defined $site_html_head_string) {
+               print to_utf8($site_html_head_string);
+       }
+
        print "</head>\n" .
              "<body>\n";
 
index c279bfb2446880bb18a5e6c898ef533805e78e56..f7ce511bbbfbff5a479200f2814ad87b96f16791 100644 (file)
@@ -570,30 +570,10 @@ sub wc_chdir {
 (exception is thrown otherwise), in array context returns allows the
 variable to be set multiple times and returns all the values.
 
-This currently wraps command('config') so it is not so fast.
-
 =cut
 
 sub config {
-       my ($self, $var) = _maybe_self(@_);
-
-       try {
-               my @cmd = ('config');
-               unshift @cmd, $self if $self;
-               if (wantarray) {
-                       return command(@cmd, '--get-all', $var);
-               } else {
-                       return command_oneline(@cmd, '--get', $var);
-               }
-       } catch Git::Error::Command with {
-               my $E = shift;
-               if ($E->value() == 1) {
-                       # Key not found.
-                       return;
-               } else {
-                       throw $E;
-               }
-       };
+       return _config_common({}, @_);
 }
 
 
@@ -603,28 +583,18 @@ sub config {
 is usable as a boolean in perl (and C<undef> if it's not defined,
 of course).
 
-This currently wraps command('config') so it is not so fast.
-
 =cut
 
 sub config_bool {
-       my ($self, $var) = _maybe_self(@_);
+       my $val = scalar _config_common({'kind' => '--bool'}, @_);
 
-       try {
-               my @cmd = ('config', '--bool', '--get', $var);
-               unshift @cmd, $self if $self;
-               my $val = command_oneline(@cmd);
-               return undef unless defined $val;
+       # Do not rewrite this as return (defined $val && $val eq 'true')
+       # as some callers do care what kind of falsehood they receive.
+       if (!defined $val) {
+               return undef;
+       } else {
                return $val eq 'true';
-       } catch Git::Error::Command with {
-               my $E = shift;
-               if ($E->value() == 1) {
-                       # Key not found.
-                       return undef;
-               } else {
-                       throw $E;
-               }
-       };
+       }
 }
 
 
@@ -633,32 +603,13 @@ sub config_bool {
 Retrieve the path configuration C<VARIABLE>. The return value
 is an expanded path or C<undef> if it's not defined.
 
-This currently wraps command('config') so it is not so fast.
-
 =cut
 
 sub config_path {
-       my ($self, $var) = _maybe_self(@_);
-
-       try {
-               my @cmd = ('config', '--path');
-               unshift @cmd, $self if $self;
-               if (wantarray) {
-                       return command(@cmd, '--get-all', $var);
-               } else {
-                       return command_oneline(@cmd, '--get', $var);
-               }
-       } catch Git::Error::Command with {
-               my $E = shift;
-               if ($E->value() == 1) {
-                       # Key not found.
-                       return undef;
-               } else {
-                       throw $E;
-               }
-       };
+       return _config_common({'kind' => '--path'}, @_);
 }
 
+
 =item config_int ( VARIABLE )
 
 Retrieve the integer configuration C<VARIABLE>. The return value
@@ -667,22 +618,31 @@ sub config_path {
 by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
 It would return C<undef> if configuration variable is not defined,
 
-This currently wraps command('config') so it is not so fast.
-
 =cut
 
 sub config_int {
+       return scalar _config_common({'kind' => '--int'}, @_);
+}
+
+# Common subroutine to implement bulk of what the config* family of methods
+# do. This curently wraps command('config') so it is not so fast.
+sub _config_common {
+       my ($opts) = shift @_;
        my ($self, $var) = _maybe_self(@_);
 
        try {
-               my @cmd = ('config', '--int', '--get', $var);
+               my @cmd = ('config', $opts->{'kind'} ? $opts->{'kind'} : ());
                unshift @cmd, $self if $self;
-               return command_oneline(@cmd);
+               if (wantarray) {
+                       return command(@cmd, '--get-all', $var);
+               } else {
+                       return command_oneline(@cmd, '--get', $var);
+               }
        } catch Git::Error::Command with {
                my $E = shift;
                if ($E->value() == 1) {
                        # Key not found.
-                       return undef;
+                       return;
                } else {
                        throw $E;
                }
index 01a0e2505121f10544ee03948e545d07c24f366e..5790a91044e4fdf5b2eec515051a66c110e0daa4 100644 (file)
@@ -1249,9 +1249,9 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en
 
 static inline size_t estimate_cache_size(size_t ondisk_size, unsigned int entries)
 {
-       long per_entry;
-
-       per_entry = sizeof(struct cache_entry) - sizeof(struct ondisk_cache_entry);
+       size_t fix_size_mem = offsetof(struct cache_entry, name);
+       size_t fix_size_dsk = offsetof(struct ondisk_cache_entry, name);
+       long per_entry = (fix_size_mem - fix_size_dsk + 7) & ~7;
 
        /*
         * Alignment can cause differences. This should be "alignof", but
index 2f62c9a3ed914152d8071aa11950f3d9c2799122..e2ef99114478c49863809ea5cef46392a5a8c0e9 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -803,59 +803,56 @@ static int match_name_with_pattern(const char *key, const char *name,
        return ret;
 }
 
-char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
-                    const char *name)
+static int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
 {
        int i;
-       char *ret = NULL;
-       for (i = 0; i < nr_refspec; i++) {
-               struct refspec *refspec = refspecs + i;
-               if (refspec->pattern) {
-                       if (match_name_with_pattern(refspec->src, name,
-                                                   refspec->dst, &ret))
-                               return ret;
-               } else if (!strcmp(refspec->src, name))
-                       return xstrdup(refspec->dst);
-       }
-       return NULL;
-}
+       int find_src = !query->src;
 
-int remote_find_tracking(struct remote *remote, struct refspec *refspec)
-{
-       int find_src = refspec->src == NULL;
-       char *needle, **result;
-       int i;
+       if (find_src && !query->dst)
+               return error("query_refspecs: need either src or dst");
 
-       if (find_src) {
-               if (!refspec->dst)
-                       return error("find_tracking: need either src or dst");
-               needle = refspec->dst;
-               result = &refspec->src;
-       } else {
-               needle = refspec->src;
-               result = &refspec->dst;
-       }
+       for (i = 0; i < ref_count; i++) {
+               struct refspec *refspec = &refs[i];
+               const char *key = find_src ? refspec->dst : refspec->src;
+               const char *value = find_src ? refspec->src : refspec->dst;
+               const char *needle = find_src ? query->dst : query->src;
+               char **result = find_src ? &query->src : &query->dst;
 
-       for (i = 0; i < remote->fetch_refspec_nr; i++) {
-               struct refspec *fetch = &remote->fetch[i];
-               const char *key = find_src ? fetch->dst : fetch->src;
-               const char *value = find_src ? fetch->src : fetch->dst;
-               if (!fetch->dst)
+               if (!refspec->dst)
                        continue;
-               if (fetch->pattern) {
+               if (refspec->pattern) {
                        if (match_name_with_pattern(key, needle, value, result)) {
-                               refspec->force = fetch->force;
+                               query->force = refspec->force;
                                return 0;
                        }
                } else if (!strcmp(needle, key)) {
                        *result = xstrdup(value);
-                       refspec->force = fetch->force;
+                       query->force = refspec->force;
                        return 0;
                }
        }
        return -1;
 }
 
+char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
+                    const char *name)
+{
+       struct refspec query;
+
+       memset(&query, 0, sizeof(struct refspec));
+       query.src = (char *)name;
+
+       if (query_refspecs(refspecs, nr_refspec, &query))
+               return NULL;
+
+       return query.dst;
+}
+
+int remote_find_tracking(struct remote *remote, struct refspec *refspec)
+{
+       return query_refspecs(remote->fetch, remote->fetch_refspec_nr, refspec);
+}
+
 static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen,
                const char *name)
 {
@@ -1659,36 +1656,47 @@ struct ref *guess_remote_head(const struct ref *head,
 }
 
 struct stale_heads_info {
-       struct remote *remote;
        struct string_list *ref_names;
        struct ref **stale_refs_tail;
+       struct refspec *refs;
+       int ref_count;
 };
 
 static int get_stale_heads_cb(const char *refname,
        const unsigned char *sha1, int flags, void *cb_data)
 {
        struct stale_heads_info *info = cb_data;
-       struct refspec refspec;
-       memset(&refspec, 0, sizeof(refspec));
-       refspec.dst = (char *)refname;
-       if (!remote_find_tracking(info->remote, &refspec)) {
-               if (!((flags & REF_ISSYMREF) ||
-                   string_list_has_string(info->ref_names, refspec.src))) {
-                       struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
-                       hashcpy(ref->new_sha1, sha1);
-               }
+       struct refspec query;
+       memset(&query, 0, sizeof(struct refspec));
+       query.dst = (char *)refname;
+
+       if (query_refspecs(info->refs, info->ref_count, &query))
+               return 0; /* No matches */
+
+       /*
+        * If we did find a suitable refspec and it's not a symref and
+        * it's not in the list of refs that currently exist in that
+        * remote we consider it to be stale.
+        */
+       if (!((flags & REF_ISSYMREF) ||
+             string_list_has_string(info->ref_names, query.src))) {
+               struct ref *ref = make_linked_ref(refname, &info->stale_refs_tail);
+               hashcpy(ref->new_sha1, sha1);
        }
+
+       free(query.src);
        return 0;
 }
 
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map)
+struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fetch_map)
 {
        struct ref *ref, *stale_refs = NULL;
        struct string_list ref_names = STRING_LIST_INIT_NODUP;
        struct stale_heads_info info;
-       info.remote = remote;
        info.ref_names = &ref_names;
        info.stale_refs_tail = &stale_refs;
+       info.refs = refs;
+       info.ref_count = ref_count;
        for (ref = fetch_map; ref; ref = ref->next)
                string_list_append(&ref_names, ref->name);
        sort_string_list(&ref_names);
index 67294778b6a7af3f0fa2c3cb1c0a34cc11d508b1..b3955983ba5caea698a78868abcbb54451b6daa8 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -164,6 +164,6 @@ struct ref *guess_remote_head(const struct ref *head,
                              int all);
 
 /* Return refs which no longer exist on remote */
-struct ref *get_stale_heads(struct remote *remote, struct ref *fetch_map);
+struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fetch_map);
 
 #endif
index 292753f77c4daf5f3cb55de1c28269b13455544f..21d11d6c2d65982d94f933b2a673b744cbc2e28a 100644 (file)
@@ -16,6 +16,7 @@ our \$projectroot = "$safe_pwd";
 our \$project_maxdepth = 8;
 our \$home_link_str = 'projects';
 our \$site_name = '[localhost]';
+our \$site_html_head_string = '';
 our \$site_header = '';
 our \$site_footer = '';
 our \$home_text = 'indextext.html';
index 7e433b179f9fcb0b3ccdd0ec83c6ec850735e391..e0af4c4e62c40a563f692361944cc58e2c8e38e2 100755 (executable)
@@ -76,6 +76,56 @@ test_expect_success "fetch test for-merge" '
        cut -f -2 .git/FETCH_HEAD >actual &&
        test_cmp expected actual'
 
+test_expect_success 'fetch --prune on its own works as expected' '
+       cd "$D" &&
+       git clone . prune &&
+       cd prune &&
+       git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+
+       git fetch --prune origin &&
+       test_must_fail git rev-parse origin/extrabranch
+'
+
+test_expect_success 'fetch --prune with a branch name keeps branches' '
+       cd "$D" &&
+       git clone . prune-branch &&
+       cd prune-branch &&
+       git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+
+       git fetch --prune origin master &&
+       git rev-parse origin/extrabranch
+'
+
+test_expect_success 'fetch --prune with a namespace keeps other namespaces' '
+       cd "$D" &&
+       git clone . prune-namespace &&
+       cd prune-namespace &&
+
+       git fetch --prune origin refs/heads/a/*:refs/remotes/origin/a/* &&
+       git rev-parse origin/master
+'
+
+test_expect_success 'fetch --prune --tags does not delete the remote-tracking branches' '
+       cd "$D" &&
+       git clone . prune-tags &&
+       cd prune-tags &&
+       git fetch origin refs/heads/master:refs/tags/sometag &&
+
+       git fetch --prune --tags origin &&
+       git rev-parse origin/master &&
+       test_must_fail git rev-parse somebranch
+'
+
+test_expect_success 'fetch --prune --tags with branch does not delete other remote-tracking branches' '
+       cd "$D" &&
+       git clone . prune-tags-branch &&
+       cd prune-tags-branch &&
+       git fetch origin refs/heads/master:refs/remotes/origin/extrabranch &&
+
+       git fetch --prune --tags origin master &&
+       git rev-parse origin/extrabranch
+'
+
 test_expect_success 'fetch tags when there is no tags' '
 
     cd "$D" &&
diff --git a/t/t7511-status-index.sh b/t/t7511-status-index.sh
new file mode 100755 (executable)
index 0000000..bca359d
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+test_description='git status with certain file name lengths'
+
+. ./test-lib.sh
+
+files="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z"
+
+check() {
+       len=$1
+       prefix=$2
+
+       for i in $files
+       do
+               : >$prefix$i
+       done
+
+       test_expect_success "status, filename length $len" "
+               git add $prefix* &&
+               git status
+       "
+       rm $prefix* .git/index
+}
+
+check  1
+check  2 p
+check  3 pr
+check  4 pre
+check  5 pref
+check  6 prefi
+check  7 prefix
+check  8 prefix-
+check  9 prefix-p
+check 10 prefix-pr
+check 11 prefix-pre
+check 12 prefix-pref
+check 13 prefix-prefi
+check 14 prefix-prefix
+check 15 prefix-prefix-
+check 16 prefix-prefix-p
+check 17 prefix-prefix-pr
+check 18 prefix-prefix-pre
+check 19 prefix-prefix-pref
+check 20 prefix-prefix-prefi
+check 21 prefix-prefix-prefix
+check 22 prefix-prefix-prefix-
+check 23 prefix-prefix-prefix-p
+check 24 prefix-prefix-prefix-pr
+
+test_done
index 3787186703f51f75103824f562c3849483ceaae1..435d8964763d3f048a71db5453b3a19e0cbb7fb9 100755 (executable)
@@ -43,7 +43,11 @@ test_expect_success \
      git config --add test.booltrue true &&
      git config --add test.boolfalse no &&
      git config --add test.boolother other &&
-     git config --add test.int 2k
+     git config --add test.int 2k &&
+     git config --add test.path "~/foo" &&
+     git config --add test.pathexpanded "$HOME/foo" &&
+     git config --add test.pathmulti foo &&
+     git config --add test.pathmulti bar
      '
 
 # The external test will outputs its own plan
index 13ba96e21a9295805aed40c89ecd5178db6bfae4..3b9b48408a87150fad9b1ac1f8cf5ea65e2b09ba 100755 (executable)
@@ -33,6 +33,10 @@ BEGIN
 is($r->config_int("test.nonexistent"), undef, "config_int: nonexistent");
 ok($r->config_bool("test.booltrue"), "config_bool: true");
 ok(!$r->config_bool("test.boolfalse"), "config_bool: false");
+is($r->config_path("test.path"), $r->config("test.pathexpanded"),
+   "config_path: ~/foo expansion");
+is_deeply([$r->config_path("test.pathmulti")], ["foo", "bar"],
+   "config_path: multiple values");
 our $ansi_green = "\x1b[32m";
 is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color");
 # Cannot test $r->get_colorbool("color.foo")) because we do not
index b187c4bb1f256e19c25f80dd64f3451ced77e123..18c48297652174ffae65b877dd131711a5746181 100755 (executable)
@@ -18,6 +18,9 @@ fi
 # If you want to allow non-ascii filenames set this variable to true.
 allownonascii=$(git config hooks.allownonascii)
 
+# Redirect output to stderr.
+exec 1>&2
+
 # Cross platform projects tend to avoid non-ascii filenames; prevent
 # them from being added to the repository. We exploit the fact that the
 # printable range starts at the space character and ends with tilde.
@@ -25,8 +28,8 @@ if [ "$allownonascii" != "true" ] &&
        # Note that the use of brackets around a tr range is ok here, (it's
        # even required, for portability to Solaris 10's /usr/bin/tr), since
        # the square bracket bytes happen to fall in the designated range.
-       test "$(git diff --cached --name-only --diff-filter=A -z $against |
-         LC_ALL=C tr -d '[ -~]\0')"
+       test $(git diff --cached --name-only --diff-filter=A -z $against |
+         LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
 then
        echo "Error: Attempt to add a non-ascii file name."
        echo
@@ -43,4 +46,5 @@ then
        exit 1
 fi
 
+# If there are whitespace errors, print the offending file names and fail.
 exec git diff-index --check --cached $against --