git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 5/5] Add test for using Git at root directory

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 11, 2010, 14:43 UTC
Message-ID
<1265899403-15904-6-git-send-email-pclouds@gmail.com>
In-Reply-To
<1265899403-15904-1-git-send-email-pclouds@gmail.com>

This kind of test requires a throw-away root filesystem so that it can play on. If you have such a system, go ahead, "chmod 777 /" and run this test manually. Because this is a dangerous test, you are required to set an env variable, and not to use root to run it.

Script prepare-root.sh may help you set up a chroot environment with Git test suite inside. You will need Linux, static linked busybox, rsync and root permission to use it.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t1509-root-worktree.sh  |  249 +++++++++++++++++++++++++++++++++++++++++++++
 t/t1509/excludes          |   14 +++
 t/t1509/prepare-chroot.sh |   38 +++++++
 3 files changed, 301 insertions(+), 0 deletions(-)
 create mode 100755 t/t1509-root-worktree.sh
 create mode 100644 t/t1509/excludes
 create mode 100755 t/t1509/prepare-chroot.sh
diff --git a/t/t1509-root-worktree.sh b/t/t1509-root-worktree.sh
new file mode 100755
index 0000000..5322a3b
--- /dev/null
+++ b/t/t1509-root-worktree.sh
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+test_description='Test Git when git repository is located at root
+
+This test requires write access in root. Do not bother if you do not
+have a throwaway chroot or VM.
+
+Script t1509/prepare-chroot.sh may help you setup chroot, then you
+can chroot in and execute this test from there.
+'
+
+. ./test-lib.sh
+
+test_cmp_val() {
+	echo "$1" > expected
+	echo "$2" > result
+	test_cmp expected result
+}
+
+test_vars() {
+	test_expect_success "$1: gitdir" '
+		test_cmp_val "'"$2"'" "$(git rev-parse --git-dir)"
+	'
+
+	test_expect_success "$1: worktree" '
+		test_cmp_val "'"$3"'" "$(git rev-parse --show-toplevel)"
+	'
+
+	test_expect_success "$1: prefix" '
+		test_cmp_val "'"$4"'" "$(git rev-parse --show-prefix)"
+	'
+}
+
+test_foobar_root() {
+	test_expect_success 'add relative' '
+		test -z "$(cd / && git ls-files)" &&
+		git add foo/foome &&
+		git add foo/bar/barme &&
+		git add me &&
+		( cd / && git ls-files --stage ) > result &&
+		test_cmp /ls.expected result &&
+		rm "$(git rev-parse --git-dir)/index"
+	'
+
+	test_expect_success 'add absolute' '
+		test -z "$(cd / && git ls-files)" &&
+		git add /foo/foome &&
+		git add /foo/bar/barme &&
+		git add /me &&
+		( cd / && git ls-files --stage ) > result &&
+		test_cmp /ls.expected result &&
+		rm "$(git rev-parse --git-dir)/index"
+	'
+
+}
+
+test_foobar_foo() {
+	test_expect_success 'add relative' '
+		test -z "$(cd / && git ls-files)" &&
+		git add foome &&
+		git add bar/barme &&
+		git add ../me &&
+		( cd / && git ls-files --stage ) > result &&
+		test_cmp /ls.expected result &&
+		rm "$(git rev-parse --git-dir)/index"
+	'
+
+	test_expect_success 'add absolute' '
+		test -z "$(cd / && git ls-files)" &&
+		git add /foo/foome &&
+		git add /foo/bar/barme &&
+		git add /me &&
+		( cd / && git ls-files --stage ) > result &&
+		test_cmp /ls.expected result &&
+		rm "$(git rev-parse --git-dir)/index"
+	'
+}
+
+test_foobar_foobar() {
+	test_expect_success 'add relative' '
+		test -z "$(cd / && git ls-files)" &&
+		git add ../foome &&
+		git add barme &&
+		git add ../../me &&
+		( cd / && git ls-files --stage ) > result &&
+		test_cmp /ls.expected result &&
+		rm "$(git rev-parse --git-dir)/index"
+	'
+
+	test_expect_success 'add absolute' '
+		test -z "$(cd / && git ls-files)" &&
+		git add /foo/foome &&
+		git add /foo/bar/barme &&
+		git add /me &&
+		( cd / && git ls-files --stage ) > result &&
+		test_cmp /ls.expected result &&
+		rm "$(git rev-parse --git-dir)/index"
+	'
+}
+
+if ! test_have_prereq POSIXPERM || ! [ -w / ]; then
+	say "Dangerous test skipped. Read this test if you want to execute it"
+	test_done
+fi
+
+if [ "$IKNOWWHATIAMDOING" != "YES" ]; then
+	say "You must set env var IKNOWWHATIAMDOING=YES in order to run this test"
+	test_done
+fi
+
+if [ "$UID" = 0 ]; then
+	say "No you can't run this with root"
+	test_done
+fi
+
+ONE_SHA1=d00491fd7e5bb6fa28c517a0bb32b8b506539d4d
+
+test_expect_success 'setup' '
+	rm -rf /foo
+	mkdir /foo &&
+	mkdir /foo/bar &&
+	echo 1 > /foo/foome &&
+	echo 1 > /foo/bar/barme &&
+	echo 1 > /me
+'
+
+say "GIT_DIR absolute, GIT_WORK_TREE set"
+
+test_expect_success 'go to /' 'cd /'
+
+cat >ls.expected <<EOF
+100644 $ONE_SHA1 0	foo/bar/barme
+100644 $ONE_SHA1 0	foo/foome
+100644 $ONE_SHA1 0	me
+EOF
+
+export GIT_DIR="$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'abs gitdir, root' "$GIT_DIR" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /foo' 'cd /foo'
+
+test_vars 'abs gitdir, foo' "$GIT_DIR" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+
+test_vars 'abs gitdir, foo/bar' "$GIT_DIR" "/" "foo/bar/"
+test_foobar_foobar
+
+say "GIT_DIR relative, GIT_WORK_TREE set"
+
+test_expect_success 'go to /' 'cd /'
+
+export GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'rel gitdir, root' "$GIT_DIR" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /foo' 'cd /foo'
+
+export GIT_DIR="../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'rel gitdir, foo' "$TRASH_DIRECTORY/.git" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+
+export GIT_DIR="../../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=/
+
+test_vars 'rel gitdir, foo/bar' "$TRASH_DIRECTORY/.git" "/" "foo/bar/"
+test_foobar_foobar
+
+say "GIT_DIR relative, GIT_WORK_TREE relative"
+
+test_expect_success 'go to /' 'cd /'
+
+export GIT_DIR="$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git"
+export GIT_WORK_TREE=.
+
+test_vars 'rel gitdir, root' "$GIT_DIR" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /' 'cd /foo'
+
+export GIT_DIR="../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=..
+
+test_vars 'rel gitdir, foo' "$TRASH_DIRECTORY/.git" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+
+export GIT_DIR="../../$TRASH_DIRECTORY/.git"
+export GIT_WORK_TREE=../..
+
+test_vars 'rel gitdir, foo/bar' "$TRASH_DIRECTORY/.git" "/" "foo/bar/"
+test_foobar_foobar
+
+say ".git at root"
+
+unset GIT_DIR
+unset GIT_WORK_TREE
+
+test_expect_success 'go to /' 'cd /'
+test_expect_success 'setup' '
+	rm -rf /.git
+	echo "Initialized empty Git repository in /.git/" > expected &&
+	git init > result &&
+	test_cmp expected result
+'
+
+test_vars 'auto gitdir, root' ".git" "/" ""
+test_foobar_root
+
+test_expect_success 'go to /foo' 'cd /foo'
+test_vars 'auto gitdir, foo' "/.git" "/" "foo/"
+test_foobar_foo
+
+test_expect_success 'go to /foo/bar' 'cd /foo/bar'
+test_vars 'auto gitdir, foo/bar' "/.git" "/" "foo/bar/"
+test_foobar_foobar
+
+test_expect_success 'cleanup' 'rm -rf /.git'
+
+say "auto bare gitdir"
+
+# DESTROYYYYY!!!!!
+test_expect_success 'setup' '
+	rm -rf /refs /objects /info /hooks
+	rm /*
+	cd / &&
+	echo "Initialized empty Git repository in /" > expected &&
+	git init --bare > result &&
+	test_cmp expected result
+'
+
+test_vars 'auto gitdir, root' "." "" ""
+
+test_expect_success 'go to /foo' 'cd /foo'
+
+test_vars 'auto gitdir, root' "/" "" ""
+
+test_done
diff --git a/t/t1509/excludes b/t/t1509/excludes
new file mode 100644
index 0000000..d4d21d3
--- /dev/null
+++ b/t/t1509/excludes
@@ -0,0 +1,14 @@
+*.o
+*~
+*.bak
+*.c
+*.h
+.git
+contrib
+Documentation
+git-gui
+gitk-git
+gitweb
+t/t4013
+t/t5100
+t/t5515
diff --git a/t/t1509/prepare-chroot.sh b/t/t1509/prepare-chroot.sh
new file mode 100755
index 0000000..407f2d2
--- /dev/null
+++ b/t/t1509/prepare-chroot.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+die() {
+	echo >&2 "$@"
+	exit 1
+}
+
+xmkdir() {
+	while [ -n "$1" ]; do
+		[ -d "$1" ] || mkdir "$1" || die "Unable to mkdir $1"
+		shift
+	done
+}
+
+R="$1"
+
+[ -n "$R" ] || die "Usage: prepare-chroot.sh <root>"
+[ -x git ] || die "This script needs to be executed at git source code's top directory"
+[ -x /bin/busybox ] || die "You need busybox"
+
+xmkdir "$R" "$R/bin" "$R/etc" "$R/lib" "$R/dev"
+[ -c "$R/dev/null" ] || die "/dev/null is missing. Do mknod $R/dev/null c 1 3 && chmod 666 $R/dev/null"
+echo "root:x:0:0:root:/:/bin/sh" > "$R/etc/passwd"
+echo "$(id -nu):x:$(id -u):$(id -g)::$(pwd)/t:/bin/sh" >> "$R/etc/passwd"
+echo "root::0:root" > "$R/etc/group"
+echo "$(id -ng)::$(id -g):$(id -nu)" >> "$R/etc/group"
+
+[ -x "$R/bin/busybox" ] || cp /bin/busybox "$R/bin/busybox"
+[ -x "$R/bin/sh" ] || ln -s /bin/busybox "$R/bin/sh"
+[ -x "$R/bin/su" ] || ln -s /bin/busybox "$R/bin/su"
+
+mkdir -p "$R$(pwd)"
+rsync --exclude-from t/t1509/excludes -Ha . "$R$(pwd)"
+ldd git | grep '=> /' | sed 's,.* => *\([^ ]*\) .*,\1,' | while read i; do
+	mkdir -p "$R$(dirname $i)"
+	cp "$i" "$R/$i"
+done
+echo "Execute this in root: 'chroot $R /bin/su - $(id -nu)'"
-- 
1.7.0.rc2.182.g3adef
Previous: Nguyễn Thái Ngọc DuyNext: Johannes Sixt
Message 7 of 10 in “Worktree/Gitdir at root directory”
  1. 0/5 Worktree/Gitdir at root directoryNguyễn Thái Ngọc Duy, Feb 11, 2010
  2. 1/5 make_absolute_path(): Do not append redundant slashNguyễn Thái Ngọc Duy, Feb 11, 2010
  3. 2/5 init-db, rev-parse --git-dir: do not append redundant slashNguyễn Thái Ngọc Duy, Feb 11, 2010
  4. 3/5 Add is_root_path()Nguyễn Thái Ngọc Duy, Feb 11, 2010
  5. Johannes SixtFeb 12, 2010
  6. 4/5 Support working directory located at rootNguyễn Thái Ngọc Duy, Feb 11, 2010
  7. 5/5 Add test for using Git at root directoryNguyễn Thái Ngọc Duy, Feb 11, 2010
  8. Johannes SixtFeb 12, 2010
  9. João Carlos Mendes LuísFeb 12, 2010
  10. Johannes SixtFeb 12, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.