From: Paul Smith <paul@mad-scientist.net>
To: git@vger.kernel.org
Subject: [PATCH v4] git-new-workdir: Don't fail if the target directory is empty
Date: Wed, 26 Nov 2014 15:38:28 -0500 [thread overview]
Message-ID: <1417034308.23650.51.camel@homebase> (raw)
Allow new workdirs to be created in an empty directory (similar to "git
clone"). Provide more error checking and clean up on failure.
Signed-off-by: Paul Smith <paul@mad-scientist.net>
---
Hopefully this doesn't contain unwanted stylistic changes. There's a
kind of gross thing about the behavior here: because we cd much earlier
than in my previous version we could actually trap and "rm -rf" while
our current working directory is inside the removed location (inside
$cleandir). On a traditional UNIX filesystem this is fine, of course,
but it's possible that some filesystems don't like this in some way. In
Windows for example this will definitely fail (but new-workdir doesn't
support Windows anyway). The only options are (a) don't worry about it
(that's what this patch does), (b) put the "cd" after the trap reset
again, (c) move the trap reset earlier and don't clean up if we get
failures after we "cd", or (d) "cd" again inside the cleanup function.
Of these, (d) is the most complex and hence my least favorite.
contrib/workdir/git-new-workdir | 53 +++++++++++++++++++++++++++++------------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/contrib/workdir/git-new-workdir b/contrib/workdir/git-new-workdir
index 75e8b25..d1d7f32 100755
--- a/contrib/workdir/git-new-workdir
+++ b/contrib/workdir/git-new-workdir
@@ -10,6 +10,10 @@ die () {
exit 128
}
+failed () {
+ die "unable to create new workdir \"$new_workdir\"!"
+}
+
if test $# -lt 2 || test $# -gt 3
then
usage "$0 <repository> <new_workdir> [<branch>]"
@@ -35,7 +39,7 @@ esac
# don't link to a configured bare repository
isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
-if test ztrue = z$isbare
+if test ztrue = "z$isbare"
then
die "\"$git_dir\" has core.bare set to true," \
" remove from \"$git_dir/config\" to use $0"
@@ -48,35 +52,54 @@ then
"a complete repository."
fi
-# don't recreate a workdir over an existing repository
-if test -e "$new_workdir"
+# make sure the links in the workdir have full paths to the original repo
+git_dir=$(cd "$git_dir" && pwd) || exit 1
+
+# don't recreate a workdir over an existing directory, unless it's empty
+if test -d "$new_workdir"
then
- die "destination directory '$new_workdir' already exists."
+ if test $(ls -a1 "$new_workdir/." | wc -l) -ne 2
+ then
+ die "destination directory '$new_workdir' is not empty."
+ fi
+ cleandir="$new_workdir/.git"
+else
+ cleandir="$new_workdir"
fi
-# make sure the links use full paths
-git_dir=$(cd "$git_dir"; pwd)
+mkdir -p "$new_workdir/.git" || failed
+cleandir=$(cd "$cleandir" && pwd) || failed
-# create the workdir
-mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"
+cleanup () {
+ rm -rf "$cleandir"
+}
+siglist="0 1 2 15"
+trap cleanup $siglist
# create the links to the original repo. explicitly exclude index, HEAD and
# logs/HEAD from the list since they are purely related to the current working
# directory, and should not be shared.
for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
do
+ # create a containing directory if needed
case $x in
*/*)
- mkdir -p "$(dirname "$new_workdir/.git/$x")"
+ mkdir -p "$new_workdir/.git/${x%/*}"
;;
esac
- ln -s "$git_dir/$x" "$new_workdir/.git/$x"
+
+ ln -s "$git_dir/$x" "$new_workdir/.git/$x" || failed
done
-# now setup the workdir
-cd "$new_workdir"
+# commands below this are run in the context of the new workdir
+cd "$new_workdir" || failed
+
# copy the HEAD from the original repository as a default branch
-cp "$git_dir/HEAD" .git/HEAD
-# checkout the branch (either the same as HEAD from the original repository, or
-# the one that was asked for)
+cp "$git_dir/HEAD" .git/HEAD || failed
+
+# the workdir is set up. if the checkout fails, the user can fix it.
+trap - $siglist
+
+# checkout the branch (either the same as HEAD from the original repository,
+# or the one that was asked for)
git checkout -f $branch
--
1.8.5.3
next reply other threads:[~2014-11-26 20:45 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-26 20:38 Paul Smith [this message]
2014-11-26 21:55 ` [PATCH v4] git-new-workdir: Don't fail if the target directory is empty Junio C Hamano
2014-11-26 22:31 ` Paul Smith
2014-11-26 23:16 ` Junio C Hamano
2014-11-28 18:34 ` Paul Smith
2014-12-10 17:16 ` Paul Smith
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=1417034308.23650.51.camel@homebase \
--to=paul@mad-scientist.net \
--cc=git@vger.kernel.org \
/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).