From: Junio C Hamano Date: Sun, 13 Sep 2009 08:31:55 +0000 (-0700) Subject: Merge branch 'db/vcs-helper' X-Git-Tag: v1.6.5-rc1~11 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/cd03eebbfdae712bd4a10d6b393980a8137ce305?ds=inline;hp=-c Merge branch 'db/vcs-helper' * db/vcs-helper: Makefile: remove remnant of separate http/https/ftp helpers Use a clearer style to issue commands to remote helpers Make the "traditionally-supported" URLs a special case Makefile: install hardlinks for git-remote- supported by libcurl if possible Makefile: do not link three copies of git-remote-* programs Makefile: git-http-fetch does not need expat http-fetch: Fix Makefile dependancies Add transport native helper executables to .gitignore git-http-fetch: not a builtin Use an external program to implement fetching with curl Add support for external programs for handling native fetches --- cd03eebbfdae712bd4a10d6b393980a8137ce305 diff --combined .gitignore index 10808e3a73,46c26cd010..47672b0c15 --- a/.gitignore +++ b/.gitignore @@@ -104,8 -104,8 +104,9 @@@ git-receive-pac git-reflog git-relink git-remote + git-remote-curl git-repack +git-replace git-repo-config git-request-pull git-rerere diff --combined Makefile index 1cc9a4183a,1ac02d1c9f..01eea770d3 --- a/Makefile +++ b/Makefile @@@ -16,7 -16,7 +16,7 @@@ all: # when attempting to read from an fopen'ed directory. # # Define NO_OPENSSL environment variable if you do not have OpenSSL. -# This also implies MOZILLA_SHA1. +# This also implies BLK_SHA1. # # Define NO_CURL if you do not have libcurl installed. git-http-pull and # git-http-push are not built, and you cannot use http:// and https:// @@@ -84,16 -84,18 +84,16 @@@ # specify your own (or DarwinPort's) include directories and # library directories by defining CFLAGS and LDFLAGS appropriately. # +# Define BLK_SHA1 environment variable if you want the C version +# of the SHA1 that assumes you can do unaligned 32-bit loads and +# have a fast htonl() function. +# # Define PPC_SHA1 environment variable when running make to make use of # a bundled SHA1 routine optimized for PowerPC. # -# Define ARM_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine optimized for ARM. -# -# Define MOZILLA_SHA1 environment variable when running make to make use of -# a bundled SHA1 routine coming from Mozilla. It is GPL'd and should be fast -# on non-x86 architectures (e.g. PowerPC), while the OpenSSL version (default -# choice) has very fast version optimized for i586. +# Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin). # -# Define NEEDS_SSL_WITH_CRYPTO if you need -lcrypto with -lssl (Darwin). +# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin). # # Define NEEDS_LIBICONV if linking with libc is not enough (Darwin). # @@@ -359,6 -361,7 +359,6 @@@ PROGRAMS += git-patch-id$ PROGRAMS += git-shell$X PROGRAMS += git-show-index$X PROGRAMS += git-unpack-file$X -PROGRAMS += git-update-server-info$X PROGRAMS += git-upload-pack$X PROGRAMS += git-var$X @@@ -380,7 -383,8 +380,8 @@@ BUILT_INS += git-stage$ BUILT_INS += git-status$X BUILT_INS += git-whatchanged$X - # what 'all' will build and 'install' will install, in gitexecdir + # what 'all' will build and 'install' will install in gitexecdir, + # excluding programs for built-in commands ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) # what 'all' will build but not install in gitexecdir @@@ -529,7 -533,6 +530,7 @@@ LIB_OBJS += read-cache. LIB_OBJS += reflog-walk.o LIB_OBJS += refs.o LIB_OBJS += remote.o +LIB_OBJS += replace_object.o LIB_OBJS += rerere.o LIB_OBJS += revision.o LIB_OBJS += run-command.o @@@ -547,6 -550,7 +548,7 @@@ LIB_OBJS += symlinks. LIB_OBJS += tag.o LIB_OBJS += trace.o LIB_OBJS += transport.o + LIB_OBJS += transport-helper.o LIB_OBJS += tree-diff.o LIB_OBJS += tree.o LIB_OBJS += tree-walk.o @@@ -619,7 -623,6 +621,7 @@@ BUILTIN_OBJS += builtin-read-tree. BUILTIN_OBJS += builtin-receive-pack.o BUILTIN_OBJS += builtin-reflog.o BUILTIN_OBJS += builtin-remote.o +BUILTIN_OBJS += builtin-replace.o BUILTIN_OBJS += builtin-rerere.o BUILTIN_OBJS += builtin-reset.o BUILTIN_OBJS += builtin-rev-list.o @@@ -637,7 -640,6 +639,7 @@@ BUILTIN_OBJS += builtin-tar-tree. BUILTIN_OBJS += builtin-unpack-objects.o BUILTIN_OBJS += builtin-update-index.o BUILTIN_OBJS += builtin-update-ref.o +BUILTIN_OBJS += builtin-update-server-info.o BUILTIN_OBJS += builtin-upload-archive.o BUILTIN_OBJS += builtin-verify-pack.o BUILTIN_OBJS += builtin-verify-tag.o @@@ -706,7 -708,6 +708,7 @@@ ifeq ($(uname_S),SCO_SV TAR = gtar endif ifeq ($(uname_S),Darwin) + NEEDS_CRYPTO_WITH_SSL = YesPlease NEEDS_SSL_WITH_CRYPTO = YesPlease NEEDS_LIBICONV = YesPlease ifeq ($(shell expr "$(uname_R)" : '[15678]\.'),2) @@@ -752,6 -753,9 +754,6 @@@ ifeq ($(uname_S),SunOS NO_C99_FORMAT = YesPlease NO_STRTOUMAX = YesPlease endif - ifdef NO_IPV6 - NEEDS_RESOLV = YesPlease - endif INSTALL = /usr/ucb/install TAR = gtar BASIC_CFLAGS += -D__EXTENSIONS__ -D__sun__ -DHAVE_ALLOCA_H @@@ -920,6 -924,10 +922,6 @@@ els NO_PTHREADS = YesPlease endif endif -ifneq (,$(findstring arm,$(uname_M))) - ARM_SHA1 = YesPlease - NO_MKSTEMPS = YesPlease -endif -include config.mak.autogen -include config.mak @@@ -973,9 -981,7 +975,7 @@@ els else CURL_LIBCURL = -lcurl endif - BUILTIN_OBJS += builtin-http-fetch.o - EXTLIBS += $(CURL_LIBCURL) - LIB_OBJS += http.o http-walker.o + PROGRAMS += git-remote-curl$X git-http-fetch$X curl_check := $(shell (echo 070908; curl-config --vernum) | sort -r | sed -ne 2p) ifeq "$(curl_check)" "070908" ifndef NO_EXPAT @@@ -1010,12 -1016,9 +1010,12 @@@ ifndef NO_OPENSS else OPENSSL_LINK = endif + ifdef NEEDS_CRYPTO_WITH_SSL + OPENSSL_LINK += -lcrypto + endif else BASIC_CFLAGS += -DNO_OPENSSL - MOZILLA_SHA1 = 1 + BLK_SHA1 = 1 OPENSSL_LIBSSL = endif ifdef NEEDS_SSL_WITH_CRYPTO @@@ -1164,18 -1167,23 +1164,18 @@@ ifdef NO_DEFLATE_BOUN BASIC_CFLAGS += -DNO_DEFLATE_BOUND endif +ifdef BLK_SHA1 + SHA1_HEADER = "block-sha1/sha1.h" + LIB_OBJS += block-sha1/sha1.o +else ifdef PPC_SHA1 SHA1_HEADER = "ppc/sha1.h" LIB_OBJS += ppc/sha1.o ppc/sha1ppc.o -else -ifdef ARM_SHA1 - SHA1_HEADER = "arm/sha1.h" - LIB_OBJS += arm/sha1.o arm/sha1_arm.o -else -ifdef MOZILLA_SHA1 - SHA1_HEADER = "mozilla-sha1/sha1.h" - LIB_OBJS += mozilla-sha1/sha1.o else SHA1_HEADER = EXTLIBS += $(LIB_4_CRYPTO) endif endif -endif ifdef NO_PERL_MAKEMAKER export NO_PERL_MAKEMAKER endif @@@ -1249,6 -1257,7 +1249,7 @@@ ifndef QUIET_LINK = @echo ' ' LINK $@; QUIET_BUILT_IN = @echo ' ' BUILTIN $@; QUIET_GEN = @echo ' ' GEN $@; + QUIET_LNCP = @echo ' ' LN/CP $@; QUIET_SUBDIR0 = +@subdir= QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ $(MAKE) $(PRINT_DIR) -C $$subdir @@@ -1476,12 -1485,21 +1477,21 @@@ git-imap-send$X: imap-send.o $(GITLIBS $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL) - http.o http-walker.o http-push.o transport.o: http.h + http.o http-walker.o http-push.o: http.h + http.o http-walker.o: $(LIB_H) + + git-http-fetch$X: revision.o http.o http-walker.o http-fetch.o $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ + $(LIBS) $(CURL_LIBCURL) git-http-push$X: revision.o http.o http-push.o $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) + git-remote-curl$X: remote-curl.o http.o http-walker.o $(GITLIBS) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ + $(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) + $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) $(patsubst git-%$X,%.o,$(PROGRAMS)) git.o: $(LIB_H) $(wildcard */*.h) builtin-revert.o wt-status.o: wt-status.h diff --combined git.c index 271579c351,c1e8f05e5f..9883009b5d --- a/git.c +++ b/git.c @@@ -5,10 -5,7 +5,10 @@@ #include "run-command.h" const char git_usage_string[] = - "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]"; + "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]\n" + " [-p|--paginate|--no-pager]\n" + " [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]\n" + " [--help] COMMAND [ARGS]"; const char git_more_info_string[] = "See 'git help COMMAND' for more information on a specific command."; @@@ -312,9 -309,6 +312,6 @@@ static void handle_internal_command(in { "get-tar-commit-id", cmd_get_tar_commit_id }, { "grep", cmd_grep, RUN_SETUP | USE_PAGER }, { "help", cmd_help }, - #ifndef NO_CURL - { "http-fetch", cmd_http_fetch, RUN_SETUP }, - #endif { "init", cmd_init_db }, { "init-db", cmd_init_db }, { "log", cmd_log, RUN_SETUP | USE_PAGER }, @@@ -342,7 -336,6 +339,7 @@@ { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, + { "replace", cmd_replace, RUN_SETUP }, { "repo-config", cmd_config }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, @@@ -362,7 -355,6 +359,7 @@@ { "unpack-objects", cmd_unpack_objects, RUN_SETUP }, { "update-index", cmd_update_index, RUN_SETUP }, { "update-ref", cmd_update_ref, RUN_SETUP }, + { "update-server-info", cmd_update_server_info, RUN_SETUP }, { "upload-archive", cmd_upload_archive }, { "verify-tag", cmd_verify_tag, RUN_SETUP }, { "version", cmd_version }, @@@ -421,9 -413,13 +418,9 @@@ static void execv_dashed_external(cons * if we fail because the command is not found, it is * OK to return. Otherwise, we just pass along the status code. */ - status = run_command_v_opt(argv, 0); - if (status != -ERR_RUN_COMMAND_EXEC) { - if (IS_RUN_COMMAND_ERR(status)) - die("unable to run '%s'", argv[0]); - exit(-status); - } - errno = ENOENT; /* as if we called execvp */ + status = run_command_v_opt(argv, RUN_SILENT_EXEC_FAILURE); + if (status >= 0 || errno != ENOENT) + exit(status); argv[0] = tmp; diff --combined transport.c index d6c35d91ce,b654d71d5a..4cb807700a --- a/transport.c +++ b/transport.c @@@ -1,9 -1,6 +1,6 @@@ #include "cache.h" #include "transport.h" #include "run-command.h" - #ifndef NO_CURL - #include "http.h" - #endif #include "pkt-line.h" #include "fetch-pack.h" #include "send-pack.h" @@@ -352,50 -349,12 +349,11 @@@ static int rsync_transport_push(struct return result; } - /* Generic functions for using commit walkers */ - - #ifndef NO_CURL /* http fetch is the only user */ - static int fetch_objs_via_walker(struct transport *transport, - int nr_objs, const struct ref **to_fetch) - { - char *dest = xstrdup(transport->url); - struct walker *walker = transport->data; - char **objs = xmalloc(nr_objs * sizeof(*objs)); - int i; - - walker->get_all = 1; - walker->get_tree = 1; - walker->get_history = 1; - walker->get_verbosely = transport->verbose >= 0; - walker->get_recover = 0; - - for (i = 0; i < nr_objs; i++) - objs[i] = xstrdup(sha1_to_hex(to_fetch[i]->old_sha1)); - - if (walker_fetch(walker, nr_objs, objs, NULL, NULL)) - die("Fetch failed."); - - for (i = 0; i < nr_objs; i++) - free(objs[i]); - free(objs); - free(dest); - return 0; - } - #endif /* NO_CURL */ - - static int disconnect_walker(struct transport *transport) - { - struct walker *walker = transport->data; - if (walker) - walker_free(walker); - return 0; - } - #ifndef NO_CURL static int curl_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) { const char **argv; int argc; - int err; if (flags & TRANSPORT_PUSH_MIRROR) return error("http transport does not support mirror mode"); @@@ -415,99 -374,22 +373,9 @@@ while (refspec_nr--) argv[argc++] = *refspec++; argv[argc] = NULL; - err = run_command_v_opt(argv, RUN_GIT_CMD); - switch (err) { - case -ERR_RUN_COMMAND_FORK: - error("unable to fork for %s", argv[0]); - case -ERR_RUN_COMMAND_EXEC: - error("unable to exec %s", argv[0]); - break; - case -ERR_RUN_COMMAND_WAITPID: - case -ERR_RUN_COMMAND_WAITPID_WRONG_PID: - case -ERR_RUN_COMMAND_WAITPID_SIGNAL: - case -ERR_RUN_COMMAND_WAITPID_NOEXIT: - error("%s died with strange error", argv[0]); - } - return !!err; + return !!run_command_v_opt(argv, RUN_GIT_CMD); } - static struct ref *get_refs_via_curl(struct transport *transport, int for_push) - { - struct strbuf buffer = STRBUF_INIT; - char *data, *start, *mid; - char *ref_name; - char *refs_url; - int i = 0; - int http_ret; - - struct ref *refs = NULL; - struct ref *ref = NULL; - struct ref *last_ref = NULL; - - struct walker *walker; - - if (for_push) - return NULL; - - if (!transport->data) - transport->data = get_http_walker(transport->url, - transport->remote); - - walker = transport->data; - - refs_url = xmalloc(strlen(transport->url) + 11); - sprintf(refs_url, "%s/info/refs", transport->url); - - http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); - switch (http_ret) { - case HTTP_OK: - break; - case HTTP_MISSING_TARGET: - die("%s not found: did you run git update-server-info on the" - " server?", refs_url); - default: - http_error(refs_url, http_ret); - die("HTTP request failed"); - } - - data = buffer.buf; - start = NULL; - mid = data; - while (i < buffer.len) { - if (!start) - start = &data[i]; - if (data[i] == '\t') - mid = &data[i]; - if (data[i] == '\n') { - data[i] = 0; - ref_name = mid + 1; - ref = xmalloc(sizeof(struct ref) + - strlen(ref_name) + 1); - memset(ref, 0, sizeof(struct ref)); - strcpy(ref->name, ref_name); - get_sha1_hex(start, ref->old_sha1); - if (!refs) - refs = ref; - if (last_ref) - last_ref->next = ref; - last_ref = ref; - start = NULL; - } - i++; - } - - strbuf_release(&buffer); - - ref = alloc_ref("HEAD"); - if (!walker->fetch_ref(walker, ref) && - !resolve_remote_symref(ref, refs)) { - ref->next = refs; - refs = ref; - } else { - free(ref); - } - - strbuf_release(&buffer); - free(refs_url); - return refs; - } - - static int fetch_objs_via_curl(struct transport *transport, - int nr_objs, const struct ref **to_fetch) - { - if (!transport->data) - transport->data = get_http_walker(transport->url, - transport->remote); - return fetch_objs_via_walker(transport, nr_objs, to_fetch); - } - #endif struct bundle_transport_data { @@@ -667,21 -549,6 +535,21 @@@ static int fetch_refs_via_pack(struct t return (refs ? 0 : -1); } +static int push_had_errors(struct ref *ref) +{ + for (; ref; ref = ref->next) { + switch (ref->status) { + case REF_STATUS_NONE: + case REF_STATUS_UPTODATE: + case REF_STATUS_OK: + break; + default: + return 1; + } + } + return 0; +} + static int refs_pushed(struct ref *ref) { for (; ref; ref = ref->next) { @@@ -821,7 -688,7 +689,7 @@@ static int print_one_push_status(struc } static void print_push_status(const char *dest, struct ref *refs, - int verbose, int porcelain) + int verbose, int porcelain, int * nonfastforward) { struct ref *ref; int n = 0; @@@ -836,14 -703,11 +704,14 @@@ if (ref->status == REF_STATUS_OK) n += print_one_push_status(ref, dest, n, porcelain); + *nonfastforward = 0; for (ref = refs; ref; ref = ref->next) { if (ref->status != REF_STATUS_NONE && ref->status != REF_STATUS_UPTODATE && ref->status != REF_STATUS_OK) n += print_one_push_status(ref, dest, n, porcelain); + if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) + *nonfastforward = 1; } } @@@ -896,7 -760,6 +764,7 @@@ static int git_transport_push(struct tr args.force_update = !!(flags & TRANSPORT_PUSH_FORCE); args.use_thin_pack = data->thin; args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE); + args.quiet = !!(flags & TRANSPORT_PUSH_QUIET); args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN); ret = send_pack(&args, data->fd, data->conn, remote_refs, @@@ -955,14 -818,12 +823,12 @@@ struct transport *transport_get(struct } else if (!prefixcmp(url, "http://") || !prefixcmp(url, "https://") || !prefixcmp(url, "ftp://")) { + transport_helper_init(ret, "curl"); #ifdef NO_CURL error("git was compiled without libcurl support."); #else - ret->get_refs_list = get_refs_via_curl; - ret->fetch = fetch_objs_via_curl; ret->push = curl_transport_push; #endif - ret->disconnect = disconnect_walker; } else if (is_local(url) && is_file(url)) { struct bundle_transport_data *data = xcalloc(1, sizeof(*data)); @@@ -1002,8 -863,7 +868,8 @@@ int transport_set_option(struct transpo } int transport_push(struct transport *transport, - int refspec_nr, const char **refspec, int flags) + int refspec_nr, const char **refspec, int flags, + int * nonfastforward) { verify_remote_names(refspec_nr, refspec); @@@ -1015,7 -875,6 +881,7 @@@ struct ref *local_refs = get_local_heads(); int match_flags = MATCH_REFS_NONE; int verbose = flags & TRANSPORT_PUSH_VERBOSE; + int quiet = flags & TRANSPORT_PUSH_QUIET; int porcelain = flags & TRANSPORT_PUSH_PORCELAIN; int ret; @@@ -1031,10 -890,7 +897,10 @@@ ret = transport->push_refs(transport, remote_refs, flags); - print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain); + if (!quiet || push_had_errors(remote_refs)) + print_push_status(transport->url, remote_refs, + verbose | porcelain, porcelain, + nonfastforward); if (!(flags & TRANSPORT_PUSH_DRY_RUN)) { struct ref *ref; @@@ -1042,7 -898,7 +908,7 @@@ update_tracking_ref(transport->remote, ref, verbose); } - if (!ret && !refs_pushed(remote_refs)) + if (!quiet && !ret && !refs_pushed(remote_refs)) fprintf(stderr, "Everything up-to-date\n"); return ret; } @@@ -1059,12 -915,11 +925,12 @@@ const struct ref *transport_get_remote_ int transport_fetch_refs(struct transport *transport, const struct ref *refs) { int rc; - int nr_heads = 0, nr_alloc = 0; + int nr_heads = 0, nr_alloc = 0, nr_refs = 0; const struct ref **heads = NULL; const struct ref *rm; for (rm = refs; rm; rm = rm->next) { + nr_refs++; if (rm->peer_ref && !hashcmp(rm->peer_ref->old_sha1, rm->old_sha1)) continue; @@@ -1072,19 -927,6 +938,19 @@@ heads[nr_heads++] = rm; } + if (!nr_heads) { + /* + * When deepening of a shallow repository is requested, + * then local and remote refs are likely to still be equal. + * Just feed them all to the fetch method in that case. + * This condition shouldn't be met in a non-deepening fetch + * (see builtin-fetch.c:quickfetch()). + */ + heads = xmalloc(nr_refs * sizeof(*heads)); + for (rm = refs; rm; rm = rm->next) + heads[nr_heads++] = rm; + } + rc = transport->fetch(transport, nr_heads, heads); free(heads); return rc; diff --combined transport.h index 171a01c7a3,b49c10f57d..c14da6f1e5 --- a/transport.h +++ b/transport.h @@@ -36,7 -36,6 +36,7 @@@ struct transport #define TRANSPORT_PUSH_MIRROR 8 #define TRANSPORT_PUSH_VERBOSE 16 #define TRANSPORT_PUSH_PORCELAIN 32 +#define TRANSPORT_PUSH_QUIET 64 /* Returns a transport suitable for the url */ struct transport *transport_get(struct remote *, const char *); @@@ -69,8 -68,7 +69,8 @@@ int transport_set_option(struct transpo const char *value); int transport_push(struct transport *connection, - int refspec_nr, const char **refspec, int flags); + int refspec_nr, const char **refspec, int flags, + int * nonfastforward); const struct ref *transport_get_remote_refs(struct transport *transport); @@@ -79,4 -77,7 +79,7 @@@ void transport_unlock_pack(struct trans int transport_disconnect(struct transport *transport); char *transport_anonymize_url(const char *url); + /* Transport methods defined outside transport.c */ + int transport_helper_init(struct transport *transport, const char *name); + #endif