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
next prev parent 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