summaryrefslogtreecommitdiff
path: root/path.c
diff options
context:
space:
mode:
Diffstat (limited to 'path.c')
-rw-r--r--path.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/path.c b/path.c
index 0c16dc5fdb..fa62da58ed 100644
--- a/path.c
+++ b/path.c
@@ -558,6 +558,51 @@ const char *relative_path(const char *in, const char *prefix,
}
/*
+ * A simpler implementation of relative_path
+ *
+ * Get relative path by removing "prefix" from "in". This function
+ * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter
+ * to increase performance when traversing the path to work_tree.
+ */
+const char *remove_leading_path(const char *in, const char *prefix)
+{
+ static char buf[PATH_MAX + 1];
+ int i = 0, j = 0;
+
+ if (!prefix || !prefix[0])
+ return in;
+ while (prefix[i]) {
+ if (is_dir_sep(prefix[i])) {
+ if (!is_dir_sep(in[j]))
+ return in;
+ while (is_dir_sep(prefix[i]))
+ i++;
+ while (is_dir_sep(in[j]))
+ j++;
+ continue;
+ } else if (in[j] != prefix[i]) {
+ return in;
+ }
+ i++;
+ j++;
+ }
+ if (
+ /* "/foo" is a prefix of "/foo" */
+ in[j] &&
+ /* "/foo" is not a prefix of "/foobar" */
+ !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j])
+ )
+ return in;
+ while (is_dir_sep(in[j]))
+ j++;
+ if (!in[j])
+ strcpy(buf, ".");
+ else
+ strcpy(buf, in + j);
+ return buf;
+}
+
+/*
* It is okay if dst == src, but they should not overlap otherwise.
*
* Performs the following normalizations on src, storing the result in dst: