From: Phil Hord Date: Tue, 4 Oct 2011 20:08:20 +0000 (-0400) Subject: Teach transport about the gitfile mechanism X-Git-Tag: v1.7.8-rc0~31^2~2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=7ab8777e8dd365e9a5dc06eb3042903e296ef1b0;p=git.git Teach transport about the gitfile mechanism The transport_get() function assumes that a regular file is a bundle rather than a local git directory. Look inside the file for the telltale "gitlink: " header to see if it is actually a gitfile. If so, do not try to process it as a bundle, but treat it as a local repository instead. Signed-off-by: Phil Hord Signed-off-by: Junio C Hamano --- diff --git a/transport.c b/transport.c index fa279d531..1707c5244 100644 --- a/transport.c +++ b/transport.c @@ -866,6 +866,28 @@ static int is_local(const char *url) has_dos_drive_prefix(url); } +static int is_gitfile(const char *url) +{ + struct stat st; + char buf[9]; + int fd, len; + if (stat(url, &st)) + return 0; + if (!S_ISREG(st.st_mode)) + return 0; + if (st.st_size < 10 || st.st_size > PATH_MAX) + return 1; + + fd = open(url, O_RDONLY); + if (fd < 0) + die_errno("Error opening '%s'", url); + len = read_in_full(fd, buf, sizeof(buf)); + close(fd); + if (len != sizeof(buf)) + die("Error reading %s", url); + return !prefixcmp(buf, "gitdir: "); +} + static int is_file(const char *url) { struct stat buf; @@ -914,7 +936,7 @@ struct transport *transport_get(struct remote *remote, const char *url) ret->fetch = fetch_objs_via_rsync; ret->push = rsync_transport_push; ret->smart_options = NULL; - } else if (is_local(url) && is_file(url)) { + } else if (is_local(url) && is_file(url) && !is_gitfile(url)) { struct bundle_transport_data *data = xcalloc(1, sizeof(*data)); ret->data = data; ret->get_refs_list = get_refs_from_bundle;