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

[PATCH v3 3/4] setup: Add 'abspath_part_inside_repo' function

From
Martin Erik Werner <martinerikwerner@gmail.com>
Date
Jan 31, 2014, 20:22 UTC
Message-ID
<20140131202248.GD9731@mule>
In-Reply-To
<1390781250-20389-2-git-send-email-martinerikwerner@gmail.com>

In order to extract the part of an absolute path which lies inside the repo, it is not possible to directly use real_path, since that would dereference symlinks both outside and inside the work tree.

Add an 'abspath_part_inside_repo' function which incrementally checks each path level by temporarily NUL-terminating at each '/' and comparing against the work tree path. When a match is found, it copies the remainder (which will be the in-repo part) to a destination buffer.

The path being the filesystem root or exactly equal to the work tree are special cases handled separately, since then there is no directory separator between the work tree and in-repo part.

Signed-off-by: Martin Erik Werner <martinerikwerner@gmail.com>
---
 cache.h |  1 +
 setup.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
diff --git a/cache.h b/cache.h
index ce377e1..242f27d 100644
--- a/cache.h
+++ b/cache.h
@@ -426,6 +426,7 @@ extern void verify_filename(const char *prefix,
 			    int diagnose_misspelt_rev);
 extern void verify_non_filename(const char *prefix, const char *name);
 extern int path_inside_repo(const char *prefix, const char *path);
+extern int abspath_part_inside_repo(char *dst, const char *path);
 
 #define INIT_DB_QUIET 0x0001
 
diff --git a/setup.c b/setup.c
index 5432a31..e606846 100644
--- a/setup.c
+++ b/setup.c
@@ -77,6 +77,69 @@ int path_inside_repo(const char *prefix, const char *path)
 	return 0;
 }
 
