Git development
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Daniel Barkalow <barkalow@iabervon.org>
Cc: zuh@iki.fi, git@vger.kernel.org
Subject: Re: Git clone behaviour change in 1.5.6 (vs 1.5.5.1)
Date: Mon, 23 Jun 2008 16:38:36 -0400	[thread overview]
Message-ID: <20080623203835.GA8105@sigill.intra.peff.net> (raw)
In-Reply-To: <alpine.LNX.1.00.0806231554380.19665@iabervon.org>

On Mon, Jun 23, 2008 at 03:56:41PM -0400, Daniel Barkalow wrote:

> > Switching to the 1.5.6 release from 1.5.5.1, I found out that the
> > rewritten git-clone command changed its behaviour wrt cloning to a
> > non-existing destination directory structure. In the shell version the
> > destination (work tree) is created with 'mkdir -p' but in the C
> > version with just the mkdir() call which doesn't create the parent
> > directories.
> > 
> > I can't find any indication that this would be intended in the repo
> > history nor in the mailing list, so I'm left thinking that this is an
> > unwanted regression. Could someone confirm this?
> 
> It wasn't an intentional change, anyway.

Here is a partial fix. For --bare repo creation, we follow a different
codepath, and I think the fix is likely to be a bit tricky. We actually
fail in make_absolute_path, before we try creating the directory. But I
suspect we can't just create the directory ourselves because init_db
expects it not to exist.

-- >8 --
clone: create intermediate directories of repo destination

The shell version used to use "mkdir -p" to create the repo
path, but the C version just calls "mkdir". Let's replicate
the old behavior.
---
 builtin-clone.c  |   40 +++++++++++++++++++++++++++++++++++++++-
 t/t5601-clone.sh |   14 ++++++++++++++
 2 files changed, 53 insertions(+), 1 deletions(-)

diff --git a/builtin-clone.c b/builtin-clone.c
index 5c5acb4..758d02c 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -168,6 +168,44 @@ static void setup_reference(const char *repo)
 	free(ref_git_copy);
 }
 
+static int mkdirp_recurse(char *path, int mode)
+{
+	int n;
+	char tmp;
+	int r;
+
+	if (mkdir(path, mode) == 0)
+		return 0;
+	if (errno != ENOENT)
+		return -1;
+
+	for (n = strlen(path); n > 0 && path[n] != '/'; n--)
+		;
+	if (n == 0)
+		return -1;
+	tmp = path[n];
+	path[n] = '\0';
+	r = mkdirp_recurse(path, mode);
+	path[n] = tmp;
+	if (r < 0)
+		return -1;
+	return mkdir(path, mode);
+}
+
+static int mkdirp(const char *path, int mode)
+{
+	char buf[PATH_MAX];
+	int n;
+
+	n = strlen(path);
+	if (n >= PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return -1;
+	}
+	memcpy(buf, path, n+1);
+	return mkdirp_recurse(buf, mode);
+}
+
 static void copy_or_link_directory(char *src, char *dest)
 {
 	struct dirent *de;
@@ -404,7 +442,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 	if (!option_bare) {
 		junk_work_tree = work_tree;
-		if (mkdir(work_tree, 0755))
+		if (mkdirp(work_tree, 0755))
 			die("could not create work tree dir '%s'.", work_tree);
 		set_git_work_tree(work_tree);
 	}
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 593d1a3..c2c83f0 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -30,4 +30,18 @@ test_expect_success 'clone checks out files' '
 
 '
 
+test_expect_success 'clone creates intermediate directories' '
+
+	git clone src long/path/to/dst &&
+	test -f long/path/to/dst/file
+
+'
+
+test_expect_failure 'clone creates intermediate directories for bare repo' '
+
+	git clone --bare src long/path/to/bare/dst &&
+	test -f long/path/to/bare/dst/config
+
+'
+
 test_done
-- 
1.5.6.105.gceec6.dirty

  reply	other threads:[~2008-06-23 20:39 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-23 19:51 Git clone behaviour change in 1.5.6 (vs 1.5.5.1) Kalle Vahlman
2008-06-23 19:56 ` Daniel Barkalow
2008-06-23 20:38   ` Jeff King [this message]
2008-06-23 21:03     ` Brandon Casey
2008-06-24  5:50       ` [PATCH] clone: create intermediate directories of destination repo Jeff King
2008-06-24  7:39         ` Junio C Hamano
2008-06-24  8:04           ` Jeff King
2008-06-24 15:20             ` Daniel Barkalow
2008-06-25  5:41               ` Jeff King
2008-06-25  6:11                 ` Daniel Barkalow

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=20080623203835.GA8105@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=barkalow@iabervon.org \
    --cc=git@vger.kernel.org \
    --cc=zuh@iki.fi \
    /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