Skip to content

Commit 44788c9

Browse files
authored
Merge pull request libgit2#4662 from pks-t/pks/gitfile-api
path: unify `git_path_is_*` APIs
2 parents bc0f322 + 92159bd commit 44788c9

File tree

3 files changed

+76
-134
lines changed

3 files changed

+76
-134
lines changed

src/path.c

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,14 +1766,14 @@ static bool verify_component(
17661766
if (flags & GIT_PATH_REJECT_DOT_GIT_HFS) {
17671767
if (!verify_dotgit_hfs(component, len))
17681768
return false;
1769-
if (S_ISLNK(mode) && git_path_is_hfs_dotgit_modules(component, len))
1769+
if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_HFS))
17701770
return false;
17711771
}
17721772

17731773
if (flags & GIT_PATH_REJECT_DOT_GIT_NTFS) {
17741774
if (!verify_dotgit_ntfs(repo, component, len))
17751775
return false;
1776-
if (S_ISLNK(mode) && git_path_is_ntfs_dotgit_modules(component, len))
1776+
if (S_ISLNK(mode) && git_path_is_gitfile(component, len, GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_NTFS))
17771777
return false;
17781778
}
17791779

@@ -1872,64 +1872,40 @@ int git_path_normalize_slashes(git_buf *out, const char *path)
18721872
return 0;
18731873
}
18741874

1875-
static int verify_dotgit_generic(const char *name, size_t len, const char *dotgit_name, size_t dotgit_len, const char *shortname_pfix)
1876-
{
1877-
if (!verify_dotgit_ntfs_generic(name, len, dotgit_name, dotgit_len, shortname_pfix))
1878-
return false;
1879-
1880-
return verify_dotgit_hfs_generic(name, len, dotgit_name, dotgit_len);
1881-
}
1882-
1883-
int git_path_is_ntfs_dotgit_modules(const char *name, size_t len)
1884-
{
1885-
return !verify_dotgit_ntfs_generic(name, len, "gitmodules", CONST_STRLEN("gitmodules"), "gi7eba");
1886-
}
1887-
1888-
int git_path_is_hfs_dotgit_modules(const char *name, size_t len)
1889-
{
1890-
return !verify_dotgit_hfs_generic(name, len, "gitmodules", CONST_STRLEN("gitmodules"));
1891-
}
1892-
1893-
int git_path_is_dotgit_modules(const char *name, size_t len)
1894-
{
1895-
if (git_path_is_hfs_dotgit_modules(name, len))
1896-
return 1;
1897-
1898-
return git_path_is_ntfs_dotgit_modules(name, len);
1899-
}
1900-
1901-
int git_path_is_ntfs_dotgit_ignore(const char *name, size_t len)
1902-
{
1903-
return !verify_dotgit_ntfs_generic(name, len, "gitignore", CONST_STRLEN("gitignore"), "gi250a");
1904-
}
1875+
static const struct {
1876+
const char *file;
1877+
const char *hash;
1878+
size_t filelen;
1879+
} gitfiles[] = {
1880+
{ "gitignore", "gi250a", CONST_STRLEN("gitignore") },
1881+
{ "gitmodules", "gi7eba", CONST_STRLEN("gitmodules") },
1882+
{ "gitattributes", "gi7d29", CONST_STRLEN("gitattributes") }
1883+
};
19051884

1906-
int git_path_is_hfs_dotgit_ignore(const char *name, size_t len)
1885+
extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs)
19071886
{
1908-
return !verify_dotgit_hfs_generic(name, len, "gitignore", CONST_STRLEN("gitignore"));
1909-
}
1910-
1911-
int git_path_is_dotgit_ignore(const char *name, size_t len)
1912-
{
1913-
if (git_path_is_hfs_dotgit_ignore(name, len))
1914-
return 1;
1915-
1916-
return git_path_is_ntfs_dotgit_ignore(name, len);
1917-
}
1887+
const char *file, *hash;
1888+
size_t filelen;
19181889

