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

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

From
LHLars Hjemli <hjemli@gmail.com>
Date
Feb 4, 2008, 20:59 UTC
Message-ID
<1202158761-31211-2-git-send-email-hjemli@gmail.com>
In-Reply-To
<1202158761-31211-1-git-send-email-hjemli@gmail.com>

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
Previous: Lars HjemliNext: Lars Hjemli
Message 2 of 13 in “Introduce the .git-file”
  1. 0/4 Introduce the .git-fileLars Hjemli, Feb 4, 2008
  2. 1/4 Add platform-independent .git "symlink"Lars Hjemli, Feb 4, 2008
  3. 2/4 Document the .git-fileLars Hjemli, Feb 4, 2008
  4. 3/4 Add tests for .git fileLars Hjemli, Feb 4, 2008
  5. 4/4 git-submodule: prepare for the .git-fileLars Hjemli, Feb 4, 2008
  6. Mike HommeyFeb 4, 2008
  7. Lars HjemliFeb 4, 2008
  8. Junio C HamanoFeb 6, 2008
  9. 3/4 Add tests for .git fileLars Hjemli, Feb 6, 2008
  10. Junio C HamanoFeb 6, 2008
  11. Lars HjemliFeb 6, 2008
  12. Junio C HamanoFeb 6, 2008
  13. Lars HjemliFeb 6, 2008

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.