From: Shawn O. Pearce Date: Thu, 25 Sep 2008 16:39:24 +0000 (-0700) Subject: Merge branch 'jc/alternate-push' X-Git-Tag: v1.6.1-rc1~203 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/1ad6d46235d135582d5cbb91ec0186b485c7b5c1?ds=inline;hp=-c Merge branch 'jc/alternate-push' * jc/alternate-push: push: receiver end advertises refs from alternate repositories push: prepare sender to receive extended ref information from the receiver receive-pack: make it a builtin is_directory(): a generic helper function --- 1ad6d46235d135582d5cbb91ec0186b485c7b5c1 diff --combined Makefile index 3c0664a073,f9c54ffd2f..48547a2113 --- a/Makefile +++ b/Makefile @@@ -294,7 -294,6 +294,6 @@@ PROGRAMS += git-mktag$ PROGRAMS += git-mktree$X PROGRAMS += git-pack-redundant$X PROGRAMS += git-patch-id$X - PROGRAMS += git-receive-pack$X PROGRAMS += git-send-pack$X PROGRAMS += git-shell$X PROGRAMS += git-show-index$X @@@ -546,6 -545,7 +545,7 @@@ BUILTIN_OBJS += builtin-prune-packed. BUILTIN_OBJS += builtin-prune.o BUILTIN_OBJS += builtin-push.o BUILTIN_OBJS += builtin-read-tree.o + BUILTIN_OBJS += builtin-receive-pack.o BUILTIN_OBJS += builtin-reflog.o BUILTIN_OBJS += builtin-remote.o BUILTIN_OBJS += builtin-rerere.o @@@ -636,8 -636,6 +636,8 @@@ ifeq ($(uname_S),Darwin endif NO_STRLCPY = YesPlease NO_MEMMEM = YesPlease + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o endif ifeq ($(uname_S),SunOS) NEEDS_SOCKET = YesPlease @@@ -688,8 -686,6 +688,8 @@@ ifeq ($(uname_S),FreeBSD BASIC_LDFLAGS += -L/usr/local/lib DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease THREADED_DELTA_SEARCH = YesPlease + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o endif ifeq ($(uname_S),OpenBSD) NO_STRCASESTR = YesPlease @@@ -716,8 -712,6 +716,8 @@@ ifeq ($(uname_S),AIX INTERNAL_QSORT = UnfortunatelyYes NEEDS_LIBICONV=YesPlease BASIC_CFLAGS += -D_LARGE_FILES + COMPAT_CFLAGS += -Icompat/regex + COMPAT_OBJS += compat/regex/regex.o endif ifeq ($(uname_S),GNU) # GNU/Hurd @@@ -769,10 -763,10 +769,10 @@@ ifneq (,$(findstring MINGW,$(uname_S)) NO_PERL_MAKEMAKER = YesPlease NO_POSIX_ONLY_PROGRAMS = YesPlease NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease - COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat + COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" - COMPAT_OBJS += compat/mingw.o compat/fnmatch.o compat/regex.o compat/winansi.o + COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/regex/regex.o compat/winansi.o EXTLIBS += -lws2_32 X = .exe gitexecdir = ../libexec/git-core @@@ -1271,12 -1265,6 +1271,12 @@@ $(XDIFF_LIB): $(XDIFF_OBJS doc: $(MAKE) -C Documentation all +man: + $(MAKE) -C Documentation man + +html: + $(MAKE) -C Documentation html + info: $(MAKE) -C Documentation info @@@ -1380,7 -1368,7 +1380,7 @@@ install: al $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' - $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X '$(DESTDIR_SQ)$(bindir_SQ)' + $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X git-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)' $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install ifndef NO_TCLTK @@@ -1413,9 -1401,6 +1413,9 @@@ install-info quick-install-doc: $(MAKE) -C Documentation quick-install +quick-install-html: + $(MAKE) -C Documentation quick-install-html + ### Maintainer's dist rules diff --combined builtin-clone.c index 5b40e07ba7,a4b87904fc..49d2eb9c2b --- a/builtin-clone.c +++ b/builtin-clone.c @@@ -58,7 -58,7 +58,7 @@@ static struct option builtin_clone_opti OPT_STRING(0, "reference", &option_reference, "repo", "reference repository"), OPT_STRING('o', "origin", &option_origin, "branch", - "use instead or 'origin' to track upstream"), + "use instead of 'origin' to track upstream"), OPT_STRING('u', "upload-pack", &option_upload_pack, "path", "path to git-upload-pack on the remote"), OPT_STRING(0, "depth", &option_depth, "depth", @@@ -77,7 -77,7 +77,7 @@@ static char *get_repo_path(const char * for (i = 0; i < ARRAY_SIZE(suffix); i++) { const char *path; path = mkpath("%s%s", repo, suffix[i]); - if (!stat(path, &st) && S_ISDIR(st.st_mode)) { + if (is_directory(path)) { *is_bundle = 0; return xstrdup(make_nonrelative_path(path)); } @@@ -140,13 -140,6 +140,6 @@@ static char *guess_dir_name(const char return xstrndup(start, end - start); } - static int is_directory(const char *path) - { - struct stat buf; - - return !stat(path, &buf) && S_ISDIR(buf.st_mode); - } - static void strip_trailing_slashes(char *dir) { char *end = dir + strlen(dir); diff --combined builtin-fetch-pack.c index 4dfef29bcd,e0c25615ef..fa3c936493 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@@ -735,7 -735,7 +735,7 @@@ int cmd_fetch_pack(int argc, const cha conn = git_connect(fd, (char *)dest, args.uploadpack, args.verbose ? CONNECT_VERBOSE : 0); if (conn) { - get_remote_heads(fd[0], &ref, 0, NULL, 0); + get_remote_heads(fd[0], &ref, 0, NULL, 0, NULL); ref = fetch_pack(&args, fd, conn, ref, dest, nr_heads, heads, NULL); close(fd[0]); @@@ -750,7 -750,7 +750,7 @@@ if (!ret && nr_heads) { /* If the heads to pull were given, we should have * consumed all of them by matching the remote. - * Otherwise, 'git-fetch remote no-such-ref' would + * Otherwise, 'git fetch remote no-such-ref' would * silently succeed without issuing an error. */ for (i = 0; i < nr_heads; i++) diff --combined builtin-send-pack.c index 2af9f29341,b3c22f6a4a..910db92b62 --- a/builtin-send-pack.c +++ b/builtin-send-pack.c @@@ -18,7 -18,7 +18,7 @@@ static struct send_pack_args args = /* * Make a pack stream and spit it out into file descriptor fd */ - static int pack_objects(int fd, struct ref *refs) + static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra) { /* * The child becomes pack-objects --revs; we feed @@@ -34,6 -34,8 +34,8 @@@ NULL, }; struct child_process po; + int i; + char buf[42]; if (args.use_thin_pack) argv[4] = "--thin"; @@@ -43,15 -45,21 +45,21 @@@ po.out = fd; po.git_cmd = 1; if (start_command(&po)) - die("git-pack-objects failed (%s)", strerror(errno)); + die("git pack-objects failed (%s)", strerror(errno)); /* * We feed the pack-objects we just spawned with revision * parameters by writing to the pipe. */ - while (refs) { - char buf[42]; + for (i = 0; i < extra->nr; i++) { + memcpy(buf + 1, sha1_to_hex(&extra->array[i][0]), 40); + buf[0] = '^'; + buf[41] = '\n'; + if (!write_or_whine(po.in, buf, 42, "send-pack: send refs")) + break; + } + while (refs) { if (!is_null_sha1(refs->old_sha1) && has_sha1_file(refs->old_sha1)) { memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40); @@@ -381,14 -389,17 +389,17 @@@ static int do_send_pack(int in, int out int expect_status_report = 0; int flags = MATCH_REFS_NONE; int ret; + struct extra_have_objects extra_have; + memset(&extra_have, 0, sizeof(extra_have)); if (args.send_all) flags |= MATCH_REFS_ALL; if (args.send_mirror) flags |= MATCH_REFS_MIRROR; /* No funny business with the matcher */ - remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL); + remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL, + &extra_have); get_local_heads(); /* Does the other end support the reporting? */ @@@ -496,7 -507,7 +507,7 @@@ packet_flush(out); if (new_refs && !args.dry_run) { - if (pack_objects(out, remote_refs) < 0) + if (pack_objects(out, remote_refs, &extra_have) < 0) return -1; } else diff --combined builtin.h index 8893b3ca59,5d7cdca70c..1495cf6a20 --- a/builtin.h +++ b/builtin.h @@@ -17,8 -17,7 +17,8 @@@ extern int read_line_with_nul(char *buf extern int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out); extern int commit_tree(const char *msg, unsigned char *tree, - struct commit_list *parents, unsigned char *ret); + struct commit_list *parents, unsigned char *ret, + const char *author); extern int check_pager_config(const char *cmd); extern int cmd_add(int argc, const char **argv, const char *prefix); @@@ -79,6 -78,7 +79,7 @@@ extern int cmd_prune(int argc, const ch extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); extern int cmd_push(int argc, const char **argv, const char *prefix); extern int cmd_read_tree(int argc, const char **argv, const char *prefix); + extern int cmd_receive_pack(int argc, const char **argv, const char *prefix); extern int cmd_reflog(int argc, const char **argv, const char *prefix); extern int cmd_remote(int argc, const char **argv, const char *prefix); extern int cmd_config(int argc, const char **argv, const char *prefix); diff --combined daemon.c index 0e026f65ec,ab7a273859..3e5582d289 --- a/daemon.c +++ b/daemon.c @@@ -1083,8 -1083,7 +1083,8 @@@ int main(int argc, char **argv openlog("git-daemon", LOG_PID, LOG_DAEMON); set_die_routine(daemon_die); } else - setlinebuf(stderr); /* avoid splitting a message in the middle */ + /* avoid splitting a message in the middle */ + setvbuf(stderr, NULL, _IOLBF, 0); if (inetd_mode && (group_name || user_name)) die("--user and --group are incompatible with --inetd"); @@@ -1116,13 -1115,9 +1116,9 @@@ if (strict_paths && (!ok_paths || !*ok_paths)) die("option --strict-paths requires a whitelist"); - if (base_path) { - struct stat st; - - if (stat(base_path, &st) || !S_ISDIR(st.st_mode)) - die("base-path '%s' does not exist or " - "is not a directory", base_path); - } + if (base_path && !is_directory(base_path)) + die("base-path '%s' does not exist or is not a directory", + base_path); if (inetd_mode) { struct sockaddr_storage ss; diff --combined git.c index 00f5dd1d49,2f5b4d72ee..f4b0cf611b --- a/git.c +++ b/git.c @@@ -162,8 -162,6 +162,8 @@@ static int handle_alias(int *argcp, con alias_string + 1, alias_command); } count = split_cmdline(alias_string, &new_argv); + if (count < 0) + die("Bad alias.%s string", alias_command); option_count = handle_options(&new_argv, &count, &envchanged); if (envchanged) die("alias '%s' changes environment variables\n" @@@ -330,6 -328,7 +330,7 @@@ static void handle_internal_command(in { "prune-packed", cmd_prune_packed, RUN_SETUP }, { "push", cmd_push, RUN_SETUP }, { "read-tree", cmd_read_tree, RUN_SETUP }, + { "receive-pack", cmd_receive_pack }, { "reflog", cmd_reflog, RUN_SETUP }, { "remote", cmd_remote, RUN_SETUP }, { "repo-config", cmd_config }, @@@ -366,7 -365,7 +367,7 @@@ if (sizeof(ext) > 1) { i = strlen(argv[0]) - strlen(ext); if (i > 0 && !strcmp(argv[0] + i, ext)) { - char *argv0 = strdup(argv[0]); + char *argv0 = xstrdup(argv[0]); argv[0] = cmd = argv0; argv0[i] = '\0'; } diff --combined sha1_file.c index 7d4f24d564,12be17b5da..70ff904717 --- a/sha1_file.c +++ b/sha1_file.c @@@ -99,11 -99,7 +99,11 @@@ int safe_create_leading_directories(cha pos = strchr(pos, '/'); if (!pos) break; - *pos = 0; + while (*++pos == '/') + ; + if (!*pos) + break; + *--pos = '\0'; if (!stat(path, &st)) { /* path exists */ if (!S_ISDIR(st.st_mode)) { @@@ -254,7 -250,6 +254,6 @@@ static void read_info_alternates(const */ static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth) { - struct stat st; const char *objdir = get_object_directory(); struct alternate_object_database *ent; struct alternate_object_database *alt; @@@ -285,7 -280,7 +284,7 @@@ ent->base[pfxlen] = ent->base[entlen-1] = 0; /* Detect cases where alternate disappeared */ - if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) { + if (!is_directory(ent->base)) { error("object directory %s does not exist; " "check .git/objects/info/alternates.", ent->base); @@@ -398,6 -393,16 +397,16 @@@ void add_to_alternates_file(const char link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0); } + void foreach_alt_odb(alt_odb_fn fn, void *cb) + { + struct alternate_object_database *ent; + + prepare_alt_odb(); + for (ent = alt_odb_list; ent; ent = ent->next) + if (fn(ent, cb)) + return; + } + void prepare_alt_odb(void) { const char *alt; @@@ -2140,9 -2145,7 +2149,9 @@@ static void write_sha1_file_prepare(con */ int move_temp_to_file(const char *tmpfile, const char *filename) { - int ret = link(tmpfile, filename); + int ret = 0; + if (link(tmpfile, filename)) + ret = errno; /* * Coda hack - coda doesn't like cross-directory links,