# [PATCH 3/4] Teach transport about the gitfile mechanism

2 messages from 2011-10-04 to 2011-10-04. Participants: Phil Hord, Nguyen Thai Ngoc Duy.
Thread: https://gitlist.dev/t/28575

## Phil Hord, 2011-10-04 20:08

Subject: [PATCH 3/4] Teach transport about the gitfile mechanism
Message-ID: <CABURp0qkVcpNRyEg8gcNPjv2KbRbdHYk1XsqCjkp8Yrf7T_Lkw@mail.gmail.com>
URL: https://gitlist.dev/e/CABURp0qkVcpNRyEg8gcNPjv2KbRbdHYk1XsqCjkp8Yrf7T_Lkw%40mail.gmail.com

```
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 <hordp@cisco.com>

diff --git a/transport.c b/transport.c
index cd49a25..f7017c1 100644
--- a/transport.c
+++ b/transport.c
@@ -867,6 +867,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;
@@ -915,7 +937,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;
-- 
1.7.7.503.g26392.dirty

```

## Nguyen Thai Ngoc Duy, 2011-10-04 21:46

Subject: Re: [PATCH 3/4] Teach transport about the gitfile mechanism
Message-ID: <CACsJy8AtUWbuXVQxA7jT7rQmAzPpd72trqcSH_6X=P0FBU1vwQ@mail.gmail.com>
URL: https://gitlist.dev/e/CACsJy8AtUWbuXVQxA7jT7rQmAzPpd72trqcSH_6X%3DP0FBU1vwQ%40mail.gmail.com
In-Reply-To: <CABURp0qkVcpNRyEg8gcNPjv2KbRbdHYk1XsqCjkp8Yrf7T_Lkw@mail.gmail.com>

```
On Wed, Oct 5, 2011 at 7:08 AM, Phil Hord <phil.hord@gmail.com> wrote:
> +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: ");
> +}
> +

There's similar code in get_repo_path(), builtin/clone.c, added in
commit 9b0ebc7 (clone: allow to clone from .git file). Perhaps you can
reuse this function there and remove duplicate code.
-- 
Duy

```
