Merge branch 'ta/glossary' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 22 Apr 2013 18:26:58 +0000 (11:26 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Apr 2013 18:26:58 +0000 (11:26 -0700)
* ta/glossary:
glossary: improve definitions of refspec and pathspec
The name of the hash function is "SHA-1", not "SHA1"
glossary: improve description of SHA-1 related topics
glossary: remove outdated/misleading/irrelevant entries

26 files changed:
Documentation/git-daemon.txt
Documentation/git-http-backend.txt
Documentation/glossary-content.txt
builtin/apply.c
builtin/show-branch.c
bundle.c
combine-diff.c
contrib/completion/git-prompt.sh
contrib/remote-helpers/git-remote-hg
git-filter-branch.sh
grep.c
grep.h
help.c
perl/Git.pm
rerere.c
t/lib-httpd/apache.conf
t/t2030-unresolve-info.sh
t/t4038-diff-combined.sh
t/t4124-apply-ws-rule.sh
t/t4150-am.sh
t/t5541-http-push.sh
t/t5704-bundle.sh
t/t7003-filter-branch.sh
t/t9700/test.pl
t/test-lib-functions.sh
t/test-lib.sh
index 77da564134f92e692e078888d7f87bd6710e821f..bfb106cccd5880f0cd40b03059aa79a5569acb63 100644 (file)
@@ -147,6 +147,13 @@ OPTIONS
 Giving these options is an error when used with `--inetd`; use
 the facility of inet daemon to achieve the same before spawning
 'git daemon' if needed.
++
+Like many programs that switch user id, the daemon does not reset
+environment variables such as `$HOME` when it runs git programs,
+e.g. `upload-pack` and `receive-pack`. When using this option, you
+may also want to set and export `HOME` to point at the home
+directory of `<user>` before starting the daemon, and make sure any
+Git configuration files in that directory are readable by `<user>`.
 
 --enable=<service>::
 --disable=<service>::
index 7b1e85cd15b8ced793e56b8accc1e32dfa5aabc9..e3bcdb50e30ea984cb8ae842df0cf1e561e32a62 100644 (file)
@@ -80,7 +80,30 @@ ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
 ----------------------------------------------------------------
 +
 To enable anonymous read access but authenticated write access,
-require authorization with a LocationMatch directive:
+require authorization for both the initial ref advertisement (which we
+detect as a push via the service parameter in the query string), and the
+receive-pack invocation itself:
++
+----------------------------------------------------------------
+RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
+RewriteCond %{REQUEST_URI} /git-receive-pack$
+RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]
+
+<LocationMatch "^/git/">
+       Order Deny,Allow
+       Deny from env=AUTHREQUIRED
+
+       AuthType Basic
+       AuthName "Git Access"
+       Require group committers
+       Satisfy Any
+       ...
+</LocationMatch>
+----------------------------------------------------------------
++
+If you do not have `mod_rewrite` available to match against the query
+string, it is sufficient to just protect `git-receive-pack` itself,
+like:
 +
 ----------------------------------------------------------------
 <LocationMatch "^/git/.*/git-receive-pack$">
@@ -91,6 +114,15 @@ require authorization with a LocationMatch directive:
 </LocationMatch>
 ----------------------------------------------------------------
 +
+In this mode, the server will not request authentication until the
+client actually starts the object negotiation phase of the push, rather
+than during the initial contact.  For this reason, you must also enable
+the `http.receivepack` config option in any repositories that should
+accept a push. The default behavior, if `http.receivepack` is not set,
+is to reject any pushes by unauthenticated users; the initial request
+will therefore report `403 Forbidden` to the client, without even giving
+an opportunity for authentication.
++
 To require authentication for both reads and writes, use a Location
 directive around the repository, or one of its parent directories:
 +
@@ -158,6 +190,54 @@ ScriptAliasMatch \
 ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
 ----------------------------------------------------------------
 
