Skip to content

Commit e32afab

Browse files
madscientistgitster
authored andcommitted
git-new-workdir: don't fail if the target directory is empty
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent e69b1ce commit e32afab

File tree

1 file changed

+38
-15
lines changed

1 file changed

+38
-15
lines changed

contrib/workdir/git-new-workdir

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ die () {
1010
exit 128
1111
}
1212

13+
failed () {
14+
die "unable to create new workdir '$new_workdir'!"
15+
}
16+
1317
if test $# -lt 2 || test $# -gt 3
1418
then
1519
usage "$0 <repository> <new_workdir> [<branch>]"
@@ -35,7 +39,7 @@ esac
3539

3640
# don't link to a configured bare repository
3741
isbare=$(git --git-dir="$git_dir" config --bool --get core.bare)
38-
if test ztrue = z$isbare
42+
if test ztrue = "z$isbare"
3943
then
4044
die "\"$git_dir\" has core.bare set to true," \
4145
" remove from \"$git_dir/config\" to use $0"
@@ -48,35 +52,54 @@ then
4852
"a complete repository."
4953
fi
5054

51-
# don't recreate a workdir over an existing repository
52-
if test -e "$new_workdir"
55+
# make sure the links in the workdir have full paths to the original repo
56+
git_dir=$(cd "$git_dir" && pwd) || exit 1
57+
58+
# don't recreate a workdir over an existing directory, unless it's empty
59+
if test -d "$new_workdir"
5360
then
54-
die "destination directory '$new_workdir' already exists."
61+
if test $(ls -a1 "$new_workdir/." | wc -l) -ne 2
62+
then
63+
die "destination directory '$new_workdir' is not empty."
64+
fi
65+
cleandir="$new_workdir/.git"
66+
else
67+
cleandir="$new_workdir"
5568
fi
5669

57-
# make sure the links use full paths
58-
git_dir=$(cd "$git_dir"; pwd)
70+
mkdir -p "$new_workdir/.git" || failed
71+
cleandir=$(cd "$cleandir" && pwd) || failed
5972

60-
# create the workdir
61-
mkdir -p "$new_workdir/.git" || die "unable to create \"$new_workdir\"!"
73+
cleanup () {
74+
rm -rf "$cleandir"
75+
}
76+
siglist="0 1 2 15"
77+
trap cleanup $siglist
6278

6379
# create the links to the original repo. explicitly exclude index, HEAD and
6480
# logs/HEAD from the list since they are purely related to the current working
6581
# directory, and should not be shared.
6682
for x in config refs logs/refs objects info hooks packed-refs remotes rr-cache svn
6783
do
84+
# create a containing directory if needed
6885
case $x in
6986
*/*)
70-
mkdir -p "$(dirname "$new_workdir/.git/$x")"
87+
mkdir -p "$new_workdir/.git/${x%/*}"
7188
;;
7289
esac
73-
ln -s "$git_dir/$x" "$new_workdir/.git/$x"
90+
91+
ln -s "$git_dir/$x" "$new_workdir/.git/$x" || failed
7492
done
7593

76-
# now setup the workdir
77-
cd "$new_workdir"
94+
# commands below this are run in the context of the new workdir
95+
cd "$new_workdir" || failed
96+
7897
# copy the HEAD from the original repository as a default branch
79-
cp "$git_dir/HEAD" .git/HEAD
80-
# checkout the branch (either the same as HEAD from the original repository, or
81-
# the one that was asked for)
98+
cp "$git_dir/HEAD" .git/HEAD || failed
99+
100+
# the workdir is set up. if the checkout fails, the user can fix it.
101+
trap - $siglist
102+
103+
# checkout the branch (either the same as HEAD from the original repository,
104+
# or the one that was asked for)
82105
git checkout -f $branch

0 commit comments

Comments
 (0)