* [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 0/4 v3] Introducing the .git file @ 2008-02-20 22:13 Lars Hjemli 2008-02-20 22:13 ` [PATCH 1/4] Add platform-independent .git "symlink" Lars Hjemli 0 siblings, 1 reply; 14+ messages in thread From: Lars Hjemli @ 2008-02-20 22:13 UTC (permalink / raw) To: Junio C Hamano; +Cc: git This is a resend of my previous series implementing the .git file, rebased on top of todays master (e3c58f8b). The patches are identical to the final suggestions in http://thread.gmane.org/gmane.comp.version-control.git/74258 except for the previous 1/5 which is dropped from the series (since it already appears in master). There are also some minor touch-ups to the commit messages. Shortlog: Add platform-independent .git "symlink" Teach resolve_gitlink_ref() about the .git file Teach git-submodule.sh about the .git file Teach GIT-VERSION-GEN about the .git file Diffstat: Documentation/repository-layout.txt | 5 ++- GIT-VERSION-GEN | 2 +- cache.h | 1 + environment.c | 2 + git-submodule.sh | 4 +- refs.c | 17 +++++- setup.c | 47 ++++++++++++++++ t/t0002-gitfile.sh | 103 +++++++++++++++++++++++++++++++++++ 8 files changed, 174 insertions(+), 7 deletions(-) ^ 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).