Merge branch 'lt/setup' into __/setup-n-mv
authorJunio C Hamano <junkio@cox.net>
Sat, 29 Jul 2006 08:54:54 +0000 (01:54 -0700)
committerJunio C Hamano <junkio@cox.net>
Sat, 29 Jul 2006 08:54:54 +0000 (01:54 -0700)
This merges the new built-in calling convention code into Johannes's
builtin-mv topic in order to resolve their conflicts early on.

Signed-off-by: Junio C Hamano <junkio@cox.net>
60 files changed:
Documentation/git-daemon.txt
Documentation/git-http-fetch.txt
Documentation/git-local-fetch.txt
Documentation/git.txt
Makefile
blame.c
builtin-add.c
builtin-apply.c
builtin-cat-file.c
builtin-check-ref-format.c
builtin-commit-tree.c
builtin-count.c
builtin-diff-files.c
builtin-diff-index.c
builtin-diff-stages.c
builtin-diff-tree.c
builtin-diff.c
builtin-fmt-merge-msg.c
builtin-grep.c
builtin-help.c
builtin-init-db.c
builtin-log.c
builtin-ls-files.c
builtin-ls-tree.c
builtin-mailinfo.c
builtin-mailsplit.c
builtin-mv.c
builtin-prune.c
builtin-push.c
builtin-read-tree.c
builtin-rev-list.c
builtin-rev-parse.c
builtin-rm.c
builtin-show-branch.c
builtin-stripspace.c
builtin-tar-tree.c
builtin-update-index.c
builtin-update-ref.c
builtin-upload-tar.c
builtin-write-tree.c
builtin.h
daemon.c
fetch.c
fetch.h
git-cvsserver.perl
git-instaweb.sh
git-lost-found.sh
git-reset.sh
git.c
gitweb/gitweb.cgi
http-fetch.c
http-push.c
local-fetch.c
refs.c
revision.c
revision.h
ssh-fetch.c
t/t1400-update-ref.sh
t/t4102-apply-rename.sh
t/t4103-apply-binary.sh
index 4c357daf6ab23e3b3359388b101be8d363ae3be7..0f7d274eaba3722dabfdbf7ab14592a938933a56 100644 (file)
@@ -11,7 +11,7 @@ SYNOPSIS
 'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
              [--timeout=n] [--init-timeout=n] [--strict-paths]
              [--base-path=path] [--user-path | --user-path=path]
-            [directory...]
+            [--reuseaddr] [--detach] [--pid-file=file] [directory...]
 
 DESCRIPTION
 -----------
@@ -82,6 +82,17 @@ OPTIONS
 --verbose::
        Log details about the incoming connections and requested files.
 
+--reuseaddr::
+       Use SO_REUSEADDR when binding the listening socket.
+       This allows the server to restart without waiting for
+       old connections to time out.
+
+--detach::
+       Detach from the shell. Implies --syslog.
+
+--pid-file=file::
+       Save the process id in 'file'.
+
 <directory>::
        A directory to add to the whitelist of allowed directories. Unless
        --strict-paths is specified this will also include subdirectories
index bc1a13289153976c31718d3694de2a188d5b8478..3d508094afc6a79d40b84ce0a3380f487a40d5e8 100644 (file)
@@ -8,7 +8,7 @@ git-http-fetch - downloads a remote git repository via HTTP
 
 SYNOPSIS
 --------
-'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] <commit> <url>
+'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url>
 
 DESCRIPTION
 -----------
@@ -33,6 +33,12 @@ commit-id::
         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
         the local end after the transfer is complete.
 
+--stdin::
+       Instead of a commit id on the commandline (which is not expected in this
+       case), 'git-http-fetch' expects lines on stdin in the format
+
+               <commit-id>['\t'<filename-as-in--w>]
+
 Author
 ------
 Written by Linus Torvalds <torvalds@osdl.org>
index 87abec1c4e46ad53e018264046091af4455da307..2fbdfe086a4c974d19c3d8f4c6a1722728b0114a 100644 (file)
@@ -29,6 +29,12 @@ OPTIONS
         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on
         the local end after the transfer is complete.
 
+--stdin::
+       Instead of a commit id on the commandline (which is not expected in this
+       case), 'git-local-fetch' expects lines on stdin in the format
+
+               <commit-id>['\t'<filename-as-in--w>]
+
 Author
 ------
 Written by Junio C Hamano <junkio@cox.net>
index ce3058182fead833c45daf02a2806f151b15f61f..7310a2b8b8bc474f53d498d254cab772a8ef45ae 100644 (file)
@@ -8,7 +8,8 @@ git - the stupid content tracker
 
 SYNOPSIS
 --------
-'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [--help] COMMAND [ARGS]
+'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
+       [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
 
 DESCRIPTION
 -----------
@@ -41,6 +42,15 @@ OPTIONS
        environment variable. If no path is given 'git' will print
        the current setting and then exit.
 
+-p|--paginate::
+       Pipe all output into 'less' (or if set, $PAGER).
+
+--git-dir=<path>::
+       Set the path to the repository. This can also be controlled by
+       setting the GIT_DIR environment variable.
+
+--bare::
+       Same as --git-dir=`pwd`.
 
 FURTHER DOCUMENTATION
 ---------------------
index 73733e9025ac40708e70a2daa092744cef138708..6ecf9ddee2c169662983c0397290928921d404d2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -615,6 +615,8 @@ $(SIMPLE_PROGRAMS) : git-%$X : %.o
        $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
                $(LIB_FILE) $(SIMPLE_LIB)
 
+ssh-pull.o: ssh-fetch.c
+ssh-push.o: ssh-upload.c
 git-local-fetch$X: fetch.o
 git-ssh-fetch$X: rsh.o fetch.o
 git-ssh-upload$X: rsh.o
diff --git a/blame.c b/blame.c
index b04b8f58aaf718208ab13e5cbfd8cd2a4444cbd7..76712b5962bcb0f511cc4a18766d1a45dc901675 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -834,7 +834,7 @@ int main(int argc, const char **argv)
        }
 
 
-       init_revisions(&rev);
+       init_revisions(&rev, setup_git_directory());
        rev.remove_empty_trees = 1;
        rev.topo_order = 1;
        rev.prune_fn = simplify_commit;
index 72d2853176f9c6d8b7c678bce64f5f482c2c5345..f548b8007de79d66f7ed3fad0d96bce75c6bbf57 100644 (file)
@@ -84,11 +84,10 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec)
 
 static struct lock_file lock_file;
 
-int cmd_add(int argc, const char **argv, char **envp)
+int cmd_add(int argc, const char **argv, const char *prefix)
 {
        int i, newfd;
        int verbose = 0, show_only = 0;
-       const char *prefix = setup_git_directory();
        const char **pathspec;
        struct dir_struct dir;
 
index d924ac3d0ab663c2ceb05c2cb9943f6caa23c0ef..f8c6763c7464a01ea81fae0665a7aef50809d031 100644 (file)
@@ -120,7 +120,7 @@ struct fragment {
 struct patch {
        char *new_name, *old_name, *def_name;
        unsigned int old_mode, new_mode;
-       int is_rename, is_copy, is_new, is_delete, is_binary;
+       int is_rename, is_copy, is_new, is_delete, is_binary, is_reverse;
 #define BINARY_DELTA_DEFLATED 1
 #define BINARY_LITERAL_DEFLATED 2
        unsigned long deflate_origlen;
@@ -1119,6 +1119,34 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
        return offset + hdrsize + patchsize;
 }
 
+#define swap(a,b) myswap((a),(b),sizeof(a))
+
+#define myswap(a, b, size) do {                \
+       unsigned char mytmp[size];      \
+       memcpy(mytmp, &a, size);                \
+       memcpy(&a, &b, size);           \
+       memcpy(&b, mytmp, size);                \
+} while (0)
+
+static void reverse_patches(struct patch *p)
+{
+       for (; p; p = p->next) {
+               struct fragment *frag = p->fragments;
+
+               swap(p->new_name, p->old_name);
+               swap(p->new_mode, p->old_mode);
+               swap(p->is_new, p->is_delete);
+               swap(p->lines_added, p->lines_deleted);
+               swap(p->old_sha1_prefix, p->new_sha1_prefix);
+
+               for (; frag; frag = frag->next) {
+                       swap(frag->newpos, frag->oldpos);
+                       swap(frag->newlines, frag->oldlines);
+               }
+               p->is_reverse = !p->is_reverse;
+       }
+}
+
 static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
 static const char minuses[]= "----------------------------------------------------------------------";
 
@@ -1336,7 +1364,7 @@ static int apply_line(char *output, const char *patch, int plen)
 }
 
 static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