+Lighttpd::
+       Ensure that `mod_cgi`, `mod_alias, `mod_auth`, `mod_setenv` are
+       loaded, then set `GIT_PROJECT_ROOT` appropriately and redirect
+       all requests to the CGI:
++
+----------------------------------------------------------------
+alias.url += ( "/git" => "/usr/lib/git-core/git-http-backend" )
+$HTTP["url"] =~ "^/git" {
+       cgi.assign = ("" => "")
+       setenv.add-environment = (
+               "GIT_PROJECT_ROOT" => "/var/www/git",
+               "GIT_HTTP_EXPORT_ALL" => ""
+       )
+}
+----------------------------------------------------------------
++
+To enable anonymous read access but authenticated write access:
++
+----------------------------------------------------------------
+$HTTP["querystring"] =~ "service=git-receive-pack" {
+       include "git-auth.conf"
+}
+$HTTP["url"] =~ "^/git/.*/git-receive-pack$" {
+       include "git-auth.conf"
+}
+----------------------------------------------------------------
++
+where `git-auth.conf` looks something like:
++
+----------------------------------------------------------------
+auth.require = (
+       "/" => (
+               "method" => "basic",
+               "realm" => "Git Access",
+               "require" => "valid-user"
+              )
+)
+# ...and set up auth.backend here
+----------------------------------------------------------------
++
+To require authentication for both reads and writes:
++
+----------------------------------------------------------------
+$HTTP["url"] =~ "^/git/private" {
+       include "git-auth.conf"
+}
+----------------------------------------------------------------
+
 
 ENVIRONMENT
 -----------
index 740bb325bf8006340c30659e58a76ac84f47b851..ce3e4fae731b6c6c4e67034393309cd20f69b7dc 100644 (file)
@@ -100,9 +100,22 @@ to point at the new commit.
 
 [[def_detached_HEAD]]detached HEAD::
        Normally the <<def_HEAD,HEAD>> stores the name of a
-       <<def_branch,branch>>.  However, Git also allows you to <<def_checkout,check out>>
-       an arbitrary <<def_commit,commit>> that isn't necessarily the tip of any
-       particular branch.  In this case HEAD is said to be "detached".
+       <<def_branch,branch>>, and commands that operate on the
+       history HEAD represents operate on the history leading to the
+       tip of the branch the HEAD points at.  However, Git also
+       allows you to <<def_checkout,check out>> an arbitrary
+       <<def_commit,commit>> that isn't necessarily the tip of any
+       particular branch.  The HEAD in such a state is called
+       "detached".
++
+Note that commands that operate on the history of the current branch
+(e.g. `git commit` to build a new history on top of it) still work
+while the HEAD is detached. They update the HEAD to point at the tip
+of the updated history without affecting any branch.  Commands that
+update or inquire information _about_ the current branch (e.g. `git
+branch --set-upstream-to` that sets what remote tracking branch the
+current branch integrates with) obviously do not work, as there is no
+(real) current branch to ask about in this state.
 
 [[def_directory]]directory::
        The list you get with "ls" :-)
index f6a3c97dd5903a8b7d42383da370428067c3e14e..30eefc3c7b390800e9452a06da18208d2fef4f11 100644 (file)
@@ -2117,10 +2117,10 @@ static void update_pre_post_images(struct image *preimage,
 
        /*
         * Adjust the common context lines in postimage. This can be
-        * done in-place when we are just doing whitespace fixing,
-        * which does not make the string grow, but needs a new buffer
-        * when ignoring whitespace causes the update, since in this case
-        * we could have e.g. tabs converted to multiple spaces.
+        * done in-place when we are shrinking it with whitespace
+        * fixing, but needs a new buffer when ignoring whitespace or
+        * expanding leading tabs to spaces.
+        *
         * We trust the caller to tell us if the update can be done
         * in place (postlen==0) or not.
         */
@@ -2185,7 +2185,7 @@ static int match_fragment(struct image *img,
        int i;
        char *fixed_buf, *buf, *orig, *target;
        struct strbuf fixed;
-       size_t fixed_len;
+       size_t fixed_len, postlen;
        int preimage_limit;
 
        if (preimage->nr + try_lno <= img->nr) {
@@ -2335,6 +2335,7 @@ static int match_fragment(struct image *img,
        strbuf_init(&fixed, preimage->len + 1);
        orig = preimage->buf;
        target = img->buf + try;
+       postlen = 0;
        for (i = 0; i < preimage_limit; i++) {
                size_t oldlen = preimage->line[i].len;
                size_t tgtlen = img->line[try_lno + i].len;
@@ -2362,6 +2363,7 @@ static int match_fragment(struct image *img,
                match = (tgtfix.len == fixed.len - fixstart &&
                         !memcmp(tgtfix.buf, fixed.buf + fixstart,
                                             fixed.len - fixstart));
+               postlen += tgtfix.len;
 
                strbuf_release(&tgtfix);
                if (!match)
@@ -2399,8 +2401,10 @@ static int match_fragment(struct image *img,
         * hunk match.  Update the context lines in the postimage.
         */
        fixed_buf = strbuf_detach(&fixed, &fixed_len);
+       if (postlen < postimage->len)
+               postlen = 0;
        update_pre_post_images(preimage, postimage,
-                              fixed_buf, fixed_len, 0);
+                              fixed_buf, fixed_len, postlen);
        return 1;
 
  unmatch_exit:
index d208fd6c6821c729a713edb485a20bbe8d5e2692..90fc6b1b9d2a397ae43dfc4c0aba6bc192c9823c 100644 (file)
@@ -162,29 +162,28 @@ static void name_commits(struct commit_list *list,
                        nth = 0;
                        while (parents) {
                                struct commit *p = parents->item;
-                               char newname[1000], *en;
+                               struct strbuf newname = STRBUF_INIT;
                                parents = parents->next;
                                nth++;
                                if (p->util)
                                        continue;
-                               en = newname;
                                switch (n->generation) {
                                case 0:
-                                       en += sprintf(en, "%s", n->head_name);
+                                       strbuf_addstr(&newname, n->head_name);
                                        break;
                                case 1:
-                                       en += sprintf(en, "%s^", n->head_name);
+                                       strbuf_addf(&newname, "%s^", n->head_name);
                                        break;
                                default:
-                                       en += sprintf(en, "%s~%d",
-                                               n->head_name, n->generation);
+                                       strbuf_addf(&newname, "%s~%d",
+                                                   n->head_name, n->generation);
                                        break;
                                }
                                if (nth == 1)
-                                       en += sprintf(en, "^");
+                                       strbuf_addch(&newname, '^');
                                else
-                                       en += sprintf(en, "^%d", nth);
-                               name_commit(p, xstrdup(newname), 0);
+                                       strbuf_addf(&newname, "^%d", nth);
+                               name_commit(p, strbuf_detach(&newname, NULL), 0);
                                i++;
                                name_first_parent_chain(p);
                        }
index 505e07e93468b68454c7ec906f40eacea9746551..4b0e5cd51b82f916c26d3776f81f22cdb3045fa6 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -57,7 +57,7 @@ static int parse_bundle_header(int fd, struct bundle_header *header,
                 * followed by SP and subject line.
                 */
                if (get_sha1_hex(buf.buf, sha1) ||
-                   (40 <= buf.len && !isspace(buf.buf[40])) ||
+                   (buf.len > 40 && !isspace(buf.buf[40])) ||
                    (!is_prereq && buf.len <= 40)) {
                        if (report_path)
                                error(_("unrecognized header: %s%s (%d)"),
index 35d41cd56d2ddb8df416e5e422552ec473294055..6288485965b5f79c1311e48e8de5c1be97730977 100644 (file)
@@ -5,6 +5,7 @@
 #include "diffcore.h"
 #include "quote.h"
 #include "xdiff-interface.h"
+#include "xdiff/xmacros.h"
 #include "log-tree.h"
 #include "refs.h"
 #include "userdiff.h"
@@ -122,7 +123,47 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode,
        return blob;
 }
 
-static void append_lost(struct sline *sline, int n, const char *line, int len)
+static int match_string_spaces(const char *line1, int len1,
+                              const char *line2, int len2,
+                              long flags)
+{
+       if (flags & XDF_WHITESPACE_FLAGS) {
+               for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
+               for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
+       }
+
+       if (!(flags & (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)))
+               return (len1 == len2 && !memcmp(line1, line2, len1));
+
+       while (len1 > 0 && len2 > 0) {
+               len1--;
+               len2--;
+               if (XDL_ISSPACE(line1[len1]) || XDL_ISSPACE(line2[len2])) {
+                       if ((flags & XDF_IGNORE_WHITESPACE_CHANGE) &&
+                           (!XDL_ISSPACE(line1[len1]) || !XDL_ISSPACE(line2[len2])))
+                               return 0;
+
+                       for (; len1 > 0 && XDL_ISSPACE(line1[len1]); len1--);
+                       for (; len2 > 0 && XDL_ISSPACE(line2[len2]); len2--);
+               }
+               if (line1[len1] != line2[len2])
+                       return 0;
+       }
+
+       if (flags & XDF_IGNORE_WHITESPACE) {
+               /* Consume remaining spaces */
+               for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
+               for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
+       }
+
+       /* We matched full line1 and line2 */
+       if (!len1 && !len2)
+               return 1;
+
+       return 0;
+}
+
+static void append_lost(struct sline *sline, int n, const char *line, int len, long flags)
 {
        struct lline *lline;
        unsigned long this_mask = (1UL<<n);
@@ -133,8 +174,8 @@ static void append_lost(struct sline *sline, int n, const char *line, int len)
        if (sline->lost_head) {
                lline = sline->next_lost;
                while (lline) {
-                       if (lline->len == len &&
-                           !memcmp(lline->line, line, len)) {
+                       if (match_string_spaces(lline->line, lline->len,
+                                               line, len, flags)) {
                                lline->parent_map |= this_mask;
                                sline->next_lost = lline->next;
                                return;
@@ -162,6 +203,7 @@ struct combine_diff_state {
        int n;
        struct sline *sline;
        struct sline *lost_bucket;
+       long flags;
 };
 
 static void consume_line(void *state_, char *line, unsigned long len)
@@ -201,7 +243,7 @@ static void consume_line(void *state_, char *line, unsigned long len)
                return; /* not in any hunk yet */
        switch (line[0]) {
        case '-':
-               append_lost(state->lost_bucket, state->n, line+1, len-1);
+               append_lost(state->lost_bucket, state->n, line+1, len-1, state->flags);
                break;
        case '+':
                state->sline[state->lno-1].flag |= state->nmask;
@@ -215,7 +257,7 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
                         struct sline *sline, unsigned int cnt, int n,
                         int num_parent, int result_deleted,
                         struct userdiff_driver *textconv,
-                        const char *path)
+                        const char *path, long flags)
 {
        unsigned int p_lno, lno;
        unsigned long nmask = (1UL << n);
@@ -231,9 +273,10 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
        parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
        parent_file.size = sz;
        memset(&xpp, 0, sizeof(xpp));
-       xpp.flags = 0;
+       xpp.flags = flags;
        memset(&xecfg, 0, sizeof(xecfg));
        memset(&state, 0, sizeof(state));
+       state.flags = flags;
        state.nmask = nmask;
        state.sline = sline;
        state.lno = 1;
@@ -962,7 +1005,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
                                     elem->parent[i].mode,
                                     &result_file, sline,
                                     cnt, i, num_parent, result_deleted,
-                                    textconv, elem->path);
+                                    textconv, elem->path, opt->xdl_opts);
        }
 
        show_hunks = make_hunks(sline, cnt, num_parent, dense);
index 341422a766efe70580817d98a574d95bd9ddebf9..756a9514591c7664c82c93d3a6d50d91f46857d8 100644 (file)
@@ -282,6 +282,8 @@ __git_ps1 ()
                                r="|MERGING"
                        elif [ -f "$g/CHERRY_PICK_HEAD" ]; then
                                r="|CHERRY-PICKING"
+                       elif [ -f "$g/REVERT_HEAD" ]; then
+                               r="|REVERTING"
                        elif [ -f "$g/BISECT_LOG" ]; then
                                r="|BISECTING"
                        fi
index 328c2dc76dd33e47cfe69064757631e9717771e6..45f6c80d45ab9848d1197e34a00b8ac5977a05fc 100755 (executable)
@@ -326,6 +326,8 @@ def export_ref(repo, name, kind, head):
         else:
             modified, removed = get_filechanges(repo, c, parents[0])
 
+        desc += '\n'
+
         if mode == 'hg':
             extra_msg = ''
 
@@ -349,7 +351,6 @@ def export_ref(repo, name, kind, head):
                 else:
                     extra_msg += "extra : %s : %s\n" % (key, urllib.quote(value))
 
-            desc += '\n'
             if extra_msg:
                 desc += '\n--HG--\n' + extra_msg
 
index 53142492afcfb92f0453359af9a00a045c51e7e9..ac2a005fdb23c48d8451188ffd7b1c8194b0295f 100755 (executable)
@@ -199,6 +199,7 @@ t)
        test -d "$tempdir" &&
                die "$tempdir already exists, please remove it"
 esac
+orig_dir=$(pwd)
 mkdir -p "$tempdir/t" &&
 tempdir="$(cd "$tempdir"; pwd)" &&
 cd "$tempdir/t" &&
@@ -206,7 +207,7 @@ workdir="$(pwd)" ||
 die ""
 
 # Remove tempdir on exit
-trap 'cd ../..; rm -rf "$tempdir"' 0
+trap 'cd "$orig_dir"; rm -rf "$tempdir"' 0
 
 ORIG_GIT_DIR="$GIT_DIR"
 ORIG_GIT_WORK_TREE="$GIT_WORK_TREE"
@@ -469,7 +470,7 @@ if [ "$filter_tag_name" ]; then
        done
 fi
 
-cd ../..
+cd "$orig_dir"
 rm -rf "$tempdir"
 
 trap - 0
diff --git a/grep.c b/grep.c
index 4bd1b8b1dd67e4f5c2223536b435198ce67463ba..bb548cae69d1eece8832c97332a91daac5f8dceb 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -625,7 +625,8 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
        for (p = opt->header_list; p; p = p->next) {
                if (p->token != GREP_PATTERN_HEAD)
                        die("bug: a non-header pattern in grep header list.");
-               if (p->field < 0 || GREP_HEADER_FIELD_MAX <= p->field)
+               if (p->field < GREP_HEADER_FIELD_MIN ||
+                   GREP_HEADER_FIELD_MAX <= p->field)
                        die("bug: unknown header field %d", p->field);
                compile_regexp(p, opt);
        }
diff --git a/grep.h b/grep.h
index 8fc854f400802c3329fc3c028942de55b820ac90..e4a1df56a423548af4cba728811eb21b62518e15 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -28,7 +28,8 @@ enum grep_context {
 };
 
 enum grep_header_field {
-       GREP_HEADER_AUTHOR = 0,
+       GREP_HEADER_FIELD_MIN = 0,
+       GREP_HEADER_AUTHOR = GREP_HEADER_FIELD_MIN,
        GREP_HEADER_COMMITTER,
        GREP_HEADER_REFLOG,
 
diff --git a/help.c b/help.c
index 1dfa0b05827e6e75dc463092b2838cd1c991623c..02ba043319932411e90121d4147f25395782dfb5 100644 (file)
--- a/help.c
+++ b/help.c
@@ -397,6 +397,10 @@ const char *help_unknown_cmd(const char *cmd)
 
 int cmd_version(int argc, const char **argv, const char *prefix)
 {
+       /*
+        * The format of this string should be kept stable for compatibility
+        * with external projects that rely on the output of "git version".
+        */
        printf("git version %s\n", git_version_string);
        return 0;
 }
index f207b47183a00fc02320a3785a8d4085b42259fe..a69467feaa73b44a5ad88abd05dd72df116c1488 100644 (file)
@@ -1335,12 +1335,12 @@ sub _command_common_pipe {
                if (not defined $pid) {
                        throw Error::Simple("open failed: $!");
                } elsif ($pid == 0) {
-                       if (defined $opts{STDERR}) {
-                               close STDERR;
-                       }
                        if ($opts{STDERR}) {
                                open (STDERR, '>&', $opts{STDERR})
                                        or die "dup failed: $!";
+                       } elsif (defined $opts{STDERR}) {
+                               open (STDERR, '>', '/dev/null')
+                                       or die "opening /dev/null failed: $!";
                        }
                        _cmd_exec($self, $cmd, @args);
                }
index a6a5cd57bef4aaf204f1bad293c18b5af6f57f53..98e3e294d0dc295290b7b891a834186c0791e43a 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -284,8 +284,10 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
        strbuf_release(sb);
        if (!io->input.len)
                return -1;
-       ep = strchrnul(io->input.buf, '\n');
-       if (*ep == '\n')
+       ep = memchr(io->input.buf, '\n', io->input.len);
+       if (!ep)
+               ep = io->input.buf + io->input.len;
+       else if (*ep == '\n')
                ep++;
        len = ep - io->input.buf;
        strbuf_add(sb, io->input.buf, len);
@@ -295,7 +297,7 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
 
 static int handle_cache(const char *path, unsigned char *sha1, const char *output)
 {
-       mmfile_t mmfile[3];
+       mmfile_t mmfile[3] = {{NULL}};
        mmbuffer_t result = {NULL, 0};
        struct cache_entry *ce;
        int pos, len, i, hunk_no;
@@ -314,17 +316,16 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
        for (i = 0; i < 3; i++) {
                enum object_type type;
                unsigned long size;
+               int j;
 
-               mmfile[i].size = 0;
-               mmfile[i].ptr = NULL;
                if (active_nr <= pos)
                        break;
                ce = active_cache[pos++];
-               if (ce_namelen(ce) != len || memcmp(ce->name, path, len)
-                   || ce_stage(ce) != i + 1)
-                       break;
-               mmfile[i].ptr = read_sha1_file(ce->sha1, &type, &size);
-               mmfile[i].size = size;
+               if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
+                       continue;
+               j = ce_stage(ce) - 1;
+               mmfile[j].ptr = read_sha1_file(ce->sha1, &type, &size);
+               mmfile[j].size = size;
        }
        for (i = 0; i < 3; i++) {
                if (!mmfile[i].ptr && !mmfile[i].size)
index 938b4cf803b3b4ea07be20338425f784b80cdf0c..542241b229c96a51bc1b32d72e33b9fcb0d313be 100644 (file)
@@ -40,6 +40,9 @@ ErrorLog error.log
 <IfModule !mod_authz_user.c>
        LoadModule authz_user_module modules/mod_authz_user.so
 </IfModule>
+<IfModule !mod_authz_host.c>
+       LoadModule authz_host_module modules/mod_authz_host.so
+</IfModule>
 </IfVersion>
 
 PassEnv GIT_VALGRIND
@@ -110,6 +113,21 @@ SSLEngine On
        Require valid-user
 </LocationMatch>
 
+RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
+RewriteCond %{REQUEST_URI} /git-receive-pack$
+RewriteRule ^/half-auth-complete/ - [E=AUTHREQUIRED:yes]
+
+<Location /half-auth-complete/>
+  Order Deny,Allow
+  Deny from env=AUTHREQUIRED
+
+  AuthType Basic
+  AuthName "Git Access"
+  AuthUserFile passwd
+  Require valid-user
+  Satisfy Any
+</Location>
+
 <IfDefine DAV>
        LoadModule dav_module modules/mod_dav.so
        LoadModule dav_fs_module modules/mod_dav_fs.so
index f2620650ce1d25252210c07db20e54f99bd515c6..309199bca272b63499ca69edbb953bcc8c770ecc 100755 (executable)
@@ -44,14 +44,21 @@ prime_resolve_undo () {
 
 test_expect_success setup '
        mkdir fi &&
+       printf "a\0a" >binary &&
+       git add binary &&
        test_commit initial fi/le first &&
        git branch side &&
        git branch another &&
+       printf "a\0b" >binary &&
+       git add binary &&
        test_commit second fi/le second &&
        git checkout side &&
        test_commit third fi/le third &&
+       git branch add-add &&
        git checkout another &&
        test_commit fourth fi/le fourth &&
+       git checkout add-add &&
+       test_commit fifth add-differently &&
        git checkout master
 '
 
@@ -167,4 +174,22 @@ test_expect_success 'rerere and rerere forget (subdirectory)' '
        test_cmp expect actual
 '
 
+test_expect_success 'rerere forget (binary)' '
+       git checkout -f side &&
+       printf "a\0c" >binary &&
+       git commit -a -m binary &&
+       test_must_fail git merge second &&
+       git rerere forget binary
+'
+
+test_expect_success 'rerere forget (add-add conflict)' '
+       git checkout -f master &&
+       echo master >add-differently &&
+       git add add-differently &&
+       git commit -m "add differently" &&
+       test_must_fail git merge fifth &&
+       git rerere forget add-differently 2>actual &&
+       test_i18ngrep "no remembered" actual
+'
+
 test_done
index 614425adac536d84e6835d9d707b86fe8f5f4d36..b7e16a7840afc32d36c6a118ed2fa1dbb579476a 100755 (executable)
@@ -3,6 +3,7 @@
 test_description='combined diff'
 
 . ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
 
 setup_helper () {
        one=$1 branch=$2 side=$3 &&
@@ -113,4 +114,114 @@ test_expect_success 'check --cc --raw with forty trees' '
        grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
 '
 
+test_expect_success 'setup combined ignore spaces' '
+       git checkout master &&
+       >test &&
+       git add test &&
+       git commit -m initial &&
+
+       tr -d Q <<-\EOF >test &&
+       always coalesce
+       eol space coalesce Q
+       space  change coalesce
+       all spa ces coalesce
+       eol spaces Q
+       space  change
+       all spa ces
+       EOF
+       git commit -m "test space change" -a &&
+
+       git checkout -b side HEAD^ &&
+       tr -d Q <<-\EOF >test &&
+       always coalesce
+       eol space coalesce
+       space change coalesce
+       all spaces coalesce
+       eol spaces
+       space change
+       all spaces
+       EOF
+       git commit -m "test other space changes" -a &&
+
+       test_must_fail git merge master &&
+       tr -d Q <<-\EOF >test &&
+       eol spaces Q
+       space  change
+       all spa ces
+       EOF
+       git commit -m merged -a
+'
+
+test_expect_success 'check combined output (no ignore space)' '
+       git show >actual.tmp &&
+       sed -e "1,/^@@@/d" < actual.tmp >actual &&
+       tr -d Q <<-\EOF >expected &&
+       --always coalesce
+       - eol space coalesce
+       - space change coalesce
+       - all spaces coalesce
+       - eol spaces
+       - space change
+       - all spaces
+        -eol space coalesce Q
+        -space  change coalesce
+        -all spa ces coalesce
+       + eol spaces Q
+       + space  change
+       + all spa ces
+       EOF
+       compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore space at eol)' '
+       git show --ignore-space-at-eol >actual.tmp &&
+       sed -e "1,/^@@@/d" < actual.tmp >actual &&
+       tr -d Q <<-\EOF >expected &&
+       --always coalesce
+       --eol space coalesce
+       - space change coalesce
+       - all spaces coalesce
+        -space  change coalesce
+        -all spa ces coalesce
+         eol spaces Q
+       - space change
+       - all spaces
+       + space  change
+       + all spa ces
+       EOF
+       compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore space change)' '
+       git show -b >actual.tmp &&
+       sed -e "1,/^@@@/d" < actual.tmp >actual &&
+       tr -d Q <<-\EOF >expected &&
+       --always coalesce
+       --eol space coalesce
+       --space change coalesce
+       - all spaces coalesce
+        -all spa ces coalesce
+         eol spaces Q
+         space  change
+       - all spaces
+       + all spa ces
+       EOF
+       compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore all spaces)' '
+       git show -w >actual.tmp &&
+       sed -e "1,/^@@@/d" < actual.tmp >actual &&
+       tr -d Q <<-\EOF >expected &&
+       --always coalesce
+       --eol space coalesce
+       --space change coalesce
+       --all spaces coalesce
+         eol spaces Q
+         space  change
+         all spa ces
+       EOF
+       compare_diff_patch expected actual
+'
+
 test_done
index 581a801649f20a74e81c32f9503f233c3cd3d507..5d0c5983381b4072d915de0f8d75053b19172d66 100755 (executable)
@@ -486,4 +486,30 @@ test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
        test_cmp one expect
 '
 
+test_expect_success 'whitespace=fix to expand' '
+       qz_to_tab_space >preimage <<-\EOF &&
+       QQa
+       QQb
+       QQc
+       ZZZZZZZZZZZZZZZZd
+       QQe
+       QQf
+       QQg
+       EOF
+       qz_to_tab_space >patch <<-\EOF &&
+       diff --git a/preimage b/preimage
+       --- a/preimage
+       +++ b/preimage
+       @@ -1,7 +1,6 @@
+        QQa
+        QQb
+        QQc
+       -QQd
+        QQe
+        QQf
+        QQg
+       EOF
+       git -c core.whitespace=tab-in-indent apply --whitespace=fix patch
+'
+
 test_done
index cdafd7e7c1e6c73a97c36a60f77810badff603f2..12f6b027acbccae3fe524906970ff139ddccfed0 100755 (executable)
@@ -17,7 +17,7 @@ test_expect_success 'setup: messages' '
        vero eos et accusam et justo duo dolores et ea rebum.
 
        EOF
-       q_to_tab <<-\EOF >>msg &&
+       qz_to_tab_space <<-\EOF >>msg &&
        QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
        Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
        Qat vero eros et accumsan et iusto odio dignissim qui blandit
index 4b4b4a604f3075dec1056b31da5cccc0c4ed5a9a..8a9dc859317dc085dc99ddbd28eeada26c4d7d7e 100755 (executable)
@@ -295,5 +295,35 @@ test_expect_success 'push to auth-only-for-push repo' '
        test_cmp expect actual
 '
 
+test_expect_success 'create repo without http.receivepack set' '
+       cd "$ROOT_PATH" &&
+       git init half-auth &&
+       (
+               cd half-auth &&
+               test_commit one
+       ) &&
+       git clone --bare half-auth "$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git"
+'
+
+test_expect_success 'clone via half-auth-complete does not need password' '
+       cd "$ROOT_PATH" &&
+       set_askpass wrong &&
+       git clone "$HTTPD_URL"/half-auth-complete/smart/half-auth.git \
+               half-auth-clone &&
+       expect_askpass none
+'
+
+test_expect_success 'push into half-auth-complete requires password' '
+       cd "$ROOT_PATH/half-auth-clone" &&
+       echo two >expect &&
+       test_commit two &&
+       set_askpass user@host &&
+       git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" &&
+       git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \
+               log -1 --format=%s >actual &&
+       expect_askpass both user@host &&
+       test_cmp expect actual
+'
+
 stop_httpd
 test_done
index 9e43731fe504c46737c5294e4d508b5c20bbb663..a45c31692e17218988e6619742c366043e426039 100755 (executable)
@@ -58,4 +58,14 @@ test_expect_success 'ridiculously long subject in boundary' '
        grep "^-[0-9a-f]\\{40\\} " boundary
 '
 
+test_expect_success 'prerequisites with an empty commit message' '
+       : >file1 &&
+       git add file1 &&
+       test_tick &&
+       git commit --allow-empty-message -m "" &&
+       test_commit file2 &&
+       git bundle create bundle HEAD^.. &&
+       git bundle verify bundle
+'
+
 test_done
index 1e7a209efa715bc52d14d7f653ecfc13ffb5301f..9496736a89eb6b0b1ece64052cd2726c516c952b 100755 (executable)
@@ -64,6 +64,20 @@ test_expect_success 'correct GIT_DIR while using -d' '
        grep drepo "$TRASHDIR/backup-refs"
 '
 
+test_expect_success 'tree-filter works with -d' '
+       git init drepo-tree &&
+       (
+               cd drepo-tree &&
+               test_commit one &&
+               git filter-branch -d "$TRASHDIR/dfoo" \
+                       --tree-filter "echo changed >one.t" &&
+               echo changed >expect &&
+               git cat-file blob HEAD:one.t >actual &&
+               test_cmp expect actual &&
+               test_cmp one.t actual
+       )
+'
+
 test_expect_success 'Fail if commit filter fails' '
        test_must_fail git filter-branch -f --commit-filter "exit 1" HEAD
 '
index 0d4e366232c29bdde0e1059d431ae96afc259112..1140767b50706f03b0da5b2c8befdae6898e4136 100755 (executable)
@@ -45,7 +45,8 @@ BEGIN
 # Failure cases for config:
 # Save and restore STDERR; we will probably extract this into a
 # "dies_ok" method and possibly move the STDERR handling to Git.pm.
-open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR;
+open our $tmpstderr, ">&STDERR" or die "cannot save STDERR";
+open STDERR, ">", "/dev/null" or die "cannot redirect STDERR to /dev/null";
 is($r->config("test.dupstring"), "value2", "config: multivar");
 eval { $r->config_bool("test.boolother") };
 ok($@, "config_bool: non-boolean values fail");
index fa62d010f68e3ee97e6754687ad4d08564d3c96b..3fc9cc92884bd03f1d4f6a2b543b4c0e0fb55959 100644 (file)
@@ -91,6 +91,10 @@ q_to_tab () {
        tr Q '\011'
 }
 
+qz_to_tab_space () {
+       tr QZ '\011\040'
+}
+
 append_cr () {
        sed -e 's/$/Q/' | tr Q '\015'
 }
index 8d76cf23d46c813991fbf59da2f1f3b79110547c..657b0bd862b7473b66b2feb378b8985e455e5ac9 100644 (file)
@@ -592,14 +592,14 @@ then
 fi
 
 # Test repository
-test="trash directory.$(basename "$0" .sh)"
-test -n "$root" && test="$root/$test"
-case "$test" in
-/*) TRASH_DIRECTORY="$test" ;;
- *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$test" ;;
+TRASH_DIRECTORY="trash directory.$(basename "$0" .sh)"
+test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
+case "$TRASH_DIRECTORY" in
+/*) ;; # absolute path is good
+ *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
 esac
 test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
-rm -fr "$test" || {
+rm -fr "$TRASH_DIRECTORY" || {
        GIT_EXIT_OK=t
        echo >&5 "FATAL: Cannot prepare test area"
        exit 1
@@ -610,13 +610,13 @@ export HOME
 
 if test -z "$TEST_NO_CREATE_REPO"
 then
-       test_create_repo "$test"
+       test_create_repo "$TRASH_DIRECTORY"
 else
-       mkdir -p "$test"
+       mkdir -p "$TRASH_DIRECTORY"
 fi
 # Use -P to resolve symlinks in our working directory so that the cwd
 # in subprocesses like git equals our $PWD (for pathname comparisons).
-cd -P "$test" || exit 1
+cd -P "$TRASH_DIRECTORY" || exit 1
 
 this_test=${0##*/}
 this_test=${this_test%%-*}