Code

Merge /pub/scm/git/git to recover lost side branch
authorJunio C Hamano <junio@hera.kernel.org>
Fri, 21 Oct 2005 00:06:15 +0000 (17:06 -0700)
committerJunio C Hamano <junio@hera.kernel.org>
Fri, 21 Oct 2005 00:06:15 +0000 (17:06 -0700)
Sorry for the mistake of rewinding something already pushed out.
This recovers the side branch lost by that mistake, specifically
ea5a65a59916503d2a14369c46b1023384d51645 commit.

Signed-off-by: Junio C Hamano <junio@hera.kernel.org>
12 files changed:
Documentation/git-clone-pack.txt
Documentation/git-fetch.txt
Documentation/git-pull.txt
Documentation/git-push.txt
Documentation/pull-fetch-param.txt
clone-pack.c
daemon.c
fetch-pack.c
git-count-objects.sh
http-fetch.c
sha1_name.c
upload-pack.c

index b58165a5fc03a8556217599ef6a6f24f2f87f696..cfc7b62f31b6470b9d9011b49d73d135a0623dd9 100644 (file)
@@ -8,26 +8,17 @@ git-clone-pack - Clones a repository by receiving packed objects.
 
 SYNOPSIS
 --------
-'git-clone-pack' [-q] [--keep] [--exec=<git-upload-pack>] [<host>:]<directory> [<head>...]
+'git-clone-pack' [--exec=<git-upload-pack>] [<host>:]<directory> [<head>...]
 
 DESCRIPTION
 -----------
 Clones a repository into the current repository by invoking
 'git-upload-pack', possibly on the remote host via ssh, in
-the named repository, and invoking 'git-unpack-objects' locally
-to receive the pack.
+the named repository, and stores the sent pack in the local
+repository.
 
 OPTIONS
 -------
--q::
-       Pass '-q' flag to 'git-unpack-objects'; this makes the
-       cloning process less verbose.
-
---keep::
-       Do not invoke 'git-unpack-objects' on received data, but
-       create a single packfile out of it instead, and store it
-       in the object database.
-
 --exec=<git-upload-pack>::
        Use this to specify the path to 'git-upload-pack' on the
        remote side, if it is not found on your $PATH.
index c0b5aac5f281b07aea61183c4c6a09b79447c8ea..71693650c4194514f62dd5d8524b446dd8641805 100644 (file)
@@ -25,6 +25,11 @@ OPTIONS
 -------
 include::pull-fetch-param.txt[]
 
+-a, \--append::
+       Append ref names and object names of fetched refs to the
+       existing contents of $GIT_DIR/FETCH_HEAD.  Without this
+       option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
+
 -u, \--update-head-ok::
        By default 'git-fetch' refuses to update the head which
        corresponds to the current branch.  This flag disables the
index 952779292b56ad70aae4d287357a8ca3db61414c..bae05dee99ebaa7866885d3d8a36cde81e5d700e 100644 (file)
@@ -24,6 +24,10 @@ OPTIONS
 -------
 include::pull-fetch-param.txt[]
 
+-a, \--append::
+       Append ref names and object names of fetched refs to the
+       existing contents of $GIT_DIR/FETCH_HEAD.  Without this
+       option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
 
 Author
 ------
index 809ac8ba069a8a97a686d62f1bb586005836f896..f45ac5ee4910198fa351e56bb40333612787fcd2 100644 (file)
@@ -21,6 +21,15 @@ OPTIONS
 -------
 include::pull-fetch-param.txt[]
 
+\--all::
+       Instead of naming each ref to push, specifies all refs
+       to be pushed.
+
+-f, \--force::
+       Usually, the command refuses to update a local ref that is
+       not an ancestor of the remote ref used to overwrite it.
+       This flag disables the check.  What this means is that the
+       local repository can lose commits; use it with care.
 
 Author
 ------
index 51222b6f3fd584639b77457be4da2cd82f9f8450..e8db9d7ca5bae5b5accdc8508e20a743ff053213 100644 (file)
@@ -75,13 +75,3 @@ Some short-cut notations are also supported.
   pushing.  That is, do not store it locally if
   fetching, and update the same name if pushing.
 
