From 83035cde1d98ac8dfd71143d3b1d2666c7a08733 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Wed, 16 Dec 2009 22:20:55 +0100 Subject: [PATCH] core.hidedotfiles: hide '.git' dir by default At least for cross-platform projects, it makes sense to hide the files starting with a dot, as this is the behavior on Unix/MacOSX. However, at least Eclipse has problems interpreting the hidden flag correctly, so the default is to hide only the .git/ directory. The config setting core.hideDotFiles therefore supports not only 'true' and 'false', but also 'dotGitOnly'. [jes: clarified the commit message, made git init respect the setting by marking the .git/ directory only after reading the config, and added documentation, and rebased on top of current junio/next] Signed-off-by: Erik Faye-Lund Signed-off-by: Johannes Schindelin --- Documentation/config.txt | 6 +++++ builtin/init-db.c | 1 + cache.h | 7 ++++++ compat/mingw.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++-- compat/mingw.h | 8 +++--- config.c | 9 +++++++ environment.c | 1 + git-compat-util.h | 4 +++ 8 files changed, 95 insertions(+), 6 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index c081657be7..58d4da28c8 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -169,6 +169,12 @@ The default is true, except linkgit:git-clone[1] or linkgit:git-init[1] will probe and set core.fileMode false if appropriate when the repository is created. +core.hideDotFiles:: + (Windows-only) If true (which is the default), mark newly-created + directories and files whose name starts with a dot as hidden. + If 'dotGitOnly', only the .git/ directory is hidden, but no other + files starting with a dot. + core.ignoreCygwinFSTricks:: This option is only used by Cygwin implementation of Git. If false, the Cygwin stat() and lstat() functions are used. This may be useful diff --git a/builtin/init-db.c b/builtin/init-db.c index 0dacb8b79c..4b1718f4b6 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -384,6 +384,7 @@ int init_db(const char *template_dir, unsigned int flags) check_repository_format(); reinit = create_default_files(template_dir); + mark_as_git_dir(get_git_dir()); create_object_directory(); diff --git a/cache.h b/cache.h index a8aceb5aee..099eb72a20 100644 --- a/cache.h +++ b/cache.h @@ -605,6 +605,13 @@ extern int fsync_object_files; extern int core_preload_index; extern int core_apply_sparse_checkout; +enum hide_dotfiles_type { + HIDE_DOTFILES_FALSE = 0, + HIDE_DOTFILES_TRUE, + HIDE_DOTFILES_DOTGITONLY, +}; +extern enum hide_dotfiles_type hide_dotfiles; + enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, BRANCH_TRACK_NEVER = 0, diff --git a/compat/mingw.c b/compat/mingw.c index a0ac487c0c..cc1b34999d 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -3,8 +3,10 @@ #include #include "../strbuf.h" #include "../run-command.h" +#include "../cache.h" static const int delay[] = { 0, 1, 10, 20, 40 }; +unsigned int _CRT_fmode = _O_BINARY; int err_win_to_posix(DWORD winerr) { @@ -278,6 +280,38 @@ int mingw_rmdir(const char *pathname) return ret; } +static int make_hidden(const char *path) +{ + DWORD attribs = GetFileAttributes(path); + if (SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN | attribs)) + return 0; + errno = err_win_to_posix(GetLastError()); + return -1; +} + +void mingw_mark_as_git_dir(const char *dir) +{ + if (hide_dotfiles != HIDE_DOTFILES_FALSE && make_hidden(dir)) + warning("Failed to make '%s' hidden", dir); +} + +#undef mkdir +int mingw_mkdir(const char *path, int mode) +{ + int ret = mkdir(path); + if (!ret && hide_dotfiles == HIDE_DOTFILES_TRUE) { + /* + * In Windows a file or dir starting with a dot is not + * automatically hidden. So lets mark it as hidden when + * such a directory is created. + */ + const char *start = basename((char*)path); + if (*start == '.') + return make_hidden(path); + } + return ret; +} + #undef open int mingw_open (const char *filename, int oflags, ...) { @@ -299,6 +333,17 @@ int mingw_open (const char *filename, int oflags, ...) if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) errno = EISDIR; } + if ((oflags & O_CREAT) && fd >= 0 && + hide_dotfiles == HIDE_DOTFILES_TRUE) { + /* + * In Windows a file or dir starting with a dot is not + * automatically hidden. So lets mark it as hidden when + * such a file is created. + */ + const char *start = basename((char*)filename); + if (*start == '.' && make_hidden(filename)) + warning("Could not mark '%s' as hidden.", filename); + } return fd; } @@ -322,17 +367,33 @@ ssize_t mingw_write(int fd, const void *buf, size_t count) #undef fopen FILE *mingw_fopen (const char *filename, const char *otype) { + int hide = 0; + FILE *file; + if (hide_dotfiles == HIDE_DOTFILES_TRUE && + basename((char*)filename)[0] == '.') + hide = access(filename, F_OK); if (filename && !strcmp(filename, "/dev/null")) filename = "nul"; - return fopen(filename, otype); + file = fopen(filename, otype); + if (file && hide && make_hidden(filename)) + warning("Could not mark '%s' as hidden.", filename); + return file; } #undef freopen FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) { + int hide = 0; + FILE *file; + if (hide_dotfiles == HIDE_DOTFILES_TRUE && + basename((char*)filename)[0] == '.') + hide = access(filename, F_OK); if (filename && !strcmp(filename, "/dev/null")) filename = "nul"; - return freopen(filename, otype, stream); + file = freopen(filename, otype, stream); + if (file && hide && make_hidden(filename)) + warning("Could not mark '%s' as hidden.", filename); + return file; } /* diff --git a/compat/mingw.h b/compat/mingw.h index 0ff1e04812..699a3dd395 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -113,10 +113,7 @@ static inline int fcntl(int fd, int cmd, ...) * simple adaptors */ -static inline int mingw_mkdir(const char *path, int mode) -{ - return mkdir(path); -} +int mingw_mkdir(const char *path, int mode); #define mkdir mingw_mkdir #define WNOHANG 1 @@ -318,6 +315,9 @@ static inline char *mingw_find_last_dir_sep(const char *path) void mingw_open_html(const char *path); #define open_html mingw_open_html +void mingw_mark_as_git_dir(const char *dir); +#define mark_as_git_dir mingw_mark_as_git_dir + /* * helpers */ diff --git a/config.c b/config.c index 68d32940f3..1759695d16 100644 --- a/config.c +++ b/config.c @@ -752,6 +752,15 @@ static int git_default_core_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.hidedotfiles")) { + if (value && !strcasecmp(value, "dotgitonly")) { + hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; + return 0; + } + hide_dotfiles = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } diff --git a/environment.c b/environment.c index c93b8f44df..bf6f0c29ed 100644 --- a/environment.c +++ b/environment.c @@ -63,6 +63,7 @@ int core_apply_sparse_checkout; int merge_log_config = -1; struct startup_info *startup_info; unsigned long pack_size_limit_cfg; +enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; /* Parallel index stat data preload? */ int core_preload_index = 0; diff --git a/git-compat-util.h b/git-compat-util.h index ed11ad8119..14fa4e117a 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -595,4 +595,8 @@ int rmdir_or_warn(const char *path); */ int remove_or_warn(unsigned int mode, const char *path); +#ifndef mark_as_git_dir +#define mark_as_git_dir(x) /* noop */ +#endif + #endif -- 2.11.4.GIT