{"thread":{"id":"5026","subject":"[PATCH 3/4] Teach git-local-fetch the --stdin switch","startedAt":"2006-07-27T21:53:26Z","lastAt":"2006-07-28T01:57:27Z","messageCount":7,"participants":["Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"24268","messageId":"20060727215326.24240.20118.stgit@machine","threadId":"5026","inReplyTo":null,"subject":"[PATCH 0/4] Fetching mass of objects at once","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-27T21:53:26Z","receivedAt":"2006-07-27T21:53:26Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"  Hi,\n\n  this series implements support for fetching many objects at once with\ngit-local-fetch and git-http-fetch, greatly helping Cogito's performance.  It\nwould be of course nice to have this in Git 1.4.2, but it's probably too late\nfor that.\n\n  I didn't bother to convert git-ssh-fetch since I think noone uses that\nanymore anyway (why would they...), or only some legacy users do.\n\n  I will followup with a patch for Cogito to take advantage of this. It's\nnow roughly on par with Git in cloning speed.\n"},{"id":"24269","messageId":"20060727215614.24240.89387.stgit@machine","threadId":"5026","inReplyTo":"20060727215326.24240.20118.stgit@machine","subject":"[PATCH 1/4] Make pull() take some implicit data as explicit arguments","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-27T21:56:14Z","receivedAt":"2006-07-27T21:56:14Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Currently it's a bit weird that pull() takes a single argument\ndescribing the commit but takes the write_ref from a global variable.\nThis makes it take that as a parameter as well, which might be nicer\nfor the libification in the future, but especially it will make for\nnicer code when we implement pull()ing multiple commits at once.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n fetch.c       |    6 ++----\n fetch.h       |   11 ++++-------\n http-fetch.c  |    4 ++--\n local-fetch.c |    4 ++--\n ssh-fetch.c   |    4 ++--\n 5 files changed, 12 insertions(+), 17 deletions(-)\n\ndiff --git a/fetch.c b/fetch.c\nindex 989d7a4..3255cc6 100644\n--- a/fetch.c\n+++ b/fetch.c\n@@ -8,9 +8,6 @@ #include \"tag.h\"\n #include \"blob.h\"\n #include \"refs.h\"\n \n-const char *write_ref = NULL;\n-const char *write_ref_log_details = NULL;\n-\n int get_tree = 0;\n int get_history = 0;\n int get_all = 0;\n@@ -213,7 +210,8 @@ static int mark_complete(const char *pat\n \treturn 0;\n }\n \n-int pull(char *target)\n+int pull(char *target, const char *write_ref,\n+         const char *write_ref_log_details)\n {\n \tstruct ref_lock *lock = NULL;\n \tunsigned char sha1[20];\ndiff --git a/fetch.h b/fetch.h\nindex 841bb1a..7bda355 100644\n--- a/fetch.h\n+++ b/fetch.h\n@@ -22,12 +22,6 @@ extern void prefetch(unsigned char *sha1\n  */\n extern int fetch_ref(char *ref, unsigned char *sha1);\n \n-/* If set, the ref filename to write the target value to. */\n-extern const char *write_ref;\n-\n-/* If set additional text will appear in the ref log. */\n-extern const char *write_ref_log_details;\n-\n /* Set to fetch the target tree. */\n extern int get_tree;\n \n@@ -46,6 +40,9 @@ extern int get_recover;\n /* Report what we got under get_verbosely */\n extern void pull_say(const char *, const char *);\n \n-extern int pull(char *target);\n+/* If write_ref is set, the ref filename to write the target value to. */\n+/* If write_ref_log_details is set, additional text will appear in the ref log. */\n+extern int pull(char *target, const char *write_ref,\n+\t\tconst char *write_ref_log_details);\n \n #endif /* PULL_H */\ndiff --git a/http-fetch.c b/http-fetch.c\nindex dc286b7..963d439 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -1216,6 +1216,7 @@ int fetch_ref(char *ref, unsigned char *\n \n int main(int argc, char **argv)\n {\n+\tconst char *write_ref = NULL;\n \tchar *commit_id;\n \tchar *url;\n \tchar *path;\n@@ -1250,7 +1251,6 @@ int main(int argc, char **argv)\n \t}\n \tcommit_id = argv[arg];\n \turl = argv[arg + 1];\n-\twrite_ref_log_details = url;\n \n \thttp_init();\n \n@@ -1268,7 +1268,7 @@ int main(int argc, char **argv)\n \t\t\talt->path_len = strlen(path);\n \t}\n \n-\tif (pull(commit_id))\n+\tif (pull(commit_id, write_ref, url))\n \t\trc = 1;\n \n \thttp_cleanup();\ndiff --git a/local-fetch.c b/local-fetch.c\nindex 65a803a..308ed00 100644\n--- a/local-fetch.c\n+++ b/local-fetch.c\n@@ -204,6 +204,7 @@ static const char local_pull_usage[] =\n  */\n int main(int argc, char **argv)\n {\n+\tconst char *write_ref = NULL;\n \tchar *commit_id;\n \tint arg = 1;\n \n@@ -240,9 +241,8 @@ int main(int argc, char **argv)\n \t\tusage(local_pull_usage);\n \tcommit_id = argv[arg];\n \tpath = argv[arg + 1];\n-\twrite_ref_log_details = path;\n \n-\tif (pull(commit_id))\n+\tif (pull(commit_id, write_ref, path))\n \t\treturn 1;\n \n \treturn 0;\ndiff --git a/ssh-fetch.c b/ssh-fetch.c\nindex a8a6cfb..aef3aa4 100644\n--- a/ssh-fetch.c\n+++ b/ssh-fetch.c\n@@ -123,6 +123,7 @@ static const char ssh_fetch_usage[] =\n   \" [-c] [-t] [-a] [-v] [--recover] [-w ref] commit-id url\";\n int main(int argc, char **argv)\n {\n+\tconst char *write_ref = NULL;\n \tchar *commit_id;\n \tchar *url;\n \tint arg = 1;\n@@ -159,7 +160,6 @@ int main(int argc, char **argv)\n \t}\n \tcommit_id = argv[arg];\n \turl = argv[arg + 1];\n-\twrite_ref_log_details = url;\n \n \tif (setup_connection(&fd_in, &fd_out, prog, url, arg, argv + 1))\n \t\treturn 1;\n@@ -167,7 +167,7 @@ int main(int argc, char **argv)\n \tif (get_version())\n \t\treturn 1;\n \n-\tif (pull(commit_id))\n+\tif (pull(commit_id, write_ref, url))\n \t\treturn 1;\n \n \treturn 0;\n"},{"id":"24267","messageId":"20060727215617.24240.4753.stgit@machine","threadId":"5026","inReplyTo":"20060727215326.24240.20118.stgit@machine","subject":"[PATCH 2/4] Make pull() support fetching multiple targets at once","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-27T21:56:17Z","receivedAt":"2006-07-27T21:56:17Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"pull() now takes an array of arguments instead of just one of each kind.\nCurrently, no users use the new capability, but that'll change.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n fetch.c       |   78 +++++++++++++++++++++++++++++++++------------------------\n fetch.h       |    2 +\n http-fetch.c  |    2 +\n local-fetch.c |    2 +\n ssh-fetch.c   |    2 +\n 5 files changed, 49 insertions(+), 37 deletions(-)\n\ndiff --git a/fetch.c b/fetch.c\nindex 3255cc6..281df61 100644\n--- a/fetch.c\n+++ b/fetch.c\n@@ -210,55 +210,67 @@ static int mark_complete(const char *pat\n \treturn 0;\n }\n \n-int pull(char *target, const char *write_ref,\n+int pull(int targets, char **target, const char **write_ref,\n          const char *write_ref_log_details)\n {\n-\tstruct ref_lock *lock = NULL;\n-\tunsigned char sha1[20];\n+\tstruct ref_lock **lock = xcalloc(targets, sizeof(struct ref_lock *));\n+\tunsigned char *sha1 = xmalloc(targets * 20);\n \tchar *msg;\n \tint ret;\n+\tint i;\n \n \tsave_commit_buffer = 0;\n \ttrack_object_refs = 0;\n-\tif (write_ref) {\n-\t\tlock = lock_ref_sha1(write_ref, NULL, 0);\n-\t\tif (!lock) {\n-\t\t\terror(\"Can't lock ref %s\", write_ref);\n-\t\t\treturn -1;\n+\n+\tfor (i = 0; i < targets; i++) {\n+\t\tif (!write_ref[i])\n+\t\t\tcontinue;\n+\n+\t\tlock[i] = lock_ref_sha1(write_ref[i], NULL, 0);\n+\t\tif (!lock[i]) {\n+\t\t\terror(\"Can't lock ref %s\", write_ref[i]);\n+\t\t\tgoto unlock_and_fail;\n \t\t}\n \t}\n \n \tif (!get_recover)\n \t\tfor_each_ref(mark_complete);\n \n-\tif (interpret_target(target, sha1)) {\n-\t\terror(\"Could not interpret %s as something to pull\", target);\n-\t\tif (lock)\n-\t\t\tunlock_ref(lock);\n-\t\treturn -1;\n+\tfor (i = 0; i < targets; i++) {\n+\t\tif (interpret_target(target[i], &sha1[20 * i])) {\n+\t\t\terror(\"Could not interpret %s as something to pull\", target[i]);\n+\t\t\tgoto unlock_and_fail;\n+\t\t}\n+\t\tif (process(lookup_unknown_object(&sha1[20 * i])))\n+\t\t\tgoto unlock_and_fail;\n \t}\n-\tif (process(lookup_unknown_object(sha1))) {\n-\t\tif (lock)\n-\t\t\tunlock_ref(lock);\n-\t\treturn -1;\n+\n+\tif (loop())\n+\t\tgoto unlock_and_fail;\n+\n+\tif (write_ref_log_details) {\n+\t\tmsg = xmalloc(strlen(write_ref_log_details) + 12);\n+\t\tsprintf(msg, \"fetch from %s\", write_ref_log_details);\n+\t} else {\n+\t\tmsg = NULL;\n \t}\n-\tif (loop()) {\n-\t\tif (lock)\n-\t\t\tunlock_ref(lock);\n-\t\treturn -1;\n+\tfor (i = 0; i < targets; i++) {\n+\t\tif (!write_ref[i])\n+\t\t\tcontinue;\n+\t\tret = write_ref_sha1(lock[i], &sha1[20 * i], msg ? msg : \"fetch (unknown)\");\n+\t\tlock[i] = NULL;\n+\t\tif (ret)\n+\t\t\tgoto unlock_and_fail;\n \t}\n+\tif (msg)\n+\t\tfree(msg);\n \n-\tif (write_ref) {\n-\t\tif (write_ref_log_details) {\n-\t\t\tmsg = xmalloc(strlen(write_ref_log_details) + 12);\n-\t\t\tsprintf(msg, \"fetch from %s\", write_ref_log_details);\n-\t\t}\n-\t\telse\n-\t\t\tmsg = NULL;\n-\t\tret = write_ref_sha1(lock, sha1, msg ? msg : \"fetch (unknown)\");\n-\t\tif (msg)\n-\t\t\tfree(msg);\n-\t\treturn ret;\n-\t}\n \treturn 0;\n+\n+\n+unlock_and_fail:\n+\tfor (i = 0; i < targets; i++)\n+\t\tif (lock[i])\n+\t\t\tunlock_ref(lock[i]);\n+\treturn -1;\n }\ndiff --git a/fetch.h b/fetch.h\nindex 7bda355..75e48af 100644\n--- a/fetch.h\n+++ b/fetch.h\n@@ -42,7 +42,7 @@ extern void pull_say(const char *, const\n \n /* If write_ref is set, the ref filename to write the target value to. */\n /* If write_ref_log_details is set, additional text will appear in the ref log. */\n-extern int pull(char *target, const char *write_ref,\n+extern int pull(int targets, char **target, const char **write_ref,\n \t\tconst char *write_ref_log_details);\n \n #endif /* PULL_H */\ndiff --git a/http-fetch.c b/http-fetch.c\nindex 963d439..bc67db1 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -1268,7 +1268,7 @@ int main(int argc, char **argv)\n \t\t\talt->path_len = strlen(path);\n \t}\n \n-\tif (pull(commit_id, write_ref, url))\n+\tif (pull(1, &commit_id, &write_ref, url))\n \t\trc = 1;\n \n \thttp_cleanup();\ndiff --git a/local-fetch.c b/local-fetch.c\nindex 308ed00..eb19f1a 100644\n--- a/local-fetch.c\n+++ b/local-fetch.c\n@@ -242,7 +242,7 @@ int main(int argc, char **argv)\n \tcommit_id = argv[arg];\n \tpath = argv[arg + 1];\n \n-\tif (pull(commit_id, write_ref, path))\n+\tif (pull(1, &commit_id, &write_ref, path))\n \t\treturn 1;\n \n \treturn 0;\ndiff --git a/ssh-fetch.c b/ssh-fetch.c\nindex aef3aa4..6e16568 100644\n--- a/ssh-fetch.c\n+++ b/ssh-fetch.c\n@@ -167,7 +167,7 @@ int main(int argc, char **argv)\n \tif (get_version())\n \t\treturn 1;\n \n-\tif (pull(commit_id, write_ref, url))\n+\tif (pull(1, &commit_id, &write_ref, url))\n \t\treturn 1;\n \n \treturn 0;\n"},{"id":"24265","messageId":"20060727215619.24240.39537.stgit@machine","threadId":"5026","inReplyTo":"20060727215326.24240.20118.stgit@machine","subject":"[PATCH 3/4] Teach git-local-fetch the --stdin switch","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-27T21:56:19Z","receivedAt":"2006-07-27T21:56:19Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"This makes it possible to fetch many commits (refs) at once, greatly\nspeeding up cg-clone.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n Documentation/git-local-fetch.txt |    6 ++++++\n fetch.c                           |   40 +++++++++++++++++++++++++++++++++++++\n fetch.h                           |    6 ++++++\n local-fetch.c                     |   32 ++++++++++++++++++++----------\n 4 files changed, 74 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-local-fetch.txt b/Documentation/git-local-fetch.txt\nindex 87abec1..bd19820 100644\n--- a/Documentation/git-local-fetch.txt\n+++ b/Documentation/git-local-fetch.txt\n@@ -29,6 +29,12 @@ OPTIONS\n         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on\n         the local end after the transfer is complete.\n \n+--stdin::\n+\tInstead of a commit id on the commandline (which is not expected in this\n+\tcase), 'git-local-fetch' excepts lines on stdin in the format\n+\n+\t\t<commit-id>['\\t'<filename-as-in--w>]\n+\n Author\n ------\n Written by Junio C Hamano <junkio@cox.net>\ndiff --git a/fetch.c b/fetch.c\nindex 281df61..2151c7b 100644\n--- a/fetch.c\n+++ b/fetch.c\n@@ -7,6 +7,7 @@ #include \"tree-walk.h\"\n #include \"tag.h\"\n #include \"blob.h\"\n #include \"refs.h\"\n+#include \"strbuf.h\"\n \n int get_tree = 0;\n int get_history = 0;\n@@ -210,6 +211,45 @@ static int mark_complete(const char *pat\n \treturn 0;\n }\n \n+int pull_targets_stdin(char ***target, const char ***write_ref)\n+{\n+\tint targets = 0, targets_alloc = 0;\n+\tstruct strbuf buf;\n+\t*target = NULL; *write_ref = NULL;\n+\tstrbuf_init(&buf);\n+\twhile (1) {\n+\t\tchar *rf_one = NULL;\n+\t\tchar *tg_one;\n+\n+\t\tread_line(&buf, stdin, '\\n');\n+\t\tif (buf.eof)\n+\t\t\tbreak;\n+\t\ttg_one = buf.buf;\n+\t\trf_one = strchr(tg_one, '\\t');\n+\t\tif (rf_one)\n+\t\t\t*rf_one++ = 0;\n+\n+\t\tif (targets >= targets_alloc) {\n+\t\t\ttargets_alloc = targets_alloc ? targets_alloc * 2 : 64;\n+\t\t\t*target = xrealloc(*target, targets_alloc * sizeof(**target));\n+\t\t\t*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));\n+\t\t}\n+\t\t(*target)[targets] = strdup(tg_one);\n+\t\t(*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL;\n+\t\ttargets++;\n+\t}\n+\treturn targets;\n+}\n+\n+void pull_targets_free(int targets, char **target, const char **write_ref)\n+{\n+\twhile (targets--) {\n+\t\tfree(target[targets]);\n+\t\tif (write_ref[targets])\n+\t\t\tfree((char *) write_ref[targets]);\n+\t}\n+}\n+\n int pull(int targets, char **target, const char **write_ref,\n          const char *write_ref_log_details)\n {\ndiff --git a/fetch.h b/fetch.h\nindex 75e48af..be48c6f 100644\n--- a/fetch.h\n+++ b/fetch.h\n@@ -40,6 +40,12 @@ extern int get_recover;\n /* Report what we got under get_verbosely */\n extern void pull_say(const char *, const char *);\n \n+/* Load pull targets from stdin */\n+extern int pull_targets_stdin(char ***target, const char ***write_ref);\n+\n+/* Free up loaded targets */\n+extern void pull_targets_free(int targets, char **target, const char **write_ref);\n+\n /* If write_ref is set, the ref filename to write the target value to. */\n /* If write_ref_log_details is set, additional text will appear in the ref log. */\n extern int pull(int targets, char **target, const char **write_ref,\ndiff --git a/local-fetch.c b/local-fetch.c\nindex eb19f1a..84b68a6 100644\n--- a/local-fetch.c\n+++ b/local-fetch.c\n@@ -8,8 +8,9 @@ #include \"fetch.h\"\n static int use_link = 0;\n static int use_symlink = 0;\n static int use_filecopy = 1;\n+static int commits_on_stdin = 0;\n \n-static char *path; /* \"Remote\" git repository */\n+static const char *path; /* \"Remote\" git repository */\n \n void prefetch(unsigned char *sha1)\n {\n@@ -194,7 +195,7 @@ int fetch_ref(char *ref, unsigned char *\n }\n \n static const char local_pull_usage[] =\n-\"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] commit-id path\";\n+\"git-local-fetch [-c] [-t] [-a] [-v] [-w filename] [--recover] [-l] [-s] [-n] [--stdin] commit-id path\";\n \n /* \n  * By default we only use file copy.\n@@ -202,10 +203,11 @@ static const char local_pull_usage[] =\n  * If -s is specified, then a symlink is attempted.\n  * If -n is _not_ specified, then a regular file-to-file copy is done.\n  */\n-int main(int argc, char **argv)\n+int main(int argc, const char **argv)\n {\n-\tconst char *write_ref = NULL;\n-\tchar *commit_id;\n+\tint commits;\n+\tconst char **write_ref = NULL;\n+\tchar **commit_id;\n \tint arg = 1;\n \n \tsetup_git_directory();\n@@ -230,20 +232,30 @@ int main(int argc, char **argv)\n \t\telse if (argv[arg][1] == 'v')\n \t\t\tget_verbosely = 1;\n \t\telse if (argv[arg][1] == 'w')\n-\t\t\twrite_ref = argv[++arg];\n+\t\t\twrite_ref = &argv[++arg];\n \t\telse if (!strcmp(argv[arg], \"--recover\"))\n \t\t\tget_recover = 1;\n+\t\telse if (!strcmp(argv[arg], \"--stdin\"))\n+\t\t\tcommits_on_stdin = 1;\n \t\telse\n \t\t\tusage(local_pull_usage);\n \t\targ++;\n \t}\n-\tif (argc < arg + 2)\n+\tif (argc < arg + 2 - commits_on_stdin)\n \t\tusage(local_pull_usage);\n-\tcommit_id = argv[arg];\n-\tpath = argv[arg + 1];\n+\tif (commits_on_stdin) {\n+\t\tcommits = pull_targets_stdin(&commit_id, &write_ref);\n+\t} else {\n+\t\tcommit_id = (char **) &argv[arg++];\n+\t\tcommits = 1;\n+\t}\n+\tpath = argv[arg];\n \n-\tif (pull(1, &commit_id, &write_ref, path))\n+\tif (pull(commits, commit_id, write_ref, path))\n \t\treturn 1;\n \n+\tif (commits_on_stdin)\n+\t\tpull_targets_free(commits, commit_id, write_ref);\n+\n \treturn 0;\n }\n"},{"id":"24266","messageId":"20060727215622.24240.56894.stgit@machine","threadId":"5026","inReplyTo":"20060727215326.24240.20118.stgit@machine","subject":"[PATCH 4/4] Teach git-http-fetch the --stdin switch","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-27T21:56:22Z","receivedAt":"2006-07-27T21:56:22Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Speeds up things quite a lot when fetching tags with Cogito.\n\nSigned-off-by: Petr Baudis <pasky@suse.cz>\n---\n\n Documentation/git-http-fetch.txt |    8 ++++++-\n http-fetch.c                     |   45 ++++++++++++++++++++++++--------------\n 2 files changed, 36 insertions(+), 17 deletions(-)\n\ndiff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt\nindex bc1a132..bea522e 100644\n--- a/Documentation/git-http-fetch.txt\n+++ b/Documentation/git-http-fetch.txt\n@@ -8,7 +8,7 @@ git-http-fetch - downloads a remote git \n \n SYNOPSIS\n --------\n-'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] <commit> <url>\n+'git-http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url>\n \n DESCRIPTION\n -----------\n@@ -32,6 +32,12 @@ commit-id::\n -w <filename>::\n         Writes the commit-id into the filename under $GIT_DIR/refs/<filename> on\n         the local end after the transfer is complete.\n+ \n+--stdin::\n+\tInstead of a commit id on the commandline (which is not expected in this\n+\tcase), 'git-http-fetch' excepts lines on stdin in the format\n+\n+\t\t<commit-id>['\\t'<filename-as-in--w>]\n \n Author\n ------\ndiff --git a/http-fetch.c b/http-fetch.c\nindex bc67db1..1aad39b 100644\n--- a/http-fetch.c\n+++ b/http-fetch.c\n@@ -36,6 +36,8 @@ #endif\n #define PREV_BUF_SIZE 4096\n #define RANGE_HEADER_SIZE 30\n \n+static int commits_on_stdin = 0;\n+\n static int got_alternates = -1;\n static int corrupt_object_found = 0;\n \n@@ -43,7 +45,7 @@ static struct curl_slist *no_pragma_head\n \n struct alt_base\n {\n-\tchar *base;\n+\tconst char *base;\n \tint path_len;\n \tint got_indices;\n \tstruct packed_git *packs;\n@@ -81,7 +83,7 @@ struct object_request\n };\n \n struct alternates_request {\n-\tchar *base;\n+\tconst char *base;\n \tchar *url;\n \tstruct buffer *buffer;\n \tstruct active_request_slot *slot;\n@@ -142,7 +144,7 @@ static size_t fwrite_sha1_file(void *ptr\n \treturn size;\n }\n \n-static void fetch_alternates(char *base);\n+static void fetch_alternates(const char *base);\n \n static void process_object_response(void *callback_data);\n \n@@ -507,7 +509,7 @@ static void process_alternates_response(\n \t\t(struct alternates_request *)callback_data;\n \tstruct active_request_slot *slot = alt_req->slot;\n \tstruct alt_base *tail = alt;\n-\tchar *base = alt_req->base;\n+\tconst char *base = alt_req->base;\n \tstatic const char null_byte = '\\0';\n \tchar *data;\n \tint i = 0;\n@@ -612,7 +614,7 @@ static void process_alternates_response(\n \tgot_alternates = 1;\n }\n \n-static void fetch_alternates(char *base)\n+static void fetch_alternates(const char *base)\n {\n \tstruct buffer buffer;\n \tchar *url;\n@@ -1185,7 +1187,7 @@ int fetch_ref(char *ref, unsigned char *\n         char *url;\n         char hex[42];\n         struct buffer buffer;\n-\tchar *base = alt->base;\n+\tconst char *base = alt->base;\n \tstruct active_request_slot *slot;\n \tstruct slot_results results;\n         buffer.size = 41;\n@@ -1214,11 +1216,12 @@ int fetch_ref(char *ref, unsigned char *\n         return 0;\n }\n \n-int main(int argc, char **argv)\n+int main(int argc, const char **argv)\n {\n-\tconst char *write_ref = NULL;\n-\tchar *commit_id;\n-\tchar *url;\n+\tint commits;\n+\tconst char **write_ref = NULL;\n+\tchar **commit_id;\n+\tconst char *url;\n \tchar *path;\n \tint arg = 1;\n \tint rc = 0;\n@@ -1238,19 +1241,26 @@ int main(int argc, char **argv)\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\twrite_ref = argv[arg + 1];\n+\t\t\twrite_ref = &argv[arg + 1];\n \t\t\targ++;\n \t\t} else if (!strcmp(argv[arg], \"--recover\")) {\n \t\t\tget_recover = 1;\n+\t\t} else if (!strcmp(argv[arg], \"--stdin\")) {\n+\t\t\tcommits_on_stdin = 1;\n \t\t}\n \t\targ++;\n \t}\n-\tif (argc < arg + 2) {\n-\t\tusage(\"git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] commit-id url\");\n+\tif (argc < arg + 2 - commits_on_stdin) {\n+\t\tusage(\"git-http-fetch [-c] [-t] [-a] [-v] [--recover] [-w ref] [--stdin] commit-id url\");\n \t\treturn 1;\n \t}\n-\tcommit_id = argv[arg];\n-\turl = argv[arg + 1];\n+\tif (commits_on_stdin) {\n+\t\tcommits = pull_targets_stdin(&commit_id, &write_ref);\n+\t} else {\n+\t\tcommit_id = (char **) &argv[arg++];\n+\t\tcommits = 1;\n+\t}\n+\turl = argv[arg];\n \n \thttp_init();\n \n@@ -1268,13 +1278,16 @@ int main(int argc, char **argv)\n \t\t\talt->path_len = strlen(path);\n \t}\n \n-\tif (pull(1, &commit_id, &write_ref, url))\n+\tif (pull(commits, commit_id, write_ref, url))\n \t\trc = 1;\n \n \thttp_cleanup();\n \n \tcurl_slist_free_all(no_pragma_header);\n \n+\tif (commits_on_stdin)\n+\t\tpull_targets_free(commits, commit_id, write_ref);\n+\n \tif (corrupt_object_found) {\n \t\tfprintf(stderr,\n \"Some loose object were found to be corrupt, but they might be just\\n\"\n"},{"id":"24270","messageId":"20060727215705.GF13776@pasky.or.cz","threadId":"5026","inReplyTo":"20060727215326.24240.20118.stgit@machine","subject":"Re: [PATCH 0/4] Fetching mass of objects at once","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-27T21:57:05Z","receivedAt":"2006-07-27T21:57:05Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Thu, Jul 27, 2006 at 11:53:26PM CEST, I got a letter\nwhere Petr Baudis <pasky@suse.cz> said that...\n>   I will followup with a patch for Cogito to take advantage of this. It's\n> now roughly on par with Git in cloning speed.\n\ndiff --git a/cg-Xfetchprogress b/cg-Xfetchprogress\nindex 53bcbd3..4a272db 100755\n--- a/cg-Xfetchprogress\n+++ b/cg-Xfetchprogress\n@@ -67,7 +67,7 @@ sub getline {\n \tif (m#^(link|symlink|copy|got) ([a-f0-9]{2})([a-f0-9]{38})#) {\n \t\t$object = \"$2/$3\";\n \n-\t} elsif (m#^(walk) ([a-f0-9]{2})([a-f0-9]{38})#) {\n+\t} elsif (m#^(ref|walk) ([a-f0-9]{2})([a-f0-9]{38})#) {\n \t\treturn 1; # redundant information\n \n \t# rsync\ndiff --git a/cg-fetch b/cg-fetch\nindex a6e6959..9277f99 100755\n--- a/cg-fetch\n+++ b/cg-fetch\n@@ -124,16 +124,10 @@ get_rsync()\n \treturn ${PIPESTATUS[0]}\n }\n \n-fetch_rsync()\n+fetch_rsync_save()\n {\n-\tif [ $verbose -ge 2 ]; then\n-\t\t# We must not pipe to prevent buffered I/O\n-\t\tget_rsync -s -d \"$2/objects\" \"$_git_objects\"\n-\telse\n-\t\tget_rsync -s -d \"$2/objects\" \"$_git_objects\" | fetch_progress\n-\tfi\n \tret=${PIPESTATUS[0]}\n-\tif [ \"$3\" ] && [ \"$ret\" -eq \"0\" ]; then\n+\tif [ \"$1\" ] && [ \"$ret\" -eq \"0\" ]; then\n \t\tif [ \"$orig_head\" ]; then\n \t\t\tgit-rev-list --objects $new_head ^$orig_head |\n \t\t\t\twhile read obj type; do\n@@ -141,12 +135,29 @@ fetch_rsync()\n \t\t\t\tdone ||\n \t\t\tdie \"rsync fetch incomplete, some objects missing\"\n \t\tfi\n-\t\tcat \"$_git/refs/${3%/*}/.${3##*/}-fetching\" > \"$_git/refs/$3\"\n+\t\tcat \"$_git/refs/${3%/*}/.${3##*/}-fetching\" > \"$_git/refs/$1\"\n \tfi\n \treturn $ret\n }\n \n \n+fetch_rsync()\n+{\n+\tif [ $verbose -ge 2 ]; then\n+\t\t# We must not pipe to prevent buffered I/O\n+\t\tget_rsync -s -d \"$2/objects\" \"$_git_objects\"\n+\telse\n+\t\tget_rsync -s -d \"$2/objects\" \"$_git_objects\" | fetch_progress\n+\tfi\n+\tif [ x\"$1\" = x\"--stdin\" ]; then\n+\t\twhile read c w; do\n+\t\t\techo \"$c\" >\"$_git/refs/$w\"\n+\t\tdone\n+\telse\n+\t\tfetch_rsync_save \"$3\"\n+\tfi\n+}\n+\n get_http()\n {\n \t[ \"$1\" = \"-b\" ] && shift\n@@ -229,21 +240,13 @@ fetch_tags()\n \n \t\t\t# if so, fetch the tag -- which should be\n \t\t\t# a cheap operation -- to complete the chain.\n-\t\t\techo -n \"Missing tag ${tagname#tags/}... \"\n-\t\t\tif $fetch \"$tagname\" \"$uri\" \"$tagname\" 2>/dev/null >&2; then\n-\t\t\t\techo \"retrieved\"\n-\t\t\telse\n-\t\t\t\t# 17 is code from packed transport, which\n-\t\t\t\t# will grab all of them en masse later\n-\t\t\t\tif [ \"$?\" -ne \"17\" ]; then\n-\t\t\t\t\techo \"unable to retrieve\"\n-\t\t\t\telse\n-\t\t\t\t\techo \"\"\n-\t\t\t\tfi\n-\t\t\tfi\n-\t\tdone\n-\t[ \"${PIPESTATUS[0]}\" -eq \"0\" ] ||\n-\t\techo \"unable to get tags list (non-fatal)\" >&2\n+\t\t\techo \"Missing tag ${tagname#tags/}...\" >&2\n+\t\t\techo -e \"$tagname\"\\\\t\"$tagname\"\n+\t\tdone |\n+\t\tsort | uniq | $fetch --stdin \"$uri\"\n+\tif [ \"${PIPESTATUS[0]}\" -ne 0 -o \"$?\" -ne 0 ]; then\n+\t\techo \"unable to fetch tags (non-fatal)\" >&2\n+\tfi\n \treturn 0\n }\n \n@@ -364,21 +367,15 @@ if [ \"$packed_transport\" ]; then\n \t\tfetch_pack_recorder \"refs/heads/$name\" \"fetching pack failed\" ||\n \t\texit\n \n-\texport _cg_taglist=\"$(mktemp -t gitfetch.XXXXXX)\"\n \trecord_tags_to_fetch () {\n-\t\techo \"refs/$1\" >>\"$_cg_taglist\"\n-\t\treturn 17\n-\t}\n-\tfetch=record_tags_to_fetch\n-\tfetch_tags\n-\tif [ -s \"$_cg_taglist\" ]; then\n-\t\t( cat \"$_cg_taglist\" | tr '\\n' '\\0' |\n+\t\t( cut -f 1 | tr '\\n' '\\0' |\n \t\t\txargs -0 git-fetch-pack $cloneorfetch \"$uri\" ||\n \t\t  echo \"failed\" \"$rembranch\" ) |\n \n \t\tfetch_pack_recorder \"\" \"unable to retrieve tags (non-fatal)\"\n-\tfi\n-\trm \"$_cg_taglist\"\n+\t}\n+\tfetch=record_tags_to_fetch\n+\tfetch_tags\n \n \trm \"$dirtyfile\"\n \tshow_changes_summary \"$orig_head\" \"$(cg-object-id \"$name\")\"\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nSnow falling on Perl. White noise covering line noise.\nHides all the bugs too. -- J. Putnam\n"},{"id":"24276","messageId":"20060728015727.GJ13776@pasky.or.cz","threadId":"5026","inReplyTo":"20060727215622.24240.56894.stgit@machine","subject":"Re: [PATCH 3/4] Teach git-local-fetch the --stdin switch","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2006-07-28T01:57:27Z","receivedAt":"2006-07-28T01:57:27Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"Dear diary, on Thu, Jul 27, 2006 at 11:56:19PM CEST, I got a letter\nwhere Petr Baudis <pasky@suse.cz> said that...\n> +--stdin::\n> +\tInstead of a commit id on the commandline (which is not expected in this\n> +\tcase), 'git-local-fetch' excepts lines on stdin in the format\n                                 ^^^^^^^\n\nOops, should read \"expects\" in both patches - thanks, alp!\n\nI blame all those tiny bugs lured into the room by light and then, well,\nbugging you. (Real-world bugs, but they can transform.)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nSnow falling on Perl. White noise covering line noise.\nHides all the bugs too. -- J. Putnam\n"}]}