@@ -1105,57 +1105,45 @@ int file_exists(const char *f)
11051105}
11061106
11071107/*
1108- * get_relative_cwd() gets the prefix of the current working directory
1109- * relative to 'dir'. If we are not inside 'dir', it returns NULL.
1110- *
1111- * As a convenience, it also returns NULL if 'dir' is already NULL. The
1112- * reason for this behaviour is that it is natural for functions returning
1113- * directory names to return NULL to say "this directory does not exist"
1114- * or "this directory is invalid". These cases are usually handled the
1115- * same as if the cwd is not inside 'dir' at all, so get_relative_cwd()
1116- * returns NULL for both of them.
1117- *
1118- * Most notably, get_relative_cwd(buffer, size, get_git_work_tree())
1119- * unifies the handling of "outside work tree" with "no work tree at all".
1108+ * Given two normalized paths (a trailing slash is ok), if subdir is
1109+ * outside dir, return -1. Otherwise return the offset in subdir that
1110+ * can be used as relative path to dir.
11201111 */
1121- char * get_relative_cwd ( char * buffer , int size , const char * dir )
1112+ int dir_inside_of ( const char * subdir , const char * dir )
11221113{
1123- char * cwd = buffer ;
1124-
1125- if (!dir )
1126- return NULL ;
1127- if (!getcwd (buffer , size ))
1128- die_errno ("can't find the current directory" );
1114+ int offset = 0 ;
11291115
1130- if (!is_absolute_path (dir ))
1131- dir = real_path (dir );
1116+ assert (dir && subdir && * dir && * subdir );
11321117
1133- while (* dir && * dir == * cwd ) {
1118+ while (* dir && * subdir && * dir == * subdir ) {
11341119 dir ++ ;
1135- cwd ++ ;
1136- }
1137- if (* dir )
1138- return NULL ;
1139- switch (* cwd ) {
1140- case '\0' :
1141- return cwd ;
1142- case '/' :
1143- return cwd + 1 ;
1144- default :
1145- /*
1146- * dir can end with a path separator when it's root
1147- * directory. Return proper prefix in that case.
1148- */
1149- if (dir [-1 ] == '/' )
1150- return cwd ;
1151- return NULL ;
1120+ subdir ++ ;
1121+ offset ++ ;
11521122 }
1123+
1124+ /* hel[p]/me vs hel[l]/yeah */
1125+ if (* dir && * subdir )
1126+ return -1 ;
1127+
1128+ if (!* subdir )
1129+ return !* dir ? offset : -1 ; /* same dir */
1130+
1131+ /* foo/[b]ar vs foo/[] */
1132+ if (is_dir_sep (dir [-1 ]))
1133+ return is_dir_sep (subdir [-1 ]) ? offset : -1 ;
1134+
1135+ /* foo[/]bar vs foo[] */
1136+ return is_dir_sep (* subdir ) ? offset + 1 : -1 ;
11531137}
11541138
11551139int is_inside_dir (const char * dir )
11561140{
1157- char buffer [PATH_MAX ];
1158- return get_relative_cwd (buffer , sizeof (buffer ), dir ) != NULL ;
1141+ char cwd [PATH_MAX ];
1142+ if (!dir )
1143+ return 0 ;
1144+ if (!getcwd (cwd , sizeof (cwd )))
1145+ die_errno ("can't find the current directory" );
1146+ return dir_inside_of (cwd , dir ) >= 0 ;
11591147}
11601148
11611149int is_empty_dir (const char * path )
0 commit comments