git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hui Wang <jason77.wang@gmail.com>
To: <gitster@pobox.com>, <git@vger.kernel.org>
Subject: [PATCH v2 1/1] clone: replace relative paths in the alternates
Date: Mon, 22 Aug 2011 17:05:57 +0800	[thread overview]
Message-ID: <1314003957-9455-2-git-send-email-jason77.wang@gmail.com> (raw)
In-Reply-To: <1314003957-9455-1-git-send-email-jason77.wang@gmail.com>

When we clone a local source repository to a new local destination
repository without "--shared" option, if source repository has
relative path in the alternates, the clone will fail.

The root cause is when cloning local source repository to local
destination repository, the alternates of the source repository
will be copied to the destination repository, the relative path in
the alternates is source repository to base repository rather than
destination repository to base repository, so the destination
repository get a wrong relative path in the alternates, this will
cause errors when refer to base repository in the destination
repository.

To fix it, adding a function update_alt_rel_path() to replace all
relative paths to absolute paths in the alternates of the destination
repository before destination repository use those paths to look for
the base repository.

Signed-off-by: Hui Wang <jason77.wang@gmail.com>
---
 builtin/clone.c |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
 cache.h         |    1 +
 sha1_file.c     |   11 +++++++++++
 3 files changed, 58 insertions(+), 1 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index 7663bc2..7b5e603 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -286,6 +286,50 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 	closedir(dir);
 }
 
+/*
+ * This function is called by clone_local() of clone.c
+ * If alternates in the src_repo (source repository) has relative path,
+ * call this function will replace the relative path to absolute path
+ * in the des_repo (destination repository) alternates.
+ */
+static void update_alt_rel_path(const char *src_repo)
+{
+	int need_update = 0;
+	FILE *ifp;
+	struct strbuf istr = STRBUF_INIT;
+	struct strbuf ostr = STRBUF_INIT;
+
+	ifp = fopen(git_path("objects/info/alternates"), "r");
+	if (!ifp)
+		return;
+
+	while (strbuf_getline(&istr, ifp, '\n') != EOF) {
+		/* comment line, empty line or absolute path line */
+		if (istr.buf[0] == '#' || istr.len == 0 || is_absolute_path(istr.buf)) {
+			strbuf_add(&ostr, istr.buf, istr.len);
+			strbuf_add(&ostr, "\n", 1);
+		} else {
+			char *abs_path, abs_buf[PATH_MAX];
+			int len;
+
+			abs_path = mkpath("%s/objects/%s", src_repo, istr.buf);
+			normalize_path_copy(abs_buf, abs_path);
+			len = strlen(abs_buf);
+			strbuf_add(&ostr, abs_buf, len);
+			strbuf_add(&ostr, "\n", 1);
+			need_update = 1;
+		}
+	}
+
+	fclose(ifp);
+
+	if (need_update)
+		update_alternates_file_content(ostr.buf);
+
+	strbuf_release(&istr);
+	strbuf_release(&ostr);
+}
+
 static const struct ref *clone_local(const char *src_repo,
 				     const char *dest_repo)
 {
@@ -303,8 +347,9 @@ static const struct ref *clone_local(const char *src_repo,
 		copy_or_link_directory(&src, &dest);
 		strbuf_release(&src);
 		strbuf_release(&dest);
-	}
 
+		update_alt_rel_path(src_repo);
+	}
 	remote = remote_get(src_repo);
 	transport = transport_get(remote, src_repo);
 	ret = transport_get_remote_refs(transport);
diff --git a/cache.h b/cache.h
index fcf4501..d81c0f0 100644
--- a/cache.h
+++ b/cache.h
@@ -913,6 +913,7 @@ extern struct alternate_object_database {
 } *alt_odb_list;
 extern void prepare_alt_odb(void);
 extern void add_to_alternates_file(const char *reference);
+extern void update_alternates_file_content(const char *content);
 typedef int alt_odb_fn(struct alternate_object_database *, void *);
 extern void foreach_alt_odb(alt_odb_fn, void*);
 
diff --git a/sha1_file.c b/sha1_file.c
index d5616dc..dae7bf6 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -388,6 +388,17 @@ void add_to_alternates_file(const char *reference)
 		link_alt_odb_entries(alt, alt + strlen(alt), '\n', NULL, 0);
 }
 
+void update_alternates_file_content(const char *content)
+{
+	struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+	int fd = hold_lock_file_for_update(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR);
+	write_or_die(fd, content, strlen(content));
+	if (commit_lock_file(lock))
+		die("could not close alternates file");
+	if (alt_odb_tail)
+		link_alt_odb_entries(content, content + strlen(content), '\n', NULL, 0);
+}
+
 void foreach_alt_odb(alt_odb_fn fn, void *cb)
 {
 	struct alternate_object_database *ent;
-- 
1.7.6

  reply	other threads:[~2011-08-22  9:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-22  9:05 [PATCH v2 0/1] git-clone: fix relative path problem in the alternates Hui Wang
2011-08-22  9:05 ` Hui Wang [this message]
2011-08-22 19:10 ` Junio C Hamano
2011-08-22 20:38   ` Junio C Hamano
2011-08-22 21:57     ` Junio C Hamano
2011-08-23  1:05       ` [PATCH 0/2] clone-local fixup Junio C Hamano
2011-08-23  1:05         ` [PATCH 1/2] clone: allow more than one --reference Junio C Hamano
2011-08-23  1:05         ` [PATCH 2/2] clone: clone from a repository with relative alternates Junio C Hamano
2011-08-23  3:43         ` [PATCH 0/2] clone-local fixup Hui Wang
2011-08-23 16:26           ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1314003957-9455-2-git-send-email-jason77.wang@gmail.com \
    --to=jason77.wang@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).