author | Junio C Hamano <junio@hera.kernel.org> | |
Fri, 21 Oct 2005 00:06:15 +0000 (17:06 -0700) | ||
committer | Junio 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>
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:
index b58165a5fc03a8556217599ef6a6f24f2f87f696..cfc7b62f31b6470b9d9011b49d73d135a0623dd9 100644 (file)
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)
-------
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)
-------
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)
-------
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)
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.
diff --git a/clone-pack.c b/clone-pack.c
index f9b263a441eb2559a904e3db9fb35fac05b9590e..4f4975b4ab7faecb172482f308999e48ea643d37 100644 (file)
--- a/clone-pack.c
+++ b/clone-pack.c
#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)
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];
}
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;
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;
diff --git a/daemon.c b/daemon.c
index 9ea6c31cd17fad509c8a97bb2ff099e8a5489ce8..c3381b344ccbeff2f13a52c83f17b9960798d8c3 100644 (file)
--- a/daemon.c
+++ b/daemon.c
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;
/* 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)
{
/* 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);
*/
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;
}
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;
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;
diff --git a/fetch-pack.c b/fetch-pack.c
index 969e72a7816701ed3f86ab42db1472346cab991e..8566ab1744b029e9696976e78bac4d48d2324129 100644 (file)
--- a/fetch-pack.c
+++ b/fetch-pack.c
"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) {
return retval;
}
-#define COMPLETE (1U << 0)
static struct commit_list *complete = NULL;
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);
diff --git a/git-count-objects.sh b/git-count-objects.sh
index 74ee4f371f749cb5ae9fdb7e789d341f60997e62..843d2fd9f2ef53ccd1600dd9b89ec70fbc639146 100755 (executable)
--- a/git-count-objects.sh
+++ b/git-count-objects.sh
. 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.
diff --git a/http-fetch.c b/http-fetch.c
index efa6e82329ad514fc31f7c5d335e9b6ec962d95b..a7dc2cc3bdbcda8eee8cdadb706aba51782e68da 100644 (file)
--- a/http-fetch.c
+++ b/http-fetch.c
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
{
}
#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);
}
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;
}
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') {
#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)
diff --git a/sha1_name.c b/sha1_name.c
index 75c688ecf2d9381d665f4b2f388df4ceaa0fdab5..cc320d3d7fc38787190598034fceb787d95336d6 100644 (file)
--- a/sha1_name.c
+++ b/sha1_name.c
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 {
*/
while (1) {
- if (!o)
+ if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
if (o->type == type_string) {
memcpy(sha1, o->sha1, 20);
diff --git a/upload-pack.c b/upload-pack.c
index 21b4b8b7575dd3ceb2fdf40b5aa4b7483168ec1e..8a41cafaaa3fd3bc571aa21e3427260feaa84a65 100644 (file)
--- a/upload-pack.c
+++ b/upload-pack.c
#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)
{
for(;;) {
len = packet_read_line(0, line, sizeof(line));
+ reset_timeout();
if (!len) {
packet_write(1, "NAK\n");
for (;;) {
len = packet_read_line(0, line, sizeof(line));
+ reset_timeout();
if (!len)
continue;
len = strip(line, len);
for (;;) {
unsigned char dummy[20], *sha1_buf;
len = packet_read_line(0, line, sizeof(line));
+ reset_timeout();
if (!len)
return needs;
static int upload_pack(void)
{
+ reset_timeout();
head_ref(send_ref);
for_each_ref(send_ref);
packet_flush(1);
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;