--a, \--append::
-       Append ref names and object names of fetched refs to the
-       existing contents of $GIT_DIR/FETCH_HEAD.  Without this
-       option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
-
--f, \--force::
-       Usually, the command refuses to update a local ref that is
-       not an ancestor of the remote ref used to overwrite it.
-       This flag disables the check.  What this means is that the
-       local repository can lose commits; use it with care.
index f9b263a441eb2559a904e3db9fb35fac05b9590e..4f4975b4ab7faecb172482f308999e48ea643d37 100644 (file)
@@ -3,10 +3,8 @@
 #include "pkt-line.h"
 #include <sys/wait.h>
 
-static int quiet;
-static int keep_pack;
 static const char clone_pack_usage[] =
-"git-clone-pack [-q] [--keep] [--exec=<git-upload-pack>] [<host>:]<directory> [<heads>]*";
+"git-clone-pack [--exec=<git-upload-pack>] [<host>:]<directory> [<heads>]*";
 static const char *exec = "git-upload-pack";
 
 static void clone_handshake(int fd[2], struct ref *ref)
@@ -114,41 +112,6 @@ static void write_refs(struct ref *ref)
        free(head_path);
 }
 
-static int clone_by_unpack(int fd[2])
-{
-       int status;
-       pid_t pid;
-
-       pid = fork();
-       if (pid < 0)
-               die("git-clone-pack: unable to fork off git-unpack-objects");
-       if (!pid) {
-               dup2(fd[0], 0);
-               close(fd[0]);
-               close(fd[1]);
-               execlp("git-unpack-objects", "git-unpack-objects",
-                       quiet ? "-q" : NULL, NULL);
-               die("git-unpack-objects exec failed");
-       }
-       close(fd[0]);
-       close(fd[1]);
-       while (waitpid(pid, &status, 0) < 0) {
-               if (errno != EINTR)
-                       die("waiting for git-unpack-objects: %s", strerror(errno));
-       }
-       if (WIFEXITED(status)) {
-               int code = WEXITSTATUS(status);
-               if (code)
-                       die("git-unpack-objects died with error code %d", code);
-               return 0;
-       }
-       if (WIFSIGNALED(status)) {
-               int sig = WTERMSIG(status);
-               die("git-unpack-objects died of signal %d", sig);
-       }
-       die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status);
-}
-
 static int finish_pack(const char *pack_tmp_name)
 {
        int pipe_fd[2];
@@ -294,35 +257,13 @@ static int clone_pack(int fd[2], int nr_match, char **match)
        }
        clone_handshake(fd, refs);
 
-       if (keep_pack)
-               status = clone_without_unpack(fd);
-       else
-               status = clone_by_unpack(fd);
+       status = clone_without_unpack(fd);
 
        if (!status)
                write_refs(refs);
        return status;
 }
 
