mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 02:16:21 +00:00
Merge pull request #3352 from ethomson/hidden
win32: ensure hidden files can be staged
This commit is contained in:
commit
aa06ecaf5b
@ -1279,7 +1279,7 @@ static int repo_write_template(
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
if (!error && hidden) {
|
||||
if (git_win32__sethidden(path.ptr) < 0)
|
||||
if (git_win32__set_hidden(path.ptr, true) < 0)
|
||||
error = -1;
|
||||
}
|
||||
#else
|
||||
@ -1373,7 +1373,7 @@ static int repo_init_structure(
|
||||
/* Hide the ".git" directory */
|
||||
#ifdef GIT_WIN32
|
||||
if ((opts->flags & GIT_REPOSITORY_INIT__HAS_DOTGIT) != 0) {
|
||||
if (git_win32__sethidden(repo_dir) < 0) {
|
||||
if (git_win32__set_hidden(repo_dir, true) < 0) {
|
||||
giterr_set(GITERR_OS,
|
||||
"Failed to mark Git repository folder as hidden");
|
||||
return -1;
|
||||
|
@ -48,7 +48,35 @@ bool git_win32__findfirstfile_filter(git_win32_path dest, const char *src)
|
||||
* @param path The path which should receive the +H bit.
|
||||
* @return 0 on success; -1 on failure
|
||||
*/
|
||||
int git_win32__sethidden(const char *path)
|
||||
int git_win32__set_hidden(const char *path, bool hidden)
|
||||
{
|
||||
git_win32_path buf;
|
||||
DWORD attrs, newattrs;
|
||||
|
||||
if (git_win32_path_from_utf8(buf, path) < 0)
|
||||
return -1;
|
||||
|
||||
attrs = GetFileAttributesW(buf);
|
||||
|
||||
/* Ensure the path exists */
|
||||
if (attrs == INVALID_FILE_ATTRIBUTES)
|
||||
return -1;
|
||||
|
||||
if (hidden)
|
||||
newattrs = attrs | FILE_ATTRIBUTE_HIDDEN;
|
||||
else
|
||||
newattrs = attrs & ~FILE_ATTRIBUTE_HIDDEN;
|
||||
|
||||
if (attrs != newattrs && !SetFileAttributesW(buf, newattrs)) {
|
||||
giterr_set(GITERR_OS, "Failed to %s hidden bit for '%s'",
|
||||
hidden ? "set" : "unset", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_win32__hidden(bool *out, const char *path)
|
||||
{
|
||||
git_win32_path buf;
|
||||
DWORD attrs;
|
||||
@ -62,11 +90,7 @@ int git_win32__sethidden(const char *path)
|
||||
if (attrs == INVALID_FILE_ATTRIBUTES)
|
||||
return -1;
|
||||
|
||||
/* If the item isn't already +H, add the bit */
|
||||
if ((attrs & FILE_ATTRIBUTE_HIDDEN) == 0 &&
|
||||
!SetFileAttributesW(buf, attrs | FILE_ATTRIBUTE_HIDDEN))
|
||||
return -1;
|
||||
|
||||
*out = (attrs & FILE_ATTRIBUTE_HIDDEN) ? true : false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -40,12 +40,22 @@ GIT_INLINE(bool) git_win32__isalpha(wchar_t c)
|
||||
bool git_win32__findfirstfile_filter(git_win32_path dest, const char *src);
|
||||
|
||||
/**
|
||||
* Ensures the given path (file or folder) has the +H (hidden) attribute set.
|
||||
* Ensures the given path (file or folder) has the +H (hidden) attribute set
|
||||
* or unset.
|
||||
*
|
||||
* @param path The path which should receive the +H bit.
|
||||
* @param path The path that should receive the +H bit.
|
||||
* @param hidden true to set +H, false to unset it
|
||||
* @return 0 on success; -1 on failure
|
||||
*/
|
||||
int git_win32__sethidden(const char *path);
|
||||
extern int git_win32__set_hidden(const char *path, bool hidden);
|
||||
|
||||
/**
|
||||
* Determines if the given file or folder has the hidden attribute set.
|
||||
* @param hidden pointer to store hidden value
|
||||
* @param path The path that should be queried for hiddenness.
|
||||
* @return 0 on success or an error code.
|
||||
*/
|
||||
extern int git_win32__hidden(bool *hidden, const char *path);
|
||||
|
||||
/**
|
||||
* Removes any trailing backslashes from a path, except in the case of a drive
|
||||
|
@ -307,6 +307,41 @@ void test_index_addall__files_in_folders(void)
|
||||
git_index_free(index);
|
||||
}
|
||||
|
||||
void test_index_addall__hidden_files(void)
|
||||
{
|
||||
git_index *index;
|
||||
|
||||
GIT_UNUSED(index);
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
addall_create_test_repo(true);
|
||||
|
||||
cl_git_pass(git_repository_index(&index, g_repo));
|
||||
|
||||
cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL));
|
||||
check_stat_data(index, TEST_DIR "/file.bar", true);
|
||||
check_status(g_repo, 2, 0, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
cl_git_mkfile(TEST_DIR "/file.zzz", "yet another one");
|
||||
cl_git_mkfile(TEST_DIR "/more.zzz", "yet another one");
|
||||
cl_git_mkfile(TEST_DIR "/other.zzz", "yet another one");
|
||||
|
||||
check_status(g_repo, 2, 0, 0, 3, 0, 0, 1, 0);
|
||||
|
||||
cl_git_pass(git_win32__set_hidden(TEST_DIR "/file.zzz", true));
|
||||
cl_git_pass(git_win32__set_hidden(TEST_DIR "/more.zzz", true));
|
||||
cl_git_pass(git_win32__set_hidden(TEST_DIR "/other.zzz", true));
|
||||
|
||||
check_status(g_repo, 2, 0, 0, 3, 0, 0, 1, 0);
|
||||
|
||||
cl_git_pass(git_index_add_all(index, NULL, 0, NULL, NULL));
|
||||
check_stat_data(index, TEST_DIR "/file.bar", true);
|
||||
check_status(g_repo, 5, 0, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
git_index_free(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int addall_match_prefix(
|
||||
const char *path, const char *matched_pathspec, void *payload)
|
||||
{
|
||||
|
@ -46,3 +46,29 @@ void test_index_bypath__add_submodule_unregistered(void)
|
||||
cl_assert_equal_s(sm_head, git_oid_tostr_s(&entry->id));
|
||||
cl_assert_equal_s(sm_name, entry->path);
|
||||
}
|
||||
|
||||
void test_index_bypath__add_hidden(void)
|
||||
{
|
||||
const git_index_entry *entry;
|
||||
bool hidden;
|
||||
|
||||
GIT_UNUSED(entry);
|
||||
GIT_UNUSED(hidden);
|
||||
|
||||
#ifdef GIT_WIN32
|
||||
cl_git_mkfile("submod2/hidden_file", "you can't see me");
|
||||
|
||||
cl_git_pass(git_win32__hidden(&hidden, "submod2/hidden_file"));
|
||||
cl_assert(!hidden);
|
||||
|
||||
cl_git_pass(git_win32__set_hidden("submod2/hidden_file", true));
|
||||
|
||||
cl_git_pass(git_win32__hidden(&hidden, "submod2/hidden_file"));
|
||||
cl_assert(hidden);
|
||||
|
||||
cl_git_pass(git_index_add_bypath(g_idx, "hidden_file"));
|
||||
|
||||
cl_assert(entry = git_index_get_bypath(g_idx, "hidden_file", 0));
|
||||
cl_assert_equal_i(GIT_FILEMODE_BLOB, entry->mode);
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user