From: Junio C Hamano Date: Mon, 14 Nov 2005 21:50:05 +0000 (-0800) Subject: Merge branch 'svnup' of http://netz.smurf.noris.de/git/git X-Git-Tag: v0.99.9i^2~8 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/b6ebac9e4316cd5d35c2c24f83f1eb51ce17beb9?hp=0f3f5e3f69020f8d08a9ca7b097cb225b933dafb Merge branch 'svnup' of netz.smurf.noris.de/git/git Signed-off-by: Junio C Hamano --- diff --git a/.gitignore b/.gitignore index 328b399f9f..0dd7b9c7b4 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,7 @@ git-index-pack git-init-db git-local-fetch git-log -git-lost+found +git-lost-found git-ls-files git-ls-remote git-ls-tree @@ -74,7 +74,6 @@ git-read-tree git-rebase git-receive-pack git-relink -git-rename git-repack git-request-pull git-reset diff --git a/Documentation/git-lost+found.txt b/Documentation/git-lost+found.txt deleted file mode 100644 index a8cc5739d7..0000000000 --- a/Documentation/git-lost+found.txt +++ /dev/null @@ -1,78 +0,0 @@ -git-lost+found(1) -================= - -NAME ----- -git-lost+found - Recover lost refs that luckily have not yet been pruned. - -SYNOPSIS --------- -'git-lost+found' - -DESCRIPTION ------------ -Finds dangling commits and tags from the object database, and -creates refs to them in .git/lost-found/ directory. Commits and -tags that dereference to commits go to .git/lost-found/commit -and others are stored in .git/lost-found/other directory. - - -OUTPUT ------- -One line description from the commit and tag found along with -their object name are printed on the standard output. - - -EXAMPLE -------- - -Suppose you run 'git tag -f' and mistyped the tag to overwrite. -The ref to your tag is overwritten, but until you run 'git -prune', it is still there. - ------------- -$ git lost+found -[1ef2b196d909eed523d4f3c9bf54b78cdd6843c6] GIT 0.99.9c -... ------------- - -Also you can use gitk to browse how they relate to each other -and existing (probably old) tags. - ------------- -$ gitk $(cd .git/lost-found/commit && echo ??*) ------------- - -After making sure that it is the object you are looking for, you -can reconnect it to your regular .git/refs hierarchy. - ------------- -$ git cat-file -t 1ef2b196 -tag -$ git cat-file tag 1ef2b196 -object fa41bbce8e38c67a218415de6cfa510c7e50032a -type commit -tag v0.99.9c -tagger Junio C Hamano 1131059594 -0800 - -GIT 0.99.9c - -This contains the following changes from the "master" branch, since -... -$ git update-ref refs/tags/not-lost-anymore 1ef2b196 -$ git rev-parse not-lost-anymore -1ef2b196d909eed523d4f3c9bf54b78cdd6843c6 ------------- - -Author ------- -Written by Junio C Hamano 濱野 純 - -Documentation --------------- -Documentation by Junio C Hamano and the git-list . - - -GIT ---- -Part of the gitlink:git[7] suite diff --git a/Documentation/git-lost-found.txt b/Documentation/git-lost-found.txt new file mode 100644 index 0000000000..03156f218b --- /dev/null +++ b/Documentation/git-lost-found.txt @@ -0,0 +1,78 @@ +git-lost-found(1) +================= + +NAME +---- +git-lost-found - Recover lost refs that luckily have not yet been pruned. + +SYNOPSIS +-------- +'git-lost-found' + +DESCRIPTION +----------- +Finds dangling commits and tags from the object database, and +creates refs to them in .git/lost-found/ directory. Commits and +tags that dereference to commits go to .git/lost-found/commit +and others are stored in .git/lost-found/other directory. + + +OUTPUT +------ +One line description from the commit and tag found along with +their object name are printed on the standard output. + + +EXAMPLE +------- + +Suppose you run 'git tag -f' and mistyped the tag to overwrite. +The ref to your tag is overwritten, but until you run 'git +prune', it is still there. + +------------ +$ git lost-found +[1ef2b196d909eed523d4f3c9bf54b78cdd6843c6] GIT 0.99.9c +... +------------ + +Also you can use gitk to browse how they relate to each other +and existing (probably old) tags. + +------------ +$ gitk $(cd .git/lost-found/commit && echo ??*) +------------ + +After making sure that it is the object you are looking for, you +can reconnect it to your regular .git/refs hierarchy. + +------------ +$ git cat-file -t 1ef2b196 +tag +$ git cat-file tag 1ef2b196 +object fa41bbce8e38c67a218415de6cfa510c7e50032a +type commit +tag v0.99.9c +tagger Junio C Hamano 1131059594 -0800 + +GIT 0.99.9c + +This contains the following changes from the "master" branch, since +... +$ git update-ref refs/tags/not-lost-anymore 1ef2b196 +$ git rev-parse not-lost-anymore +1ef2b196d909eed523d4f3c9bf54b78cdd6843c6 +------------ + +Author +------ +Written by Junio C Hamano 濱野 純 + +Documentation +-------------- +Documentation by Junio C Hamano and the git-list . + + +GIT +--- +Part of the gitlink:git[7] suite diff --git a/Documentation/git-rename.txt b/Documentation/git-rename.txt deleted file mode 100644 index 583cb0315e..0000000000 --- a/Documentation/git-rename.txt +++ /dev/null @@ -1,32 +0,0 @@ -git-rename(1) -============= - -NAME ----- -git-rename - Script used to rename a file, directory or symlink. - - -SYNOPSIS --------- -'git-rename' - -DESCRIPTION ------------ -This script is used to rename a file, directory or symlink. - -The index is updated after successful completion, but the change must still be -committed. - -Author ------- -Written by Linus Torvalds -Rewritten by Ryan Anderson - -Documentation --------------- -Documentation by David Greaves, Junio C Hamano and the git-list . - -GIT ---- -Part of the gitlink:git[7] suite - diff --git a/Documentation/git.txt b/Documentation/git.txt index a9d47c115c..7045f3f97e 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -262,9 +262,6 @@ gitlink:git-push[1]:: gitlink:git-rebase[1]:: Rebase local commits to new upstream head. -gitlink:git-rename[1]:: - Rename files and directories. - gitlink:git-repack[1]:: Pack unpacked objects in a repository. @@ -309,7 +306,7 @@ gitlink:git-convert-objects[1]:: gitlink:git-cvsimport[1]:: Salvage your data out of another SCM people love to hate. -gitlink:git-lost+found[1]:: +gitlink:git-lost-found[1]:: Recover lost refs that luckily have not yet been pruned. gitlink:git-merge-one-file[1]:: diff --git a/Makefile b/Makefile index b75cb13787..63cb99847f 100644 --- a/Makefile +++ b/Makefile @@ -52,10 +52,12 @@ GIT_VERSION = 0.99.9.GIT -# CFLAGS is for the users to override from the command line. +# CFLAGS and LDFLAGS are for the users to override from the command line. CFLAGS = -g -O2 -Wall +LDFLAGS = ALL_CFLAGS = $(CFLAGS) +ALL_LDFLAGS = $(LDFLAGS) prefix = $(HOME) bindir = $(prefix)/bin @@ -90,11 +92,11 @@ SCRIPT_SH = \ git-applymbox.sh git-applypatch.sh git-am.sh \ git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \ git-merge-resolve.sh git-merge-ours.sh git-grep.sh \ - git-lost+found.sh + git-lost-found.sh SCRIPT_PERL = \ git-archimport.perl git-cvsimport.perl git-relink.perl \ - git-rename.perl git-shortlog.perl git-fmt-merge-msg.perl \ + git-shortlog.perl git-fmt-merge-msg.perl \ git-svnimport.perl git-mv.perl git-cvsexportcommit.perl SCRIPT_PYTHON = \ @@ -187,9 +189,11 @@ ifeq ($(uname_S),Darwin) NEEDS_SSL_WITH_CRYPTO = YesPlease NEEDS_LIBICONV = YesPlease ## fink - ALL_CFLAGS += -I/sw/include -L/sw/lib + ALL_CFLAGS += -I/sw/include + ALL_LDFLAGS += -L/sw/lib ## darwinports - ALL_CFLAGS += -I/opt/local/include -L/opt/local/lib + ALL_CFLAGS += -I/opt/local/include + ALL_LDFLAGS += -L/opt/local/lib endif ifeq ($(uname_S),SunOS) NEEDS_SOCKET = YesPlease @@ -211,7 +215,13 @@ endif ifeq ($(uname_S),OpenBSD) NO_STRCASESTR = YesPlease NEEDS_LIBICONV = YesPlease - ALL_CFLAGS += -I/usr/local/include -L/usr/local/lib + ALL_CFLAGS += -I/usr/local/include + ALL_LDFLAGS += -L/usr/local/lib +endif +ifeq ($(uname_S),NetBSD) + NEEDS_LIBICONV = YesPlease + ALL_CFLAGS += -I/usr/pkg/include + ALL_LDFLAGS += -L/usr/pkg/lib -Wl,-rpath,/usr/pkg/lib endif ifneq (,$(findstring arm,$(uname_M))) ARM_SHA1 = YesPlease @@ -221,7 +231,7 @@ endif ifndef NO_CURL ifdef CURLDIR - # This is still problematic -- gcc does not want -R. + # This is still problematic -- gcc does not always want -R. ALL_CFLAGS += -I$(CURLDIR)/include CURL_LIBCURL = -L$(CURLDIR)/lib -R$(CURLDIR)/lib -lcurl else @@ -369,12 +379,13 @@ git-cherry-pick: git-revert $(CC) -o $*.o -c $(ALL_CFLAGS) $< git-%$X: %.o $(LIB_FILE) - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIBS) + $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) git-mailinfo$X : SIMPLE_LIB += $(LIB_4_ICONV) $(SIMPLE_PROGRAMS) : $(LIB_FILE) $(SIMPLE_PROGRAMS) : git-%$X : %.o - $(CC) $(ALL_CFLAGS) -o $@ $(filter %.o,$^) $(LIB_FILE) $(SIMPLE_LIB) + $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ + $(LIB_FILE) $(SIMPLE_LIB) git-http-fetch$X: fetch.o git-local-fetch$X: fetch.o @@ -408,10 +419,10 @@ test: all $(MAKE) -C t/ all test-date$X: test-date.c date.o ctype.o - $(CC) $(ALL_CFLAGS) -o $@ test-date.c date.o ctype.o + $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) test-date.c date.o ctype.o test-delta$X: test-delta.c diff-delta.o patch-delta.o - $(CC) $(ALL_CFLAGS) -o $@ $^ + $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^ check: for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i; done diff --git a/debian/changelog b/debian/changelog index 10f67b8a2e..376f0fa5a3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +git-core (0.99.9.GIT-2) unstable; urgency=low + + * Build Dependency did not include libexpat-dev. + + -- Junio C Hamano Sun, 13 Nov 2005 01:55:34 -0800 + git-core (0.99.9.GIT-1) unstable; urgency=low * Do not scatter txt and html documentation into feature diff --git a/debian/control b/debian/control index 965fb6281b..ded0a576d6 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: git-core Section: devel Priority: optional Maintainer: Junio C Hamano -Build-Depends-Indep: libz-dev, libssl-dev, libcurl3-dev|libcurl3-gnutls-dev|libcurl3-openssl-dev, asciidoc (>= 7), xmlto, debhelper (>= 4.0.0), bc +Build-Depends-Indep: libz-dev, libssl-dev, libcurl3-dev|libcurl3-gnutls-dev|libcurl3-openssl-dev, asciidoc (>= 7), xmlto, debhelper (>= 4.0.0), bc, libexpat-dev Standards-Version: 3.6.1 Package: git-core diff --git a/git-clone.sh b/git-clone.sh index f99e0adf86..c09979a7a4 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -9,7 +9,7 @@ unset CDPATH usage() { - echo >&2 "* git clone [-l [-s]] [-q] [-u ] [-n] " + echo >&2 "* git clone [-l [-s]] [-q] [-u ] [-n] []" exit 1 } @@ -98,7 +98,7 @@ fi dir="$2" # Try using "humanish" part of source repo if user didn't specify one [ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*/||g') -[ -e "$dir" ] && $(echo "$dir already exists."; usage) +[ -e "$dir" ] && echo "$dir already exists." && usage mkdir -p "$dir" && D=$( (cd "$dir" && git-init-db && pwd) diff --git a/git-core.spec.in b/git-core.spec.in index 6a482ad1f1..16c626902a 100644 --- a/git-core.spec.in +++ b/git-core.spec.in @@ -7,9 +7,9 @@ License: GPL Group: Development/Tools URL: http://kernel.org/pub/software/scm/git/ Source: http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz -BuildRequires: zlib-devel >= 1.2, openssl-devel, curl-devel %{!?_without_docs:, xmlto, asciidoc > 6.0.3} +BuildRequires: zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel %{!?_without_docs:, xmlto, asciidoc > 6.0.3} BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Requires: zlib >= 1.2, rsync, rcs, curl, less, openssh-clients, python >= 2.3, tk >= 8.4 +Requires: zlib >= 1.2, rsync, rcs, curl, less, openssh-clients, python >= 2.3, expat %description This is a stupid (but extremely fast) directory content manager. It @@ -47,6 +47,13 @@ Requires: git-core = %{version}-%{release} %description email Git tools for sending email. +%package tk +Summary: Git revision tree visualiser ('gitk') +Group: Development/Tools +Requires: git-core = %{version}-%{release}, tk >= 8.4 +%description tk +Git revision tree visualiser ('gitk') + %prep %setup -q @@ -60,9 +67,9 @@ make %{_smp_mflags} DESTDIR=$RPM_BUILD_ROOT WITH_OWN_SUBPROCESS_PY=YesPlease WIT prefix=%{_prefix} mandir=%{_mandir} \ install %{!?_without_docs: install-doc} -(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "arch|svn|cvs|email" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files +(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "arch|svn|cvs|email|gitk" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files %if %{!?_without_docs:1}0 -(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "arch|svn|git-cvs|email" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files +(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "arch|svn|git-cvs|email|gitk" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files %endif %clean @@ -96,6 +103,13 @@ rm -rf $RPM_BUILD_ROOT %{!?_without_docs: %{_mandir}/man1/*email*.1*} %{!?_without_docs: %doc Documentation/*email*.html } +%files tk +%defattr(-,root,root) +%doc Documentation/*gitk*.txt +%{_bindir}/*gitk* +%{!?_without_docs: %{_mandir}/man1/*gitk*.1*} +%{!?_without_docs: %doc Documentation/*gitk*.html } + %files -f bin-man-doc-files %defattr(-,root,root) %{_datadir}/git-core/ diff --git a/git-lost+found.sh b/git-lost+found.sh deleted file mode 100755 index 3892f52005..0000000000 --- a/git-lost+found.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh - -. git-sh-setup || die "Not a git archive." - -laf="$GIT_DIR/lost-found" -rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit - -git fsck-objects | -while read dangling type sha1 -do - case "$dangling" in - dangling) - if git-rev-parse --verify "$sha1^0" >/dev/null 2>/dev/null - then - dir="$laf/commit" - git-show-branch "$sha1" - else - dir="$laf/other" - fi - echo "$sha1" >"$dir/$sha1" - ;; - esac -done diff --git a/git-lost-found.sh b/git-lost-found.sh new file mode 100755 index 0000000000..3892f52005 --- /dev/null +++ b/git-lost-found.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +. git-sh-setup || die "Not a git archive." + +laf="$GIT_DIR/lost-found" +rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit + +git fsck-objects | +while read dangling type sha1 +do + case "$dangling" in + dangling) + if git-rev-parse --verify "$sha1^0" >/dev/null 2>/dev/null + then + dir="$laf/commit" + git-show-branch "$sha1" + else + dir="$laf/other" + fi + echo "$sha1" >"$dir/$sha1" + ;; + esac +done diff --git a/git-rename.perl b/git-rename.perl deleted file mode 100755 index 3b1127b1b2..0000000000 --- a/git-rename.perl +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/perl -# -# Copyright 2005, Ryan Anderson -# -# This file is licensed under the GPL v2, or a later version -# at the discretion of Linus Torvalds. - - -use warnings; -use strict; - -sub usage($); - -# Sanity checks: -my $GIT_DIR = $ENV{'GIT_DIR'} || ".git"; - -unless ( -d $GIT_DIR && -d $GIT_DIR . "/objects" && - -d $GIT_DIR . "/objects/" && -d $GIT_DIR . "/refs") { - usage("Git repository not found."); -} - -usage("") if scalar @ARGV != 2; - -my ($src,$dst) = @ARGV; - -unless (-f $src || -l $src || -d $src) { - usage("git rename: bad source '$src'"); -} - -if (-e $dst) { - usage("git rename: destinations '$dst' already exists"); -} - -my (@allfiles,@srcfiles,@dstfiles); - -$/ = "\0"; -open(F,"-|","git-ls-files","-z") - or die "Failed to open pipe from git-ls-files: " . $!; - -@allfiles = map { chomp; $_; } ; -close(F); - -my $safesrc = quotemeta($src); -@srcfiles = grep /^$safesrc/, @allfiles; -@dstfiles = @srcfiles; -s#^$safesrc(/|$)#$dst$1# for @dstfiles; - -rename($src,$dst) - or die "rename failed: $!"; - -my $rc = system("git-update-index","--add","--",@dstfiles); -die "git-update-index failed to add new name with code $?\n" if $rc; - -$rc = system("git-update-index","--remove","--",@srcfiles); -die "git-update-index failed to remove old name with code $?\n" if $rc; - - -sub usage($) { - my $s = shift; - print $s, "\n" if (length $s != 0); - print < -source must exist and be either a file, symlink or directory. -dest must NOT exist. - -Renames source to dest, and updates the git cache to reflect the change. -Use "git commit" to make record the change permanently. -EOT - exit(1); -} diff --git a/http-fetch.c b/http-fetch.c index f39e748fc0..b8aa965ea3 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -25,7 +25,7 @@ #define PREV_BUF_SIZE 4096 #define RANGE_HEADER_SIZE 30 -static int got_alternates = 0; +static int got_alternates = -1; static int active_requests = 0; static int data_received; @@ -87,9 +87,19 @@ struct active_request_slot int done; CURLcode curl_result; long http_code; + void *callback_data; + void (*callback_func)(void *data); struct active_request_slot *next; }; +struct alt_request { + char *base; + char *url; + struct buffer *buffer; + struct active_request_slot *slot; + int http_specific; +}; + static struct transfer_request *request_queue_head = NULL; static struct active_request_slot *active_queue_head = NULL; @@ -237,7 +247,7 @@ static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, static void process_curl_messages(void); static void process_request_queue(void); #endif -static int fetch_alternates(char *base); +static void fetch_alternates(char *base); static CURL* get_curl_handle(void) { @@ -324,6 +334,8 @@ static struct active_request_slot *get_active_slot(void) slot->in_use = 1; slot->done = 0; slot->local = NULL; + slot->callback_data = NULL; + slot->callback_func = NULL; curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_range_header); curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr); @@ -601,6 +613,12 @@ static void process_curl_messages(void) } else { fprintf(stderr, "Received DONE message for unknown request!\n"); } + + /* Process slot callback if appropriate */ + if (slot->callback_func != NULL) { + slot->callback_func(slot->callback_data); + } + if (request != NULL) { request->curl_result = curl_result; request->http_code = slot->http_code; @@ -614,6 +632,8 @@ static void process_curl_messages(void) request->repo = request->repo->next; start_request(request); + } else { + finish_request(request); } } else { finish_request(request); @@ -766,72 +786,51 @@ static int setup_index(struct alt_base *repo, unsigned char *sha1) return 0; } -static int fetch_alternates(char *base) +static void process_alternates(void *callback_data) { - int ret = 0; - struct buffer buffer; - char *url; - char *data; - int i = 0; - int http_specific = 1; + struct alt_request *alt_req = (struct alt_request *)callback_data; + struct active_request_slot *slot = alt_req->slot; struct alt_base *tail = alt; + char *base = alt_req->base; static const char null_byte = '\0'; + char *data; + int i = 0; - struct active_request_slot *slot; - - if (got_alternates) - return 0; - - data = xmalloc(4096); - buffer.size = 4096; - buffer.posn = 0; - buffer.buffer = data; - - if (get_verbosely) - fprintf(stderr, "Getting alternates list for %s\n", base); - - url = xmalloc(strlen(base) + 31); - sprintf(url, "%s/objects/info/http-alternates", base); - - slot = get_active_slot(); - curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, - fwrite_buffer_dynamic); - curl_easy_setopt(slot->curl, CURLOPT_URL, url); - if (start_active_slot(slot)) { - run_active_slot(slot); - if (slot->curl_result != CURLE_OK || !buffer.posn) { - http_specific = 0; - - sprintf(url, "%s/objects/info/alternates", base); - - slot = get_active_slot(); - curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, - fwrite_buffer_dynamic); - curl_easy_setopt(slot->curl, CURLOPT_URL, url); + if (alt_req->http_specific) { + if (slot->curl_result != CURLE_OK || + !alt_req->buffer->posn) { + + /* Try reusing the slot to get non-http alternates */ + alt_req->http_specific = 0; + sprintf(alt_req->url, "%s/objects/info/alternates", + base); + curl_easy_setopt(slot->curl, CURLOPT_URL, + alt_req->url); + active_requests++; + slot->in_use = 1; + slot->done = 0; if (start_active_slot(slot)) { - run_active_slot(slot); - if (slot->curl_result != CURLE_OK) { - free(buffer.buffer); - if (slot->http_code == 404) - got_alternates = 1; - return 0; - } + return; + } else { + got_alternates = -1; + slot->done = 1; + return; } } - } else { - free(buffer.buffer); - return 0; + } else if (slot->curl_result != CURLE_OK) { + if (slot->http_code != 404) { + got_alternates = -1; + return; + } } - fwrite_buffer_dynamic(&null_byte, 1, 1, &buffer); - buffer.posn--; - data = buffer.buffer; + fwrite_buffer_dynamic(&null_byte, 1, 1, alt_req->buffer); + alt_req->buffer->posn--; + data = alt_req->buffer->buffer; - while (i < buffer.posn) { + while (i < alt_req->buffer->posn) { int posn = i; - while (posn < buffer.posn && data[posn] != '\n') + while (posn < alt_req->buffer->posn && data[posn] != '\n') posn++; if (data[posn] == '\n') { int okay = 0; @@ -855,7 +854,7 @@ static int fetch_alternates(char *base) // If the server got removed, give up. okay = strchr(base, ':') - base + 3 < serverlen; - } else if (http_specific) { + } else if (alt_req->http_specific) { char *colon = strchr(data + i, ':'); char *slash = strchr(data + i, '/'); if (colon && slash && colon < data + posn && @@ -881,15 +880,74 @@ static int fetch_alternates(char *base) while (tail->next != NULL) tail = tail->next; tail->next = newalt; - ret++; } } i = posn + 1; } got_alternates = 1; - free(buffer.buffer); - return ret; +} + +static void fetch_alternates(char *base) +{ + struct buffer buffer; + char *url; + char *data; + struct active_request_slot *slot; + static struct alt_request alt_req; + int num_transfers; + + /* If another request has already started fetching alternates, + wait for them to arrive and return to processing this request's + curl message */ + while (got_alternates == 0) { + curl_multi_perform(curlm, &num_transfers); + process_curl_messages(); + process_request_queue(); + } + + /* Nothing to do if they've already been fetched */ + if (got_alternates == 1) + return; + + /* Start the fetch */ + got_alternates = 0; + + data = xmalloc(4096); + buffer.size = 4096; + buffer.posn = 0; + buffer.buffer = data; + + if (get_verbosely) + fprintf(stderr, "Getting alternates list for %s\n", base); + + url = xmalloc(strlen(base) + 31); + sprintf(url, "%s/objects/info/http-alternates", base); + + /* Use a callback to process the result, since another request + may fail and need to have alternates loaded before continuing */ + slot = get_active_slot(); + slot->callback_func = process_alternates; + slot->callback_data = &alt_req; + + curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); + curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, + fwrite_buffer_dynamic); + curl_easy_setopt(slot->curl, CURLOPT_URL, url); + + alt_req.base = base; + alt_req.url = url; + alt_req.buffer = &buffer; + alt_req.http_specific = 1; + alt_req.slot = slot; + + if (start_active_slot(slot)) + run_active_slot(slot); + else + got_alternates = -1; + + free(data); + free(url); } static int fetch_indices(struct alt_base *repo) diff --git a/pack-redundant.c b/pack-redundant.c index 1f8c577391..28b82ee65a 100644 --- a/pack-redundant.c +++ b/pack-redundant.c @@ -593,19 +593,20 @@ int main(int argc, char **argv) minimize(&min); if (verbose) { - fprintf(stderr, "There are %ld packs available in alt-odbs.\n", - pack_list_size(altodb_packs)); + fprintf(stderr, "There are %lu packs available in alt-odbs.\n", + (unsigned long)pack_list_size(altodb_packs)); fprintf(stderr, "The smallest (bytewise) set of packs is:\n"); pl = min; while (pl) { fprintf(stderr, "\t%s\n", pl->pack->pack_name); pl = pl->next; } - fprintf(stderr, "containing %ld duplicate objects " - "with a total size of %ldkb.\n", - get_pack_redundancy(min), pack_set_bytecount(min)/1024); - fprintf(stderr, "A total of %ld unique objects were considered.\n", - all_objects->size); + fprintf(stderr, "containing %lu duplicate objects " + "with a total size of %lukb.\n", + (unsigned long)get_pack_redundancy(min), + (unsigned long)pack_set_bytecount(min)/1024); + fprintf(stderr, "A total of %lu unique objects were considered.\n", + (unsigned long)all_objects->size); fprintf(stderr, "Redundant packs (with indexes):\n"); } pl = red = pack_list_difference(local_packs, min);