{"thread":{"id":"28575","subject":"[PATCH 3/4] Teach transport about the gitfile mechanism","startedAt":"2011-10-04T20:08:20Z","lastAt":"2011-10-04T21:46:33Z","messageCount":2,"participants":["Phil Hord","Nguyen Thai Ngoc Duy"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"176870","messageId":"CABURp0qkVcpNRyEg8gcNPjv2KbRbdHYk1XsqCjkp8Yrf7T_Lkw@mail.gmail.com","threadId":"28575","inReplyTo":null,"subject":"[PATCH 3/4] Teach transport about the gitfile mechanism","fromName":"Phil Hord","fromEmail":"phil.hord@gmail.com","sentAt":"2011-10-04T20:08:20Z","receivedAt":"2011-10-04T20:08:20Z","isPatch":true,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"The transport_get() function assumes that a regular file is a\nbundle rather than a local git directory. Look inside the file\nfor the telltale \"gitlink: \" header to see if it is actually a\ngitfile.  If so, do not try to process it as a bundle, but\ntreat it as a local repository instead.\n\nSigned-off-by: Phil Hord <hordp@cisco.com>\n\ndiff --git a/transport.c b/transport.c\nindex cd49a25..f7017c1 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -867,6 +867,28 @@ static int is_local(const char *url)\n \t\thas_dos_drive_prefix(url);\n }\n\n+static int is_gitfile(const char *url)\n+{\n+\tstruct stat st;\n+\tchar buf[9];\n+\tint fd, len;\n+\tif (stat(url, &st))\n+\t\treturn 0;\n+\tif (!S_ISREG(st.st_mode))\n+\t\treturn 0;\n+\tif (st.st_size < 10 || st.st_size > PATH_MAX)\n+\t\treturn 1;\n+\n+\tfd = open(url, O_RDONLY);\n+\tif (fd < 0)\n+\t\tdie_errno(\"Error opening '%s'\", url);\n+\tlen = read_in_full(fd, buf, sizeof(buf));\n+\tclose(fd);\n+\tif (len != sizeof(buf))\n+\t\tdie(\"Error reading %s\", url);\n+\treturn !prefixcmp(buf, \"gitdir: \");\n+}\n+\n static int is_file(const char *url)\n {\n \tstruct stat buf;\n@@ -915,7 +937,7 @@ struct transport *transport_get(struct remote\n*remote, const char *url)\n \t\tret->fetch = fetch_objs_via_rsync;\n \t\tret->push = rsync_transport_push;\n \t\tret->smart_options = NULL;\n-\t} else if (is_local(url) && is_file(url)) {\n+\t} else if (is_local(url) && is_file(url) && !is_gitfile(url)) {\n \t\tstruct bundle_transport_data *data = xcalloc(1, sizeof(*data));\n \t\tret->data = data;\n \t\tret->get_refs_list = get_refs_from_bundle;\n-- \n1.7.7.503.g26392.dirty\n"},{"id":"176882","messageId":"CACsJy8AtUWbuXVQxA7jT7rQmAzPpd72trqcSH_6X=P0FBU1vwQ@mail.gmail.com","threadId":"28575","inReplyTo":"CABURp0qkVcpNRyEg8gcNPjv2KbRbdHYk1XsqCjkp8Yrf7T_Lkw@mail.gmail.com","subject":"Re: [PATCH 3/4] Teach transport about the gitfile mechanism","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-10-04T21:46:33Z","receivedAt":"2011-10-04T21:46:33Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Oct 5, 2011 at 7:08 AM, Phil Hord <phil.hord@gmail.com> wrote:\n> +static int is_gitfile(const char *url)\n> +{\n> +       struct stat st;\n> +       char buf[9];\n> +       int fd, len;\n> +       if (stat(url, &st))\n> +               return 0;\n> +       if (!S_ISREG(st.st_mode))\n> +               return 0;\n> +       if (st.st_size < 10 || st.st_size > PATH_MAX)\n> +               return 1;\n> +\n> +       fd = open(url, O_RDONLY);\n> +       if (fd < 0)\n> +               die_errno(\"Error opening '%s'\", url);\n> +       len = read_in_full(fd, buf, sizeof(buf));\n> +       close(fd);\n> +       if (len != sizeof(buf))\n> +               die(\"Error reading %s\", url);\n> +       return !prefixcmp(buf, \"gitdir: \");\n> +}\n> +\n\nThere's similar code in get_repo_path(), builtin/clone.c, added in\ncommit 9b0ebc7 (clone: allow to clone from .git file). Perhaps you can\nreuse this function there and remove duplicate code.\n-- \nDuy\n"}]}