-       int inaccurate_eof)
+       int reverse, int inaccurate_eof)
 {
        int match_beginning, match_end;
        char *buf = desc->buffer;
@@ -1350,6 +1378,7 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
        int pos, lines;
 
        while (size > 0) {
+               char first;
                int len = linelen(patch, size);
                int plen;
 
@@ -1366,16 +1395,23 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
                plen = len-1;
                if (len < size && patch[len] == '\\')
                        plen--;
-               switch (*patch) {
+               first = *patch;
+               if (reverse) {
+                       if (first == '-')
+                               first = '+';
+                       else if (first == '+')
+                               first = '-';
+               }
+               switch (first) {
                case ' ':
                case '-':
                        memcpy(old + oldsize, patch + 1, plen);
                        oldsize += plen;
-                       if (*patch == '-')
+                       if (first == '-')
                                break;
                /* Fall-through for ' ' */
                case '+':
-                       if (*patch != '+' || !no_add)
+                       if (first != '+' || !no_add)
                                newsize += apply_line(new + newsize, patch,
                                                      plen);
                        break;
@@ -1499,6 +1535,12 @@ static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch)
        void *data;
        void *result;
 
+       /* Binary patch is irreversible */
+       if (patch->is_reverse)
+               return error("cannot reverse-apply a binary patch to '%s'",
+                            patch->new_name
+                            ? patch->new_name : patch->old_name);
+
        data = inflate_it(fragment->patch, fragment->size,
                          patch->deflate_origlen);
        if (!data)
@@ -1615,7 +1657,8 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
                return apply_binary(desc, patch);
 
        while (frag) {
-               if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0)
+               if (apply_one_fragment(desc, frag, patch->is_reverse,
+                                       patch->inaccurate_eof) < 0)
                        return error("patch failed: %s:%ld",
                                     name, frag->oldpos);
                frag = frag->next;
@@ -2142,7 +2185,8 @@ static int use_patch(struct patch *p)
        return 1;
 }
 
-static int apply_patch(int fd, const char *filename, int inaccurate_eof)
+static int apply_patch(int fd, const char *filename,
+               int reverse, int inaccurate_eof)
 {
        unsigned long offset, size;
        char *buffer = read_patch_file(fd, &size);
@@ -2162,6 +2206,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
                nr = parse_chunk(buffer + offset, size, patch);
                if (nr < 0)
                        break;
+               if (reverse)
+                       reverse_patches(patch);
                if (use_patch(patch)) {
                        patch_stats(patch);
                        *listp = patch;
@@ -2222,10 +2268,11 @@ static int git_apply_config(const char *var, const char *value)
 }
 
 
-int cmd_apply(int argc, const char **argv, char **envp)
+int cmd_apply(int argc, const char **argv, const char *prefix)
 {
        int i;
        int read_stdin = 1;
+       int reverse = 0;
        int inaccurate_eof = 0;
 
        const char *whitespace_option = NULL;
@@ -2236,7 +2283,7 @@ int cmd_apply(int argc, const char **argv, char **envp)
                int fd;
 
                if (!strcmp(arg, "-")) {
-                       apply_patch(0, "<stdin>", inaccurate_eof);
+                       apply_patch(0, "<stdin>", reverse, inaccurate_eof);
                        read_stdin = 0;
                        continue;
                }
@@ -2313,6 +2360,10 @@ int cmd_apply(int argc, const char **argv, char **envp)
                        parse_whitespace_option(arg + 13);
                        continue;
                }
+               if (!strcmp(arg, "-R") || !strcmp(arg, "--reverse")) {
+                       reverse = 1;
+                       continue;
+               }
                if (!strcmp(arg, "--inaccurate-eof")) {
                        inaccurate_eof = 1;
                        continue;
@@ -2333,12 +2384,12 @@ int cmd_apply(int argc, const char **argv, char **envp)
                        usage(apply_usage);
                read_stdin = 0;
                set_default_whitespace_mode(whitespace_option);
-               apply_patch(fd, arg, inaccurate_eof);
+               apply_patch(fd, arg, reverse, inaccurate_eof);
                close(fd);
        }
        set_default_whitespace_mode(whitespace_option);
        if (read_stdin)
-               apply_patch(0, "<stdin>", inaccurate_eof);
+               apply_patch(0, "<stdin>", reverse, inaccurate_eof);
        if (whitespace_error) {
                if (squelch_whitespace_errors &&
                    squelch_whitespace_errors < whitespace_error) {
index 4d36817e5fed0e50f84eb48ac183b0c377596a86..814fb0743f7a453114991af6c28bb69ef44d4883 100644 (file)
@@ -94,7 +94,7 @@ static int pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
        return 0;
 }
 
-int cmd_cat_file(int argc, const char **argv, char **envp)
+int cmd_cat_file(int argc, const char **argv, const char *prefix)
 {
        unsigned char sha1[20];
        char type[20];
@@ -102,7 +102,6 @@ int cmd_cat_file(int argc, const char **argv, char **envp)
        unsigned long size;
        int opt;
 
-       setup_git_directory();
        git_config(git_default_config);
        if (argc != 3)
                usage("git-cat-file [-t|-s|-e|-p|<type>] <sha1>");
index 4a23936aff8c21ca42a1b1e460543b1c775ccb45..701de439ae0f508f3a8ab41559230357be60637e 100644 (file)
@@ -6,7 +6,7 @@
 #include "refs.h"
 #include "builtin.h"
 
-int cmd_check_ref_format(int argc, const char **argv, char **envp)
+int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
 {
        if (argc != 2)
                usage("git check-ref-format refname");
index ec082bf754a0ce5ae1615c41ba32c4515a927361..9c987966711d4bff1f709df0c14071170950e21d 100644 (file)
@@ -77,7 +77,7 @@ static int new_parent(int idx)
        return 1;
 }
 
-int cmd_commit_tree(int argc, const char **argv, char **envp)
+int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 {
        int i;
        int parents = 0;
@@ -88,8 +88,6 @@ int cmd_commit_tree(int argc, const char **argv, char **envp)
        unsigned int size;
 
        setup_ident();
-       setup_git_directory();
-
        git_config(git_default_config);
 
        if (argc < 2)
index 5ee72df247245cbf5fc8d5b70e8b1fddd5ab7edd..1d3729aa9914d6c68dbb6ad11cb46504b4a688e0 100644 (file)
@@ -67,7 +67,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
        }
 }
 
-int cmd_count_objects(int ac, const char **av, char **ep)
+int cmd_count_objects(int ac, const char **av, const char *prefix)
 {
        int i;
        int verbose = 0;
index 81ac2fe64aea23f9db605da181da098dcfca757a..ac13db70ff741240f1f27f98dfe09614da4ea87c 100644 (file)
@@ -13,13 +13,13 @@ static const char diff_files_usage[] =
 "git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]"
 COMMON_DIFF_OPTIONS_HELP;
 
-int cmd_diff_files(int argc, const char **argv, char **envp)
+int cmd_diff_files(int argc, const char **argv, const char *prefix)
 {
        struct rev_info rev;
        int silent = 0;
 
+       init_revisions(&rev, prefix);
        git_config(git_default_config); /* no "diff" UI options */
-       init_revisions(&rev);
        rev.abbrev = 0;
 
        argc = setup_revisions(argc, argv, &rev, NULL);
index a1fa1b85cf741cd6b5f06afd02abbe618e86f5d1..95a3db156bda2d1e8d2ad7bdf72a9f9a821c6f51 100644 (file)
@@ -9,14 +9,14 @@ static const char diff_cache_usage[] =
 "[<common diff options>] <tree-ish> [<path>...]"
 COMMON_DIFF_OPTIONS_HELP;
 
-int cmd_diff_index(int argc, const char **argv, char **envp)
+int cmd_diff_index(int argc, const char **argv, const char *prefix)
 {
        struct rev_info rev;
        int cached = 0;
        int i;
 
+       init_revisions(&rev, prefix);
        git_config(git_default_config); /* no "diff" UI options */
-       init_revisions(&rev);
        rev.abbrev = 0;
 
        argc = setup_revisions(argc, argv, &rev, NULL);
index 9c62702941569511a149eba89a8be2b478f04b70..5960e089975f1f27c55c5bd8ea1c968ffe695d1f 100644 (file)
@@ -55,10 +55,9 @@ static void diff_stages(int stage1, int stage2, const char **pathspec)
        }
 }
 
-int cmd_diff_stages(int ac, const char **av, char **envp)
+int cmd_diff_stages(int ac, const char **av, const char *prefix)
 {
        int stage1, stage2;
-       const char *prefix = setup_git_directory();
        const char **pathspec = NULL;
 
        git_config(git_default_config); /* no "diff" UI options */
index b6106685942e3cb3a5db2b3a67123b5bd554d856..24cb2d7f84064d7833fa04f33aeca6eafc8b931d 100644 (file)
@@ -59,7 +59,7 @@ static const char diff_tree_usage[] =
 "  --root        include the initial commit as diff against /dev/null\n"
 COMMON_DIFF_OPTIONS_HELP;
 
-int cmd_diff_tree(int argc, const char **argv, char **envp)
+int cmd_diff_tree(int argc, const char **argv, const char *prefix)
 {
        int nr_sha1;
        char line[1000];
@@ -67,9 +67,9 @@ int cmd_diff_tree(int argc, const char **argv, char **envp)
        static struct rev_info *opt = &log_tree_opt;
        int read_stdin = 0;
 
+       init_revisions(opt, prefix);
        git_config(git_default_config); /* no "diff" UI options */
        nr_sha1 = 0;
-       init_revisions(opt);
        opt->abbrev = 0;
        opt->diff = 1;
        argc = setup_revisions(argc, argv, opt, NULL);
index cb38f445611735cff5bc9fbafb3189e6ccc6c2fd..48d2fd03b79c9c03e1e32b7743f936872a3684f1 100644 (file)
@@ -221,7 +221,7 @@ void add_head(struct rev_info *revs)
        add_pending_object(revs, obj, "HEAD");
 }
 
-int cmd_diff(int argc, const char **argv, char **envp)
+int cmd_diff(int argc, const char **argv, const char *prefix)
 {
        int i;
        struct rev_info rev;
@@ -251,7 +251,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
         */
 
        git_config(git_diff_ui_config);
-       init_revisions(&rev);
+       init_revisions(&rev, prefix);
 
        argc = setup_revisions(argc, argv, &rev, NULL);
        if (!rev.diffopt.output_format) {
@@ -346,7 +346,15 @@ int cmd_diff(int argc, const char **argv, char **envp)
                return builtin_diff_index(&rev, argc, argv);
        else if (ents == 2)
                return builtin_diff_tree(&rev, argc, argv, ent);
+       else if ((ents == 3) && (ent[0].item->flags & UNINTERESTING)) {
+               /* diff A...B where there is one sane merge base between
+                * A and B.  We have ent[0] == merge-base, ent[1] == A,
+                * and ent[2] == B.  Show diff between the base and B.
+                */
+               return builtin_diff_tree(&rev, argc, argv, ent);
+       }
        else
-               return builtin_diff_combined(&rev, argc, argv, ent, ents);
+               return builtin_diff_combined(&rev, argc, argv,
+                                            ent, ents);
        usage(builtin_diff_usage);
 }
index f20b27b8a9cfd78ad5ae8ba67f08ec25849394e2..c84224ee84803cbe4766b9e61da16da718a6eb15 100644 (file)
@@ -242,7 +242,7 @@ static void shortlog(const char *name, unsigned char *sha1,
        free_list(&subjects);
 }
 
-int cmd_fmt_merge_msg(int argc, char **argv, char **envp)
+int cmd_fmt_merge_msg(int argc, char **argv, const char *prefix)
 {
        int limit = 20, i = 0;
        char line[1024];
@@ -342,7 +342,7 @@ int cmd_fmt_merge_msg(int argc, char **argv, char **envp)
                struct rev_info rev;
 
                head = lookup_commit(head_sha1);
-               init_revisions(&rev);
+               init_revisions(&rev, prefix);
                rev.commit_format = CMIT_FMT_ONELINE;
                rev.ignore_merges = 1;
                rev.limited = 1;
index a79bac305aea880d6decb787836fe86295ead32e..69b7c4862af3bfcbc9aea2cb52abaa65b3e8490b 100644 (file)
@@ -919,14 +919,13 @@ static const char emsg_missing_context_len[] =
 static const char emsg_missing_argument[] =
 "option requires an argument -%s";
 
-int cmd_grep(int argc, const char **argv, char **envp)
+int cmd_grep(int argc, const char **argv, const char *prefix)
 {
        int hit = 0;
        int cached = 0;
        int seen_dashdash = 0;
        struct grep_opt opt;
        struct object_array list = { 0, 0, NULL };
-       const char *prefix = setup_git_directory();
        const char **paths = NULL;
        int i;
 
index 335fe5fedcc6523a3b49a3e00686fe381098bcda..bb0b03f1ae64cc5f4fa1376169c27b8a7cb71734 100644 (file)
@@ -221,15 +221,15 @@ static void show_man_page(const char *git_cmd)
        execlp("man", "man", page, NULL);
 }
 
-int cmd_version(int argc, const char **argv, char **envp)
+int cmd_version(int argc, const char **argv, const char *prefix)
 {
        printf("git version %s\n", git_version_string);
        return 0;
 }
 
-int cmd_help(int argc, const char **argv, char **envp)
+int cmd_help(int argc, const char **argv, const char *prefix)
 {
-       const char *help_cmd = argv[1];
+       const char *help_cmd = argc > 1 ? argv[1] : NULL;
        if (!help_cmd)
                cmd_usage(0, git_exec_path(), NULL);
        else if (!strcmp(help_cmd, "--all") || !strcmp(help_cmd, "-a"))
index 7fdd2fa9f9f7fb2801c6e1fc398f78b414a269e1..52473edf569e4d318a74548acefaf4023f37c87c 100644 (file)
@@ -250,7 +250,7 @@ static const char init_db_usage[] =
  * On the other hand, it might just make lookup slower and messier. You
  * be the judge.  The default case is to have one DB per managed directory.
  */
-int cmd_init_db(int argc, const char **argv, char **envp)
+int cmd_init_db(int argc, const char **argv, const char *prefix)
 {
        const char *git_dir;
        const char *sha1_dir;
index 4052cc75bdb2e3915ff17af4d1dc59a3f84f99dd..82c69d1d0593156c5f7034746fe68f5a1a9f7276 100644 (file)
@@ -16,7 +16,7 @@
 /* this is in builtin-diff.c */
 void add_head(struct rev_info *revs);
 
-static void cmd_log_init(int argc, const char **argv, char **envp,
+static void cmd_log_init(int argc, const char **argv, const char *prefix,
                      struct rev_info *rev)
 {
        rev->abbrev = DEFAULT_ABBREV;
@@ -45,27 +45,27 @@ static int cmd_log_walk(struct rev_info *rev)
        return 0;
 }
 
-int cmd_whatchanged(int argc, const char **argv, char **envp)
+int cmd_whatchanged(int argc, const char **argv, const char *prefix)
 {
        struct rev_info rev;
 
        git_config(git_diff_ui_config);
-       init_revisions(&rev);
+       init_revisions(&rev, prefix);
        rev.diff = 1;
        rev.diffopt.recursive = 1;
        rev.simplify_history = 0;
-       cmd_log_init(argc, argv, envp, &rev);
+       cmd_log_init(argc, argv, prefix, &rev);
        if (!rev.diffopt.output_format)
                rev.diffopt.output_format = DIFF_FORMAT_RAW;
        return cmd_log_walk(&rev);
 }
 
-int cmd_show(int argc, const char **argv, char **envp)
+int cmd_show(int argc, const char **argv, const char *prefix)
 {
        struct rev_info rev;
 
        git_config(git_diff_ui_config);
-       init_revisions(&rev);
+       init_revisions(&rev, prefix);
        rev.diff = 1;
        rev.diffopt.recursive = 1;
        rev.combine_merges = 1;
@@ -73,18 +73,18 @@ int cmd_show(int argc, const char **argv, char **envp)
        rev.always_show_header = 1;
        rev.ignore_merges = 0;
        rev.no_walk = 1;
-       cmd_log_init(argc, argv, envp, &rev);
+       cmd_log_init(argc, argv, prefix, &rev);
        return cmd_log_walk(&rev);
 }
 
-int cmd_log(int argc, const char **argv, char **envp)
+int cmd_log(int argc, const char **argv, const char *prefix)
 {
        struct rev_info rev;
 
        git_config(git_diff_ui_config);
-       init_revisions(&rev);
+       init_revisions(&rev, prefix);
        rev.always_show_header = 1;
-       cmd_log_init(argc, argv, envp, &rev);
+       cmd_log_init(argc, argv, prefix, &rev);
        return cmd_log_walk(&rev);
 }
 
@@ -178,7 +178,7 @@ static int get_patch_id(struct commit *commit, struct diff_options *options,
        return diff_flush_patch_id(options, sha1);
 }
 
-static void get_patch_ids(struct rev_info *rev, struct diff_options *options)
+static void get_patch_ids(struct rev_info *rev, struct diff_options *options, const char *prefix)
 {
        struct rev_info check_rev;
        struct commit *commit;
@@ -203,7 +203,7 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options)
                die("diff_setup_done failed");
 
        /* given a range a..b get all patch ids for b..a */
-       init_revisions(&check_rev);
+       init_revisions(&check_rev, prefix);
        o1->flags ^= UNINTERESTING;
        o2->flags ^= UNINTERESTING;
        add_pending_object(&check_rev, o1, "o1");
@@ -240,7 +240,7 @@ static void gen_message_id(char *dest, unsigned int length, char *base)
                 (int)(email_end - email_start - 1), email_start + 1);
 }
 
-int cmd_format_patch(int argc, const char **argv, char **envp)
+int cmd_format_patch(int argc, const char **argv, const char *prefix)
 {
        struct commit *commit;
        struct commit **list = NULL;
@@ -259,7 +259,7 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
        char ref_message_id[1024];
 
        git_config(git_format_config);
-       init_revisions(&rev);
+       init_revisions(&rev, prefix);
        rev.commit_format = CMIT_FMT_EMAIL;
        rev.verbose_header = 1;
        rev.diff = 1;
@@ -363,7 +363,7 @@ int cmd_format_patch(int argc, const char **argv, char **envp)
        }
 
        if (ignore_if_in_upstream)
-               get_patch_ids(&rev, &patch_id_opts);
+               get_patch_ids(&rev, &patch_id_opts, prefix);
 
        if (!use_stdout)
                realstdout = fdopen(dup(1), "w");
index 8dae9f70e2f9079d521fbc80e317addf41346d0f..79ffe8f42351f6ca5d01ce5601b6708bdfac7101 100644 (file)
@@ -322,14 +322,13 @@ static const char ls_files_usage[] =
        "[ --exclude-per-directory=<filename> ] [--full-name] [--abbrev] "
        "[--] [<file>]*";
 
-int cmd_ls_files(int argc, const char **argv, char** envp)
+int cmd_ls_files(int argc, const char **argv, const char *prefix)
 {
        int i;
        int exc_given = 0;
        struct dir_struct dir;
 
        memset(&dir, 0, sizeof(dir));
-       prefix = setup_git_directory();
        if (prefix)
                prefix_offset = strlen(prefix);
        git_config(git_default_config);
index b8d0d88ba85d7c9770f64288971963250dc3391c..261147fdbe76cf9d277bd420cc17efedecc2da2f 100644 (file)
@@ -18,7 +18,7 @@ static int abbrev = 0;
 static int ls_options = 0;
 static const char **pathspec;
 static int chomp_prefix = 0;
-static const char *prefix;
+static const char *ls_tree_prefix;
 
 static const char ls_tree_usage[] =
        "git-ls-tree [-d] [-r] [-t] [-z] [--name-only] [--name-status] [--full-name] [--abbrev[=<n>]] <tree-ish> [path...]";
@@ -71,7 +71,7 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
                return 0;
 
        if (chomp_prefix &&
-           (baselen < chomp_prefix || memcmp(prefix, base, chomp_prefix)))
+           (baselen < chomp_prefix || memcmp(ls_tree_prefix, base, chomp_prefix)))
                return 0;
 
        if (!(ls_options & LS_NAME_ONLY))
@@ -85,13 +85,13 @@ static int show_tree(const unsigned char *sha1, const char *base, int baselen,
        return retval;
 }
 
-int cmd_ls_tree(int argc, const char **argv, char **envp)
+int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 {
        unsigned char sha1[20];
        struct tree *tree;
 
-       prefix = setup_git_directory();
        git_config(git_default_config);
+       ls_tree_prefix = prefix;
        if (prefix && *prefix)
                chomp_prefix = strlen(prefix);
        while (1 < argc && argv[1][0] == '-') {
index ac53f76f689fdc0a44b6e4921dc08b880e1349b0..24a4fc63b35ec4c6b5f85bda260811546b12ed46 100644 (file)
@@ -446,7 +446,7 @@ static int read_one_header_line(char *line, int sz, FILE *in)
                        break;
        }
        /* Count mbox From headers as headers */
-       if (!ofs && !memcmp(line, "From ", 5))
+       if (!ofs && (!memcmp(line, "From ", 5) || !memcmp(line, ">From ", 6)))
                ofs = 1;
        return ofs;
 }
@@ -836,7 +836,7 @@ int mailinfo(FILE *in, FILE *out, int ks, const char *encoding,
 static const char mailinfo_usage[] =
        "git-mailinfo [-k] [-u | --encoding=<encoding>] msg patch <mail >info";
 
-int cmd_mailinfo(int argc, const char **argv, char **envp)
+int cmd_mailinfo(int argc, const char **argv, const char *prefix)
 {
        /* NEEDSWORK: might want to do the optional .git/ directory
         * discovery
index e2a0058435d396161145221eab80205a934b271c..91a699d34d93462b56f2591193bb5729b42b3950 100644 (file)
@@ -138,7 +138,7 @@ int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec,
        free(name);
        return ret;
 }
-int cmd_mailsplit(int argc, const char **argv, char **envp)
+int cmd_mailsplit(int argc, const char **argv, const char *prefix)
 {
        int nr = 0, nr_prec = 4, ret;
        int allow_bare = 0;
index 42c2e39b2105db553b469f13da1d4211233d018e..62ae937cb13f43f871bf2ec3543f7db37f9e87b6 100644 (file)
@@ -56,11 +56,10 @@ static const char *add_slash(const char *path)
 
 static struct lock_file lock_file;
 
-int cmd_mv(int argc, const char **argv, char **envp)
+int cmd_mv(int argc, const char **argv, const char *prefix)
 {
        int i, newfd, count;
        int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
-       const char *prefix = setup_git_directory();
        const char **source, **destination, **dest_path;
        enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes;
        struct stat st;
index d196c41f13aee5992fe60febffa01ed4d640a97b..6a86eb52aedc45b0a59adad4da31341440f2f82e 100644 (file)
@@ -217,7 +217,7 @@ static void add_cache_refs(void)
                add_cache_tree(active_cache_tree);
 }
 
-int cmd_prune(int argc, const char **argv, char **envp)
+int cmd_prune(int argc, const char **argv, const char *prefix)
 {
        int i;
 
@@ -234,7 +234,7 @@ int cmd_prune(int argc, const char **argv, char **envp)
         * Set up revision parsing, and mark us as being interested
         * in all object types, not just commits.
         */
-       init_revisions(&revs);
+       init_revisions(&revs, prefix);
        revs.tag_objects = 1;
        revs.blob_objects = 1;
        revs.tree_objects = 1;
index 31cbfd73861326ad303472718365838329a55cb8..a824171066b8b02b82ee45030efa7e6ef359b995 100644 (file)
@@ -270,7 +270,7 @@ static int do_push(const char *repo)
        return 0;
 }
 
-int cmd_push(int argc, const char **argv, char **envp)
+int cmd_push(int argc, const char **argv, const char *prefix)
 {
        int i;
        const char *repo = "origin";    /* default repository */
index 122b6f130b37b27055efd7dffa25f41ef03698e8..49c10bf221961363b1edd073c926fe1bf92880c8 100644 (file)
@@ -870,7 +870,7 @@ static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--aggressive
 
 static struct lock_file lock_file;
 
-int cmd_read_tree(int argc, const char **argv, char **envp)
+int cmd_read_tree(int argc, const char **argv, const char *prefix)
 {
        int i, newfd, stage = 0;
        unsigned char sha1[20];
@@ -882,7 +882,6 @@ int cmd_read_tree(int argc, const char **argv, char **envp)
        state.quiet = 1;
        state.refresh_cache = 1;
 
-       setup_git_directory();
        git_config(git_default_config);
 
        newfd = hold_lock_file_for_update(&lock_file, get_index_file());
index 8f328713374679b023f1f8caaacab592c9e4f9a2..0dee1734a31308ace74b0b25cc87ffcf4993549b 100644 (file)
@@ -306,12 +306,12 @@ static void mark_edges_uninteresting(struct commit_list *list)
        }
 }
 
-int cmd_rev_list(int argc, const char **argv, char **envp)
+int cmd_rev_list(int argc, const char **argv, const char *prefix)
 {
        struct commit_list *list;
        int i;
 
-       init_revisions(&revs);
+       init_revisions(&revs, prefix);
        revs.abbrev = 0;
        revs.commit_format = CMIT_FMT_UNSPECIFIED;
        argc = setup_revisions(argc, argv, &revs, NULL);
index b3e4386c1baec7c3a56704e61e44e575203ab759..aca4a3603283a257f7621934103c85d5c0c31390 100644 (file)
@@ -209,11 +209,10 @@ static int try_difference(const char *arg)
        return 0;
 }
 
-int cmd_rev_parse(int argc, const char **argv, char **envp)
+int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 {
        int i, as_is = 0, verify = 0;
        unsigned char sha1[20];
-       const char *prefix = setup_git_directory();
 
        git_config(git_default_config);
 
index bb810ba41ae23c9dc4c38fbb0fa7883a33d43524..92d205a7153a7cc5267ea9cf774bc1e4fac887d4 100644 (file)
@@ -43,11 +43,10 @@ static int remove_file(const char *name)
 
 static struct lock_file lock_file;
 
-int cmd_rm(int argc, const char **argv, char **envp)
+int cmd_rm(int argc, const char **argv, const char *prefix)
 {
        int i, newfd;
        int verbose = 0, show_only = 0, force = 0;
-       const char *prefix = setup_git_directory();
        const char **pathspec;
        char *seen;
 
index 82f75b72dea1a5e6c620003d5c0c4c414dfe42e3..2a1b848f6c169f09cb168d12e6bb5033795b8be2 100644 (file)
@@ -550,7 +550,7 @@ static int omit_in_dense(struct commit *commit, struct commit **rev, int n)
        return 0;
 }
 
-int cmd_show_branch(int ac, const char **av, char **envp)
+int cmd_show_branch(int ac, const char **av, const char *prefix)
 {
        struct commit *rev[MAX_REVS], *commit;
        struct commit_list *list = NULL, *seen = NULL;
@@ -573,7 +573,6 @@ int cmd_show_branch(int ac, const char **av, char **envp)
        int topics = 0;
        int dense = 1;
 
-       setup_git_directory();
        git_config(git_show_branch_config);
 
        /* If nothing is specified, try the default first */
index 2ce1264f7b4bfb5baf85f82907e2a8f7219846fa..09cc9108cdaf2aa20dc10788bccd2fee0ae9b02a 100644 (file)
@@ -54,7 +54,7 @@ void stripspace(FILE *in, FILE *out)
                fputc('\n', out);
 }
 
-int cmd_stripspace(int argc, const char **argv, char **envp)
+int cmd_stripspace(int argc, const char **argv, const char *prefix)
 {
        stripspace(stdin, stdout);
        return 0;
index e5aaded820bddfe2d5175508cc9c422b55a66eec..7c48db9ec85adb1b8866b2cc1dc0eccd2d1816c7 100644 (file)
@@ -308,7 +308,7 @@ int git_tar_config(const char *var, const char *value)
        return git_default_config(var, value);
 }
 
-static int generate_tar(int argc, const char **argv, char** envp)
+static int generate_tar(int argc, const char **argv, const char *prefix)
 {
        unsigned char sha1[20], tree_sha1[20];
        struct commit *commit;
@@ -319,7 +319,6 @@ static int generate_tar(int argc, const char **argv, char** envp)
        current_path.alloc = PATH_MAX;
        current_path.len = current_path.eof = 0;
 
-       setup_git_directory();
        git_config(git_tar_config);
 
        switch (argc) {
@@ -402,19 +401,19 @@ static int remote_tar(int argc, const char **argv)
        return !!ret;
 }
 
-int cmd_tar_tree(int argc, const char **argv, char **envp)
+int cmd_tar_tree(int argc, const char **argv, const char *prefix)
 {
        if (argc < 2)
                usage(tar_tree_usage);
        if (!strncmp("--remote=", argv[1], 9))
                return remote_tar(argc, argv);
-       return generate_tar(argc, argv, envp);
+       return generate_tar(argc, argv, prefix);
 }
 
 /* ustar header + extended global header content */
 #define HEADERSIZE (2 * RECORDSIZE)
 
-int cmd_get_tar_commit_id(int argc, const char **argv, char **envp)
+int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
 {
        char buffer[HEADERSIZE];
        struct ustar_header *header = (struct ustar_header *)buffer;
index 1a4200d151dd8e876c6f84531422cae50b049aa3..24dca47d8d6e54429aa89b04e4d67bda04fa0173 100644 (file)
@@ -476,12 +476,11 @@ static int do_reupdate(int ac, const char **av,
        return 0;
 }
 
-int cmd_update_index(int argc, const char **argv, char **envp)
+int cmd_update_index(int argc, const char **argv, const char *prefix)
 {
        int i, newfd, entries, has_errors = 0, line_termination = '\n';
        int allow_options = 1;
        int read_from_stdin = 0;
-       const char *prefix = setup_git_directory();
        int prefix_length = prefix ? strlen(prefix) : 0;
        char set_executable_bit = 0;
        unsigned int refresh_flags = 0;
index 83094abe0f20d36bf2d9e65539fb2c8b7a5644fc..5bd71825fdc48392952faf170efe98c072c7e482 100644 (file)
@@ -5,7 +5,7 @@
 static const char git_update_ref_usage[] =
 "git-update-ref <refname> <value> [<oldval>] [-m <reason>]";
 
-int cmd_update_ref(int argc, const char **argv, char **envp)
+int cmd_update_ref(int argc, const char **argv, const char *prefix)
 {
        const char *refname=NULL, *value=NULL, *oldval=NULL, *msg=NULL;
        struct ref_lock *lock;
@@ -13,7 +13,6 @@ int cmd_update_ref(int argc, const char **argv, char **envp)
        int i;
 
        setup_ident();
-       setup_git_directory();
        git_config(git_default_config);
 
        for (i = 1; i < argc; i++) {
index d4fa7b56c39f03e8b48d513f967d89d4031bacb2..7b401bbb779ea0cc8bca3720eab612af2b50a4c3 100644 (file)
@@ -15,7 +15,7 @@ static int nak(const char *reason)
        return 1;
 }
 
-int cmd_upload_tar(int argc, const char **argv, char **envp)
+int cmd_upload_tar(int argc, const char **argv, const char *prefix)
 {
        int len;
        const char *dir = argv[1];
index 449a4d1b575b591aa07a40532649f9ea06eb6890..0289f59936267194ccbb8276a525ad24198a5de9 100644 (file)
@@ -60,14 +60,12 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
        return 0;
 }
 
-int cmd_write_tree(int argc, const char **argv, char **envp)
+int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 {
        int missing_ok = 0, ret;
        const char *prefix = NULL;
        unsigned char sha1[20];
 
-       setup_git_directory();
-
        while (1 < argc) {
                const char *arg = argv[1];
                if (!strcmp(arg, "--missing-ok"))
index 6f3a43957c97677ae42a136dbfe292c0abeeba26..1c8637ae22dc46961772b690d4218933725565d4 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -15,54 +15,54 @@ void cmd_usage(int show_all, const char *exec_path, const char *fmt, ...)
 #endif
        ;
 
-extern int cmd_help(int argc, const char **argv, char **envp);
-extern int cmd_version(int argc, const char **argv, char **envp);
+extern int cmd_help(int argc, const char **argv, const char *prefix);
+extern int cmd_version(int argc, const char **argv, const char *prefix);
 
-extern int cmd_whatchanged(int argc, const char **argv, char **envp);
-extern int cmd_show(int argc, const char **argv, char **envp);
-extern int cmd_log(int argc, const char **argv, char **envp);
-extern int cmd_diff(int argc, const char **argv, char **envp);
-extern int cmd_format_patch(int argc, const char **argv, char **envp);
-extern int cmd_count_objects(int argc, const char **argv, char **envp);
+extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);
+extern int cmd_show(int argc, const char **argv, const char *prefix);
+extern int cmd_log(int argc, const char **argv, const char *prefix);
+extern int cmd_diff(int argc, const char **argv, const char *prefix);
+extern int cmd_format_patch(int argc, const char **argv, const char *prefix);
+extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
 
-extern int cmd_prune(int argc, const char **argv, char **envp);
+extern int cmd_prune(int argc, const char **argv, const char *prefix);
 
-extern int cmd_push(int argc, const char **argv, char **envp);
-extern int cmd_grep(int argc, const char **argv, char **envp);
-extern int cmd_rm(int argc, const char **argv, char **envp);
-extern int cmd_add(int argc, const char **argv, char **envp);
-extern int cmd_rev_list(int argc, const char **argv, char **envp);
-extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
-extern int cmd_init_db(int argc, const char **argv, char **envp);
-extern int cmd_tar_tree(int argc, const char **argv, char **envp);
-extern int cmd_upload_tar(int argc, const char **argv, char **envp);
-extern int cmd_get_tar_commit_id(int argc, const char **argv, char **envp);
-extern int cmd_ls_files(int argc, const char **argv, char **envp);
-extern int cmd_ls_tree(int argc, const char **argv, char **envp);
-extern int cmd_read_tree(int argc, const char **argv, char **envp);
-extern int cmd_commit_tree(int argc, const char **argv, char **envp);
-extern int cmd_apply(int argc, const char **argv, char **envp);
-extern int cmd_show_branch(int argc, const char **argv, char **envp);
-extern int cmd_diff_files(int argc, const char **argv, char **envp);
-extern int cmd_diff_index(int argc, const char **argv, char **envp);
-extern int cmd_diff_stages(int argc, const char **argv, char **envp);
-extern int cmd_diff_tree(int argc, const char **argv, char **envp);
-extern int cmd_cat_file(int argc, const char **argv, char **envp);
-extern int cmd_rev_parse(int argc, const char **argv, char **envp);
-extern int cmd_update_index(int argc, const char **argv, char **envp);
-extern int cmd_update_ref(int argc, const char **argv, char **envp);
-extern int cmd_fmt_merge_msg(int argc, const char **argv, char **envp);
-extern int cmd_mv(int argc, const char **argv, char **envp);
+extern int cmd_push(int argc, const char **argv, const char *prefix);
+extern int cmd_grep(int argc, const char **argv, const char *prefix);
+extern int cmd_rm(int argc, const char **argv, const char *prefix);
+extern int cmd_add(int argc, const char **argv, const char *prefix);
+extern int cmd_rev_list(int argc, const char **argv, const char *prefix);
+extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix);
+extern int cmd_init_db(int argc, const char **argv, const char *prefix);
+extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);
+extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);
+extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
+extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_read_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_apply(int argc, const char **argv, const char *prefix);
+extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
+extern int cmd_diff_files(int argc, const char **argv, const char *prefix);
+extern int cmd_diff_index(int argc, const char **argv, const char *prefix);
+extern int cmd_diff_stages(int argc, const char **argv, const char *prefix);
+extern int cmd_diff_tree(int argc, const char **argv, const char *prefix);
+extern int cmd_cat_file(int argc, const char **argv, const char *prefix);
+extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
+extern int cmd_update_index(int argc, const char **argv, const char *prefix);
+extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
+extern int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix);
+extern int cmd_mv(int argc, const char **argv, const char *prefix);
 
-extern int cmd_write_tree(int argc, const char **argv, char **envp);
+extern int cmd_write_tree(int argc, const char **argv, const char *prefix);
 extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
 
-extern int cmd_mailsplit(int argc, const char **argv, char **envp);
+extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
 extern int split_mbox(const char **mbox, const char *dir, int allow_bare, int nr_prec, int skip);
 
-extern int cmd_mailinfo(int argc, const char **argv, char **envp);
+extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
 extern int mailinfo(FILE *in, FILE *out, int ks, const char *encoding, const char *msg, const char *patch);
 
-extern int cmd_stripspace(int argc, const char **argv, char **envp);
+extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
 extern void stripspace(FILE *in, FILE *out);
 #endif
index e4ec676301c965e0b0ec81995f4e1fb77363c373..810837f0c4b8296ce762441c80527efdb6c9c3b6 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -19,7 +19,7 @@ static const char daemon_usage[] =
 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
 "           [--base-path=path] [--user-path | --user-path=path]\n"
-"           [--reuseaddr] [directory...]";
+"           [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
 
 /* List of acceptable pathname prefixes */
 static char **ok_paths = NULL;
diff --git a/fetch.c b/fetch.c
index 989d7a47884ec7bac05d329baeb97bdb12b7b22e..aeb6bf2639cc75b6f738348bcc267179a8a0da65 100644 (file)
--- a/fetch.c
+++ b/fetch.c
@@ -7,9 +7,7 @@
 #include "tag.h"
 #include "blob.h"
 #include "refs.h"
-
-const char *write_ref = NULL;
-const char *write_ref_log_details = NULL;
+#include "strbuf.h"
 
 int get_tree = 0;
 int get_history = 0;
@@ -213,54 +211,106 @@ static int mark_complete(const char *path, const unsigned char *sha1)
        return 0;
 }
 
-int pull(char *target)
+int pull_targets_stdin(char ***target, const char ***write_ref)
+{
+       int targets = 0, targets_alloc = 0;
+       struct strbuf buf;
+       *target = NULL; *write_ref = NULL;
+       strbuf_init(&buf);
+       while (1) {
+               char *rf_one = NULL;
+               char *tg_one;
+
+               read_line(&buf, stdin, '\n');
+               if (buf.eof)
+                       break;
+               tg_one = buf.buf;
+               rf_one = strchr(tg_one, '\t');
+               if (rf_one)
+                       *rf_one++ = 0;
+
+               if (targets >= targets_alloc) {
+                       targets_alloc = targets_alloc ? targets_alloc * 2 : 64;
+                       *target = xrealloc(*target, targets_alloc * sizeof(**target));
+                       *write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
+               }
+               (*target)[targets] = strdup(tg_one);
+               (*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL;
+               targets++;
+       }
+       return targets;
+}
+
+void pull_targets_free(int targets, char **target, const char **write_ref)
 {
-       struct ref_lock *lock = NULL;
-       unsigned char sha1[20];
+       while (targets--) {
+               free(target[targets]);
+               if (write_ref && write_ref[targets])
+                       free((char *) write_ref[targets]);
+       }
+}
+
+int pull(int targets, char **target, const char **write_ref,
+         const char *write_ref_log_details)
+{
+       struct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *));
+       unsigned char *sha1 = xmalloc(targets * 20);
        char *msg;
        int ret;
+       int i;
 
        save_commit_buffer = 0;
        track_object_refs = 0;
-       if (write_ref) {
-               lock = lock_ref_sha1(write_ref, NULL, 0);
-               if (!lock) {
-                       error("Can't lock ref %s", write_ref);
-                       return -1;
+
+       for (i = 0; i < targets; i++) {
+               if (!write_ref || !write_ref[i])
+                       continue;
+
+               lock[i] = lock_ref_sha1(write_ref[i], NULL, 0);
+               if (!lock[i]) {
+                       error("Can't lock ref %s", write_ref[i]);
+                       goto unlock_and_fail;
                }
        }
 
        if (!get_recover)
                for_each_ref(mark_complete);
 
-       if (interpret_target(target, sha1)) {
-               error("Could not interpret %s as something to pull", target);
-               if (lock)
-                       unlock_ref(lock);
-               return -1;
+       for (i = 0; i < targets; i++) {
+               if (interpret_target(target[i], &sha1[20 * i])) {
+                       error("Could not interpret %s as something to pull", target[i]);
+                       goto unlock_and_fail;
+               }
+               if (process(lookup_unknown_object(&sha1[20 * i])))
+                       goto unlock_and_fail;
        }
-       if (process(lookup_unknown_object(sha1))) {
-               if (lock)
-                       unlock_ref(lock);
-               return -1;
+
+       if (loop())
+               goto unlock_and_fail;
+
+       if (write_ref_log_details) {
+               msg = xmalloc(strlen(write_ref_log_details) + 12);
+               sprintf(msg, "fetch from %s", write_ref_log_details);
+       } else {
+               msg = NULL;
        }
-       if (loop()) {
-               if (lock)
-                       unlock_ref(lock);
-               return -1;
+       for (i = 0; i < targets; i++) {
+               if (!write_ref || !write_ref[i])
+                       continue;
+               ret = write_ref_sha1(lock[i], &sha1[20 * i], msg ? msg : "fetch (unknown)");
+               lock[i] = NULL;
+               if (ret)
+                       goto unlock_and_fail;
        }
+       if (msg)
+               free(msg);
 
-       if (write_ref) {
-               if (write_ref_log_details) {
-                       msg = xmalloc(strlen(write_ref_log_details) + 12);
-                       sprintf(msg, "fetch from %s", write_ref_log_details);
-               }
-               else
-                       msg = NULL;
-               ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)");
-               if (msg)
-                       free(msg);
-               return ret;
-       }
        return 0;
+
+
+unlock_and_fail:
+       for (i = 0; i < targets; i++)
+               if (lock[i])
+                       unlock_ref(lock[i]);
+       return -1;
 }
diff --git a/fetch.h b/fetch.h
index 841bb1af9cab0c19dda3f0cb5956edaec22f9d3a..be48c6f19092a81672dd24eb38e9ffca39f5b53c 100644 (file)
--- a/fetch.h
+++ b/fetch.h
@@ -22,12 +22,6 @@ extern void prefetch(unsigned char *sha1);
  */
 extern int fetch_ref(char *ref, unsigned char *sha1);
 
-/* If set, the ref filename to write the target value to. */
-extern const char *write_ref;
-
-/* If set additional text will appear in the ref log. */
-extern const char *write_ref_log_details;
-
 /* Set to fetch the target tree. */
 extern int get_tree;
 
@@ -46,6 +40,15 @@ extern int get_recover;
 /* Report what we got under get_verbosely */
 extern void pull_say(const char *, const char *);
 
-extern int pull(char *target);
+/* Load pull targets from stdin */
+extern int pull_targets_stdin(char ***target, const char ***write_ref);
+
+/* Free up loaded targets */
+extern void pull_targets_free(int targets, char **target, const char **write_ref);
+
+/* If write_ref is set, the ref filename to write the target value to. */
+/* If write_ref_log_details is set, additional text will appear in the ref log. */
+extern int pull(int targets, char **target, const char **write_ref,
+               const char *write_ref_log_details);
 
 #endif /* PULL_H */
index 5b73837bb1e1f0b29ec089942a6a785fc38f1cbc..2130d57020de2dae570b7be0d9a516389bd1829f 100755 (executable)
@@ -1142,9 +1142,7 @@ sub req_ci
         exit;
     }
 
-    open FILE, ">", "$ENV{GIT_DIR}refs/heads/$state->{module}";
-    print FILE $commithash;
-    close FILE;
+    print LOCKFILE $commithash;
 
     $updater->update();
 
@@ -1171,7 +1169,9 @@ sub req_ci
     }
 
     close LOCKFILE;
-    unlink($lockfile);
+    my $reffile = "$ENV{GIT_DIR}refs/heads/$state->{module}";
+    unlink($reffile);
+    rename($lockfile, $reffile);
     chdir "/";
 
     print "ok\n";
index 9829c591543b0fe4dd55b996cb399d925dda08ab..16cd351f7f0d992be37be83017961c70731d4cc5 100755 (executable)
@@ -54,6 +54,10 @@ start_httpd () {
                        fi
                done
        fi
+       if test $? != 0; then
+               echo "Could not execute http daemon $httpd."
+               exit 1
+       fi
 }
 
 stop_httpd () {
@@ -184,7 +188,7 @@ EOF
        else
                # plain-old CGI
                list_mods=`echo "$httpd" | sed "s/-f$/-l/"`
-               $list_mods | grep 'mod_cgi\.c' >/dev/null || \
+               $list_mods | grep 'mod_cgi\.c' >/dev/null 2>&1 || \
                echo "LoadModule cgi_module $module_path/mod_cgi.so" >> "$conf"
                cat >> "$conf" <<EOF
 AddHandler cgi-script .cgi
@@ -234,4 +238,5 @@ esac
 
 start_httpd
 test -z "$browser" && browser=echo
-$browser http://127.0.0.1:$port
+url=http://127.0.0.1:$port
+$browser $url || echo $url
index ba6d587f3199e5847dc942810ea85b2dbec656b9..b928f2ca52c1991ee50838fc47580ed83c58fb64 100755 (executable)
@@ -12,7 +12,7 @@ fi
 laf="$GIT_DIR/lost-found"
 rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit
 
-git fsck-objects |
+git fsck-objects --full |
 while read dangling type sha1
 do
        case "$dangling" in
index 5c0224090a252bed3258bbbb127e84e61a874197..36fc8ce25b39682ba256a8d39bf9a393907ef43d 100755 (executable)
@@ -52,7 +52,8 @@ then
 else
        rm -f "$GIT_DIR/ORIG_HEAD"
 fi
-git-update-ref -m "reset $reset_type $@" HEAD "$rev"
+git-update-ref -m "reset $reset_type $*" HEAD "$rev"
+update_ref_status=$?
 
 case "$reset_type" in
 --hard )
@@ -66,3 +67,5 @@ case "$reset_type" in
 esac
 
 rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" "$GIT_DIR/SQUASH_MSG"
+
+exit $update_ref_status
diff --git a/git.c b/git.c
index d47e9d8db9503159b5655b22903758a05df3bf64..452180e23af9250bbc7fcc8a9cca70b24129dc68 100644 (file)
--- a/git.c
+++ b/git.c
@@ -35,6 +35,59 @@ static void prepend_to_path(const char *dir, int len)
        setenv("PATH", path, 1);
 }
 
+static int handle_options(const char*** argv, int* argc)
+{
+       int handled = 0;
+
+       while (*argc > 0) {
+               const char *cmd = (*argv)[0];
+               if (cmd[0] != '-')
+                       break;
+
+               /*
+                * For legacy reasons, the "version" and "help"
+                * commands can be written with "--" prepended
+                * to make them look like flags.
+                */
+               if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
+                       break;
+
+               /*
+                * Check remaining flags.
+                */
+               if (!strncmp(cmd, "--exec-path", 11)) {
+                       cmd += 11;
+                       if (*cmd == '=')
+                               git_set_exec_path(cmd + 1);
+                       else {
+                               puts(git_exec_path());
+                               exit(0);
+                       }
+               } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
+                       setup_pager();
+               } else if (!strcmp(cmd, "--git-dir")) {
+                       if (*argc < 1)
+                               return -1;
+                       setenv("GIT_DIR", (*argv)[1], 1);
+                       (*argv)++;
+                       (*argc)--;
+               } else if (!strncmp(cmd, "--git-dir=", 10)) {
+                       setenv("GIT_DIR", cmd + 10, 1);
+               } else if (!strcmp(cmd, "--bare")) {
+                       static char git_dir[1024];
+                       setenv("GIT_DIR", getcwd(git_dir, 1024), 1);
+               } else {
+                       fprintf(stderr, "Unknown option: %s\n", cmd);
+                       cmd_usage(0, NULL, NULL);
+               }
+
+               (*argv)++;
+               (*argc)--;
+               handled++;
+       }
+       return handled;
+}
+
 static const char *alias_command;
 static char *alias_string = NULL;
 
@@ -106,7 +159,7 @@ static int handle_alias(int *argcp, const char ***argv)
 
        subdir = setup_git_directory_gently(&nongit);
        if (!nongit) {
-               int count;
+               int count, option_count;
                const char** new_argv;
 
                alias_command = (*argv)[0];
@@ -114,6 +167,10 @@ static int handle_alias(int *argcp, const char ***argv)
                if (alias_string) {
 
                        count = split_cmdline(alias_string, &new_argv);
+                       option_count = handle_options(&new_argv, &count);
+                       memmove(new_argv - option_count, new_argv,
+                                       count * sizeof(char *));
+                       new_argv -= option_count;
 
                        if (count < 1)
                                die("empty alias for %s", alias_command);
@@ -157,52 +214,55 @@ static int handle_alias(int *argcp, const char ***argv)
 
 const char git_version_string[] = GIT_VERSION;
 
+#define NEEDS_PREFIX 1
+
 static void handle_internal_command(int argc, const char **argv, char **envp)
 {
        const char *cmd = argv[0];
        static struct cmd_struct {
                const char *cmd;
-               int (*fn)(int, const char **, char **);
+               int (*fn)(int, const char **, const char *);
+               int prefix;
        } commands[] = {
                { "version", cmd_version },
                { "help", cmd_help },
-               { "log", cmd_log },
-               { "whatchanged", cmd_whatchanged },
-               { "show", cmd_show },
+               { "log", cmd_log, NEEDS_PREFIX },
+               { "whatchanged", cmd_whatchanged, NEEDS_PREFIX },
+               { "show", cmd_show, NEEDS_PREFIX },
                { "push", cmd_push },
-               { "format-patch", cmd_format_patch },
+               { "format-patch", cmd_format_patch, NEEDS_PREFIX },
                { "count-objects", cmd_count_objects },
-               { "diff", cmd_diff },
-               { "grep", cmd_grep },
-               { "rm", cmd_rm },
-               { "add", cmd_add },
-               { "rev-list", cmd_rev_list },
+               { "diff", cmd_diff, NEEDS_PREFIX },
+               { "grep", cmd_grep, NEEDS_PREFIX },
+               { "rm", cmd_rm, NEEDS_PREFIX },
+               { "add", cmd_add, NEEDS_PREFIX },
+               { "rev-list", cmd_rev_list, NEEDS_PREFIX },
                { "init-db", cmd_init_db },
                { "get-tar-commit-id", cmd_get_tar_commit_id },
                { "upload-tar", cmd_upload_tar },
                { "check-ref-format", cmd_check_ref_format },
-               { "ls-files", cmd_ls_files },
-               { "ls-tree", cmd_ls_tree },
-               { "tar-tree", cmd_tar_tree },
-               { "read-tree", cmd_read_tree },
-               { "commit-tree", cmd_commit_tree },
+               { "ls-files", cmd_ls_files, NEEDS_PREFIX },
+               { "ls-tree", cmd_ls_tree, NEEDS_PREFIX },
+               { "tar-tree", cmd_tar_tree, NEEDS_PREFIX },
+               { "read-tree", cmd_read_tree, NEEDS_PREFIX },
+               { "commit-tree", cmd_commit_tree, NEEDS_PREFIX },
                { "apply", cmd_apply },
-               { "show-branch", cmd_show_branch },
-               { "diff-files", cmd_diff_files },
-               { "diff-index", cmd_diff_index },
-               { "diff-stages", cmd_diff_stages },
-               { "diff-tree", cmd_diff_tree },
-               { "cat-file", cmd_cat_file },
-               { "rev-parse", cmd_rev_parse },
-               { "write-tree", cmd_write_tree },
+               { "show-branch", cmd_show_branch, NEEDS_PREFIX },
+               { "diff-files", cmd_diff_files, NEEDS_PREFIX },
+               { "diff-index", cmd_diff_index, NEEDS_PREFIX },
+               { "diff-stages", cmd_diff_stages, NEEDS_PREFIX },
+               { "diff-tree", cmd_diff_tree, NEEDS_PREFIX },
+               { "cat-file", cmd_cat_file, NEEDS_PREFIX },
+               { "rev-parse", cmd_rev_parse, NEEDS_PREFIX },
+               { "write-tree", cmd_write_tree, NEEDS_PREFIX },
                { "mailsplit", cmd_mailsplit },
                { "mailinfo", cmd_mailinfo },
                { "stripspace", cmd_stripspace },
-               { "update-index", cmd_update_index },
-               { "update-ref", cmd_update_ref },
-               { "fmt-merge-msg", cmd_fmt_merge_msg },
-               { "prune", cmd_prune },
-               { "mv", cmd_mv },
+               { "update-index", cmd_update_index, NEEDS_PREFIX },
+               { "update-ref", cmd_update_ref, NEEDS_PREFIX },
+               { "fmt-merge-msg", cmd_fmt_merge_msg, NEEDS_PREFIX },
+               { "prune", cmd_prune, NEEDS_PREFIX },
+               { "mv", cmd_mv, NEEDS_PREFIX },
        };
        int i;
 
@@ -214,9 +274,13 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
 
        for (i = 0; i < ARRAY_SIZE(commands); i++) {
                struct cmd_struct *p = commands+i;
+               const char *prefix;
                if (strcmp(p->cmd, cmd))
                        continue;
 
+               prefix = NULL;
+               if (p->prefix)
+                       prefix = setup_git_directory();
                if (getenv("GIT_TRACE")) {
                        int i;
                        fprintf(stderr, "trace: built-in: git");
@@ -228,7 +292,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
                        fflush(stderr);
                }
 
-               exit(p->fn(argc, argv, envp));
+               exit(p->fn(argc, argv, prefix));
        }
 }
 
@@ -269,51 +333,19 @@ int main(int argc, const char **argv, char **envp)
                die("cannot handle %s internally", cmd);
        }
 
-       /* Default command: "help" */
-       cmd = "help";
-
        /* Look for flags.. */
-       while (argc > 1) {
-               cmd = *++argv;
-               argc--;
-
-               if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
-                       setup_pager();
-                       continue;
-               }
-
-               if (strncmp(cmd, "--", 2))
-                       break;
-
-               cmd += 2;
-
-               /*
-                * For legacy reasons, the "version" and "help"
-                * commands can be written with "--" prepended
-                * to make them look like flags.
-                */
-               if (!strcmp(cmd, "help"))
-                       break;
-               if (!strcmp(cmd, "version"))
-                       break;
-
-               /*
-                * Check remaining flags (which by now must be
-                * "--exec-path", but maybe we will accept
-                * other arguments some day)
-                */
-               if (!strncmp(cmd, "exec-path", 9)) {
-                       cmd += 9;
-                       if (*cmd == '=') {
-                               git_set_exec_path(cmd + 1);
-                               continue;
-                       }
-                       puts(git_exec_path());
-                       exit(0);
-               }
-               cmd_usage(0, NULL, NULL);
+       argv++;
+       argc--;
+       handle_options(&argv, &argc);
+       if (argc > 0) {
+               if (!strncmp(argv[0], "--", 2))
+                       argv[0] += 2;
+       } else {
+               /* Default command: "help" */
+               argv[0] = "help";
+               argc = 1;
        }
-       argv[0] = cmd;
+       cmd = argv[0];
 
        /*
         * We search for git commands in the following order:
index 30cb624b2a38bc5b90915f0061ff3127ac0ee34d..243a2921f849568260e848201d238b3b9fe7e1f2 100755 (executable)
@@ -1199,6 +1199,20 @@ sub git_summary {
        git_footer_html();
 }
 
+sub git_print_page_path {
+       my $name = shift;
+       my $type = shift;
+
+       if (!defined $name) {
+               print "<div class=\"page_path\"><b>/</b></div>\n";
+       } elsif ($type =~ "blob") {
+               print "<div class=\"page_path\"><b>" .
+                       $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;f=$file_name")}, esc_html($name)) . "</b><br/></div>\n";
+       } else {
+               print "<div class=\"page_path\"><b>" . esc_html($name) . "</b><br/></div>\n";
+       }
+}
+
 sub git_tag {
        my $head = git_read_head($project);
        git_header_html();
@@ -1266,7 +1280,7 @@ sub git_blame {
                "<div>" .
                $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) .
                "</div>\n";
-       print "<div class=\"page_path\"><b>" . esc_html($file_name) . "</b></div>\n";
+       git_print_page_path($file_name);
        print "<div class=\"page_body\">\n";
        print <<HTML;
 <table class="blame">
@@ -1531,6 +1545,14 @@ sub git_blob_plain_mimetype {
 }
 
 sub git_blob_plain {
+       if (!defined $hash) {
+                if (defined $file_name) {
+                        my $base = $hash_base || git_read_head($project);
+                        $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
+                } else {
+                        die_error(undef, "No file name defined.");
+                }
+        }
        my $type = shift;
        open my $fd, "-|", "$GIT cat-file blob $hash" or die_error("Couldn't cat $file_name, $hash");
 
@@ -1554,10 +1576,14 @@ sub git_blob_plain {
 }
 
 sub git_blob {
-       if (!defined $hash && defined $file_name) {
-               my $base = $hash_base || git_read_head($project);
-               $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
-       }
+       if (!defined $hash) {
+                if (defined $file_name) {
+                        my $base = $hash_base || git_read_head($project);
+                        $hash = git_get_hash_by_path($base, $file_name, "blob") || die_error(undef, "Error lookup file.");
+                } else {
+                        die_error(undef, "No file name defined.");
+                }
+        }
        my $have_blame = git_get_project_config_bool ('blame');
        open my $fd, "-|", "$GIT cat-file blob $hash" or die_error(undef, "Open failed.");
        my $mimetype = git_blob_plain_mimetype($fd, $file_name);
@@ -1592,9 +1618,7 @@ sub git_blob {
                      "<br/><br/></div>\n" .
                      "<div class=\"title\">$hash</div>\n";
        }
-       if (defined $file_name) {
-               print "<div class=\"page_path\"><b>" . esc_html($file_name) . "</b></div>\n";
-       }
+       git_print_page_path($file_name, "blob");
        print "<div class=\"page_body\">\n";
        my $nr;
        while (my $line = <$fd>) {
@@ -1659,10 +1683,8 @@ sub git_tree {
        }
        if (defined $file_name) {
                $base = esc_html("$file_name/");
-               print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b></div>\n";
-       } else {
-               print "<div class=\"page_path\"><b>/</b></div>\n";
        }
+       git_print_page_path($file_name);
        print "<div class=\"page_body\">\n";
        print "<table cellspacing=\"0\">\n";
        my $alternate = 0;
@@ -1687,7 +1709,7 @@ sub git_tree {
                              "<td class=\"link\">" .
                              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$t_hash$base_key;f=$base$t_name")}, "blob") .
 #                            " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blame;h=$t_hash$base_key;f=$base$t_name")}, "blame") .
-                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
+                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$t_hash;hb=$hash_base;f=$base$t_name")}, "history") .
                              " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob_plain;h=$t_hash;f=$base$t_name")}, "raw") .
                              "</td>\n";
                } elsif ($t_type eq "tree") {
@@ -1696,7 +1718,7 @@ sub git_tree {
                              "</td>\n" .
                              "<td class=\"link\">" .
                              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$t_hash$base_key;f=$base$t_name")}, "tree") .
-                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash_base;f=$base$t_name")}, "history") .
+                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash_base;f=$base$t_name")}, "history") .
                              "</td>\n";
                }
                print "</tr>\n";
@@ -2041,7 +2063,7 @@ sub git_commit {
                              "<td><span class=\"file_status deleted\">[deleted " . file_type($from_mode). "]</span></td>\n" .
                              "<td class=\"link\">" .
                              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$from_id;hb=$hash;f=$file")}, "blob") .
-                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash;f=$file")}, "history") .
+                             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") .
                              "</td>\n"
                } elsif ($status eq "M" || $status eq "T") {
                        my $mode_chnge = "";
@@ -2072,7 +2094,7 @@ sub git_commit {
                        if ($to_id ne $from_id) {
                                print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file")}, "diff");
                        }
-                       print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;h=$hash;f=$file")}, "history") . "\n";
+                       print " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=history;hb=$hash;f=$file")}, "history") . "\n";
                        print "</td>\n";
                } elsif ($status eq "R") {
                        my ($from_file, $to_file) = split "\t", $file;
@@ -2120,9 +2142,7 @@ sub git_blobdiff {
                      "<br/><br/></div>\n" .
                      "<div class=\"title\">$hash vs $hash_parent</div>\n";
        }
-       if (defined $file_name) {
-               print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b></div>\n";
-       }
+       git_print_page_path($file_name, "blob");
        print "<div class=\"page_body\">\n" .
              "<div class=\"diff_info\">blob:" .
              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;h=$hash_parent;hb=$hash_base;f=$file_name")}, $hash_parent) .
@@ -2293,10 +2313,11 @@ sub git_commitdiff_plain {
 }
 
 sub git_history {
-       if (!defined $hash) {
-               $hash = git_read_head($project);
+       if (!defined $hash_base) {
+               $hash_base = git_read_head($project);
        }
-       my %co = git_read_commit($hash);
+       my $ftype;
+       my %co = git_read_commit($hash_base);
        if (!%co) {
                die_error(undef, "Unknown commit object.");
        }
@@ -2306,18 +2327,24 @@ sub git_history {
              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=summary")}, "summary") .
              " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "shortlog") .
              " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=log")}, "log") .
-             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash")}, "commit") .
-             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash")}, "commitdiff") .
-             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash")}, "tree") .
+             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base")}, "commit") .
+             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$hash_base")}, "commitdiff") .
+             " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=tree;h=$co{'tree'};hb=$hash_base")}, "tree") .
              "<br/><br/>\n" .
              "</div>\n";
        print "<div>\n" .
-             $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash"), -class => "title"}, esc_html($co{'title'})) . "\n" .
+             $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$hash_base"), -class => "title"}, esc_html($co{'title'})) . "\n" .
              "</div>\n";
-       print "<div class=\"page_path\"><b>/" . esc_html($file_name) . "</b><br/></div>\n";
+       if (!defined $hash && defined $file_name) {
+               $hash = git_get_hash_by_path($hash_base, $file_name);
+       }
+       if (defined $hash) {
+               $ftype = git_get_type($hash);
+       }
+       git_print_page_path($file_name, $ftype);
 
        open my $fd, "-|",
-               "$GIT rev-list --full-history $hash -- \'$file_name\'";
+               "$GIT rev-list --full-history $hash_base -- \'$file_name\'";
        print "<table cellspacing=\"0\">\n";
        my $alternate = 0;
        while (my $line = <$fd>) {
@@ -2345,7 +2372,7 @@ sub git_history {
                              $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") .
                              " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") .
                              " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=blob;hb=$commit;f=$file_name")}, "blob");
-                       my $blob = git_get_hash_by_path($hash, $file_name);
+                       my $blob = git_get_hash_by_path($hash_base, $file_name);
                        my $blob_parent = git_get_hash_by_path($commit, $file_name);
                        if (defined $blob && defined $blob_parent && $blob ne $blob_parent) {
                                print " | " .
index 12493fbed2822ce41b5b4c23fb85d6f4a47c104a..1aad39b4d830d32b9ac4034153a06ddc08c72bcb 100644 (file)
@@ -36,6 +36,8 @@ enum XML_Status {
 #define PREV_BUF_SIZE 4096
 #define RANGE_HEADER_SIZE 30
 
+static int commits_on_stdin = 0;
+
 static int got_alternates = -1;
 static int corrupt_object_found = 0;
 
@@ -43,7 +45,7 @@ static struct curl_slist *no_pragma_header;
 
 struct alt_base
 {
-       char *base;
+       const char *base;
        int path_len;
        int got_indices;
        struct packed_git *packs;
@@ -81,7 +83,7 @@ struct object_request
 };
 
 struct alternates_request {
-       char *base;
+       const char *base;
        char *url;
        struct buffer *buffer;
        struct active_request_slot *slot;
@@ -142,7 +144,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
        return size;
 }
 
-static void fetch_alternates(char *base);
+static void fetch_alternates(const char *base);
 
 static void process_object_response(void *callback_data);
 
@@ -507,7 +509,7 @@ static void process_alternates_response(void *callback_data)
                (struct alternates_request *)callback_data;
        struct active_request_slot *slot = alt_req->slot;
        struct alt_base *tail = alt;
-       char *base = alt_req->base;
+       const char *base = alt_req->base;
        static const char null_byte = '\0';
        char *data;
        int i = 0;
@@ -612,7 +614,7 @@ static void process_alternates_response(void *callback_data)
        got_alternates = 1;
 }
 
-static void fetch_alternates(char *base)
+static void fetch_alternates(const char *base)
 {
        struct buffer buffer;
        char *url;
@@ -1185,7 +1187,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
         char *url;
         char hex[42];
         struct buffer buffer;
-       char *base = alt->base;
+       const char *base = alt->base;
        struct active_request_slot *slot;
        struct slot_results results;
         buffer.size = 41;
@@ -1214,10 +1216,12 @@ int fetch_ref(char *ref, unsigned char *sha1)
         return 0;
 }
 
-int main(int argc, char **argv)
+int main(int argc, const char **argv)
 {
-       char *commit_id;
-       char *url;
+       int commits;
+       const char **write_ref = NULL;
+       char **commit_id;
+       const char *url;
        char *path;
        int arg = 1;
        int rc = 0;
@@ -1237,20 +1241,26 @@ int main(int argc, char **argv)
                } else if (argv[arg][1] == 'v') {
                        get_verbosely = 1;
                } else if (argv[arg][1] == 'w') {
-                       write_ref = argv[arg + 1];
+                       write_ref = &argv[arg + 1];
                        arg++;
                } else if (!strcmp(argv[arg], "--recover")) {
                        get_recover = 1;
+               } else if (!strcmp(argv[arg], "--stdin")) {
+                       commits_on_stdin = 1;
                }
                arg++;
        }
-       if (argc < arg + 2) {
-               usage("git-http-fetch [-c] [-t] [-a] [-d] [-v] [--recover] [-w ref] commit-id url");
+       if (argc < arg + 2 - commits_on_stdin) {
+               usage("git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url");
                return 1;
        }
-       commit_id = argv[arg];
-       url = argv[arg + 1];
-       write_ref_log_details = url;
+       if (commits_on_stdin) {
+               commits = pull_targets_stdin(&commit_id, &write_ref);
+       } else {
+               commit_id = (char **) &argv[arg++];
+               commits = 1;
+       }
+       url = argv[arg];
 
        http_init();
 
@@ -1268,13 +1278,16 @@ int main(int argc, char **argv)
                        alt->path_len = strlen(path);
        }
 
-       if (pull(commit_id))
+       if (pull(commits, commit_id, write_ref, url))
                rc = 1;
 
        http_cleanup();
 
        curl_slist_free_all(no_pragma_header);
 
+       if (commits_on_stdin)
+               pull_targets_free(commits, commit_id, write_ref);
+
        if (corrupt_object_found) {
                fprintf(stderr,
 "Some loose object were found to be corrupt, but they might be just\n"
index 47686195cdf41ad58fe66a606033d3156de8fd82..4021e7d9274b713a7b5c48d66f9ddf21ddc07094 100644 (file)
@@ -2521,7 +2521,7 @@ int main(int argc, char **argv)
                        commit_argv[3] = old_sha1_hex;
                        commit_argc++;
                }
-               init_revisions(&revs);
+               init_revisions(&revs, setup_git_directory());
                setup_revisions(commit_argc, commit_argv, &revs, NULL);
                free(new_sha1_hex);
                if (old_sha1_hex) {
index ffa4887570319a2cbcf4042bd6e00063a48a4b6d..b216bdd55742ef8214ed1193ef184f8bba70eb70 100644 (file)
@@ -8,8 +8,9 @@
 static int use_link = 0;
 static int use_symlink = 0;
 static int use_filecopy = 1;
+static int commits_on_stdin = 0;
 
-static char *path; /* "Remote" git repository */
+static const char *path; /* "Remote" git repository */
 
 void prefetch(unsigned char *sha1)
 {
@@ -194,17 +195,19 @@ int fetch_ref(char *ref, unsigned char *sha1)
 }
 
 static const char local_pull_usage[] =
-"git-local-fetch [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path";
+"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path";
 
-/* 
+/*
  * By default we only use file copy.
  * If -l is specified, a hard link is attempted.
  * If -s is specified, then a symlink is attempted.
  * If -n is _not_ specified, then a regular file-to-file copy is done.
  */
-int main(int argc, char **argv)
+int main(int argc, const char **argv)
 {
-       char *commit_id;
+       int commits;
+       const char **write_ref = NULL;
+       char **commit_id;
        int arg = 1;
 
        setup_git_directory();
@@ -229,21 +232,30 @@ int main(int argc, char **argv)
                else if (argv[arg][1] == 'v')
                        get_verbosely = 1;
                else if (argv[arg][1] == 'w')
-                       write_ref = argv[++arg];
+                       write_ref = &argv[++arg];
                else if (!strcmp(argv[arg], "--recover"))
                        get_recover = 1;
+               else if (!strcmp(argv[arg], "--stdin"))
+                       commits_on_stdin = 1;
                else
                        usage(local_pull_usage);
                arg++;
        }
-       if (argc < arg + 2)
+       if (argc < arg + 2 - commits_on_stdin)
                usage(local_pull_usage);
-       commit_id = argv[arg];
-       path = argv[arg + 1];
-       write_ref_log_details = path;
+       if (commits_on_stdin) {
+               commits = pull_targets_stdin(&commit_id, &write_ref);
+       } else {
+               commit_id = (char **) &argv[arg++];
+               commits = 1;
+       }
+       path = argv[arg];
 
-       if (pull(commit_id))
+       if (pull(commits, commit_id, write_ref, path))
                return 1;
 
+       if (commits_on_stdin)
+               pull_targets_free(commits, commit_id, write_ref);
+
        return 0;
 }
diff --git a/refs.c b/refs.c
index 56db394459cec2cd156ee2243a1dbac33867f926..02850b69083f793becacc59a0da97a8f69367e4e 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -294,6 +294,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path,
        int plen,
        const unsigned char *old_sha1, int mustexist)
 {
+       const char *orig_path = path;
        struct ref_lock *lock;
        struct stat st;
 
@@ -303,7 +304,11 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path,
        plen = strlen(path) - plen;
        path = resolve_ref(path, lock->old_sha1, mustexist);
        if (!path) {
+               int last_errno = errno;
+               error("unable to resolve reference %s: %s",
+                       orig_path, strerror(errno));
                unlock_ref(lock);
+               errno = last_errno;
                return NULL;
        }
        lock->lk = xcalloc(1, sizeof(struct lock_file));
index 874e349db818d52329e30f2634855e5cf14192b8..a58257ad8037f7009c69ee0502c3669756bb3987 100644 (file)
@@ -509,7 +509,7 @@ static int add_parents_only(struct rev_info *revs, const char *arg, int flags)
        return 1;
 }
 
-void init_revisions(struct rev_info *revs)
+void init_revisions(struct rev_info *revs, const char *prefix)
 {
        memset(revs, 0, sizeof(*revs));
 
@@ -521,7 +521,7 @@ void init_revisions(struct rev_info *revs)
        revs->pruning.change = file_change;
        revs->lifo = 1;
        revs->dense = 1;
-       revs->prefix = setup_git_directory();
+       revs->prefix = prefix;
        revs->max_age = -1;
        revs->min_age = -1;
        revs->max_count = -1;
index e23ec8f45a3b635d83f662e4de5d671e41f37919..0c3b8d99059fb272b913a85c2873f5fef64acc00 100644 (file)
@@ -87,7 +87,7 @@ struct rev_info {
 extern int rev_same_tree_as_empty(struct rev_info *, struct tree *t1);
 extern int rev_compare_tree(struct rev_info *, struct tree *t1, struct tree *t2);
 
-extern void init_revisions(struct rev_info *revs);
+extern void init_revisions(struct rev_info *revs, const char *prefix);
 extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
 extern void prepare_revision_walk(struct rev_info *revs);
 extern struct commit *get_revision(struct rev_info *revs);
index 28f7fd9174e8c48493983b17fa7b18cdecd41609..6e16568f88f6fcbbb79d23c1f6187860c8cfb453 100644 (file)
@@ -120,9 +120,10 @@ int fetch_ref(char *ref, unsigned char *sha1)
 
 static const char ssh_fetch_usage[] =
   MY_PROGRAM_NAME
-  " [-c] [-t] [-a] [-v] [-d] [--recover] [-w ref] commit-id url";
+  " [-c] [-t] [-a] [-v] [--recover] [-w ref] commit-id url";
 int main(int argc, char **argv)
 {
+       const char *write_ref = NULL;
        char *commit_id;
        char *url;
        int arg = 1;
@@ -159,7 +160,6 @@ int main(int argc, char **argv)
        }
        commit_id = argv[arg];
        url = argv[arg + 1];
-       write_ref_log_details = url;
 
        if (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))
                return 1;
@@ -167,7 +167,7 @@ int main(int argc, char **argv)
        if (get_version())
                return 1;
 
-       if (pull(commit_id))
+       if (pull(1, &commit_id, &write_ref, url))
                return 1;
 
        return 0;
index 04fab26621af3aee3a44913ab290a4893b4f23ca..ddc80bbeae7703b8c4a2ddcf12d8b1ec9c6bbe46 100755 (executable)
@@ -14,6 +14,8 @@ D=4444444444444444444444444444444444444444
 E=5555555555555555555555555555555555555555
 F=6666666666666666666666666666666666666666
 m=refs/heads/master
+n_dir=refs/heads/gu
+n=$n_dir/fixes
 
 test_expect_success \
        "create $m" \
@@ -25,6 +27,16 @@ test_expect_success \
         test $B = $(cat .git/$m)'
 rm -f .git/$m
 
+test_expect_success \
+       "fail to create $n" \
+       'touch .git/$n_dir
+        git-update-ref $n $A >out 2>err
+        test $? = 1 &&
+        test "" = "$(cat out)" &&
+        grep "error: unable to resolve reference" err &&
+        grep $n err'
+rm -f .git/$n_dir out err
+
 test_expect_success \
        "create $m (by HEAD)" \
        'git-update-ref HEAD $A &&
index fbb508d389e078263d983bf6736df8f1a0fe7b5d..22da6a00ccbe910d796dc84666caa2acfa9b8389 100755 (executable)
@@ -13,8 +13,8 @@ test_description='git-apply handling copy/rename patch.
 cat >test-patch <<\EOF
 diff --git a/foo b/bar
 similarity index 47%
-copy from foo
-copy to bar
+rename from foo
+rename to bar
 --- a/foo
 +++ b/bar
 @@ -1 +1 @@
@@ -39,4 +39,24 @@ else
            'test -f bar && ls -l bar | grep "^-..x......"'
 fi
 
+test_expect_success 'apply reverse' \
+    'git-apply -R --index --stat --summary --apply test-patch &&
+     test "$(cat foo)" = "This is foo"'
+
+cat >test-patch <<\EOF
+diff --git a/foo b/bar
+similarity index 47%
+copy from foo
+copy to bar
+--- a/foo
++++ b/bar
+@@ -1 +1 @@
+-This is foo
++This is bar
+EOF
+
+test_expect_success 'apply copy' \
+    'git-apply --index --stat --summary --apply test-patch &&
+     test "$(cat bar)" = "This is bar" -a "$(cat foo)" = "This is foo"'
+
 test_done
index 00bd8b15c625f3f95aefa771abded1a985342c23..ff052699a28d2d96de4bdaa4702f175527f28536 100755 (executable)
@@ -35,8 +35,8 @@ git-commit -m 'Second Version'
 git-diff-tree -p master binary >B.diff
 git-diff-tree -p -C master binary >C.diff
 
-git-diff-tree -p --full-index master binary >BF.diff
-git-diff-tree -p --full-index -C master binary >CF.diff
+git-diff-tree -p --binary master binary >BF.diff
+git-diff-tree -p --binary -C master binary >CF.diff
 
 test_expect_success 'stat binary diff -- should not fail.' \
        'git-checkout master