-static int clone_options(const char *var, const char *value)
-{
-       if (!strcmp("clone.keeppack", var)) {
-               keep_pack = git_config_bool(var, value);
-               return 0;
-       }
-       if (!strcmp("clone.quiet", var)) {
-               quiet = git_config_bool(var, value);
-               return 0;
-       }
-       /*
-        * Put other local option parsing for this program
-        * here ...
-        */
-
-       /* Fall back on the default ones */
-       return git_default_config(var, value);
-}
-
 int main(int argc, char **argv)
 {
        int i, ret, nr_heads;
@@ -330,25 +271,20 @@ int main(int argc, char **argv)
        int fd[2];
        pid_t pid;
 
-       git_config(clone_options);
        nr_heads = 0;
        heads = NULL;
        for (i = 1; i < argc; i++) {
                char *arg = argv[i];
 
                if (*arg == '-') {
-                       if (!strcmp("-q", arg)) {
-                               quiet = 1;
+                       if (!strcmp("-q", arg))
                                continue;
-                       }
                        if (!strncmp("--exec=", arg, 7)) {
                                exec = arg + 7;
                                continue;
                        }
-                       if (!strcmp("--keep", arg)) {
-                               keep_pack = 1;
+                       if (!strcmp("--keep", arg))
                                continue;
-                       }
                        usage(clone_pack_usage);
                }
                dest = arg;
index 9ea6c31cd17fad509c8a97bb2ff099e8a5489ce8..c3381b344ccbeff2f13a52c83f17b9960798d8c3 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -13,7 +13,9 @@
 static int log_syslog;
 static int verbose;
 
-static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all] [directory...]";
+static const char daemon_usage[] =
+"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
+"           [--timeout=n] [--init-timeout=n] [directory...]";
 
 /* List of acceptable pathname prefixes */
 static char **ok_paths = NULL;
@@ -21,6 +23,9 @@ static char **ok_paths = NULL;
 /* If this is set, git-daemon-export-ok is not required */
 static int export_all_trees = 0;
 
+/* Timeout, and initial timeout */
+static unsigned int timeout = 0;
+static unsigned int init_timeout = 0;
 
 static void logreport(int priority, const char *err, va_list params)
 {
@@ -170,6 +175,8 @@ static int upload(char *dir)
        /* Enough for the longest path above including final null */
        int buflen = strlen(dir)+10;
        char *dirbuf = xmalloc(buflen);
+       /* Timeout as string */
+       char timeout_buf[64];
 
        loginfo("Request for '%s'", dir);
 
@@ -190,8 +197,10 @@ static int upload(char *dir)
         */
        signal(SIGTERM, SIG_IGN);
 
+       snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
+
        /* git-upload-pack only ever reads stuff, so this is safe */
-       execlp("git-upload-pack", "git-upload-pack", ".", NULL);
+       execlp("git-upload-pack", "git-upload-pack", "--strict", timeout_buf, ".", NULL);
        return -1;
 }
 
@@ -200,7 +209,9 @@ static int execute(void)
        static char line[1000];
        int len;
 
+       alarm(init_timeout ? init_timeout : timeout);
        len = packet_read_line(0, line, sizeof(line));
+       alarm(0);
 
        if (len && line[len-1] == '\n')
                line[--len] = 0;
@@ -598,6 +609,12 @@ int main(int argc, char **argv)
                        export_all_trees = 1;
                        continue;
                }
