{"thread":{"id":"600","subject":"[PATCH 0/4] Pulling refs files","startedAt":"2005-05-13T06:49:25Z","lastAt":"2005-05-19T16:00:43Z","messageCount":23,"participants":["Daniel Barkalow","Edgar Toernig","H. Peter Anvin","Petr Baudis","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"3231","messageId":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","threadId":"600","inReplyTo":null,"subject":"[PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-13T06:49:25Z","receivedAt":"2005-05-13T06:49:25Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This series makes the following changes:\n\n 1: Adds support for having the C code know about the general existance of\n    .git/refs, and functions for writing these files.\n 2: Adds support in the generic pull code for fetching refs (and dummy\n    implementations).\n 3: Adds support in the HTTP pull code for fetching refs\n 4: Adds support in the rsh pull code for fetching refs; this requires\n    changes to the protocol. These changes should be sufficient to support\n    any future extension, however.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3232","messageId":"Pine.LNX.4.21.0505130249390.30848-100000@iabervon.org","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","subject":"[PATCH 1/4] Support for refs directory","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-13T06:53:12Z","receivedAt":"2005-05-13T06:53:12Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Add support for reading and writing files in the refs directory.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\nIndex: Makefile\n===================================================================\n--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/Makefile  (mode:100644 sha1:6afcb3e867a6857f9128dba877e433c12366c1f4)\n+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/Makefile  (mode:100644 sha1:653912b7290d1a28860db41f602fbf15ca2d9aa5)\n@@ -36,9 +36,10 @@\n \t$(INSTALL) $(PROG) $(SCRIPTS) $(dest)$(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--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/cache.h  (mode:100644 sha1:c06b94107e0e1149be0ad642812e8d4a42f2193c)\n+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/cache.h  (mode:100644 sha1:ca9d13a972e05d8d0aa15babd5a963688fdd5968)\n@@ -110,8 +110,10 @@\n #define GIT_DIR_ENVIRONMENT \"GIT_DIR\"\n #define DEFAULT_GIT_DIR_ENVIRONMENT \".git\"\n #define DB_ENVIRONMENT \"GIT_OBJECT_DIRECTORY\"\n+#define REFS_ENVIRONMENT \"GIT_REFS_DIRECTORY\"\n #define INDEX_ENVIRONMENT \"GIT_INDEX_FILE\"\n \n+extern char *get_refs_directory(void);\n extern char *get_object_directory(void);\n extern char *get_index_file(void);\n \nIndex: init-db.c\n===================================================================\n--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/init-db.c  (mode:100644 sha1:b6bb78356762bd28261949da54638f46776e6d4b)\n+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/init-db.c  (mode:100644 sha1:3441a35d7c2eb88e76db4886e8c068ca898ea8fd)\n@@ -40,6 +40,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:2a5e43fa9318a648bfb4dbf64208f4c26905a5f8)\n+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/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:2a5e43fa9318a648bfb4dbf64208f4c26905a5f8)\n+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/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 */\nIndex: sha1_file.c\n===================================================================\n--- 2a5e43fa9318a648bfb4dbf64208f4c26905a5f8/sha1_file.c  (mode:100644 sha1:942b673dc3c7fa9f057c5c452e3a1b73eaeb8707)\n+++ adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/sha1_file.c  (mode:100644 sha1:a3ab45fbb39f37622ae191fe5c3cbaf30389ec74)\n@@ -59,7 +59,7 @@\n \treturn get_sha1_hex(buffer, result);\n }\n \n-static char *git_dir, *git_object_dir, *git_index_file;\n+static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir;\n static void setup_git_env(void)\n {\n \tgit_dir = gitenv(GIT_DIR_ENVIRONMENT);\n@@ -70,6 +70,11 @@\n \t\tgit_object_dir = xmalloc(strlen(git_dir) + 9);\n \t\tsprintf(git_object_dir, \"%s/objects\", git_dir);\n \t}\n+\tgit_refs_dir = gitenv(REFS_ENVIRONMENT);\n+\tif (!git_refs_dir) {\n+\t\tgit_refs_dir = xmalloc(strlen(git_dir) + 6);\n+\t\tsprintf(git_refs_dir, \"%s/refs\", git_dir);\n+\t}\n \tgit_index_file = gitenv(INDEX_ENVIRONMENT);\n \tif (!git_index_file) {\n \t\tgit_index_file = xmalloc(strlen(git_dir) + 7);\n@@ -91,6 +96,13 @@\n \treturn git_index_file;\n }\n \n+char *get_refs_directory(void)\n+{\n+\tif (!git_refs_dir)\n+\t\tsetup_git_env();\n+\treturn git_refs_dir;\n+}\n+\n int get_sha1(const char *str, unsigned char *sha1)\n {\n \tstatic char pathname[PATH_MAX];\n\n"},{"id":"3233","messageId":"Pine.LNX.4.21.0505130253160.30848-100000@iabervon.org","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","subject":"[PATCH 2/4] Generic support for pulling refs","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-13T06:56:08Z","receivedAt":"2005-05-13T06:56:08Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This adds a pull method to pull refs, provides dummy implementations for\nthe existing programs, and uses that method to try to get refs if\nrequested. It also adds generic support for writing the target to a refs\nfile.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\nIndex: http-pull.c\n===================================================================\n--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/http-pull.c  (mode:100644 sha1:024457a9895ab10c4ef18aa6e232d12fdaab4da9)\n+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/http-pull.c  (mode:100644 sha1:af4e82fdf9c58a15564d40bef85d57e9f6626727)\n@@ -98,6 +98,11 @@\n \treturn 0;\n }\n \n+int fetch_ref(char *dir, char *name, unsigned char *sha1)\n+{\n+\treturn -1;\n+}\n+\n int main(int argc, char **argv)\n {\n \tchar *commit_id;\nIndex: local-pull.c\n===================================================================\n--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/local-pull.c  (mode:100644 sha1:3a342ab18390d7ce0df1f970a4961b31548a9417)\n+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/local-pull.c  (mode:100644 sha1:73aad965d0b190627aa95726e4feaa2623d31d26)\n@@ -18,6 +18,11 @@\n \n static char *path;\n \n+int fetch_ref(char *dir, char *name, unsigned char *sha1)\n+{\n+\treturn -1;\n+}\n+\n int fetch(unsigned char *sha1)\n {\n \tstatic int object_name_start = -1;\nIndex: pull.c\n===================================================================\n--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/pull.c  (mode:100644 sha1:0bed44f4cbf6716cfc3152f35626123992766408)\n+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/pull.c  (mode:100644 sha1:d4d858cd638e915096a408ba3c37090a1b460c21)\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@@ -98,16 +104,52 @@\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 (make_sure_we_have_it(NULL, sha1))\n+\t\treturn -1;\n+\tobj = parse_object(sha1);\n+\tif (obj->type == commit_type) {\n+\t\tmemcpy(current_commit_sha1, sha1, 20);\n+\t\treturn process_commit(sha1);\n+\t} else 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-\tif (retval)\n-\t\treturn retval;\n-\tretval = make_sure_we_have_it(commitS, 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 = process_unknown(sha1);\n \tif (retval)\n \t\treturn retval;\n-\tmemcpy(current_commit_sha1, sha1, 20);\n-\treturn process_commit(sha1);\n+\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--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/pull.h  (mode:100644 sha1:d2dca02de7c23426e84e9f63762df9428933e8d8)\n+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/pull.h  (mode:100644 sha1:de0e9245b68856bcf84c033650b6b3eb151641e2)\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--- adc28203a55e7e9d3c0b4f6546ea0c2b99106f24/rpull.c  (mode:100644 sha1:b48e63157c66c160b9751603a92831f77106044c)\n+++ 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/rpull.c  (mode:100644 sha1:493fcdae670ebb1d93b8c75d3e28798e060d7537)\n@@ -22,6 +22,11 @@\n \treturn ret;\n }\n \n+int fetch_ref(char *dir, char *name, unsigned char *sha1)\n+{\n+\treturn -1;\n+}\n+\n int main(int argc, char **argv)\n {\n \tchar *commit_id;\n\n"},{"id":"3234","messageId":"Pine.LNX.4.21.0505130256150.30848-100000@iabervon.org","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","subject":"[PATCH 3/4] Pull refs by HTTP","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-13T06:57:58Z","receivedAt":"2005-05-13T06:57:58Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Adds support for pulling refs by HTTP, and an option for writing the\npulled ref to a file.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\nIndex: http-pull.c\n===================================================================\n--- 90e05f81df7b7fd2c39d252b6f9a2374d4dd0cf5/http-pull.c  (mode:100644 sha1:af4e82fdf9c58a15564d40bef85d57e9f6626727)\n+++ 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/http-pull.c  (mode:100644 sha1:6e8dc48ddd0ea1ae89074f6ae0d89c54303895b7)\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@@ -93,14 +112,42 @@\n \t\tunlink(filename);\n \t\treturn error(\"File %s has bad hash\\n\", hex);\n \t}\n-\t\n \tpull_say(\"got %s\\n\", hex);\n \treturn 0;\n }\n \n int fetch_ref(char *dir, char *name, unsigned char *sha1)\n {\n-\treturn -1;\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@@ -120,6 +167,10 @@\n \t\t\tget_history = 1;\n \t\t} else if (argv[arg][1] == 'v') {\n \t\t\tget_verbosely = 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}\n\n"},{"id":"3235","messageId":"Pine.LNX.4.21.0505130258030.30848-100000@iabervon.org","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","subject":"[PATCH 4/4] Pulling refs by ssh","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-13T07:01:12Z","receivedAt":"2005-05-13T07:01:12Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Adds support for pulling refs by rsh.\n\nThis changes the rsh protocol to allow requests for different things, and\nto allow the server to report that it doesn't have something without\nbreaking the connection.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\nIndex: rpull.c\n===================================================================\n--- 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/rpull.c  (mode:100644 sha1:493fcdae670ebb1d93b8c75d3e28798e060d7537)\n+++ a219d8e31f3882aaa32e7dbac7a1f92b35a9dbff/rpull.c  (mode:100644 sha1:cce9e71becc95f728d320ef49e11a647a420b75d)\n@@ -8,6 +8,7 @@\n #include <stdio.h>\n #include \"rsh.h\"\n #include \"pull.h\"\n+#include \"refs.h\"\n \n static int fd_in;\n static int fd_out;\n@@ -15,16 +16,34 @@\n int fetch(unsigned char *sha1)\n {\n \tint ret;\n+\tsigned char remote;\n+\tchar type = 'o';\n+\tif (has_sha1_file(sha1))\n+\t\treturn 0;\n+\twrite(fd_out, &type, 1);\n \twrite(fd_out, sha1, 20);\n+\tif (read(fd_in, &remote, 1) < 1)\n+\t\treturn -1;\n+\tif (remote < 0)\n+\t\treturn remote;\n \tret = write_sha1_from_fd(sha1, fd_in);\n \tif (!ret)\n \t\tpull_say(\"got %s\\n\", sha1_to_hex(sha1));\n \treturn ret;\n }\n \n-int fetch_ref(char *dir, char *name, unsigned char *sha1)\n+int fetch_ref(char *name, char *dir, unsigned char *sha1)\n {\n-\treturn -1;\n+\tsigned char remote;\n+\tchar type = 'r';\n+\twrite(fd_out, &type, 1);\n+\twrite(fd_out, name, strlen(name) + 1);\n+\twrite(fd_out, dir, strlen(dir) + 1);\n+\tread(fd_in, &remote, 1);\n+\tif (remote < 0)\n+\t\treturn remote;\n+\tread(fd_in, sha1, 20);\n+\treturn 0;\n }\n \n int main(int argc, char **argv)\n@@ -44,6 +63,10 @@\n \t\t\tget_history = 1;\n \t\t} else if (argv[arg][1] == 'v') {\n \t\t\tget_verbosely = 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: rpush.c\n===================================================================\n--- 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/rpush.c  (mode:100644 sha1:26518846704ecf63ad00390599b251aa1b32713e)\n+++ a219d8e31f3882aaa32e7dbac7a1f92b35a9dbff/rpush.c  (mode:100644 sha1:c3cad4eac186307e743eacb913a0b382a455d1f4)\n@@ -2,47 +2,98 @@\n #include \"rsh.h\"\n #include <sys/socket.h>\n #include <errno.h>\n+#include \"refs.h\"\n \n-void service(int fd_in, int fd_out) {\n+int serve_object(int fd_in, int fd_out) {\n \tssize_t size;\n-\tint posn;\n+\tint posn = 0;\n \tchar sha1[20];\n \tunsigned long objsize;\n \tvoid *buf;\n+\tsigned char remote;\n \tdo {\n-\t\tposn = 0;\n-\t\tdo {\n-\t\t\tsize = read(fd_in, sha1 + posn, 20 - posn);\n-\t\t\tif (size < 0) {\n-\t\t\t\tperror(\"rpush: read \");\n-\t\t\t\treturn;\n+\t\tsize = read(fd_in, sha1 + posn, 20 - posn);\n+\t\tif (size < 0) {\n+\t\t\tperror(\"rpush: read \");\n+\t\t\treturn -1;\n+\t\t}\n+\t\tif (!size)\n+\t\t\treturn -1;\n+\t\tposn += size;\n+\t} while (posn < 20);\n+\t\n+\t/* fprintf(stderr, \"Serving %s\\n\", sha1_to_hex(sha1)); */\n+\tremote = 0;\n+\t\n+\tbuf = map_sha1_file(sha1, &objsize);\n+\t\n+\tif (!buf) {\n+\t\tfprintf(stderr, \"rpush: could not find %s\\n\", \n+\t\t\tsha1_to_hex(sha1));\n+\t\tremote = -1;\n+\t}\n+\t\n+\twrite(fd_out, &remote, 1);\n+\t\n+\tif (remote < 0)\n+\t\treturn 0;\n+\t\n+\tposn = 0;\n+\tdo {\n+\t\tsize = write(fd_out, buf + posn, objsize - posn);\n+\t\tif (size <= 0) {\n+\t\t\tif (!size) {\n+\t\t\t\tfprintf(stderr, \"rpush: write closed\");\n+\t\t\t} else {\n+\t\t\t\tperror(\"rpush: write \");\n \t\t\t}\n-\t\t\tif (!size)\n-\t\t\t\treturn;\n-\t\t\tposn += size;\n-\t\t} while (posn < 20);\n+\t\t\treturn -1;\n+\t\t}\n+\t\tposn += size;\n+\t} while (posn < objsize);\n+\treturn 0;\n+}\n \n-\t\t/* fprintf(stderr, \"Serving %s\\n\", sha1_to_hex(sha1)); */\n+int serve_ref(int fd_in, int fd_out)\n+{\n+\tchar dir[PATH_MAX], name[PATH_MAX];\n+\tunsigned char sha1[20];\n+\tint posn = 0;\n+\tsigned char remote = 0;\n+\tdo {\n+\t\tif (read(fd_in, dir + posn, 1) < 1)\n+\t\t\treturn -1;\n+\t\tposn++;\n+\t} while (dir[posn - 1]);\n+\tposn = 0;\n+\tdo {\n+\t\tif (read(fd_in, name + posn, 1) < 1)\n+\t\t\treturn -1;\n+\t\tposn++;\n+\t} while (name[posn - 1]);\n+\tif (get_split_ref_sha1(dir, name, sha1))\n+\t\tremote = -1;\n+\twrite(fd_out, &remote, 1);\n+\tif (remote)\n+\t\treturn 0;\n+\twrite(fd_out, sha1, 20);\n+\treturn 0;\n+}\n \n-\t\tbuf = map_sha1_file(sha1, &objsize);\n-\t\tif (!buf) {\n-\t\t\tfprintf(stderr, \"rpush: could not find %s\\n\", \n-\t\t\t\tsha1_to_hex(sha1));\n+void service(int fd_in, int fd_out) {\n+\tchar type;\n+\tint retval;\n+\tdo {\n+\t\tretval = read(fd_in, &type, 1);\n+\t\tif (retval < 1) {\n+\t\t\tif (retval < 0)\n+\t\t\t\tperror(\"rpush: read \");\n \t\t\treturn;\n \t\t}\n-\t\tposn = 0;\n-\t\tdo {\n-\t\t\tsize = write(fd_out, buf + posn, objsize - posn);\n-\t\t\tif (size <= 0) {\n-\t\t\t\tif (!size) {\n-\t\t\t\t\tfprintf(stderr, \"rpush: write closed\");\n-\t\t\t\t} else {\n-\t\t\t\t\tperror(\"rpush: write \");\n-\t\t\t\t}\n-\t\t\t\treturn;\n-\t\t\t}\n-\t\t\tposn += size;\n-\t\t} while (posn < objsize);\n+\t\tif (type == 'o' && serve_object(fd_in, fd_out))\n+\t\t\treturn;\n+\t\tif (type == 'r' && serve_ref(fd_in, fd_out))\n+\t\t\treturn;\n \t} while (1);\n }\n \n@@ -53,6 +104,8 @@\n         char *url;\n \tint fd_in, fd_out;\n \twhile (arg < argc && argv[arg][0] == '-') {\n+\t\tif (argv[arg][1] == 'w')\n+\t\t\targ++;\n                 arg++;\n         }\n         if (argc < arg + 2) {\nIndex: rsh.c\n===================================================================\n--- 4931f2d8b9c2ab83718f6446d5ef3af5fa320b3f/rsh.c  (mode:100644 sha1:5d1cb9d578a8e679fc190a9d7d2c842ad811223f)\n+++ a219d8e31f3882aaa32e7dbac7a1f92b35a9dbff/rsh.c  (mode:100644 sha1:192d8f67e9a5e2bf7bb9e14c8c037dff49e74d57)\n@@ -36,8 +36,8 @@\n \t*(path++) = '\\0';\n \t/* ssh <host> 'cd /<path>; stdio-pull <arg...> <commit-id>' */\n \tsnprintf(command, COMMAND_SIZE, \n-\t\t \"cd /%s; %s=objects %s\",\n-\t\t path, DB_ENVIRONMENT, remote_prog);\n+\t\t \"cd /%s; GIT_DIR=. %s\",\n+\t\t path, remote_prog);\n \tposn = command + strlen(command);\n \tfor (i = 0; i < rmt_argc; i++) {\n \t\t*(posn++) = ' ';\n\n"},{"id":"3241","messageId":"20050513131531.4317677b.froese@gmx.de","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130256150.30848-100000@iabervon.org","subject":"Re: [PATCH 3/4] Pull refs by HTTP","fromName":"Edgar Toernig","fromEmail":"froese@gmx.de","sentAt":"2005-05-13T11:15:31Z","receivedAt":"2005-05-13T11:15:31Z","isPatch":true,"sender":{"key":"froese@gmx.de","avatar":null},"body":"Daniel Barkalow wrote:\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\nHave you ever heard of sprintf & co?\n\n\tsprintf(url, \"%srefs/%s/%s\", base, dir, name);\n\nCiao, ET.\n"},{"id":"3250","messageId":"4284F909.9000309@zytor.com","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130258030.30848-100000@iabervon.org","subject":"Re: [PATCH 4/4] Pulling refs by ssh","fromName":"H. Peter Anvin","fromEmail":"hpa@zytor.com","sentAt":"2005-05-13T18:59:21Z","receivedAt":"2005-05-13T18:59:21Z","isPatch":true,"sender":{"key":"hpa@zytor.com","avatar":null},"body":"Daniel Barkalow wrote:\n> Adds support for pulling refs by rsh.\n> \n> This changes the rsh protocol to allow requests for different things, and\n> to allow the server to report that it doesn't have something without\n> breaking the connection.\n> \n\nUse && rather than semicolon, and make sure you quote things that need \nto be quoted.\n\n\t-hpa\n"},{"id":"3252","messageId":"20050513221935.GC32232@pasky.ji.cz","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-05-13T22:19:35Z","receivedAt":"2005-05-13T22:19:35Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Fri, May 13, 2005 at 08:49:25AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> This series makes the following changes:\n> \n>  1: Adds support for having the C code know about the general existance of\n>     .git/refs, and functions for writing these files.\n>  2: Adds support in the generic pull code for fetching refs (and dummy\n>     implementations).\n>  3: Adds support in the HTTP pull code for fetching refs\n>  4: Adds support in the rsh pull code for fetching refs; this requires\n>     changes to the protocol. These changes should be sufficient to support\n>     any future extension, however.\n\nHmm, I've honestly expected something different - a generic way to\nspecify any file in the repository to be pulled along, instead of a\nintroducing refs awareness at this level of git. What would be the\nadvantages of that approach against just specifying list of other files\nto pull along?\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"3264","messageId":"Pine.LNX.4.21.0505131853020.30848-100000@iabervon.org","threadId":"600","inReplyTo":"20050513221935.GC32232@pasky.ji.cz","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-13T23:14:22Z","receivedAt":"2005-05-13T23:14:22Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 14 May 2005, Petr Baudis wrote:\n\n> Hmm, I've honestly expected something different - a generic way to\n> specify any file in the repository to be pulled along, instead of a\n> introducing refs awareness at this level of git. What would be the\n> advantages of that approach against just specifying list of other files\n> to pull along?\n\nThe point is to specify the commit to pull by fetching a file from the\nother side, not just to move a file. So you need to be specifying that the\nfile is a hex encoding of the sha1 hash of the starting point of the pull,\nand the refs/ area is where these are expected to be. (Note that it still\ndoesn't have any knowledge about the meanings of files in refs/; you tell\nit which one you want to use, and optionally which one you want to write\nto, and it will use the names you provide).\n\nIt wouldn't help much to download the head file if you had to know the\ncontents of that file already in order to do everything as a single\ntransfer.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3267","messageId":"20050513233738.GL32232@pasky.ji.cz","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505131853020.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-05-13T23:37:39Z","receivedAt":"2005-05-13T23:37:39Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sat, May 14, 2005 at 01:14:22AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> On Sat, 14 May 2005, Petr Baudis wrote:\n> \n> > Hmm, I've honestly expected something different - a generic way to\n> > specify any file in the repository to be pulled along, instead of a\n> > introducing refs awareness at this level of git. What would be the\n> > advantages of that approach against just specifying list of other files\n> > to pull along?\n> \n> The point is to specify the commit to pull by fetching a file from the\n> other side, not just to move a file. So you need to be specifying that the\n> file is a hex encoding of the sha1 hash of the starting point of the pull,\n> and the refs/ area is where these are expected to be. (Note that it still\n> doesn't have any knowledge about the meanings of files in refs/; you tell\n> it which one you want to use, and optionally which one you want to write\n> to, and it will use the names you provide).\n> \n> It wouldn't help much to download the head file if you had to know the\n> contents of that file already in order to do everything as a single\n> transfer.\n\nSo what about just something like\n\n\tgit-wormhole-pull remote:refs/head/master wormhole://localhost/\n\nThat is, you could just specify remote:path_relative_to_url instead of\nSHA1 id as the commit.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"3337","messageId":"Pine.LNX.4.21.0505142306021.30848-100000@iabervon.org","threadId":"600","inReplyTo":"20050513233738.GL32232@pasky.ji.cz","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-15T03:23:18Z","receivedAt":"2005-05-15T03:23:18Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 14 May 2005, Petr Baudis wrote:\n\n> So what about just something like\n> \n> \tgit-wormhole-pull remote:refs/head/master wormhole://localhost/\n> \n> That is, you could just specify remote:path_relative_to_url instead of\n> SHA1 id as the commit.\n\nDo you have any sensible alternatives to \"remote:refs/<something>\" in\nmind? I suppose that \"remote:HEAD\" would also work. How are you thinking\nof having the value get written locally?\n\nDo you also have some idea for user-invoked rpush? It has to call\nsomething that writes the value on the other side (and I'd ideally like it\nto do the update atomically and locked against other clients). This series\nuses the same mechanism to write it that it uses to write hashes fetched\nfrom remote machines.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3341","messageId":"7v4qd5xdby.fsf@assigned-by-dhcp.cox.net","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505130245260.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-05-15T05:33:53Z","receivedAt":"2005-05-15T05:33:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"I am having a bit hard time understanding how the end user uses\nwhat you are trying to give them.  Is the basic idea to let them\nsay \"I want to get Pasky's $GIT_DIR/refs/heads/master and store\nit in my $GIT_DIR/refs/heads/git-pb, and then I want to start\nthe pull starting from the commit recorded in that ref\"?\n\nAssuming that is what you are doing, I do not have much\nobjection to it.  I however think introducing REFS_ENVIRONMENT\nis going overboard.\n\nMy understanding of the definition of GIT_DIR is \"the directory\ntraditionally known as $(pwd)/.git/ where various things hang\nunderneath\".  We have GIT_OBJECT_DIRECTORY configurable to be\nset to something other than $GIT_DIR/objects because people may\nwant to use shared object pools.  We have GIT_INDEX_FILE\nconfigurable to be set to something other than $GIT_DIR/index\nbecause being able to have it on tmp filesystem for some\napplication (like \"merge my head and his head without using what\nI have in my work dir which is a bit ahead of my head already\")\nhelps performance; also some Porcelain operations benefit from\nbeing able to switch between multiple cache files.  I cannot\nthink of a similar argument with an example use pattern that\njustifies REFS_ENVIRONMENT being set to anything other than\n$GIT_DIR/refs/.\n\n"},{"id":"3362","messageId":"Pine.LNX.4.21.0505151129200.30848-100000@iabervon.org","threadId":"600","inReplyTo":"7v4qd5xdby.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-15T15:40:52Z","receivedAt":"2005-05-15T15:40:52Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Sat, 14 May 2005, Junio C Hamano wrote:\n\n> I am having a bit hard time understanding how the end user uses\n> what you are trying to give them.  Is the basic idea to let them\n> say \"I want to get Pasky's $GIT_DIR/refs/heads/master and store\n> it in my $GIT_DIR/refs/heads/git-pb, and then I want to start\n> the pull starting from the commit recorded in that ref\"?\n\nYes. This would be: git-http-pull -w heads/git-pb heads/master\nhttp://www.kernel.org/pub/scm/cogito/git-pb.git/\n\n> Assuming that is what you are doing, I do not have much\n> objection to it.  I however think introducing REFS_ENVIRONMENT\n> is going overboard.\n\nNow that we have GIT_DIR, you're probably right. I mainly kept it there\nfor symmetry. On the other hand, I think that, if you're using a shared\nobjects directory, you want to also use a shared refs directory, or you'll\nnever be able to identify unreachable objects accurately.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3364","messageId":"Pine.LNX.4.21.0505151146540.30848-100000@iabervon.org","threadId":"600","inReplyTo":"4284F909.9000309@zytor.com","subject":"Re: [PATCH 4/4] Pulling refs by ssh","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-15T15:48:30Z","receivedAt":"2005-05-15T15:48:30Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Fri, 13 May 2005, H. Peter Anvin wrote:\n\n> Use && rather than semicolon, and make sure you quote things that need \n> to be quoted.\n\nThis is a separate issue from the change for refs; could you send a patch\nthat quotes things properly? The \"cd\" should be unnecessary now that we\nhave the GIT_DIR environment variable.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3408","messageId":"7v4qd3pptd.fsf@assigned-by-dhcp.cox.net","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505151129200.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-05-16T07:55:58Z","receivedAt":"2005-05-16T07:55:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"DB\" == Daniel Barkalow <barkalow@iabervon.org> writes:\n\nDB> On Sat, 14 May 2005, Junio C Hamano wrote:\n>> I am having a bit hard time understanding how the end user uses\n>> what you are trying to give them.  Is the basic idea to let them\n>> say \"I want to get Pasky's $GIT_DIR/refs/heads/master and store\n>> it in my $GIT_DIR/refs/heads/git-pb, and then I want to start\n>> the pull starting from the commit recorded in that ref\"?\n\nDB> Yes. This would be: git-http-pull -w heads/git-pb heads/master\nDB> http://www.kernel.org/pub/scm/cogito/git-pb.git/\n\nThat would be quite handy.  IIRC, Pasky had a gripe about\nlimiting this under refs hierarchy (that's why you can write\n\"heads/master\" in your example not \"refs/heads/master\", though),\nand I am sympathetic to it.  Giving unlimited download access\nanywhere under foobar.git/ would be fine.  About the receiving\nside, letting things to be written anywhere the user wants would\nalso be fine.\n\nSince this will all be scripted anyway, I do not mind if the\nabove example needs to be spelled as:\n\n $ git-http-pull -w ${GIT_DIR-.git}/refs/heads/git-pb refs/heads/master \\\n   http://www.kernel.org/pub/scm/cogito/git-pb.git/\n\n"},{"id":"3464","messageId":"20050517201436.GC7136@pasky.ji.cz","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505142306021.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-05-17T20:14:36Z","receivedAt":"2005-05-17T20:14:36Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Sun, May 15, 2005 at 05:23:18AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> On Sat, 14 May 2005, Petr Baudis wrote:\n> \n> > So what about just something like\n> > \n> > \tgit-wormhole-pull remote:refs/head/master wormhole://localhost/\n> > \n> > That is, you could just specify remote:path_relative_to_url instead of\n> > SHA1 id as the commit.\n> \n> Do you have any sensible alternatives to \"remote:refs/<something>\" in\n> mind? I suppose that \"remote:HEAD\" would also work. How are you thinking\n> of having the value get written locally?\n\nAnything that gets eventually wound up in the info/ directory. (The name\nof the ignore file saved in info/ignore is the current hit.)\n\n> Do you also have some idea for user-invoked rpush? It has to call\n> something that writes the value on the other side (and I'd ideally like it\n> to do the update atomically and locked against other clients). This series\n> uses the same mechanism to write it that it uses to write hashes fetched\n> from remote machines.\n\nWell, it'd be again nice to have some generic mechanism for this so that\nthe user could theoretically push over rsync too or something (although\nthat'll be even more racy, it is fine for single-user repository).\n\nI think the remote file to write the value inside should be porcelain\nbusiness. What you should always check though is that before the pull\n(and after the locking) the value in that file is the same as the \"push\nbase\". This way you make sure that you are still following a single\nbranch and in case of multiuser repositories that you were fully merged\nbefore pushing.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"3471","messageId":"Pine.LNX.4.21.0505171645130.30848-100000@iabervon.org","threadId":"600","inReplyTo":"20050517201436.GC7136@pasky.ji.cz","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-17T21:20:54Z","receivedAt":"2005-05-17T21:20:54Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 17 May 2005, Petr Baudis wrote:\n\n> Dear diary, on Sun, May 15, 2005 at 05:23:18AM CEST, I got a letter\n> where Daniel Barkalow <barkalow@iabervon.org> told me that...\n> > On Sat, 14 May 2005, Petr Baudis wrote:\n> > \n> > > So what about just something like\n> > > \n> > > \tgit-wormhole-pull remote:refs/head/master wormhole://localhost/\n> > > \n> > > That is, you could just specify remote:path_relative_to_url instead of\n> > > SHA1 id as the commit.\n> > \n> > Do you have any sensible alternatives to \"remote:refs/<something>\" in\n> > mind? I suppose that \"remote:HEAD\" would also work. How are you thinking\n> > of having the value get written locally?\n> \n> Anything that gets eventually wound up in the info/ directory. (The name\n> of the ignore file saved in info/ignore is the current hit.)\n\nHmm... maybe the right thing is to make the implementation-provided\ntransfer code handle arbitrary things in GIT_DIR, but have code for\nupdating reference files atomically and using a reference file to start\nfrom use \"refs/\"? Certainly, there's nothing special about reference files\nin transit.\n\nCertainly the things in the info/ directory shouldn't be treated a head\nthat you're going to pull, so that has to be different above the protocol\nlevel anyway.\n\n> Well, it'd be again nice to have some generic mechanism for this so that\n> the user could theoretically push over rsync too or something (although\n> that'll be even more racy, it is fine for single-user repository).\n\nHmm; I'm not sure what would be good for interfacing with rsync.\n\n> I think the remote file to write the value inside should be porcelain\n> business.\n\nCertainly it's porcelain business what remote file to write; but I think\nit has to be core business doing the lock, test, and update. I think it\nwould be inconvenient to go back to the porcelain layer in the middle of\nthe operation, particularly since it would have to go back to the core,\nwhich is what has the connection to the remote host.\n\n> What you should always check though is that before the pull\n> (and after the locking) the value in that file is the same as the \"push\n> base\". This way you make sure that you are still following a single\n> branch and in case of multiuser repositories that you were fully merged\n> before pushing.\n\nSo the remote receiver should get an instruction: change X from OLD to NEW\nand pull NEW. It should:\n\n - lock the file against further updates\n - check that the current value is the provided OLD\n - pull the necessary objects\n - write NEW to the file\n - report success\n\nOn failure of any step, it should unlock the file without changing it.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3479","messageId":"20050517214533.GP7136@pasky.ji.cz","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505171645130.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-05-17T21:45:33Z","receivedAt":"2005-05-17T21:45:33Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Tue, May 17, 2005 at 11:20:54PM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> On Tue, 17 May 2005, Petr Baudis wrote:\n> > Anything that gets eventually wound up in the info/ directory. (The name\n> > of the ignore file saved in info/ignore is the current hit.)\n> \n> Hmm... maybe the right thing is to make the implementation-provided\n> transfer code handle arbitrary things in GIT_DIR, but have code for\n> updating reference files atomically and using a reference file to start\n> from use \"refs/\"? Certainly, there's nothing special about reference files\n> in transit.\n> \n> Certainly the things in the info/ directory shouldn't be treated a head\n> that you're going to pull, so that has to be different above the protocol\n> level anyway.\n\n*confused* :) I'm sorry, I have trouble understanding this. Could you\nrephrase, please?\n\n> > Well, it'd be again nice to have some generic mechanism for this so that\n> > the user could theoretically push over rsync too or something (although\n> > that'll be even more racy, it is fine for single-user repository).\n> \n> Hmm; I'm not sure what would be good for interfacing with rsync.\n\nI've been thinking about writing some FTP-like client for rsync, where\nyou could \"interactively\" tell it what files to download etc.\n\n> > I think the remote file to write the value inside should be porcelain\n> > business.\n> \n> Certainly it's porcelain business what remote file to write; but I think\n> it has to be core business doing the lock, test, and update. I think it\n> would be inconvenient to go back to the porcelain layer in the middle of\n> the operation, particularly since it would have to go back to the core,\n> which is what has the connection to the remote host.\n\nOf course. The porcelain file would just provide the filename.\n\n> > What you should always check though is that before the pull\n> > (and after the locking) the value in that file is the same as the \"push\n> > base\". This way you make sure that you are still following a single\n> > branch and in case of multiuser repositories that you were fully merged\n> > before pushing.\n> \n> So the remote receiver should get an instruction: change X from OLD to NEW\n> and pull NEW. It should:\n> \n>  - lock the file against further updates\n>  - check that the current value is the provided OLD\n>  - pull the necessary objects\n>  - write NEW to the file\n- unlock the file ;-))\n>  - report success\n> \n> On failure of any step, it should unlock the file without changing it.\n\nSounds right.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"3481","messageId":"Pine.LNX.4.21.0505171802570.30848-100000@iabervon.org","threadId":"600","inReplyTo":"20050517214533.GP7136@pasky.ji.cz","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-17T22:20:40Z","receivedAt":"2005-05-17T22:20:40Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 17 May 2005, Petr Baudis wrote:\n\n> Dear diary, on Tue, May 17, 2005 at 11:20:54PM CEST, I got a letter\n> where Daniel Barkalow <barkalow@iabervon.org> told me that...\n> > Hmm... maybe the right thing is to make the implementation-provided\n> > transfer code handle arbitrary things in GIT_DIR, but have code for\n> > updating reference files atomically and using a reference file to start\n> > from use \"refs/\"? Certainly, there's nothing special about reference files\n> > in transit.\n> > \n> > Certainly the things in the info/ directory shouldn't be treated a head\n> > that you're going to pull, so that has to be different above the protocol\n> > level anyway.\n> \n> *confused* :) I'm sorry, I have trouble understanding this. Could you\n> rephrase, please?\n\nIf you want to get info/ignore, you want to get it and save it, not\ndownload a set of objects it refers to. So it's different from specifying\nthat you want to use refs/heads/master as the starting point for a pull.\n\nThere would be a separation between transfering whatever file you specify\nand treating the specified (remote) file from refs/ as the starting point\nfor pulling objects.\n\nAlso, you don't need to do the same kind of careful update, since the\ndesired value of info/ignore isn't going to depend on the previous\nvalue.\n\n> > So the remote receiver should get an instruction: change X from OLD to NEW\n> > and pull NEW. It should:\n> > \n> >  - lock the file against further updates\n> >  - check that the current value is the provided OLD\n> >  - pull the necessary objects\n> >  - write NEW to the file\n> - unlock the file ;-))\n\nThe way I'm actually doing things is to write NEW into the lock file at\nsome arbitrary point, and \"writing to the file\" is actually renaming the\nlock file to the normal filename. So writing unlocks the file\nautomatically.\n\n> >  - report success\n> > \n> > On failure of any step, it should unlock the file without changing it.\n> \n> Sounds right.\n\nI think I'll get to implementing it Wednesday night. I might be able to\nget the first step done tonight (my previous patch, except with the\ntransfer applying to arbitrary files).\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3518","messageId":"20050518213529.GE10358@pasky.ji.cz","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505171802570.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-05-18T21:35:29Z","receivedAt":"2005-05-18T21:35:29Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Wed, May 18, 2005 at 12:20:40AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n> On Tue, 17 May 2005, Petr Baudis wrote:\n> \n> > Dear diary, on Tue, May 17, 2005 at 11:20:54PM CEST, I got a letter\n> > where Daniel Barkalow <barkalow@iabervon.org> told me that...\n> > > Hmm... maybe the right thing is to make the implementation-provided\n> > > transfer code handle arbitrary things in GIT_DIR, but have code for\n> > > updating reference files atomically and using a reference file to start\n> > > from use \"refs/\"? Certainly, there's nothing special about reference files\n> > > in transit.\n> > > \n> > > Certainly the things in the info/ directory shouldn't be treated a head\n> > > that you're going to pull, so that has to be different above the protocol\n> > > level anyway.\n> > \n> > *confused* :) I'm sorry, I have trouble understanding this. Could you\n> > rephrase, please?\n> \n> If you want to get info/ignore, you want to get it and save it, not\n> download a set of objects it refers to. So it's different from specifying\n> that you want to use refs/heads/master as the starting point for a pull.\n\nObviously. I think you should need to \"explicitly\" tell pull to actually\nsave any files locally, since you (I mean Cogito) certainly does not\nwant the pull stuff to touch the local refs/heads/master - it wants it\nin some other file.\n\n> > > So the remote receiver should get an instruction: change X from OLD to NEW\n> > > and pull NEW. It should:\n> > > \n> > >  - lock the file against further updates\n> > >  - check that the current value is the provided OLD\n> > >  - pull the necessary objects\n> > >  - write NEW to the file\n> > - unlock the file ;-))\n> \n> The way I'm actually doing things is to write NEW into the lock file at\n> some arbitrary point, and \"writing to the file\" is actually renaming the\n> lock file to the normal filename. So writing unlocks the file\n> automatically.\n\nAh. Obviously. That makes sense. :-)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"3531","messageId":"Pine.LNX.4.21.0505182259060.30848-100000@iabervon.org","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505171802570.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-19T03:19:01Z","receivedAt":"2005-05-19T03:19:01Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 17 May 2005, Daniel Barkalow wrote:\n\n> I think I'll get to implementing it Wednesday night. I might be able to\n> get the first step done tonight (my previous patch, except with the\n> transfer applying to arbitrary files).\n\nUpon further consideration, I think there are three things that pull\nimplementation needs to handle:\n\n 1) fetching object files by hash, validating them, and writing them to\n    the local objects directory\n 2) fetching reference files by name, and making them available to the\n    local program without writing them to disk at all.\n 3) fetching other files by name and writing them to either the\n    corresponding filename or a provided replacement.\n\nI had thought that (2) could be done as a special case of (3), but I think\nthat it has to be separate, because (2) just returns the value, while\n(3) can't just return the contents, but has to write it somewhere, since\nit isn't constrained to be exactly 20 bytes.\n\nSo I think I'd like to do essentially the original series, slightly\nrearranged and with a few edits, and then add (3) afterwards; this should\nbe easy once the rpush/rpull changes to make the protocol extensible are\nin place.\n\nI'll also do additional (independant) patches to provide an expected\nstarting point and lock things appropriately.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"},{"id":"3534","messageId":"20050519065207.GB18281@pasky.ji.cz","threadId":"600","inReplyTo":"Pine.LNX.4.21.0505182259060.30848-100000@iabervon.org","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Petr Baudis","fromEmail":"pasky@ucw.cz","sentAt":"2005-05-19T06:52:07Z","receivedAt":"2005-05-19T06:52:07Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Thu, May 19, 2005 at 05:19:01AM CEST, I got a letter\nwhere Daniel Barkalow <barkalow@iabervon.org> told me that...\n>  2) fetching reference files by name, and making them available to the\n>     local program without writing them to disk at all.\n>  3) fetching other files by name and writing them to either the\n>     corresponding filename or a provided replacement.\n> \n> I had thought that (2) could be done as a special case of (3), but I think\n> that it has to be separate, because (2) just returns the value, while\n> (3) can't just return the contents, but has to write it somewhere, since\n> it isn't constrained to be exactly 20 bytes.\n\nHuh. How would (2) be useful and why can't you just still write it e.g.\nto some user-supplied temporary file? I think that'd be still actually\nmuch less trouble for the scripts to handle.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nC++: an octopus made by nailing extra legs onto a dog. -- Steve Taylor\n"},{"id":"3555","messageId":"Pine.LNX.4.21.0505191147480.30848-100000@iabervon.org","threadId":"600","inReplyTo":"20050519065207.GB18281@pasky.ji.cz","subject":"Re: [PATCH 0/4] Pulling refs files","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-05-19T16:00:43Z","receivedAt":"2005-05-19T16:00:43Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 19 May 2005, Petr Baudis wrote:\n\n> Dear diary, on Thu, May 19, 2005 at 05:19:01AM CEST, I got a letter\n> where Daniel Barkalow <barkalow@iabervon.org> told me that...\n> >  2) fetching reference files by name, and making them available to the\n> >     local program without writing them to disk at all.\n> >  3) fetching other files by name and writing them to either the\n> >     corresponding filename or a provided replacement.\n> > \n> > I had thought that (2) could be done as a special case of (3), but I think\n> > that it has to be separate, because (2) just returns the value, while\n> > (3) can't just return the contents, but has to write it somewhere, since\n> > it isn't constrained to be exactly 20 bytes.\n> \n> Huh. How would (2) be useful and why can't you just still write it e.g.\n> to some user-supplied temporary file? I think that'd be still actually\n> much less trouble for the scripts to handle.\n\n(2) is what is needed if the user just requests downloading objects\nstarting with a reference stored remotely, and doesn't request that the\nreference be written anywhere. It is also useful because the system wants\nto verify that it has actually downloaded the objects successfully before\nwriting the reference.\n\nNote that the scripts see a higher-level interface; these are the\noperations that (e.g.) http-pull.c has to provide for pull.c, which builds\na larger operation (determine the target hash, download the objects, write\nthe specified ref file) out of them. It would be inconvenient for pull.c \nto download to a temporary file and then read the temporary file, which\nshouldn't normally be visible yet, to figure out what it's doing. It wants\nto have a function that takes a string and returns a hash, getting the\nvalue from the remote host, and it's inconvenient to deal with the disk in\nthe middle.\n\n\t-Daniel\n*This .sig left intentionally blank*\n\n"}]}