summaryrefslogtreecommitdiff
path: root/setup.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2008-05-06 02:16:16 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-05-06 02:16:16 (GMT)
commite2e2defc14a79ea5b4aaae23e33072f29c5965eb (patch)
tree6a86523e0105c66bef7e7ee8610773d185b7cad3 /setup.c
parent9c36e1700f99811ea9190279ea197424dcbb0303 (diff)
parentc48799e560c826905e87c8a8a71effeb0ca5e897 (diff)
downloadgit-e2e2defc14a79ea5b4aaae23e33072f29c5965eb.zip
git-e2e2defc14a79ea5b4aaae23e33072f29c5965eb.tar.gz
git-e2e2defc14a79ea5b4aaae23e33072f29c5965eb.tar.bz2
Merge branch 'lh/git-file'
* lh/git-file: Teach GIT-VERSION-GEN about the .git file Teach git-submodule.sh about the .git file Teach resolve_gitlink_ref() about the .git file Add platform-independent .git "symlink"
Diffstat (limited to 'setup.c')
-rw-r--r--setup.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/setup.c b/setup.c
index 1b4fa6a..b8fd476 100644
--- a/setup.c
+++ b/setup.c
@@ -315,6 +315,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.
*/
@@ -323,6 +361,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;
/*
@@ -377,8 +416,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/
@@ -386,6 +427,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(".")) {