+               if (!strncmp(arg, "--timeout=", 10)) {
+                       timeout = atoi(arg+10);
+               }
+               if (!strncmp(arg, "--init-timeout=", 10)) {
+                       init_timeout = atoi(arg+15);
+               }
                if (!strcmp(arg, "--")) {
                        ok_paths = &argv[i+1];
                        break;
index 969e72a7816701ed3f86ab42db1472346cab991e..8566ab1744b029e9696976e78bac4d48d2324129 100644 (file)
@@ -12,31 +12,66 @@ static const char fetch_pack_usage[] =
 "git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory <refs>...";
 static const char *exec = "git-upload-pack";
 
+#define COMPLETE       (1U << 0)
+
 static int find_common(int fd[2], unsigned char *result_sha1,
                       struct ref *refs)
 {
        int fetching;
        static char line[1000];
-       int count = 0, flushes = 0, retval;
+       static char rev_command[1024];
+       int count = 0, flushes = 0, retval, rev_command_len;
        FILE *revs;
 
-       revs = popen("git-rev-list $(git-rev-parse --all)", "r");
-       if (!revs)
-               die("unable to run 'git-rev-list'");
-
+       strcpy(rev_command, "git-rev-list $(git-rev-parse --all)");
+       rev_command_len = strlen(rev_command);
        fetching = 0;
        for ( ; refs ; refs = refs->next) {
                unsigned char *remote = refs->old_sha1;
-               unsigned char *local = refs->new_sha1;
+               struct object *o;
 
-               if (!memcmp(remote, local, 20))
+               /*
+                * If that object is complete (i.e. it is an ancestor of a
+                * local ref), we tell them we have it but do not have to
+                * tell them about its ancestors, which they already know
+                * about.
+                *
+                * We use lookup_object here because we are only
+                * interested in the case we *know* the object is
+                * reachable and we have already scanned it.
+                */
+               if (((o = lookup_object(remote)) != NULL) &&
+                   (o->flags & COMPLETE)) {
+                       struct commit_list *p;
+                       struct commit *commit =
+                               (struct commit *) (o = deref_tag(o));
+                       if (!o)
+                               goto repair;
+                       if (o->type != commit_type)
+                               continue;
+                       p = commit->parents;
+                       while (p &&
+                              rev_command_len + 44 < sizeof(rev_command)) {
+                               snprintf(rev_command + rev_command_len, 44,
+                                        " ^%s",
+                                        sha1_to_hex(p->item->object.sha1));
+                               rev_command_len += 43;
+                               p = p->next;
+                       }
                        continue;
+               }
+       repair:
                packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
                fetching++;
        }
        packet_flush(fd[1]);
        if (!fetching)
                return 1;
+
+       revs = popen(rev_command, "r");
+       if (!revs)
+               die("unable to run 'git-rev-list'");
+
        flushes = 1;
        retval = -1;
        while (fgets(line, sizeof(line), revs) != NULL) {
@@ -81,7 +116,6 @@ static int find_common(int fd[2], unsigned char *result_sha1,
        return retval;
 }
 
-#define COMPLETE       (1U << 0)
 static struct commit_list *complete = NULL;
 
 static int mark_complete(const char *path, const unsigned char *sha1)
@@ -89,10 +123,13 @@ static int mark_complete(const char *path, const unsigned char *sha1)
        struct object *o = parse_object(sha1);
 
        while (o && o->type == tag_type) {
+               struct tag *t = (struct tag *) o;
+               if (!t->tagged)
+                       break; /* broken repository */
                o->flags |= COMPLETE;
-               o = parse_object(((struct tag *)o)->tagged->sha1);
+               o = parse_object(t->tagged->sha1);
        }
-       if (o->type == commit_type) {
+       if (o && o->type == commit_type) {
                struct commit *commit = (struct commit *)o;
                commit->object.flags |= COMPLETE;
                insert_by_date(commit, &complete);
index 74ee4f371f749cb5ae9fdb7e789d341f60997e62..843d2fd9f2ef53ccd1600dd9b89ec70fbc639146 100755 (executable)
@@ -2,7 +2,7 @@
 
 . git-sh-setup
 
-echo $(find "$GIT_DIR/objects"/?? -type f -print | wc -l) objects, \
+echo $(find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null | wc -l) objects, \
 $({
     echo 0
     # "no-such" is to help Darwin folks by not using xargs -r.
index efa6e82329ad514fc31f7c5d335e9b6ec962d95b..a7dc2cc3bdbcda8eee8cdadb706aba51782e68da 100644 (file)
@@ -100,6 +100,8 @@ static char *ssl_key = NULL;
 static char *ssl_capath = NULL;
 #endif
 static char *ssl_cainfo = NULL;
+static long curl_low_speed_limit = -1;
+static long curl_low_speed_time = -1;
 
 struct buffer
 {
@@ -158,6 +160,17 @@ static int http_options(const char *var, const char *value)
        }
 #endif
 
+       if (!strcmp("http.lowspeedlimit", var)) {
+               if (curl_low_speed_limit == -1)
+                       curl_low_speed_limit = (long)git_config_int(var, value);
+               return 0;
+       }
+       if (!strcmp("http.lowspeedtime", var)) {
+               if (curl_low_speed_time == -1)
+                       curl_low_speed_time = (long)git_config_int(var, value);
+               return 0;
+       }
+
        /* Fall back on the default ones */
        return git_default_config(var, value);
 }
@@ -246,6 +259,13 @@ static CURL* get_curl_handle(void)
                curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
        curl_easy_setopt(result, CURLOPT_FAILONERROR, 1);
 
+       if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) {
+               curl_easy_setopt(result, CURLOPT_LOW_SPEED_LIMIT,
+                                curl_low_speed_limit);
+               curl_easy_setopt(result, CURLOPT_LOW_SPEED_TIME,
+                                curl_low_speed_time);
+       }
+
        return result;
 }
 
@@ -1177,6 +1197,8 @@ int main(int argc, char **argv)
        char *url;
        int arg = 1;
        struct active_request_slot *slot;
+       char *low_speed_limit;
+       char *low_speed_time;
 
        while (arg < argc && argv[arg][0] == '-') {
                if (argv[arg][1] == 't') {
@@ -1232,6 +1254,13 @@ int main(int argc, char **argv)
 #endif
        ssl_cainfo = getenv("GIT_SSL_CAINFO");
 
+       low_speed_limit = getenv("GIT_HTTP_LOW_SPEED_LIMIT");
+       if (low_speed_limit != NULL)
+               curl_low_speed_limit = strtol(low_speed_limit, NULL, 10);
+       low_speed_time = getenv("GIT_HTTP_LOW_SPEED_TIME");
+       if (low_speed_time != NULL)
+               curl_low_speed_time = strtol(low_speed_time, NULL, 10);
+
        git_config(http_options);
 
        if (curl_ssl_verify == -1)
index 75c688ecf2d9381d665f4b2f388df4ceaa0fdab5..cc320d3d7fc38787190598034fceb787d95336d6 100644 (file)
@@ -323,6 +323,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
                return -1;
        if (!type_string) {
                o = deref_tag(o);
+               if (!o || (!o->parsed && !parse_object(o->sha1)))
+                       return -1;
                memcpy(sha1, o->sha1, 20);
        }
        else {
@@ -332,7 +334,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
                 */
 
                while (1) {
-                       if (!o)
+                       if (!o || (!o->parsed && !parse_object(o->sha1)))
                                return -1;
                        if (o->type == type_string) {
                                memcpy(sha1, o->sha1, 20);
index 21b4b8b7575dd3ceb2fdf40b5aa4b7483168ec1e..8a41cafaaa3fd3bc571aa21e3427260feaa84a65 100644 (file)
@@ -4,13 +4,19 @@
 #include "tag.h"
 #include "object.h"
 
-static const char upload_pack_usage[] = "git-upload-pack <dir>";
+static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
 
 #define MAX_HAS (16)
 #define MAX_NEEDS (256)
 static int nr_has = 0, nr_needs = 0;
 static unsigned char has_sha1[MAX_HAS][20];
 static unsigned char needs_sha1[MAX_NEEDS][20];
+static unsigned int timeout = 0;
+
+static void reset_timeout(void)
+{
+       alarm(timeout);
+}
 
 static int strip(char *line, int len)
 {
@@ -100,6 +106,7 @@ static int get_common_commits(void)
 
        for(;;) {
                len = packet_read_line(0, line, sizeof(line));
+               reset_timeout();
 
                if (!len) {
                        packet_write(1, "NAK\n");
@@ -122,6 +129,7 @@ static int get_common_commits(void)
 
        for (;;) {
                len = packet_read_line(0, line, sizeof(line));
+               reset_timeout();
                if (!len)
                        continue;
                len = strip(line, len);
@@ -145,6 +153,7 @@ static int receive_needs(void)
        for (;;) {
                unsigned char dummy[20], *sha1_buf;
                len = packet_read_line(0, line, sizeof(line));
+               reset_timeout();
                if (!len)
                        return needs;
 
@@ -179,6 +188,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
 
 static int upload_pack(void)
 {
+       reset_timeout();
        head_ref(send_ref);
        for_each_ref(send_ref);
        packet_flush(1);
@@ -193,18 +203,43 @@ static int upload_pack(void)
 int main(int argc, char **argv)
 {
        const char *dir;
-       if (argc != 2)
+       int i;
+       int strict = 0;
+
+       for (i = 1; i < argc; i++) {
+               char *arg = argv[i];
+
+               if (arg[0] != '-')
+                       break;
+               if (!strcmp(arg, "--strict")) {
+                       strict = 1;
+                       continue;
+               }
+               if (!strncmp(arg, "--timeout=", 10)) {
+                       timeout = atoi(arg+10);
+                       continue;
+               }
+               if (!strcmp(arg, "--")) {
+                       i++;
+                       break;
+               }
+       }
+       
+       if (i != argc-1)
                usage(upload_pack_usage);
-       dir = argv[1];
+       dir = argv[i];
 
        /* chdir to the directory. If that fails, try appending ".git" */
        if (chdir(dir) < 0) {
-               if (chdir(mkpath("%s.git", dir)) < 0)
+               if (strict || chdir(mkpath("%s.git", dir)) < 0)
                        die("git-upload-pack unable to chdir to %s", dir);
        }
-       chdir(".git");
+       if (!strict)
+               chdir(".git");
+
        if (access("objects", X_OK) || access("refs", X_OK))
                die("git-upload-pack: %s doesn't seem to be a git archive", dir);
+
        putenv("GIT_DIR=.");
        upload_pack();
        return 0;