MCPcopy Index your code
hub / github.com/git/git / relative_path

Function relative_path

path.c:942–1037  ·  view source on GitHub ↗

* Give path as relative to prefix. * * The strbuf may or may not be used, so do not assume it contains the * returned path. */

Source from the content-addressed store, hash-verified

940 * returned path.
941 */
942const char *relative_path(const char *in, const char *prefix,
943 struct strbuf *sb)
944{
945 int in_len = in ? strlen(in) : 0;
946 int prefix_len = prefix ? strlen(prefix) : 0;
947 int in_off = 0;
948 int prefix_off = 0;
949 int i = 0, j = 0;
950
951 if (!in_len)
952 return "./";
953 else if (!prefix_len)
954 return in;
955
956 if (have_same_root(in, prefix))
957 /* bypass dos_drive, for "c:" is identical to "C:" */
958 i = j = has_dos_drive_prefix(in);
959 else {
960 return in;
961 }
962
963 while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
964 if (is_dir_sep(prefix[i])) {
965 while (is_dir_sep(prefix[i]))
966 i++;
967 while (is_dir_sep(in[j]))
968 j++;
969 prefix_off = i;
970 in_off = j;
971 } else {
972 i++;
973 j++;
974 }
975 }
976
977 if (
978 /* "prefix" seems like prefix of "in" */
979 i >= prefix_len &&
980 /*
981 * but "/foo" is not a prefix of "/foobar"
982 * (i.e. prefix not end with '/')
983 */
984 prefix_off < prefix_len) {
985 if (j >= in_len) {
986 /* in="/a/b", prefix="/a/b" */
987 in_off = in_len;
988 } else if (is_dir_sep(in[j])) {
989 /* in="/a/b/c", prefix="/a/b" */
990 while (is_dir_sep(in[j]))
991 j++;
992 in_off = j;
993 } else {
994 /* in="/a/bbb/c", prefix="/a/b" */
995 i = prefix_off;
996 }
997 } else if (
998 /* "in" is short than "prefix" */
999 j >= in_len &&

Callers 15

write_archive_entryFunction · 0.85
reject_outsideFunction · 0.85
quote_pathFunction · 0.85
cmd__path_utilsFunction · 0.85
show_tree_fmtFunction · 0.85
show_tree_name_onlyFunction · 0.85
grep_source_nameFunction · 0.85

Calls 3

have_same_rootFunction · 0.85
strbuf_growFunction · 0.85
strbuf_addstrFunction · 0.85

Tested by 1

cmd__path_utilsFunction · 0.68