+/*
+ * It is ok if dst == src, but they should not overlap otherwise.
+ * No checking if the path is in fact an absolute path is done, and it must
+ * already be normalized.
+ *
+ * Find the part of an absolute path that lies inside the work tree by
+ * dereferencing symlinks outside the work tree, for example:
+ * /dir1/repo/dir2/file   (work tree is /dir1/repo)      -> dir2/file
+ * /dir/file              (work tree is /)               -> dir/file
+ * /dir/symlink1/symlink2 (symlink1 points to work tree) -> symlink2
+ * /dir/repo              (exactly equal to work tree)   -> (empty string)
+ */
+int abspath_part_inside_repo(char *dst, const char* src)
+{
+	size_t len;
+	char *dst0;
+	char temp;
+
+	const char* work_tree = get_git_work_tree();
+	if (!work_tree)
+		return -1;
+	len = strlen(src);
+	dst0 = dst;
+
+	// check root level
+	if (has_dos_drive_prefix(src)) {
+		*dst++ = *src++;
+		*dst++ = *src++;
+		*dst++ = *src++;
+	} else {
+		*dst++ = *src++;
+	}
+	temp = *dst;
+	*dst = '\0';
+	if (strcmp(real_path(dst0), work_tree) == 0) {
+		*dst = temp;
+		memmove(dst0, src, len - (dst - dst0) + 1);
+		return 0;
+	}
+	*dst = temp;
+
+	// check each level
+	while (*dst != '\0') {
+		*dst++ = *src++;
+		if (*dst == '/') {
+			*dst = '\0';
+			if (strcmp(real_path(dst0), work_tree) == 0) {
+				memmove(dst0, src + 1, len - (dst - dst0));
+				return 0;
+			}
+			*dst = '/';
+		}
+	}
+
+	// check whole path
+	if (strcmp(real_path(dst0), work_tree) == 0) {
+		*dst0 = '\0';
+		return 0;
+	}
+
+	return -1;
+}
+
 int check_filename(const char *prefix, const char *arg)
 {
 	const char *name;
-- 
1.8.5.2
Previous: Martin Erik WernerNext: Torsten Bögershausen
Message 52 of 56 in “git-mv with absolute path derefereces symlinks”
  1. Martin Erik WernerJan 15, 2014
  2. 0/2 in-tree symlink handling with absolute pathsMartin Erik Werner, Jan 26, 2014
  3. 1/2 t0060: Add test for manipulating symlinks via absolute pathsMartin Erik Werner, Jan 26, 2014
  4. 2/2 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Jan 26, 2014
  5. Torsten BögershausenJan 26, 2014
  6. Martin Erik WernerJan 27, 2014
  7. 2/2 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Jan 27, 2014
  8. Duy NguyenJan 27, 2014
  9. Junio C HamanoJan 27, 2014
  10. 0/4 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Jan 31, 2014
  11. 0/4 Handling of in-tree symlinks for absolute pathsMartin Erik Werner, Feb 2, 2014
  12. 1/4 t0060: Add test for manipulating symlinks via absolute pathsMartin Erik Werner, Feb 2, 2014
  13. 2/4 t0060: Add test for prefix_path when path == work treeMartin Erik Werner, Feb 2, 2014
  14. 3/4 setup: Add 'abspath_part_inside_repo' functionMartin Erik Werner, Feb 2, 2014
  15. Duy NguyenFeb 2, 2014
  16. Duy NguyenFeb 2, 2014
  17. Martin Erik WernerFeb 2, 2014
  18. David KastrupFeb 2, 2014
  19. Torsten BögershausenFeb 2, 2014
  20. Martin Erik WernerFeb 2, 2014
  21. Torsten BögershausenFeb 2, 2014
  22. Duy NguyenFeb 2, 2014
  23. 4/4 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Feb 2, 2014
  24. 0/5 Handling of in-tree symlinks for absolute pathsMartin Erik Werner, Feb 2, 2014
  25. 1/5 t0060: Add test for manipulating symlinks via absolute pathsMartin Erik Werner, Feb 2, 2014
  26. Junio C HamanoFeb 3, 2014
  27. Junio C HamanoFeb 3, 2014
  28. Martin Erik WernerFeb 3, 2014
  29. 2/5 t0060: Add test for prefix_path when path == work treeMartin Erik Werner, Feb 2, 2014
  30. 3/5 t0060: Add tests for prefix_path when path begins with work treeMartin Erik Werner, Feb 2, 2014
  31. 4/5 setup: Add 'abspath_part_inside_repo' functionMartin Erik Werner, Feb 2, 2014
  32. Junio C HamanoFeb 3, 2014
  33. Martin Erik WernerFeb 3, 2014
  34. Junio C HamanoFeb 4, 2014
  35. Martin Erik WernerFeb 4, 2014
  36. 5/5 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Feb 2, 2014
  37. Duy NguyenFeb 3, 2014
  38. Martin Erik WernerFeb 3, 2014
  39. Junio C HamanoFeb 4, 2014
  40. 0/6 Handling of in-tree symlinks for absolute pathsMartin Erik Werner, Feb 4, 2014
  41. 1/6 t3004: Add test for ls-files on symlinks via absolute pathsMartin Erik Werner, Feb 4, 2014
  42. 2/6 t0060: Add test for prefix_path on symlinks via absolute pathsMartin Erik Werner, Feb 4, 2014
  43. 3/6 t0060: Add test for prefix_path when path == work treeMartin Erik Werner, Feb 4, 2014
  44. 4/6 t0060: Add tests for prefix_path when path begins with work treeMartin Erik Werner, Feb 4, 2014
  45. Torsten BögershausenFeb 4, 2014
  46. Junio C HamanoFeb 4, 2014
  47. 5/6 setup: Add 'abspath_part_inside_repo' functionMartin Erik Werner, Feb 4, 2014
  48. Junio C HamanoFeb 4, 2014
  49. 6/6 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Feb 4, 2014
  50. 1/4 t0060: Add test for manipulating symlinks via absolute pathsMartin Erik Werner, Jan 31, 2014
  51. 2/4 t0060: Add test for prefix_path when path == work treeMartin Erik Werner, Jan 31, 2014
  52. 3/4 setup: Add 'abspath_part_inside_repo' functionMartin Erik Werner, Jan 31, 2014
  53. Torsten BögershausenJan 31, 2014
  54. Martin Erik WernerFeb 1, 2014
  55. Duy NguyenFeb 1, 2014
  56. 4/4 setup: Don't dereference in-tree symlinks for absolute pathsMartin Erik Werner, Jan 31, 2014

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.