[PATCH 0/4] Introduce the .git-file

DORMANTno replies

7 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH 0/4] Introduce the .git-file

From: Lars Hjemli <hidden>
Date: 2016-06-15 22:44:10

This is a resend of my previous patches + an update to make git-submodule
work with the .git-file + a litte documentation.

PS: Regarding the color of the bikeshed, it seems that everyone can live
with  "gitdir:" so that's what I ended up using.

Diffstat:
 Documentation/repository-layout.txt |    5 ++-
 git-submodule.sh                    |    4 +-
 setup.c                             |   40 +++++++++++++++++++
 t/t0002-gitfile.sh                  |   71 +++++++++++++++++++++++++++++++++++
 4 files changed, 117 insertions(+), 3 deletions(-)

[PATCH 4/4] git-submodule: prepare for the .git-file

From: Lars Hjemli <hidden>
Date: 2016-06-15 22:44:10

When git-submodule tried to detect 'active' submodules, it checked for the
existence of a directory named '.git'. This isn't good enough now that .git
can be a file pointing to the real $GIT_DIR so the tests are changed to
reflect this.

Signed-off-by: Lars Hjemli <redacted>
---
 git-submodule.sh |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/git-submodule.sh b/git-submodule.sh
index a6aaf40..220d64c 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -288,7 +288,7 @@ cmd_update()
 			continue
 		fi
 
-		if ! test -d "$path"/.git
+		if ! test -e "$path"/.git
 		then
 			module_clone "$path" "$url" || exit
 			subsha1=
@@ -362,7 +362,7 @@ cmd_status()
 	do
 		name=$(module_name "$path") || exit
 		url=$(git config submodule."$name".url)
-		if test -z "url" || ! test -d "$path"/.git
+		if test -z "url" || ! test -e "$path"/.git
 		then
 			say "-$sha1 $path"
 			continue;
-- 
1.5.4.5.g25d066

[PATCH 3/4] Add tests for .git file

From: Lars Hjemli <hidden>
Date: 2016-06-15 22:44:10

Verify that the basic plumbing works when .git is a file pointing at
the real git directory.

Signed-off-by: Lars Hjemli <redacted>
---
 t/t0002-gitfile.sh |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 71 insertions(+), 0 deletions(-)
 create mode 100755 t/t0002-gitfile.sh
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
new file mode 100755
index 0000000..f8f39e6
--- /dev/null
+++ b/t/t0002-gitfile.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='.git file
+
+Verify that plumbing commands work when .git is a file
+'
+. ./test-lib.sh
+
+chkfile() {
+	D=$(echo $1 | cut -b 1-2) &&
+	F=$(echo $1 | cut -b 3-40) &&
+	if test ! -f $REAL/objects/$D/$F
+	then
+		echo "Object not found: $REAL/objects/$D/$F"
+		false
+	fi
+}
+
+test_expect_success 'setup' '
+	REAL=$(pwd)/.real &&
+	mv .git $REAL &&
+	echo "gitdir: $REAL" >.git
+'
+
+test_expect_success 'check rev-parse --git-dir' '
+	test "$REAL" = "$(git rev-parse --git-dir)"
+'
+
+test_expect_success 'check hash-object' '
+	echo "foo" >bar &&
+	SHA=$(cat bar | git hash-object -w --stdin) &&
+	chkfile $SHA
+'
+
+test_expect_success 'check cat-file' '
+	git cat-file blob $SHA >actual &&
+	diff -u bar actual
+'
+
+test_expect_success 'check update-index' '
+	if test -f $REAL/index
+	then
+		echo "Hmm, $REAL/index exists?"
+		false
+	fi &&
+	rm -rf $REAL/objects/* &&
+	git update-index --add bar &&
+	if ! test -f $REAL/index
+	then
+		echo "$REAL/index not found"
+		false
+	fi &&
+	chkfile $SHA
+'
+
+test_expect_success 'check write-tree' '
+	SHA=$(git write-tree) &&
+	chkfile $SHA
+'
+
+test_expect_success 'check commit-tree' '
+	SHA=$(echo "commit bar" | git commit-tree $SHA) &&
+	chkfile $SHA
+'
+
+test_expect_success 'check rev-list' '
+	echo $SHA >$REAL/HEAD &&
+	test "$SHA" = "$(git rev-list HEAD)"
+'
+
+test_done
-- 
1.5.4.5.g25d066

[PATCH 1/4] Add platform-independent .git "symlink"

From: Lars Hjemli <hidden>
Date: 2016-06-15 22:44:10

This patch allows .git to be a regular textfile containing the path of
the real git directory (formatted like "gitdir: <path>\n"), which is
useful on platforms lacking support for real symlinks.

Signed-off-by: Lars Hjemli <redacted>
---
 setup.c |   40 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/setup.c b/setup.c
index adede16..2cbda91 100644
--- a/setup.c
+++ b/setup.c
@@ -239,6 +239,40 @@ static int check_repository_format_gently(int *nongit_ok)
 }
 
 /*
+ * Try to read the location of the git directory from the .git file,
+ * return path to git directory if found.
+ * Format of the .git file is
+ *    gitdir: <path>\n
+ */
+static const char *read_gitfile_gently(const char *path)
+{
+	static char buf[PATH_MAX + 9];  /* "gitdir: " + "\n" */
+	struct stat st;
+	int fd;
+	size_t len;
+
+	if (stat(path, &st))
+		return NULL;
+	if (!S_ISREG(st.st_mode) || st.st_size >= sizeof(buf))
+		return NULL;
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return NULL;
+	len = read_in_full(fd, buf, sizeof(buf));
+	close(fd);
+	if (len != st.st_size)
+		return NULL;
+	if (!len || buf[len - 1] != '\n')
+		return NULL;
+	buf[len - 1] = '\0';
+	if (prefixcmp(buf, "gitdir: "))
+		return NULL;
+	if (!is_git_directory(buf + 8))
+		return NULL;
+	return make_absolute_path(buf + 8);
+}
+
+/*
  * We cannot decide in this function whether we are in the work tree or
  * not, since the config can only be read _after_ this function was called.
  */
