From: Junio C Hamano Date: Tue, 29 May 2007 08:24:20 +0000 (-0700) Subject: Merge branch 'db/remote' X-Git-Tag: v1.5.3-rc0~181 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/322bcd9a9a2c0081c66414bde64e0d443c9ec922?ds=inline;hp=-c Merge branch 'db/remote' * db/remote: Move refspec pattern matching to match_refs(). Update local tracking refs when pushing Add handlers for fetch-side configuration of remotes. Move refspec parser from connect.c and cache.h to remote.{c,h} Move remote parsing into a library file out of builtin-push. --- 322bcd9a9a2c0081c66414bde64e0d443c9ec922 diff --combined Makefile index fb11fa1987,35864ed3c4..75277343f6 --- a/Makefile +++ b/Makefile @@@ -235,7 -235,7 +235,7 @@@ endi # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS = \ - git-convert-objects$X git-fetch-pack$X git-fsck$X \ + git-convert-objects$X git-fetch-pack$X \ git-hash-object$X git-index-pack$X git-local-fetch$X \ git-fast-import$X \ git-merge-base$X \ @@@ -246,7 -246,7 +246,7 @@@ git-show-index$X git-ssh-fetch$X \ git-ssh-upload$X git-unpack-file$X \ git-update-server-info$X \ - git-upload-pack$X git-verify-pack$X \ + git-upload-pack$X \ git-pack-redundant$X git-var$X \ git-merge-tree$X git-imap-send$X \ git-merge-recursive$X \ @@@ -296,7 -296,8 +296,8 @@@ LIB_H = diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \ run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \ tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \ - utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h mailmap.h + utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h \ + mailmap.h remote.h DIFF_OBJS = \ diff.o diff-lib.o diffcore-break.o diffcore-order.o \ @@@ -318,7 -319,7 +319,7 @@@ LIB_OBJS = write_or_die.o trace.o list-objects.o grep.o match-trees.o \ alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \ color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \ - convert.o attr.o decorate.o progress.o mailmap.o symlinks.o + convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o BUILTIN_OBJS = \ builtin-add.o \ diff --combined cache.h index cd875bc2e9,0e6439b0dd..ec85d93e0d --- a/cache.h +++ b/cache.h @@@ -40,8 -40,8 +40,8 @@@ * happens that everybody shares the same bit representation * in the UNIX world (and apparently wider too..) */ -#define S_IFDIRLNK 0160000 -#define S_ISDIRLNK(m) (((m) & S_IFMT) == S_IFDIRLNK) +#define S_IFGITLINK 0160000 +#define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK) /* * Intensive research over the course of many years has shown that @@@ -123,8 -123,8 +123,8 @@@ static inline unsigned int create_ce_mo { if (S_ISLNK(mode)) return htonl(S_IFLNK); - if (S_ISDIR(mode) || S_ISDIRLNK(mode)) - return htonl(S_IFDIRLNK); + if (S_ISDIR(mode) || S_ISGITLINK(mode)) + return htonl(S_IFGITLINK); return htonl(S_IFREG | ce_permissions(mode)); } static inline unsigned int ce_mode_from_stat(struct cache_entry *ce, unsigned int mode) @@@ -142,7 -142,7 +142,7 @@@ } #define canon_mode(mode) \ (S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \ - S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFDIRLNK) + S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK) #define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7) @@@ -467,8 -467,6 +467,6 @@@ struct ref extern pid_t git_connect(int fd[2], char *url, const char *prog, int flags); extern int finish_connect(pid_t pid); extern int path_match(const char *path, int nr, char **match); - extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, - int nr_refspec, char **refspec, int all); extern int get_ack(int fd, unsigned char *result_sha1); extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags); extern int server_supports(const char *feature); diff --combined connect.c index 375739205f,2f61ea3422..8cbda88dda --- a/connect.c +++ b/connect.c @@@ -4,6 -4,7 +4,7 @@@ #include "quote.h" #include "refs.h" #include "run-command.h" + #include "remote.h" static char *server_capabilities; @@@ -128,245 -129,6 +129,6 @@@ int path_match(const char *path, int nr return 0; } - struct refspec { - char *src; - char *dst; - char force; - }; - - /* - * A:B means fast forward remote B with local A. - * +A:B means overwrite remote B with local A. - * +A is a shorthand for +A:A. - * A is a shorthand for A:A. - * :B means delete remote B. - */ - static struct refspec *parse_ref_spec(int nr_refspec, char **refspec) - { - int i; - struct refspec *rs = xcalloc(sizeof(*rs), (nr_refspec + 1)); - for (i = 0; i < nr_refspec; i++) { - char *sp, *dp, *ep; - sp = refspec[i]; - if (*sp == '+') { - rs[i].force = 1; - sp++; - } - ep = strchr(sp, ':'); - if (ep) { - dp = ep + 1; - *ep = 0; - } - else - dp = sp; - rs[i].src = sp; - rs[i].dst = dp; - } - rs[nr_refspec].src = rs[nr_refspec].dst = NULL; - return rs; - } - - static int count_refspec_match(const char *pattern, - struct ref *refs, - struct ref **matched_ref) - { - int patlen = strlen(pattern); - struct ref *matched_weak = NULL; - struct ref *matched = NULL; - int weak_match = 0; - int match = 0; - - for (weak_match = match = 0; refs; refs = refs->next) { - char *name = refs->name; - int namelen = strlen(name); - int weak_match; - - if (namelen < patlen || - memcmp(name + namelen - patlen, pattern, patlen)) - continue; - if (namelen != patlen && name[namelen - patlen - 1] != '/') - continue; - - /* A match is "weak" if it is with refs outside - * heads or tags, and did not specify the pattern - * in full (e.g. "refs/remotes/origin/master") or at - * least from the toplevel (e.g. "remotes/origin/master"); - * otherwise "git push $URL master" would result in - * ambiguity between remotes/origin/master and heads/master - * at the remote site. - */ - if (namelen != patlen && - patlen != namelen - 5 && - prefixcmp(name, "refs/heads/") && - prefixcmp(name, "refs/tags/")) { - /* We want to catch the case where only weak - * matches are found and there are multiple - * matches, and where more than one strong - * matches are found, as ambiguous. One - * strong match with zero or more weak matches - * are acceptable as a unique match. - */ - matched_weak = refs; - weak_match++; - } - else { - matched = refs; - match++; - } - } - if (!matched) { - *matched_ref = matched_weak; - return weak_match; - } - else { - *matched_ref = matched; - return match; - } - } - - static void link_dst_tail(struct ref *ref, struct ref ***tail) - { - **tail = ref; - *tail = &ref->next; - **tail = NULL; - } - - static struct ref *try_explicit_object_name(const char *name) - { - unsigned char sha1[20]; - struct ref *ref; - int len; - - if (!*name) { - ref = xcalloc(1, sizeof(*ref) + 20); - strcpy(ref->name, "(delete)"); - hashclr(ref->new_sha1); - return ref; - } - if (get_sha1(name, sha1)) - return NULL; - len = strlen(name) + 1; - ref = xcalloc(1, sizeof(*ref) + len); - memcpy(ref->name, name, len); - hashcpy(ref->new_sha1, sha1); - return ref; - } - - static int match_explicit_refs(struct ref *src, struct ref *dst, - struct ref ***dst_tail, struct refspec *rs) - { - int i, errs; - for (i = errs = 0; rs[i].src; i++) { - struct ref *matched_src, *matched_dst; - - matched_src = matched_dst = NULL; - switch (count_refspec_match(rs[i].src, src, &matched_src)) { - case 1: - break; - case 0: - /* The source could be in the get_sha1() format - * not a reference name. :refs/other is a - * way to delete 'other' ref at the remote end. - */ - matched_src = try_explicit_object_name(rs[i].src); - if (matched_src) - break; - errs = 1; - error("src refspec %s does not match any.", - rs[i].src); - break; - default: - errs = 1; - error("src refspec %s matches more than one.", - rs[i].src); - break; - } - switch (count_refspec_match(rs[i].dst, dst, &matched_dst)) { - case 1: - break; - case 0: - if (!memcmp(rs[i].dst, "refs/", 5)) { - int len = strlen(rs[i].dst) + 1; - matched_dst = xcalloc(1, sizeof(*dst) + len); - memcpy(matched_dst->name, rs[i].dst, len); - link_dst_tail(matched_dst, dst_tail); - } - else if (!strcmp(rs[i].src, rs[i].dst) && - matched_src) { - /* pushing "master:master" when - * remote does not have master yet. - */ - int len = strlen(matched_src->name) + 1; - matched_dst = xcalloc(1, sizeof(*dst) + len); - memcpy(matched_dst->name, matched_src->name, - len); - link_dst_tail(matched_dst, dst_tail); - } - else { - errs = 1; - error("dst refspec %s does not match any " - "existing ref on the remote and does " - "not start with refs/.", rs[i].dst); - } - break; - default: - errs = 1; - error("dst refspec %s matches more than one.", - rs[i].dst); - break; - } - if (errs) - continue; - if (matched_dst->peer_ref) { - errs = 1; - error("dst ref %s receives from more than one src.", - matched_dst->name); - } - else { - matched_dst->peer_ref = matched_src; - matched_dst->force = rs[i].force; - } - } - return -errs; - } - - static struct ref *find_ref_by_name(struct ref *list, const char *name) - { - for ( ; list; list = list->next) - if (!strcmp(list->name, name)) - return list; - return NULL; - } - - int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, - int nr_refspec, char **refspec, int all) - { - struct refspec *rs = parse_ref_spec(nr_refspec, refspec); - - if (nr_refspec) - return match_explicit_refs(src, dst, dst_tail, rs); - - /* pick the remainder */ - for ( ; src; src = src->next) { - struct ref *dst_peer; - if (src->peer_ref) - continue; - dst_peer = find_ref_by_name(dst, src->name); - if ((dst_peer && dst_peer->peer_ref) || (!dst_peer && !all)) - continue; - if (!dst_peer) { - /* Create a new one and link it */ - int len = strlen(src->name) + 1; - dst_peer = xcalloc(1, sizeof(*dst_peer) + len); - memcpy(dst_peer->name, src->name, len); - hashcpy(dst_peer->new_sha1, src->new_sha1); - link_dst_tail(dst_peer, dst_tail); - } - dst_peer->peer_ref = src; - } - return 0; - } - enum protocol { PROTO_LOCAL = 1, PROTO_SSH, @@@ -391,23 -153,6 +153,23 @@@ static enum protocol get_protocol(cons #ifndef NO_IPV6 +static const char *ai_name(const struct addrinfo *ai) +{ + static char addr[INET_ADDRSTRLEN]; + if ( AF_INET == ai->ai_family ) { + struct sockaddr_in *in; + in = (struct sockaddr_in *)ai->ai_addr; + inet_ntop(ai->ai_family, &in->sin_addr, addr, sizeof(addr)); + } else if ( AF_INET6 == ai->ai_family ) { + struct sockaddr_in6 *in; + in = (struct sockaddr_in6 *)ai->ai_addr; + inet_ntop(ai->ai_family, &in->sin6_addr, addr, sizeof(addr)); + } else { + strcpy(addr, "(unknown)"); + } + return addr; +} + /* * Returns a connected socket() fd, or else die()s. */ @@@ -418,7 -163,6 +180,7 @@@ static int git_tcp_connect_sock(char *h const char *port = STR(DEFAULT_GIT_PORT); struct addrinfo hints, *ai0, *ai; int gai; + int cnt = 0; if (host[0] == '[') { end = strchr(host + 1, ']'); @@@ -462,18 -206,10 +224,18 @@@ } if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { saved_errno = errno; + fprintf(stderr, "%s[%d: %s]: net=%s, errno=%s\n", + host, + cnt, + ai_name(ai), + hstrerror(h_errno), + strerror(saved_errno)); close(sockfd); sockfd = -1; continue; } + if (flags & CONNECT_VERBOSE) + fprintf(stderr, "%s ", ai_name(ai)); break; } @@@ -502,7 -238,6 +264,7 @@@ static int git_tcp_connect_sock(char *h struct sockaddr_in sa; char **ap; unsigned int nport; + int cnt; if (host[0] == '[') { end = strchr(host + 1, ']'); @@@ -539,7 -274,7 +301,7 @@@ if (flags & CONNECT_VERBOSE) fprintf(stderr, "done.\nConnecting to %s (port %s) ... ", host, port); - for (ap = he->h_addr_list; *ap; ap++) { + for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) { sockfd = socket(he->h_addrtype, SOCK_STREAM, 0); if (sockfd < 0) { saved_errno = errno; @@@ -553,19 -288,10 +315,19 @@@ if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) { saved_errno = errno; + fprintf(stderr, "%s[%d: %s]: net=%s, errno=%s\n", + host, + cnt, + inet_ntoa(*(struct in_addr *)&sa.sin_addr), + hstrerror(h_errno), + strerror(saved_errno)); close(sockfd); sockfd = -1; continue; } + if (flags & CONNECT_VERBOSE) + fprintf(stderr, "%s ", + inet_ntoa(*(struct in_addr *)&sa.sin_addr)); break; }