{"thread":{"id":"1531","subject":"[PATCH] Support packs in local-pull","startedAt":"2005-08-16T04:09:13Z","lastAt":"2005-08-16T04:10:32Z","messageCount":3,"participants":["Daniel Barkalow"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"7346","messageId":"Pine.LNX.4.63.0508160004460.23242@iabervon.org","threadId":"1531","inReplyTo":null,"subject":"[PATCH 0/2] Fix local-pull on packed repository","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-08-16T04:09:13Z","receivedAt":"2005-08-16T04:09:13Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This adds essentially the same logic to local-pull that http-pull has, \nwith the exception that it reads the index out of the source directory, \nrather than copying it. This, in turn, requires the ability to use an \nindex file in some other directory.\n\n 1: Use index file in another directory\n 2: Copy/link/symlink pack files as appropriate\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"7347","messageId":"Pine.LNX.4.63.0508160009200.23242@iabervon.org","threadId":"1531","inReplyTo":"Pine.LNX.4.63.0508160004460.23242@iabervon.org","subject":"[PATCH] Add function to read an index file from an arbitrary filename.","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-08-16T04:10:03Z","receivedAt":"2005-08-16T04:10:03Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Note that the pack file has to be in the usual location if it gets\ninstalled later.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n\n cache.h     |    2 ++\n sha1_file.c |   10 ++++++++--\n 2 files changed, 10 insertions(+), 2 deletions(-)\n\n59e5c6d163edae5da6136560d48a4750cceacdc6\ndiff --git a/cache.h b/cache.h\n--- a/cache.h\n+++ b/cache.h\n@@ -319,6 +319,8 @@ extern int get_ack(int fd, unsigned char\n extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match);\n \n extern struct packed_git *parse_pack_index(unsigned char *sha1);\n+extern struct packed_git *parse_pack_index_file(unsigned char *sha1, \n+\t\t\t\t\t\tchar *idx_path);\n \n extern void prepare_packed_git(void);\n extern void install_packed_git(struct packed_git *pack);\ndiff --git a/sha1_file.c b/sha1_file.c\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -476,12 +476,18 @@ struct packed_git *add_packed_git(char *\n \n struct packed_git *parse_pack_index(unsigned char *sha1)\n {\n+\tchar *path = sha1_pack_index_name(sha1);\n+\treturn parse_pack_index_file(sha1, path);\n+}\n+\n+struct packed_git *parse_pack_index_file(unsigned char *sha1, char *idx_path)\n+{\n \tstruct packed_git *p;\n \tunsigned long idx_size;\n \tvoid *idx_map;\n-\tchar *path = sha1_pack_index_name(sha1);\n+\tchar *path;\n \n-\tif (check_packed_git_idx(path, &idx_size, &idx_map))\n+\tif (check_packed_git_idx(idx_path, &idx_size, &idx_map))\n \t\treturn NULL;\n \n \tpath = sha1_pack_name(sha1);\n"},{"id":"7345","messageId":"Pine.LNX.4.63.0508160010050.23242@iabervon.org","threadId":"1531","inReplyTo":"Pine.LNX.4.63.0508160004460.23242@iabervon.org","subject":"[PATCH] Support packs in local-pull","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-08-16T04:10:32Z","receivedAt":"2005-08-16T04:10:32Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"If it doesn't find an object, it looks for an index that contains it\nand uses the same methods on that instead.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n\n local-pull.c |  112 +++++++++++++++++++++++++++++++++++++++++++++++-----------\n 1 files changed, 91 insertions(+), 21 deletions(-)\n\naafbc7fb9ae059b9c9afa42e8d2c0548ea960f9f\ndiff --git a/local-pull.c b/local-pull.c\n--- a/local-pull.c\n+++ b/local-pull.c\n@@ -15,34 +15,54 @@ void prefetch(unsigned char *sha1)\n {\n }\n \n-int fetch(unsigned char *sha1)\n+static struct packed_git *packs = NULL;\n+\n+void setup_index(unsigned char *sha1)\n {\n-\tstatic int object_name_start = -1;\n-\tstatic char filename[PATH_MAX];\n-\tchar *hex = sha1_to_hex(sha1);\n-\tconst char *dest_filename = sha1_file_name(sha1);\n+\tstruct packed_git *new_pack;\n+\tchar filename[PATH_MAX];\n+\tstrcpy(filename, path);\n+\tstrcat(filename, \"/objects/pack/pack-\");\n+\tstrcat(filename, sha1_to_hex(sha1));\n+\tstrcat(filename, \".idx\");\n+\tnew_pack = parse_pack_index_file(sha1, filename);\n+\tnew_pack->next = packs;\n+\tpacks = new_pack;\n+}\n \n-\tif (object_name_start < 0) {\n-\t\tstrcpy(filename, path); /* e.g. git.git */\n-\t\tstrcat(filename, \"/objects/\");\n-\t\tobject_name_start = strlen(filename);\n+int setup_indices()\n+{\n+\tDIR *dir;\n+\tstruct dirent *de;\n+\tchar filename[PATH_MAX];\n+\tunsigned char sha1[20];\n+\tsprintf(filename, \"%s/objects/pack/\", path);\n+\tdir = opendir(filename);\n+\twhile ((de = readdir(dir)) != NULL) {\n+\t\tint namelen = strlen(de->d_name);\n+\t\tif (namelen != 50 || \n+\t\t    strcmp(de->d_name + namelen - 5, \".pack\"))\n+\t\t\tcontinue;\n+\t\tget_sha1_hex(sha1, de->d_name + 5);\n+\t\tsetup_index(sha1);\n \t}\n-\tfilename[object_name_start+0] = hex[0];\n-\tfilename[object_name_start+1] = hex[1];\n-\tfilename[object_name_start+2] = '/';\n-\tstrcpy(filename + object_name_start + 3, hex + 2);\n+\treturn 0;\n+}\n+\n+int copy_file(const char *source, const char *dest, const char *hex)\n+{\n \tif (use_link) {\n-\t\tif (!link(filename, dest_filename)) {\n+\t\tif (!link(source, dest)) {\n \t\t\tpull_say(\"link %s\\n\", hex);\n \t\t\treturn 0;\n \t\t}\n \t\t/* If we got ENOENT there is no point continuing. */\n \t\tif (errno == ENOENT) {\n-\t\t\tfprintf(stderr, \"does not exist %s\\n\", filename);\n+\t\t\tfprintf(stderr, \"does not exist %s\\n\", source);\n \t\t\treturn -1;\n \t\t}\n \t}\n-\tif (use_symlink && !symlink(filename, dest_filename)) {\n+\tif (use_symlink && !symlink(source, dest)) {\n \t\tpull_say(\"symlink %s\\n\", hex);\n \t\treturn 0;\n \t}\n@@ -50,25 +70,25 @@ int fetch(unsigned char *sha1)\n \t\tint ifd, ofd, status;\n \t\tstruct stat st;\n \t\tvoid *map;\n-\t\tifd = open(filename, O_RDONLY);\n+\t\tifd = open(source, O_RDONLY);\n \t\tif (ifd < 0 || fstat(ifd, &st) < 0) {\n \t\t\tclose(ifd);\n-\t\t\tfprintf(stderr, \"cannot open %s\\n\", filename);\n+\t\t\tfprintf(stderr, \"cannot open %s\\n\", source);\n \t\t\treturn -1;\n \t\t}\n \t\tmap = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);\n \t\tclose(ifd);\n \t\tif (map == MAP_FAILED) {\n-\t\t\tfprintf(stderr, \"cannot mmap %s\\n\", filename);\n+\t\t\tfprintf(stderr, \"cannot mmap %s\\n\", source);\n \t\t\treturn -1;\n \t\t}\n-\t\tofd = open(dest_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);\n+\t\tofd = open(dest, O_WRONLY | O_CREAT | O_EXCL, 0666);\n \t\tstatus = ((ofd < 0) ||\n \t\t\t  (write(ofd, map, st.st_size) != st.st_size));\n \t\tmunmap(map, st.st_size);\n \t\tclose(ofd);\n \t\tif (status)\n-\t\t\tfprintf(stderr, \"cannot write %s\\n\", dest_filename);\n+\t\t\tfprintf(stderr, \"cannot write %s\\n\", dest);\n \t\telse\n \t\t\tpull_say(\"copy %s\\n\", hex);\n \t\treturn status;\n@@ -77,6 +97,56 @@ int fetch(unsigned char *sha1)\n \treturn -1;\n }\n \n+int fetch_pack(unsigned char *sha1)\n+{\n+\tstruct packed_git *target;\n+\tchar filename[PATH_MAX];\n+\tif (setup_indices())\n+\t\treturn -1;\n+\ttarget = find_sha1_pack(sha1, packs);\n+\tif (!target)\n+\t\treturn error(\"Couldn't find %s: not separate or in any pack\", \n+\t\t\t     sha1_to_hex(sha1));\n+\tif (get_verbosely) {\n+\t\tfprintf(stderr, \"Getting pack %s\\n\",\n+\t\t\tsha1_to_hex(target->sha1));\n+\t\tfprintf(stderr, \" which contains %s\\n\",\n+\t\t\tsha1_to_hex(sha1));\n+\t}\n+\tsprintf(filename, \"%s/objects/pack/pack-%s.pack\", \n+\t\tpath, sha1_to_hex(sha1));\n+\tcopy_file(filename, sha1_pack_name(sha1), sha1_to_hex(sha1));\n+\tsprintf(filename, \"%s/objects/pack/pack-%s.idx\", \n+\t\tpath, sha1_to_hex(sha1));\n+\tcopy_file(filename, sha1_pack_index_name(sha1), sha1_to_hex(sha1));\n+\tinstall_packed_git(target);\n+\treturn 0;\n+}\n+\n+int fetch_file(unsigned char *sha1)\n+{\n+\tstatic int object_name_start = -1;\n+\tstatic char filename[PATH_MAX];\n+\tchar *hex = sha1_to_hex(sha1);\n+\tconst char *dest_filename = sha1_file_name(sha1);\n+\n+ \tif (object_name_start < 0) {\n+\t\tstrcpy(filename, path); /* e.g. git.git */\n+\t\tstrcat(filename, \"/objects/\");\n+\t\tobject_name_start = strlen(filename);\n+\t}\n+\tfilename[object_name_start+0] = hex[0];\n+\tfilename[object_name_start+1] = hex[1];\n+\tfilename[object_name_start+2] = '/';\n+\tstrcpy(filename + object_name_start + 3, hex + 2);\n+\treturn copy_file(filename, dest_filename, hex);\n+}\n+\n+int fetch(unsigned char *sha1)\n+{\n+\treturn fetch_file(sha1) && fetch_pack(sha1);\n+}\n+\n int fetch_ref(char *ref, unsigned char *sha1)\n {\n \tstatic int ref_name_start = -1;\n"}]}