{"thread":{"id":"423","subject":"[0/2] Complete http-pull","startedAt":"2005-05-01T21:49:57Z","lastAt":"2005-05-01T21:56:25Z","messageCount":3,"participants":["Daniel Barkalow"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"2327","messageId":"Pine.LNX.4.21.0505011746230.30848-100000@iabervon.org","threadId":"423","inReplyTo":null,"subject":"[0/2] Complete http-pull","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-01T21:49:57Z","receivedAt":"2005-05-01T21:49:57Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This series enables http-pull to do everything renecessary to bring your\nlocal repository up to date with respect to a remote repository by HTTP.\n\n 1: Library support for files in refs\n 2: Fetch refs over the network and write them locally\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n\n"},{"id":"2328","messageId":"Pine.LNX.4.21.0505011750050.30848-100000@iabervon.org","threadId":"423","inReplyTo":"Pine.LNX.4.21.0505011746230.30848-100000@iabervon.org","subject":"[1/2] Library support for refs/","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-01T21:52:56Z","receivedAt":"2005-05-01T21:52:56Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This includes three things: in init, create .git/refs/; a function to read\na refs file; and a function to write a refs file.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\nIndex: Makefile\n===================================================================\n--- bab2f51e8218b023728539c7841ee7613ebd36e8/Makefile  (mode:100644 sha1:a3028efd80a4165ade03158361e0224fb46364f5)\n+++ f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/Makefile  (mode:100644 sha1:e43a1db55962c771cc934227213d6520939bd0ce)\n@@ -29,9 +29,10 @@\n \tinstall $(PROG) $(SCRIPTS) $(HOME)/bin/\n \n LIB_OBJS=read-cache.o sha1_file.o usage.o object.o commit.o tree.o blob.o \\\n-\t tag.o date.o\n+\t tag.o date.o refs.o\n+\n LIB_FILE=libgit.a\n-LIB_H=cache.h object.h blob.h tree.h commit.h tag.h\n+LIB_H=cache.h object.h blob.h tree.h commit.h tag.h refs.h\n \n LIB_H += strbuf.h\n LIB_OBJS += strbuf.o\nIndex: cache.h\n===================================================================\n--- bab2f51e8218b023728539c7841ee7613ebd36e8/cache.h  (mode:100644 sha1:af6345820f3f8c533868394059b2d3b189e6b422)\n+++ f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/cache.h  (mode:100644 sha1:42a08f57c5b7a7cd013ab3e99f3965014068b787)\n@@ -100,6 +100,11 @@\n \n #define get_object_directory() (getenv(DB_ENVIRONMENT) ? : DEFAULT_DB_ENVIRONMENT)\n \n+#define REF_ENVIRONMENT \"REF_FILE_DIRECTORY\"\n+#define DEFAULT_REF_ENVIRONMENT \".git/refs\"\n+\n+#define get_refs_directory() (getenv(REF_ENVIRONMENT) ? : DEFAULT_REF_ENVIRONMENT)\n+\n #define INDEX_ENVIRONMENT \"GIT_INDEX_FILE\"\n #define DEFAULT_INDEX_ENVIRONMENT \".git/index\"\n \nIndex: init-db.c\n===================================================================\n--- bab2f51e8218b023728539c7841ee7613ebd36e8/init-db.c  (mode:100644 sha1:83f95e8b926f4fd28e0db0ccfc4f040d4172ee8a)\n+++ f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/init-db.c  (mode:100644 sha1:6bed5a6abdfd7da152ed13b825376c2d2f8820c4)\n@@ -38,6 +38,7 @@\n \tmemcpy(path, sha1_dir, len);\n \n \tsafe_create_dir(sha1_dir);\n+\tsafe_create_dir(get_refs_directory());\n \tfor (i = 0; i < 256; i++) {\n \t\tsprintf(path+len, \"/%02x\", i);\n \t\tsafe_create_dir(path);\nIndex: refs.c\n===================================================================\n--- /dev/null  (tree:bab2f51e8218b023728539c7841ee7613ebd36e8)\n+++ f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/refs.c  (mode:100644 sha1:9ba5696c15d8597236e1f5b7a4dbd609045efc81)\n@@ -0,0 +1,139 @@\n+#include \"refs.h\"\n+#include \"cache.h\"\n+\n+#include <errno.h>\n+\n+static char *split_ref_file_name(const char *dir, const char *name)\n+{\n+\tchar *base = get_refs_directory();\n+\tint baselen = strlen(base);\n+\tint dirlen = strlen(dir);\n+\tint namelen = strlen(name);\n+\tchar *ret;\n+\tif (dir[0] == '.')\n+\t\treturn NULL;\n+\tif (strchr(dir, '/'))\n+\t\treturn NULL;\n+\tif (strchr(name, '/'))\n+\t\treturn NULL;\n+\tret = xmalloc(baselen + 3 + dirlen + namelen);\n+\tstrcpy(ret, base);\n+\tret[baselen] = '/';\n+\tstrcpy(ret + baselen + 1, dir);\n+\tret[baselen + 1 + dirlen] = '/';\n+\tstrcpy(ret + baselen + 2 + dirlen, name);\n+\tret[baselen + 2 + dirlen + namelen] = '\\0';\n+\treturn ret;\n+}\n+\n+static char *ref_file_name(const char *ref)\n+{\n+\tchar *base = get_refs_directory();\n+\tint baselen = strlen(base);\n+\tint reflen = strlen(ref);\n+\tchar *ret;\n+\tchar *check;\n+\tif (ref[0] == '.')\n+\t\treturn NULL;\n+\tcheck = strchr(ref, '/');\n+\tif (!check)\n+\t\treturn NULL;\n+\tif (strchr(check + 1, '/'))\n+\t\treturn NULL;\n+\tret = xmalloc(baselen + 2 + reflen);\n+\tstrcpy(ret, base);\n+\tret[baselen] = '/';\n+\tstrcpy(ret + baselen + 1, ref);\n+\tret[baselen + 1 + reflen] = '\\0';\n+\treturn ret;\n+}\n+\n+static int read_ref_file(char *filename, unsigned char *sha1) {\n+\tint fd = open(filename, O_RDONLY);\n+\tchar hex[41];\n+\tif (fd < 0) {\n+\t\treturn error(\"Couldn't open %s\\n\", filename);\n+\t}\n+\tif ((read(fd, hex, 41) < 41) ||\n+\t    (hex[40] != '\\n') ||\n+\t    get_sha1_hex(hex, sha1)) {\n+\t\terror(\"Couldn't read a hash from %s\\n\", filename);\n+\t\tclose(fd);\n+\t\treturn -1;\n+\t}\n+\tclose(fd);\n+\treturn 0;\n+}\n+\n+int get_split_ref_sha1(const char *dir, const char *name, unsigned char *sha1)\n+{\n+\tchar *filename = split_ref_file_name(dir, name);\n+\tint retval;\n+\tif (!filename)\n+\t\treturn -1;\n+\tretval = read_ref_file(filename, sha1);\n+\tfree(filename);\n+\treturn retval;\n+}\n+\n+int get_ref_sha1(const char *ref, unsigned char *sha1)\n+{\n+\tchar *filename = ref_file_name(ref);\n+\tint retval;\n+\tif (!filename)\n+\t\treturn -1;\n+\tretval = read_ref_file(filename, sha1);\n+\tfree(filename);\n+\treturn retval;\n+}\n+\n+int write_split_ref_sha1(const char *dir, const char *name,\n+\t\t\t unsigned char *sha1)\n+{\n+\tchar *filename = split_ref_file_name(dir, name);\n+\tchar *hex = sha1_to_hex(sha1);\n+\tchar term = '\\n';\n+\tint fd;\n+\tif (!filename)\n+\t\treturn -1;\n+\tunlink(filename);\n+\tfd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);\n+\tif (fd < 0 && errno == ENOENT) {\n+\t\tchar *dirname = split_ref_file_name(dir, \"\");\n+\t\tmkdir(dirname, 0755);\n+\t\tfree(dirname);\n+\t\tfd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);\n+\t}\n+\tif (fd < 0) {\n+\t\terror(\"Couldn't open for writing %s: %s\\n\", filename,\n+\t\t      strerror(errno));\n+\t\tfree(filename);\n+\t\treturn -1;\n+\t}\n+\tif (write(fd, hex, 40) < 40 ||\n+\t    write(fd, &term, 1) < 1) {\n+\t\terror(\"Couldn't write %s\\n\", filename);\n+\t\tfree(filename);\n+\t\tclose(fd);\n+\t\treturn -1;\n+\t}\n+\tclose(fd);\n+\treturn 0;\n+\t\n+}\n+\n+int split_ref(char **dir, char **name, const char *ref)\n+{\n+\tchar *middle = strchr(ref, '/');\n+\tif (ref[0] == '.')\n+\t\treturn -1;\n+\tif (!middle)\n+\t\treturn -1;\n+\tif (strchr(middle + 1, '/'))\n+\t\treturn -1;\n+\t*dir = xmalloc(middle - ref + 1);\n+\t*name = strdup(middle + 1);\n+\t(*dir)[middle - ref] = '\\0';\n+\tmemcpy(*dir, ref, middle - ref);\n+\treturn 0;\n+}\nIndex: refs.h\n===================================================================\n--- /dev/null  (tree:bab2f51e8218b023728539c7841ee7613ebd36e8)\n+++ f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/refs.h  (mode:100644 sha1:9ef6ed7563f70273aef6574a01d5626fee28345a)\n@@ -0,0 +1,20 @@\n+#ifndef REFS_H\n+#define REFS_H\n+\n+/** Reads the refs file specified into sha1 **/\n+extern int get_split_ref_sha1(const char *dir, const char *name,\n+\t\t\t      unsigned char *sha1);\n+\n+/** Reads the refs file specified into sha1 **/\n+extern int get_ref_sha1(const char *ref, unsigned char *sha1);\n+\n+/** Writes sha1 into the refs file specified **/\n+extern int write_split_ref_sha1(const char *dir, const char *name, \n+\t\t\t\tunsigned char *sha1);\n+\n+/** Sets dir and name to the directory and name parts of ref, in new\n+ * storage. \n+ **/\n+extern int split_ref(char **dir, char **name, const char *ref);\n+\n+#endif /* REFS_H */\n\n"},{"id":"2329","messageId":"Pine.LNX.4.21.0505011753000.30848-100000@iabervon.org","threadId":"423","inReplyTo":"Pine.LNX.4.21.0505011746230.30848-100000@iabervon.org","subject":"[2/2] Complete http-pull","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-01T21:56:25Z","receivedAt":"2005-05-01T21:56:25Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This adds support for fetching a reference from the remote repository and\nfor writing to a local reference file (with the -w option). It also makes\nrpull aware that it lacks this capability.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\nIndex: http-pull.c\n===================================================================\n--- f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/http-pull.c  (mode:100644 sha1:d877c4abe3ff7766d858bfeac5c9a0eaf1385b65)\n+++ 6bae8854157f3f8b29f9afee2c54434334f899e4/http-pull.c  (mode:100644 sha1:9a52c08f51d8e9f96c4704f84f8d0d15637fe397)\n@@ -7,6 +7,8 @@\n #include <errno.h>\n #include <stdio.h>\n \n+#include \"refs.h\"\n+\n #include \"pull.h\"\n \n #include <curl/curl.h>\n@@ -45,6 +47,23 @@\n \treturn size;\n }\n \n+struct buffer\n+{\n+\tsize_t posn;\n+\tsize_t size;\n+\tvoid *buffer;\n+};\n+\n+static size_t fwrite_buffer(void *ptr, size_t eltsize, size_t nmemb,\n+\t\t\t    struct buffer *buffer) {\n+\tsize_t size = eltsize * nmemb;\n+\tif (size > buffer->size - buffer->posn)\n+\t\tsize = buffer->size - buffer->posn;\n+\tmemcpy(buffer->buffer + buffer->posn, ptr, size);\n+\tbuffer->posn += size;\n+\treturn size;\n+}\n+\n int fetch(unsigned char *sha1)\n {\n \tchar *hex = sha1_to_hex(sha1);\n@@ -103,6 +122,40 @@\n \treturn 0;\n }\n \n+int fetch_ref(char *dir, char *name, unsigned char *sha1)\n+{\n+\tchar *url, *posn;\n+\tchar hex[42];\n+\tstruct buffer buffer;\n+\tbuffer.size = 41;\n+\tbuffer.posn = 0;\n+\tbuffer.buffer = hex;\n+\thex[41] = '\\0';\n+\t\n+\tcurl_easy_setopt(curl, CURLOPT_FILE, &buffer);\n+\tcurl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);\n+\n+\turl = xmalloc(strlen(base) + 7 + strlen(dir) + strlen(name));\n+\tstrcpy(url, base);\n+\tposn = url + strlen(base);\n+\tstrcpy(posn, \"refs/\");\n+\tposn += 5;\n+\tstrcpy(posn, dir);\n+\tposn += strlen(dir);\n+\t*(posn++) = '/';\n+\tstrcpy(posn, name);\n+\n+\tcurl_easy_setopt(curl, CURLOPT_URL, url);\n+\n+\tif (curl_easy_perform(curl))\n+\t\treturn error(\"Couldn't get %s for %s/%s\\n\", url,\n+\t\t\t     dir, name);\n+\n+\thex[40] = '\\0';\n+\tget_sha1_hex(hex, sha1);\n+\treturn 0;\n+}\n+\n int main(int argc, char **argv)\n {\n \tchar *commit_id;\n@@ -118,6 +171,10 @@\n \t\t\tget_all = 1;\n \t\t\tget_tree = 1;\n \t\t\tget_history = 1;\n+\t\t} else if (argv[arg][1] == 'w') {\n+\t\t\tchar *write_ref = argv[arg + 1];\n+\t\t\tsplit_ref(&write_ref_dir, &write_ref_name, write_ref);\n+\t\t\targ++;\n \t\t}\n \t\targ++;\n \t}\nIndex: pull.c\n===================================================================\n--- f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/pull.c  (mode:100644 sha1:90d2d41ed2c56580f72f020bc93c3e1b8a3befa5)\n+++ 6bae8854157f3f8b29f9afee2c54434334f899e4/pull.c  (mode:100644 sha1:89f11906f67ea9b36e1d4d85fa87f0e9b7d08d65)\n@@ -3,6 +3,12 @@\n #include \"cache.h\"\n #include \"commit.h\"\n #include \"tree.h\"\n+#include \"tag.h\"\n+\n+#include \"refs.h\"\n+\n+char *write_ref_dir = NULL;\n+char *write_ref_name = NULL;\n \n int get_tree = 0;\n int get_history = 0;\n@@ -61,15 +67,53 @@\n \treturn 0;\n }\n \n+static int process_tag(unsigned char *sha1)\n+{\n+\treturn 0;\n+}\n+\n+static int process_unknown(unsigned char *sha1)\n+{\n+\tstruct object *obj;\n+\tif (fetch(sha1))\n+\t\treturn -1;\n+\tobj = parse_object(sha1);\n+\tif (obj->type == commit_type)\n+\t\treturn process_commit(sha1);\n+\telse if (obj->type == tag_type)\n+\t\treturn process_tag(sha1);\n+\treturn error(\"Cannot pull a %s object\", obj->type);\n+}\n+\n+static int interpret_target(char *target, unsigned char *sha1)\n+{\n+\tchar *dir, *name;\n+\tif (!get_sha1_hex(target, sha1))\n+\t\treturn 0;\n+\tif (!split_ref(&dir, &name, target)) {\n+\t\tif (!fetch_ref(dir, name, sha1)) {\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\treturn -1;\n+}\n+\n int pull(char *target)\n {\n \tint retval;\n \tunsigned char sha1[20];\n-\tretval = get_sha1_hex(target, sha1);\n+\tretval = interpret_target(target, sha1);\n+\tif (retval) {\n+\t\treturn error(\"Could not interpret %s as something to pull\",\n+\t\t\t     target);\n+\t}\n+\tretval = fetch(sha1);\n \tif (retval)\n \t\treturn retval;\n-\tretval = fetch(sha1);\n+\tretval = process_unknown(sha1);\n \tif (retval)\n \t\treturn retval;\n-\treturn process_commit(sha1);\n+\tif (write_ref_dir && write_ref_name)\n+\t\twrite_split_ref_sha1(write_ref_dir, write_ref_name, sha1);\n+\treturn 0;\n }\nIndex: pull.h\n===================================================================\n--- f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/pull.h  (mode:100644 sha1:314bc7e95ab1a73634f6a96a8a3782fda91ea261)\n+++ 6bae8854157f3f8b29f9afee2c54434334f899e4/pull.h  (mode:100644 sha1:5df0ff6001ad4129dcd8b2af7c927bade8c413d2)\n@@ -4,6 +4,12 @@\n /** To be provided by the particular implementation. **/\n extern int fetch(unsigned char *sha1);\n \n+extern int fetch_ref(char *dir, char *name, unsigned char *sha1);\n+\n+/** Ref filename to write target to. **/\n+extern char *write_ref_dir;\n+extern char *write_ref_name;\n+\n /** Set to fetch the target tree. */\n extern int get_tree;\n \nIndex: rpull.c\n===================================================================\n--- f0d6a3af54a5ec8dd588fb8e501e38f6252eda19/rpull.c  (mode:100644 sha1:6624440d5ad24854e1bd1a8dff628427581198e0)\n+++ 6bae8854157f3f8b29f9afee2c54434334f899e4/rpull.c  (mode:100644 sha1:a1c1be18195d40a152f86ed35886364dbc806d80)\n@@ -20,6 +20,11 @@\n \treturn write_sha1_from_fd(sha1, fd_in);\n }\n \n+int fetch_ref(char *name, char *dir, unsigned char *sha1)\n+{\n+\treturn -1;\n+}\n+\n int main(int argc, char **argv)\n {\n \tchar *commit_id;\n\n"}]}