1919-
int git_path_is_hfs_dotgit_attributes(const char *name, size_t len)
1920-
{
1921-
return !verify_dotgit_hfs_generic(name, len, "gitattributes", CONST_STRLEN("gitattributes"));
1922-
}
1923-
1924-
int git_path_is_ntfs_dotgit_attributes(const char *name, size_t len)
1925-
{
1926-
return !verify_dotgit_ntfs_generic(name, len, "gitattributes", CONST_STRLEN("gitattributes"), "gi7d29");
1927-
}
1928-
1929-
int git_path_is_dotgit_attributes(const char *name, size_t len)
1930-
{
1931-
if (git_path_is_hfs_dotgit_attributes(name, len))
1932-
return 1;
1890+
if (gitfile < 0 && gitfile >= ARRAY_SIZE(gitfiles)) {
1891+
giterr_set(GITERR_OS, "invalid gitfile for path validation");
1892+
return -1;
1893+
}
19331894

1934-
return git_path_is_ntfs_dotgit_attributes(name, len);
1895+
file = gitfiles[gitfile].file;
1896+
filelen = gitfiles[gitfile].filelen;
1897+
hash = gitfiles[gitfile].hash;
1898+
1899+
switch (fs) {
1900+
case GIT_PATH_FS_GENERIC:
1901+
return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash) ||
1902+
!verify_dotgit_hfs_generic(path, pathlen, file, filelen);
1903+
case GIT_PATH_FS_NTFS:
1904+
return !verify_dotgit_ntfs_generic(path, pathlen, file, filelen, hash);
1905+
case GIT_PATH_FS_HFS:
1906+
return !verify_dotgit_hfs_generic(path, pathlen, file, filelen);
1907+
default:
1908+
giterr_set(GITERR_OS, "invalid filesystem for path validation");
1909+
return -1;
1910+
}
19351911
}

src/path.h

