* [PATCH 0/4] Introduce the .git-file
@ 2008-02-04 20:59 Lars Hjemli
2008-02-04 20:59 ` [PATCH 1/4] Add platform-independent .git "symlink" Lars Hjemli
0 siblings, 1 reply; 14+ messages in thread
From: Lars Hjemli @ 2008-02-04 20:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
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(-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/4] Add platform-independent .git "symlink"
2008-02-04 20:59 [PATCH 0/4] Introduce the .git-file Lars Hjemli
@ 2008-02-04 20:59 ` Lars Hjemli
2008-02-04 20:59 ` [PATCH 2/4] Document the .git-file Lars Hjemli
0 siblings, 1 reply; 14+ messages in thread
From: Lars Hjemli @ 2008-02-04 20:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
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 <hjemli@gmail.com>
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] Document the .git-file
2008-02-04 20:59 ` [PATCH 1/4] Add platform-independent .git "symlink" Lars Hjemli
@ 2008-02-04 20:59 ` Lars Hjemli
2008-02-04 20:59 ` [PATCH 3/4] Add tests for .git file Lars Hjemli
0 siblings, 1 reply; 14+ messages in thread
From: Lars Hjemli @ 2008-02-04 20:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] Add tests for .git file
2008-02-04 20:59 ` [PATCH 2/4] Document the .git-file Lars Hjemli
@ 2008-02-04 20:59 ` Lars Hjemli
2008-02-04 20:59 ` [PATCH 4/4] git-submodule: prepare for the .git-file Lars Hjemli
2008-02-06 3:25 ` [PATCH 3/4] Add tests for .git file Junio C Hamano
0 siblings, 2 replies; 14+ messages in thread
From: Lars Hjemli @ 2008-02-04 20:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
Verify that the basic plumbing works when .git is a file pointing at
the real git directory.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/4] git-submodule: prepare for the .git-file
2008-02-04 20:59 ` [PATCH 3/4] Add tests for .git file Lars Hjemli
@ 2008-02-04 20:59 ` Lars Hjemli
2008-02-04 22:23 ` Mike Hommey
2008-02-06 3:25 ` [PATCH 3/4] Add tests for .git file Junio C Hamano
1 sibling, 1 reply; 14+ messages in thread
From: Lars Hjemli @ 2008-02-04 20:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
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 <hjemli@gmail.com>
---
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
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] git-submodule: prepare for the .git-file
2008-02-04 20:59 ` [PATCH 4/4] git-submodule: prepare for the .git-file Lars Hjemli
@ 2008-02-04 22:23 ` Mike Hommey
2008-02-04 22:44 ` Lars Hjemli
0 siblings, 1 reply; 14+ messages in thread
From: Mike Hommey @ 2008-02-04 22:23 UTC (permalink / raw)
To: Lars Hjemli; +Cc: Junio C Hamano, Johannes Schindelin, Shawn O. Pearce, git
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
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 4/4] git-submodule: prepare for the .git-file
2008-02-04 22:23 ` Mike Hommey
@ 2008-02-04 22:44 ` Lars Hjemli
0 siblings, 0 replies; 14+ messages in thread
From: Lars Hjemli @ 2008-02-04 22:44 UTC (permalink / raw)
To: Mike Hommey; +Cc: Junio C Hamano, Johannes Schindelin, Shawn O. Pearce, git
On Feb 4, 2008 11:23 PM, Mike Hommey <mh@glandium.org> wrote:
> 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...
>
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
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] Add tests for .git file
2008-02-04 20:59 ` [PATCH 3/4] Add tests for .git file Lars Hjemli
2008-02-04 20:59 ` [PATCH 4/4] git-submodule: prepare for the .git-file Lars Hjemli
@ 2008-02-06 3:25 ` Junio C Hamano
2008-02-06 7:56 ` [PATCH 3/4 v2] " Lars Hjemli
1 sibling, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2008-02-06 3:25 UTC (permalink / raw)
To: Lars Hjemli; +Cc: Johannes Schindelin, Shawn O. Pearce, git
Lars Hjemli <hjemli@gmail.com> writes:
> Verify that the basic plumbing works when .git is a file pointing at
> the real git directory.
>
> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
> ---
> 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
P=$(echo $1 | sed -e 's|\(..\)\(.*\)|\1/\2\|') &&
if test ! -f "$REAL/objects/$P"
...
Although it probably is more efficient to do this with one
process, s/cut/sed/ is mostly a style issue.
Be careful with quoting. $REAL might contain a $IFS whitespace
as you grabbed it from $(pwd)...
> +test_expect_success 'setup' '
> + REAL=$(pwd)/.real &&
> + mv .git $REAL &&
> + echo "gitdir: $REAL" >.git
> +'
> ...
> +test_expect_success 'check update-index' '
> + if test -f $REAL/index
> + then
> + echo "Hmm, $REAL/index exists?"
> + false
> + fi &&
> + rm -rf $REAL/objects/* &&
... and it matters especially if you do this ;-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4 v2] Add tests for .git file
2008-02-06 3:25 ` [PATCH 3/4] Add tests for .git file Junio C Hamano
@ 2008-02-06 7:56 ` Lars Hjemli
2008-02-06 8:40 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Lars Hjemli @ 2008-02-06 7:56 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
Verify that the basic plumbing works when .git is a file pointing at
the real git directory.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
This updated patch replaces cut with sed and tries to do proper quoting.
t/t0002-gitfile.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 74 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..7f8ee2f
--- /dev/null
+++ b/t/t0002-gitfile.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+test_description='.git file
+
+Verify that plumbing commands work when .git is a file
+'
+. ./test-lib.sh
+
+objpath() {
+ echo $1 | sed -re 's|(..)(.+)|\1/\2|'
+}
+
+objck() {
+ p=$(objpath $1)
+ if test ! -f "$REAL/objects/$p"
+ then
+ echo "Object not found: $REAL/objects/$p"
+ 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) &&
+ objck $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 -f "$REAL/objects/$(objpath $SHA)" &&
+ git update-index --add bar &&
+ if ! test -f "$REAL/index"
+ then
+ echo "$REAL/index not found"
+ false
+ fi &&
+ objck $SHA
+'
+
+test_expect_success 'check write-tree' '
+ SHA=$(git write-tree) &&
+ objck $SHA
+'
+
+test_expect_success 'check commit-tree' '
+ SHA=$(echo "commit bar" | git commit-tree $SHA) &&
+ objck $SHA
+'
+
+test_expect_success 'check rev-list' '
+ echo $SHA >"$REAL/HEAD" &&
+ test "$SHA" = "$(git rev-list HEAD)"
+'
+
+test_done
--
1.5.4.6.g6627
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4 v2] Add tests for .git file
2008-02-06 7:56 ` [PATCH 3/4 v2] " Lars Hjemli
@ 2008-02-06 8:40 ` Junio C Hamano
2008-02-06 9:30 ` Lars Hjemli
0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2008-02-06 8:40 UTC (permalink / raw)
To: Lars Hjemli; +Cc: Johannes Schindelin, Shawn O. Pearce, git
Lars Hjemli <hjemli@gmail.com> writes:
> Verify that the basic plumbing works when .git is a file pointing at
> the real git directory.
>
> Signed-off-by: Lars Hjemli <hjemli@gmail.com>
> ---
>
> This updated patch replaces cut with sed and tries to do proper quoting.
>
>
> t/t0002-gitfile.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 74 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..7f8ee2f
> --- /dev/null
> +++ b/t/t0002-gitfile.sh
> @@ -0,0 +1,74 @@
> +#!/bin/sh
> +
> +test_description='.git file
> +
> +Verify that plumbing commands work when .git is a file
> +'
> +. ./test-lib.sh
> +
> +objpath() {
> + echo $1 | sed -re 's|(..)(.+)|\1/\2|'
> +}
"sed -r"??? Please limit ourselves to the basics.
> +test_expect_success 'check commit-tree' '
> + SHA=$(echo "commit bar" | git commit-tree $SHA) &&
> + objck $SHA
> +'
> +
> +test_expect_success 'check rev-list' '
> + echo $SHA >"$REAL/HEAD" &&
> + test "$SHA" = "$(git rev-list HEAD)"
> +'
Nicely done.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4 v2] Add tests for .git file
2008-02-06 8:40 ` Junio C Hamano
@ 2008-02-06 9:30 ` Lars Hjemli
2008-02-06 10:13 ` Junio C Hamano
0 siblings, 1 reply; 14+ messages in thread
From: Lars Hjemli @ 2008-02-06 9:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
On Feb 6, 2008 9:40 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Lars Hjemli <hjemli@gmail.com> writes:
> > +objpath() {
> > + echo $1 | sed -re 's|(..)(.+)|\1/\2|'
> > +}
>
> "sed -r"??? Please limit ourselves to the basics.
Sorry, I didn't realize 'sed -r' wasn't kosher. Should I resend or is
this something you'd --amend?
--
larsh
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4 v2] Add tests for .git file
2008-02-06 9:30 ` Lars Hjemli
@ 2008-02-06 10:13 ` Junio C Hamano
2008-02-06 10:35 ` Lars Hjemli
0 siblings, 1 reply; 14+ messages in thread
From: Junio C Hamano @ 2008-02-06 10:13 UTC (permalink / raw)
To: Lars Hjemli; +Cc: Junio C Hamano, Johannes Schindelin, Shawn O. Pearce, git
"Lars Hjemli" <hjemli@gmail.com> writes:
> On Feb 6, 2008 9:40 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Lars Hjemli <hjemli@gmail.com> writes:
>> > +objpath() {
>> > + echo $1 | sed -re 's|(..)(.+)|\1/\2|'
>> > +}
>>
>> "sed -r"??? Please limit ourselves to the basics.
>
> Sorry, I didn't realize 'sed -r' wasn't kosher. Should I resend or is
> this something you'd --amend?
If we live in POSIX only world it is fine, but I try to be
conservative when I am able.
No need to resend; I've done something like this (there are
other minor amends).
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
new file mode 100755
index 0000000..d280663
--- /dev/null
+++ b/t/t0002-gitfile.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+test_description='.git file
+
+Verify that plumbing commands work when .git is a file
+'
+. ./test-lib.sh
+
+objpath() {
+ echo "$1" | sed -e 's|\(..\)|\1/|'
+}
+ ...
But the result won't be pushed out til tomorrow morning.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4 v2] Add tests for .git file
2008-02-06 10:13 ` Junio C Hamano
@ 2008-02-06 10:35 ` Lars Hjemli
0 siblings, 0 replies; 14+ messages in thread
From: Lars Hjemli @ 2008-02-06 10:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, Shawn O. Pearce, git
On Feb 6, 2008 11:13 AM, Junio C Hamano <gitster@pobox.com> wrote:
> "Lars Hjemli" <hjemli@gmail.com> writes:
>
> > On Feb 6, 2008 9:40 AM, Junio C Hamano <gitster@pobox.com> wrote:
> >> Lars Hjemli <hjemli@gmail.com> writes:
> >> > +objpath() {
> >> > + echo $1 | sed -re 's|(..)(.+)|\1/\2|'
> >> > +}
> >>
> >> "sed -r"??? Please limit ourselves to the basics.
> >
> > Sorry, I didn't realize 'sed -r' wasn't kosher. Should I resend or is
> > this something you'd --amend?
>
> If we live in POSIX only world it is fine, but I try to be
> conservative when I am able.
Ok, good to know that my lack of experience doesn't pollute the codebase ;-)
> No need to resend; I've done something like this (there are
> other minor amends).
>...
> +objpath() {
> + echo "$1" | sed -e 's|\(..\)|\1/|'
> +}
Thanks.
--
larsh
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/4] Add platform-independent .git "symlink"
2008-02-20 22:13 [PATCH 0/4 v3] Introducing the " Lars Hjemli
@ 2008-02-20 22:13 ` Lars Hjemli
0 siblings, 0 replies; 14+ messages in thread
From: Lars Hjemli @ 2008-02-20 22:13 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch allows .git to be a regular textfile containing the path of
the real git directory (prefixed with "gitdir: "), which can be useful on
platforms lacking support for real symlinks.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
---
Documentation/repository-layout.txt | 5 ++-
cache.h | 1 +
environment.c | 2 +
setup.c | 47 ++++++++++++++++
t/t0002-gitfile.sh | 103 +++++++++++++++++++++++++++++++++++
5 files changed, 157 insertions(+), 1 deletions(-)
create mode 100755 t/t0002-gitfile.sh
diff --git a/Documentation/repository-layout.txt b/Documentation/repository-layout.txt
index 6939130..bbaed2e 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>`, i.e. the path to the
+real git repository).
objects::
Object store associated with this repository. Usually
diff --git a/cache.h b/cache.h
index e1000bc..1ad822a 100644
--- a/cache.h
+++ b/cache.h
@@ -277,6 +277,7 @@ extern char *get_index_file(void);
extern char *get_graft_file(void);
extern int set_git_dir(const char *path);
extern const char *get_git_work_tree(void);
+extern const char *read_gitfile_gently(const char *path);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
diff --git a/environment.c b/environment.c
index 3527f16..8058e7b 100644
--- a/environment.c
+++ b/environment.c
@@ -49,6 +49,8 @@ static void setup_git_env(void)
{
git_dir = getenv(GIT_DIR_ENVIRONMENT);
if (!git_dir)
+ git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
+ if (!git_dir)
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
git_object_dir = getenv(DB_ENVIRONMENT);
if (!git_object_dir) {
diff --git a/setup.c b/setup.c
index 4509598..20502be 100644
--- a/setup.c
+++ b/setup.c
@@ -239,6 +239,44 @@ 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.
+ */
+const char *read_gitfile_gently(const char *path)
+{
+ char *buf;
+ struct stat st;
+ int fd;
+ size_t len;
+
+ if (stat(path, &st))
+ return NULL;
+ if (!S_ISREG(st.st_mode))
+ return NULL;
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ die("Error opening %s: %s", path, strerror(errno));
+ buf = xmalloc(st.st_size + 1);
+ len = read_in_full(fd, buf, st.st_size);
+ close(fd);
+ if (len != st.st_size)
+ die("Error reading %s", path);
+ buf[len] = '\0';
+ if (prefixcmp(buf, "gitdir: "))
+ die("Invalid gitfile format: %s", path);
+ while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
+ len--;
+ if (len < 9)
+ die("No path in gitfile: %s", path);
+ buf[len] = '\0';
+ if (!is_git_directory(buf + 8))
+ die("Not a git repository: %s", buf + 8);
+ path = make_absolute_path(buf + 8);
+ free(buf);
+ return path;
+}
+
+/*
* 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 +285,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;
/*
@@ -293,8 +332,10 @@ const char *setup_git_directory_gently(int *nongit_ok)
/*
* Test in the following order (relative to the cwd):
+ * - .git (file containing "gitdir: <path>")
* - .git/
* - ./ (bare)
+ * - ../.git
* - ../.git/
* - ../ (bare)
* - ../../.git/
@@ -302,6 +343,12 @@ 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) {
+ if (set_git_dir(gitfile_dir))
+ die("Repository setup failed");
+ break;
+ }
if (is_git_directory(DEFAULT_GIT_DIR_ENVIRONMENT))
break;
if (is_git_directory(".")) {
diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh
new file mode 100755
index 0000000..c5dbc72
--- /dev/null
+++ b/t/t0002-gitfile.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+test_description='.git file
+
+Verify that plumbing commands work when .git is a file
+'
+. ./test-lib.sh
+
+objpath() {
+ echo "$1" | sed -e 's|\(..\)|\1/|'
+}
+
+objck() {
+ p=$(objpath "$1")
+ if test ! -f "$REAL/objects/$p"
+ then
+ echo "Object not found: $REAL/objects/$p"
+ false
+ fi
+}
+
+
+test_expect_success 'initial setup' '
+ REAL="$(pwd)/.real" &&
+ mv .git "$REAL"
+'
+
+test_expect_success 'bad setup: invalid .git file format' '
+ echo "gitdir $REAL" >.git &&
+ if git rev-parse 2>.err
+ then
+ echo "git rev-parse accepted an invalid .git file"
+ false
+ fi &&
+ if ! grep -qe "Invalid gitfile format" .err
+ then
+ echo "git rev-parse returned wrong error"
+ false
+ fi
+'
+
+test_expect_success 'bad setup: invalid .git file path' '
+ echo "gitdir: $REAL.not" >.git &&
+ if git rev-parse 2>.err
+ then
+ echo "git rev-parse accepted an invalid .git file path"
+ false
+ fi &&
+ if ! grep -qe "Not a git repository" .err
+ then
+ echo "git rev-parse returned wrong error"
+ false
+ fi
+'
+
+test_expect_success 'final setup + check rev-parse --git-dir' '
+ echo "gitdir: $REAL" >.git &&
+ test "$REAL" = "$(git rev-parse --git-dir)"
+'
+
+test_expect_success 'check hash-object' '
+ echo "foo" >bar &&
+ SHA=$(cat bar | git hash-object -w --stdin) &&
+ objck $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 -f "$REAL/objects/$(objpath $SHA)" &&
+ git update-index --add bar &&
+ if ! test -f "$REAL/index"
+ then
+ echo "$REAL/index not found"
+ false
+ fi &&
+ objck $SHA
+'
+
+test_expect_success 'check write-tree' '
+ SHA=$(git write-tree) &&
+ objck $SHA
+'
+
+test_expect_success 'check commit-tree' '
+ SHA=$(echo "commit bar" | git commit-tree $SHA) &&
+ objck $SHA
+'
+
+test_expect_success 'check rev-list' '
+ echo $SHA >"$REAL/HEAD" &&
+ test "$SHA" = "$(git rev-list HEAD)"
+'
+
+test_done
--
1.5.4.1.188.g3ea1f5
^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2008-02-20 22:38 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-04 20:59 [PATCH 0/4] Introduce the .git-file Lars Hjemli
2008-02-04 20:59 ` [PATCH 1/4] Add platform-independent .git "symlink" Lars Hjemli
2008-02-04 20:59 ` [PATCH 2/4] Document the .git-file Lars Hjemli
2008-02-04 20:59 ` [PATCH 3/4] Add tests for .git file Lars Hjemli
2008-02-04 20:59 ` [PATCH 4/4] git-submodule: prepare for the .git-file Lars Hjemli
2008-02-04 22:23 ` Mike Hommey
2008-02-04 22:44 ` Lars Hjemli
2008-02-06 3:25 ` [PATCH 3/4] Add tests for .git file Junio C Hamano
2008-02-06 7:56 ` [PATCH 3/4 v2] " Lars Hjemli
2008-02-06 8:40 ` Junio C Hamano
2008-02-06 9:30 ` Lars Hjemli
2008-02-06 10:13 ` Junio C Hamano
2008-02-06 10:35 ` Lars Hjemli
-- strict thread matches above, loose matches on Subject: below --
2008-02-20 22:13 [PATCH 0/4 v3] Introducing the " Lars Hjemli
2008-02-20 22:13 ` [PATCH 1/4] Add platform-independent .git "symlink" Lars Hjemli
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).