@@ -247,6 +281,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	static char cwd[PATH_MAX+1];
 	const char *gitdirenv;
+	const char *gitfile_dir;
 	int len, offset;
 
 	/*
@@ -302,6 +337,11 @@ const char *setup_git_directory_gently(int *nongit_ok)
 	 */
 	offset = len = strlen(cwd);
 	for (;;) {
+		gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+		if (gitfile_dir) {
+			setenv(GIT_DIR_ENVIRONMENT, gitfile_dir, 1);
+			break;
+		}
 		if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
 			break;
 		if (is_git_directory(".")) {
-- 
1.5.4.5.g25d066

[PATCH 2/4] Document the .git-file

From: Lars Hjemli <hidden>
Date: 2016-06-15 22:44:10

---
 Documentation/repository-layout.txt |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt
index 6939130..e9db3a1 100644
--- a/Documentation/repository-layout.txt
+++ b/Documentation/repository-layout.txt
@@ -3,7 +3,10 @@ git repository layout
 
 You may find these things in your git repository (`.git`
 directory for a repository associated with your working tree, or
-`'project'.git` directory for a public 'bare' repository).
+`'project'.git` directory for a public 'bare' repository. It is
+also possible to have a working tree where `.git` is a plain
+ascii file containing `gitdir: <path>\n`, i.e. the path to the
+real git repository).
 
 objects::
 	Object store associated with this repository.  Usually
-- 
1.5.4.5.g25d066

Re: [PATCH 4/4] git-submodule: prepare for the .git-file

From: Mike Hommey <hidden>
Date: 2016-06-15 22:44:10

On Mon, Feb 04, 2008 at 09:59:21PM +0100, Lars Hjemli wrote:
-		if ! test -d "$path"/.git
+		if ! test -e "$path"/.git
Is test -e supported by all shells we support ? I have some doubts...

Mike

Re: [PATCH 4/4] git-submodule: prepare for the .git-file

From: Lars Hjemli <hidden>
Date: 2016-06-15 22:44:10

On Feb 4, 2008 11:23 PM, Mike Hommey [off-list ref] wrote:
On Mon, Feb 04, 2008 at 09:59:21PM +0100, Lars Hjemli wrote:
quoted
-             if ! test -d "$path"/.git
+             if ! test -e "$path"/.git
Is test -e supported by all shells we support ? I have some doubts...
I dunno, but we already use it two other places in git-submodule.

I guess we can rewrite it to something like
  test -d $path || test -f $path || test -L $path || exist=0
if needed.

-- 
lh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help