Lines changed: 37 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -645,76 +645,42 @@ extern bool git_path_isvalid(
645645
*/
646646
int git_path_normalize_slashes(git_buf *out, const char *path);
647647

648-
/**
649-
* Check whether a path component corresponds to a .gitmodules file
650-
*
651-
* @param name the path component to check
652-
* @param len the length of `name`
653-
*/
654-
extern int git_path_is_dotgit_modules(const char *name, size_t len);
655-
656-
/**
657-
* Check whether a path component corresponds to a .gitmodules file in NTFS
658-
*
659-
* @param name the path component to check
660-
* @param len the length of `name`
661-
*/
662-
extern int git_path_is_ntfs_dotgit_modules(const char *name, size_t len);
663-
664-
/**
665-
* Check whether a path component corresponds to a .gitmodules file in HFS+
666-
*
667-
* @param name the path component to check
668-
* @param len the length of `name`
669-
*/
670-
extern int git_path_is_hfs_dotgit_modules(const char *name, size_t len);
671-
672-
/**
673-
* Check whether a path component corresponds to a .gitignore file
674-
*
675-
* @param name the path component to check
676-
* @param len the length of `name`
677-
*/
678-
extern int git_path_is_dotgit_ignore(const char *name, size_t len);
679-
680-
/**
681-
* Check whether a path component corresponds to a .gitignore file in NTFS
682-
*
683-
* @param name the path component to check
684-
* @param len the length of `name`
685-
*/
686-
extern int git_path_is_ntfs_dotgit_ignore(const char *name, size_t len);
687-
688-
/**
689-
* Check whether a path component corresponds to a .gitignore file in HFS+
690-
*
691-
* @param name the path component to check
692-
* @param len the length of `name`
693-
*/
694-
extern int git_path_is_hfs_dotgit_ignore(const char *name, size_t len);
695-
696-
/**
697-
* Check whether a path component corresponds to a .gitignore file
698-
*
699-
* @param name the path component to check
700-
* @param len the length of `name`
701-
*/
702-
extern int git_path_is_dotgit_attributes(const char *name, size_t len);
703-
704-
/**
705-
* Check whether a path component corresponds to a .gitattributes file in NTFS
706-
*
707-
* @param name the path component to check
708-
* @param len the length of `name`
709-
*/
710-
extern int git_path_is_ntfs_dotgit_attributes(const char *name, size_t len);
711-
712-
/**
713-
* Check whether a path component corresponds to a .gitattributes file in HFS+
714-
*
715-
* @param name the path component to check
716-
* @param len the length of `name`
717-
*/
718-
extern int git_path_is_hfs_dotgit_attributes(const char *name, size_t len);
648+
/*
649+
* The order needs to stay the same to not break the `gitfiles`
650+
* array in path.c
651+
*/
652+
typedef enum {
653+
GIT_PATH_GITFILE_GITIGNORE,
654+
GIT_PATH_GITFILE_GITMODULES,
655+
GIT_PATH_GITFILE_GITATTRIBUTES
656+
} git_path_gitfile;
657+
658+
typedef enum {
659+
/* Do both NTFS- and HFS-specific checks */
660+
GIT_PATH_FS_GENERIC,
661+
/* Do NTFS-specific checks only */
662+
GIT_PATH_FS_NTFS,
663+
/* Do HFS-specific checks only */
664+
GIT_PATH_FS_HFS
665+
} git_path_fs;
666+
667+
/**
668+
* Check whether a path component corresponds to a .git$SUFFIX
669+
* file.
670+
*
671+
* As some filesystems do special things to filenames when
672+
* writing files to disk, you cannot always do a plain string
673+
* comparison to verify whether a file name matches an expected
674+
* path or not. This function can do the comparison for you,
675+
* depending on the filesystem you're on.
676+
*
677+
* @param path the path component to check
678+
* @param pathlen the length of `path` that is to be checked
679+
* @param gitfile which file to check against
680+
* @param fs which filesystem-specific checks to use
681+
* @return 0 in case the file does not match, a positive value if
682+
* it does; -1 in case of an error
683+
*/
684+
extern int git_path_is_gitfile(const char *path, size_t pathlen, git_path_gitfile gitfile, git_path_fs fs);
719685

720686
#endif

tests/path/dotgit.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,21 +94,21 @@ static char *gitmodules_not_altnames[] = {
9494
void test_path_dotgit__dotgit_modules(void)
9595
{
9696
size_t i;
97-
cl_assert_equal_i(1, git_path_is_dotgit_modules(".gitmodules", strlen(".gitmodules")));
98-
cl_assert_equal_i(1, git_path_is_dotgit_modules(".git\xe2\x80\x8cmodules", strlen(".git\xe2\x80\x8cmodules")));
97+
98+
cl_assert_equal_i(1, git_path_is_gitfile(".gitmodules", strlen(".gitmodules"), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC));
99+
cl_assert_equal_i(1, git_path_is_gitfile(".git\xe2\x80\x8cmodules", strlen(".git\xe2\x80\x8cmodules"), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC));
99100

100101
for (i = 0; i < ARRAY_SIZE(gitmodules_altnames); i++) {
101102
const char *name = gitmodules_altnames[i];
102-
if (!git_path_is_dotgit_modules(name, strlen(name)))
103+
if (!git_path_is_gitfile(name, strlen(name), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC))
103104
cl_fail(name);
104105
}
105106

106107
for (i = 0; i < ARRAY_SIZE(gitmodules_not_altnames); i++) {
107108
const char *name = gitmodules_not_altnames[i];
108-
if (git_path_is_dotgit_modules(name, strlen(name)))
109+
if (git_path_is_gitfile(name, strlen(name), GIT_PATH_GITFILE_GITMODULES, GIT_PATH_FS_GENERIC))
109110
cl_fail(name);
110111
}
111-
112112
}
113113

114114
void test_path_dotgit__dotgit_modules_symlink(void)

0 commit comments

Comments
 (0)