{"thread":{"id":"12609","subject":"[PATCH 2/2] Add a library function to add an alternate to the alternates file","startedAt":"2008-03-09T22:46:39Z","lastAt":"2008-03-09T23:26:27Z","messageCount":3,"participants":["Daniel Barkalow","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"71534","messageId":"alpine.LNX.1.00.0803091842100.19665@iabervon.org","threadId":"12609","inReplyTo":null,"subject":"[PATCH 2/2] Add a library function to add an alternate to the alternates file","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-03-09T22:46:39Z","receivedAt":"2008-03-09T22:46:39Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"This is in the core so that, if the alternates file has already been\nread, the addition can be parsed and put into effect for the current\nprocess.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n cache.h     |    1 +\n sha1_file.c |   12 ++++++++++++\n 2 files changed, 13 insertions(+), 0 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex 4a113b0..96dcb49 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -589,6 +589,7 @@ extern struct alternate_object_database {\n \tchar base[FLEX_ARRAY]; /* more */\n } *alt_odb_list;\n extern void prepare_alt_odb(void);\n+extern void add_to_alternates_file(const char *reference);\n \n struct pack_window {\n \tstruct pack_window *next;\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 445a871..1aa3cef 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -379,6 +379,18 @@ static void read_info_alternates(const char * relative_base, int depth)\n \tmunmap(map, mapsz);\n }\n \n+void add_to_alternates_file(const char *reference)\n+{\n+\tstruct lock_file *lock = xcalloc(1, sizeof(struct lock_file));\n+\tint fd = hold_lock_file_for_append(lock, git_path(\"objects/info/alternates\"), 1);\n+\tchar *alt = mkpath(\"%s/objects\\n\", reference);\n+\twrite_or_die(fd, alt, strlen(alt));\n+\tif (commit_lock_file(lock))\n+\t\tdie(\"could not close alternates file\");\n+\tif (alt_odb_tail)\n+\t\tlink_alt_odb_entries(alt, alt + strlen(alt), '\\n', NULL, 0);\n+}\n+\n void prepare_alt_odb(void)\n {\n \tconst char *alt;\n-- \n1.5.4.3.610.gea6cd\n"},{"id":"71537","messageId":"alpine.LSU.1.00.0803092357230.3975@racer.site","threadId":"12609","inReplyTo":"alpine.LNX.1.00.0803091842100.19665@iabervon.org","subject":"Re: [PATCH 2/2] Add a library function to add an alternate to the alternates file","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-09T23:04:19Z","receivedAt":"2008-03-09T23:04:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 9 Mar 2008, Daniel Barkalow wrote:\n\n> This is in the core so that, if the alternates file has already been \n> read, the addition can be parsed and put into effect for the current \n> process.\n\nYes, I like your two patches.\n\nBTW so to avoid clashing, I just send what my cumulative \"clean-up\" patch \nfor builtin-clone is:\n\n-- snipsnap --\n[PATCH] builtin-clone: misc clean-ups\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tObviously to be squashed into 10/11 (now 11/12 ;-)\n\n\tOh, BTW I did not start to look into falling back to copying when \n\thard-linking fails, but it should be as easy as switching the \n\torder of\n\n               if (option_no_hardlinks) {\n                        if (copy_file(dest, src, 0666))\n                                die(\"failed to copy file to %s\\n\", dest);\n               } else {\n                        if (link(src, dest))\n                                die(\"failed to create link %s\\n\", dest);\n               }\n\n\taround, issue a \"warning (...)\" instead of die()ing, setting \n\toption_no_hardlinks = 1, and replace the else with\n\tif (!option_no_hardlinks).\n\n\tBut first I have to sleep (and maybe the fairies were at work when \n\tI wake up...)\n\n builtin-clone.c |  101 ++++++++++++++++++++++++-------------------------------\n 1 files changed, 44 insertions(+), 57 deletions(-)\n\ndiff --git a/builtin-clone.c b/builtin-clone.c\nindex 3890e12..ac5a7d0 100644\n--- a/builtin-clone.c\n+++ b/builtin-clone.c\n@@ -128,9 +128,15 @@ static char *guess_dir_name(const char *repo, int is_bundle)\n \treturn xstrndup(start, end - start);\n }\n \n-void setup_reference(const char *repo)\n+static int is_directory(const char *path)\n {\n \tstruct stat buf;\n+\n+\treturn !stat(path, &buf) && S_ISDIR(buf.st_mode);\n+}\n+\n+static void setup_reference(const char *repo)\n+{\n \tconst char *ref_git;\n \tchar *ref_git_copy;\n \n@@ -138,16 +144,11 @@ void setup_reference(const char *repo)\n \tstruct transport *transport;\n \tconst struct ref *extra;\n \n-\tif (!option_reference)\n-\t\treturn;\n-\n \tref_git = make_absolute_path(option_reference);\n \n-\tif (!stat(mkpath(\"%s/.git/objects\", ref_git), &buf) &&\n-\t    S_ISDIR(buf.st_mode))\n+\tif (is_directory(mkpath(\"%s/.git/objects\", ref_git)))\n \t\tref_git = mkpath(\"%s/.git\", ref_git);\n-\telse if (stat(mkpath(\"%s/objects\", ref_git), &buf) ||\n-\t\t !S_ISDIR(buf.st_mode))\n+\telse if (!is_directory(mkpath(\"%s/objects\", ref_git)))\n \t\tdie(\"reference repository '%s' is not a local directory.\",\n \t\t    option_reference);\n \n@@ -166,8 +167,7 @@ void setup_reference(const char *repo)\n \tfree(ref_git_copy);\n }\n \n-static void\n-walk_objects(char *src, char *dest)\n+static void copy_or_link_directory(char *src, char *dest)\n {\n \tstruct dirent *de;\n \tstruct stat buf;\n@@ -196,12 +196,12 @@ walk_objects(char *src, char *dest)\n \t\tstrcpy(src + src_len + 1, de->d_name);\n \t\tstrcpy(dest + dest_len + 1, de->d_name);\n \t\tif (stat(src, &buf)) {\n-\t\t\tfprintf(stderr, \"failed to stat %s, ignoring\\n\", src);\n+\t\t\twarning (\"failed to stat %s\\n\", src);\n \t\t\tcontinue;\n \t\t}\n \t\tif (S_ISDIR(buf.st_mode)) {\n \t\t\tif (de->d_name[0] != '.')\n-\t\t\t\twalk_objects(src, dest);\n+\t\t\t\tcopy_or_link_directory(src, dest);\n \t\t\tcontinue;\n \t\t}\n \n@@ -217,8 +217,8 @@ walk_objects(char *src, char *dest)\n \t}\n }\n \n-static const struct ref *\n-clone_local(const char *src_repo, const char *dest_repo)\n+static const struct ref * clone_local(const char *src_repo,\n+\t\tconst char *dest_repo)\n {\n \tconst struct ref *ret;\n \tchar src[PATH_MAX];\n@@ -226,15 +226,14 @@ clone_local(const char *src_repo, const char *dest_repo)\n \tstruct remote *remote;\n \tstruct transport *transport;\n \n-\tif (option_shared) {\n+\tif (option_shared)\n \t\tadd_to_alternates_file(src_repo);\n-\t} else {\n+\telse {\n \t\tsnprintf(src, PATH_MAX, \"%s/objects\", src_repo);\n \t\tsnprintf(dest, PATH_MAX, \"%s/objects\", dest_repo);\n-\t\twalk_objects(src, dest);\n+\t\tcopy_or_link_directory(src, dest);\n \t}\n \n-\tfprintf(stderr, \"Get for %s\\n\", src_repo);\n \tremote = remote_get(src_repo);\n \ttransport = transport_get(remote, src_repo);\n \tret = transport_get_remote_refs(transport);\n@@ -244,22 +243,20 @@ clone_local(const char *src_repo, const char *dest_repo)\n \n static const char *junk_work_tree;\n static const char *junk_git_dir;\n-pid_t clone_pid;\n+pid_t junk_pid;\n \n static void remove_junk(void)\n {\n \tstruct strbuf sb;\n-\tif (getpid() != clone_pid)\n+\tif (getpid() != junk_pid)\n \t\treturn;\n \tstrbuf_init(&sb, 0);\n \tif (junk_git_dir) {\n-\t\tfprintf(stderr, \"Remove junk %s\\n\", junk_git_dir);\n \t\tstrbuf_addstr(&sb, junk_git_dir);\n \t\tremove_dir_recursively(&sb, 0);\n \t\tstrbuf_reset(&sb);\n \t}\n \tif (junk_work_tree) {\n-\t\tfprintf(stderr, \"Remove junk %s\\n\", junk_work_tree);\n \t\tstrbuf_addstr(&sb, junk_work_tree);\n \t\tremove_dir_recursively(&sb, 0);\n \t\tstrbuf_reset(&sb);\n@@ -303,7 +300,8 @@ static const struct ref *locate_head(const struct ref *refs,\n \treturn NULL;\n }\n \n-static struct ref *write_remote_refs(const struct ref *refs, struct refspec *refspec, const char *reflog)\n+static struct ref *write_remote_refs(const struct ref *refs,\n+\t\tstruct refspec *refspec, const char *reflog)\n {\n \tstruct ref *local_refs = NULL;\n \tstruct ref **tail = &local_refs;\n@@ -332,7 +330,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \n \tstruct refspec refspec;\n \n-\tclone_pid = getpid();\n+\tjunk_pid = getpid();\n \n \targc = parse_options(argc, argv, builtin_clone_options,\n \t\t\t     builtin_clone_usage, 0);\n@@ -357,20 +355,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \trepo_name = argv[0];\n \n \tpath = get_repo_path(repo_name, &is_bundle);\n-\tif (path != NULL)\n-\t\trepo = xstrdup(make_absolute_path(path));\n+\tif (path)\n+\t\trepo = path;\n \telse if (!strchr(repo_name, ':'))\n \t\trepo = xstrdup(make_absolute_path(repo_name));\n \telse\n \t\trepo = repo_name;\n-\tfprintf(stderr, \"repo is %s\\n\", repo);\n \n-\tif (argc == 2) {\n+\tif (argc == 2)\n \t\tdir = xstrdup(argv[1]);\n-\t} else {\n+\telse\n \t\tdir = guess_dir_name(repo_name, is_bundle);\n-\t}\n-\tfprintf(stderr, \"dir is %s\\n\", dir);\n \n \tif (!stat(dir, &buf))\n \t\tdie(\"destination directory '%s' already exists.\", dir);\n@@ -386,8 +381,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\t\tdie(\"working tree '%s' already exists.\", work_tree);\n \t}\n \n-\tatexit(remove_junk);\n-\n \tif (option_bare || work_tree)\n \t\tgit_dir = xstrdup(dir);\n \telse {\n@@ -401,17 +394,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\t\tdie(\"could not create work tree dir '%s'.\", work_tree);\n \t\tset_git_work_tree(work_tree);\n \t}\n+\tjunk_git_dir = git_dir;\n+\tatexit(remove_junk);\n \n \tsetenv(CONFIG_ENVIRONMENT, xstrdup(mkpath(\"%s/config\", git_dir)), 1);\n \n \tset_git_dir(make_absolute_path(git_dir));\n \n \tfprintf(stderr, \"Initialize %s\\n\", git_dir);\n-\tjunk_git_dir = git_dir;\n \tinit_db(option_template, option_quiet ? INIT_DB_QUIET : 0);\n-\tfprintf(stderr, \"Okay\\n\");\n \n-\tsetup_reference(git_dir);\n+\tif (option_reference)\n+\t\tsetup_reference(git_dir);\n \n \tgit_config(git_default_config);\n \n@@ -420,15 +414,16 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \n \t\tgit_config_set(\"core.bare\", \"true\");\n \t} else {\n-\t\tsnprintf(branch_top, sizeof branch_top,\n+\t\tsnprintf(branch_top, sizeof(branch_top),\n \t\t\t \"refs/remotes/%s/\", option_origin);\n \n \t\t/* Configure the remote */\n-\t\tsnprintf(key, sizeof key, \"remote.%s.url\", option_origin);\n+\t\tsnprintf(key, sizeof(key), \"remote.%s.url\", option_origin);\n \t\tgit_config_set(key, repo);\n \n-\t\tsnprintf(key, sizeof key, \"remote.%s.fetch\", option_origin);\n-\t\tsnprintf(value, sizeof value, \"+refs/heads/*:%s*\", branch_top);\n+\t\tsnprintf(key, sizeof(key), \"remote.%s.fetch\", option_origin);\n+\t\tsnprintf(value, sizeof(value),\n+\t\t\t\t\"+refs/heads/*:%s*\", branch_top);\n \t\tgit_config_set_multivar(key, value, \"^$\", 0);\n \t}\n \n@@ -437,7 +432,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \trefspec.src = \"refs/heads/\";\n \trefspec.dst = branch_top;\n \n-\tif (path != NULL && !is_bundle)\n+\tif (path && !is_bundle)\n \t\trefs = clone_local(path, git_dir);\n \telse {\n \t\tstruct remote *remote = remote_get(argv[0]);\n@@ -452,18 +447,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\tif (option_quiet)\n \t\t\ttransport->verbose = -1;\n \n-\t\t//args.no_progress = 1;\n-\n-\t\tfprintf(stderr, \"Get refs for %s\\n\", argv[0]);\n \t\trefs = transport_get_remote_refs(transport);\n-\n \t\ttransport_fetch_refs(transport, refs);\n \t}\n \n-\t// FFFF transport_get_remote_refs() ought to be able to tell\n-\t// us about HEAD being a symref, and what it's to, if it\n-\t// actually knows.\n-\n \tclear_extra_refs();\n \n \tmapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf);\n@@ -497,21 +484,24 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\t\t\t      head_points_at->peer_ref->name,\n \t\t\t\t      reflog_msg.buf);\n \n-\t\t\tsnprintf(key, sizeof key, \"branch.%s.remote\", head);\n+\t\t\tsnprintf(key, sizeof(key), \"branch.%s.remote\", head);\n \t\t\tgit_config_set(key, option_origin);\n-\t\t\tsnprintf(key, sizeof key, \"branch.%s.merge\", head);\n+\t\t\tsnprintf(key, sizeof(key), \"branch.%s.merge\", head);\n \t\t\tgit_config_set(key, head_points_at->name);\n \t\t}\n \t} else if (remote_head) {\n \t\t/* Source had detached HEAD pointing somewhere. */\n-\t\tif (!option_bare)\n+\t\tif (option_bare)\n+\t\t\toption_no_checkout = 1;\n+\t\telse\n \t\t\tupdate_ref(reflog_msg.buf, \"HEAD\",\n \t\t\t\t   remote_head->old_sha1,\n \t\t\t\t   NULL, REF_NODEREF, DIE_ON_ERR);\n \t} else {\n \t\t/* Nothing to checkout out */\n \t\tif (!option_no_checkout)\n-\t\t\tfprintf(stderr, \"Warning: Remote HEAD refers to nonexistent ref, unable to checkout.\\n\");\n+\t\t\twarning (\"remote HEAD refers to nonexistent ref, \"\n+\t\t\t\t\"unable to checkout.\\n\");\n \t\toption_no_checkout = 1;\n \t}\n \n@@ -525,8 +515,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t\t/* We need to be in the new work tree for the checkout */\n \t\tsetup_work_tree();\n \n-\t\tfprintf(stderr, \"work tree now %s\\n\", get_git_work_tree());\n-\n \t\tfd = hold_locked_index(lock_file, 1);\n \n \t\tmemset(&opts, 0, sizeof opts);\n@@ -549,7 +537,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \t}\n \n \tstrbuf_release(&reflog_msg);\n-\tjunk_work_tree = NULL;\n-\tjunk_git_dir = NULL;\n+\tjunk_pid = 0;\n \treturn 0;\n }\n-- \n1.5.4.4.642.g1343.dirty\n"},{"id":"71540","messageId":"alpine.LNX.1.00.0803091914590.19665@iabervon.org","threadId":"12609","inReplyTo":"alpine.LSU.1.00.0803092357230.3975@racer.site","subject":"Re: [PATCH 2/2] Add a library function to add an alternate to the alternates file","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-03-09T23:26:27Z","receivedAt":"2008-03-09T23:26:27Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 10 Mar 2008, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Sun, 9 Mar 2008, Daniel Barkalow wrote:\n> \n> > This is in the core so that, if the alternates file has already been \n> > read, the addition can be parsed and put into effect for the current \n> > process.\n> \n> Yes, I like your two patches.\n> \n> BTW so to avoid clashing, I just send what my cumulative \"clean-up\" patch \n> for builtin-clone is:\n> \n> -- snipsnap --\n> [PATCH] builtin-clone: misc clean-ups\n\nThey all look good to me.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"}]}