44#include <wchar.h>
55#include "../strbuf.h"
66#include "../run-command.h"
7+ #include "../cache.h"
78
89static const int delay [] = { 0 , 1 , 10 , 20 , 40 };
10+ unsigned int _CRT_fmode = _O_BINARY ;
911
1012int err_win_to_posix (DWORD winerr )
1113{
@@ -283,13 +285,44 @@ int mingw_rmdir(const char *pathname)
283285 return ret ;
284286}
285287
288+ static int make_hidden (const wchar_t * path )
289+ {
290+ DWORD attribs = GetFileAttributesW (path );
291+ if (SetFileAttributesW (path , FILE_ATTRIBUTE_HIDDEN | attribs ))
292+ return 0 ;
293+ errno = err_win_to_posix (GetLastError ());
294+ return -1 ;
295+ }
296+
297+ void mingw_mark_as_git_dir (const char * dir )
298+ {
299+ wchar_t wdir [MAX_PATH ];
300+ if (hide_dotfiles != HIDE_DOTFILES_FALSE && !is_bare_repository ())
301+ if (xutftowcs_path (wdir , dir ) < 0 || make_hidden (wdir ))
302+ warning ("Failed to make '%s' hidden" , dir );
303+ git_config_set ("core.hideDotFiles" ,
304+ hide_dotfiles == HIDE_DOTFILES_FALSE ? "false" :
305+ (hide_dotfiles == HIDE_DOTFILES_DOTGITONLY ?
306+ "dotGitOnly" : "true" ));
307+ }
308+
286309int mingw_mkdir (const char * path , int mode )
287310{
288311 int ret ;
289312 wchar_t wpath [MAX_PATH ];
290313 if (xutftowcs_path (wpath , path ) < 0 )
291314 return -1 ;
292315 ret = _wmkdir (wpath );
316+ if (!ret && hide_dotfiles == HIDE_DOTFILES_TRUE ) {
317+ /*
318+ * In Windows a file or dir starting with a dot is not
319+ * automatically hidden. So lets mark it as hidden when
320+ * such a directory is created.
321+ */
322+ const char * start = basename ((char * )path );
323+ if (* start == '.' )
324+ return make_hidden (wpath );
325+ }
293326 return ret ;
294327}
295328
@@ -316,6 +349,17 @@ int mingw_open (const char *filename, int oflags, ...)
316349 if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY ))
317350 errno = EISDIR ;
318351 }
352+ if ((oflags & O_CREAT ) && fd >= 0 &&
353+ hide_dotfiles == HIDE_DOTFILES_TRUE ) {
354+ /*
355+ * In Windows a file or dir starting with a dot is not
356+ * automatically hidden. So lets mark it as hidden when
357+ * such a file is created.
358+ */
359+ const char * start = basename ((char * )filename );
360+ if (* start == '.' && make_hidden (wfilename ))
361+ warning ("Could not mark '%s' as hidden." , filename );
362+ }
319363 return fd ;
320364}
321365
@@ -347,27 +391,39 @@ int mingw_fgetc(FILE *stream)
347391#undef fopen
348392FILE * mingw_fopen (const char * filename , const char * otype )
349393{
394+ int hide = 0 ;
350395 FILE * file ;
351396 wchar_t wfilename [MAX_PATH ], wotype [4 ];
397+ if (hide_dotfiles == HIDE_DOTFILES_TRUE &&
398+ basename ((char * )filename )[0 ] == '.' )
399+ hide = access (filename , F_OK );
352400 if (filename && !strcmp (filename , "/dev/null" ))
353401 filename = "nul" ;
354402 if (xutftowcs_path (wfilename , filename ) < 0 ||
355403 xutftowcs (wotype , otype , ARRAY_SIZE (wotype )) < 0 )
356404 return NULL ;
357405 file = _wfopen (wfilename , wotype );
406+ if (file && hide && make_hidden (wfilename ))
407+ warning ("Could not mark '%s' as hidden." , filename );
358408 return file ;
359409}
360410
361411FILE * mingw_freopen (const char * filename , const char * otype , FILE * stream )
362412{
413+ int hide = 0 ;
363414 FILE * file ;
364415 wchar_t wfilename [MAX_PATH ], wotype [4 ];
416+ if (hide_dotfiles == HIDE_DOTFILES_TRUE &&
417+ basename ((char * )filename )[0 ] == '.' )
418+ hide = access (filename , F_OK );
365419 if (filename && !strcmp (filename , "/dev/null" ))
366420 filename = "nul" ;
367421 if (xutftowcs_path (wfilename , filename ) < 0 ||
368422 xutftowcs (wotype , otype , ARRAY_SIZE (wotype )) < 0 )
369423 return NULL ;
370424 file = _wfreopen (wfilename , wotype , stream );
425+ if (file && hide && make_hidden (wfilename ))
426+ warning ("Could not mark '%s' as hidden." , filename );
371427 return file ;
372428}
373429
@@ -1899,6 +1955,23 @@ pid_t waitpid(pid_t pid, int *status, int options)
18991955 return -1 ;
19001956}
19011957
1958+ const char * get_windows_home_directory (void )
1959+ {
1960+ static const char * home_directory = NULL ;
1961+ struct strbuf buf = STRBUF_INIT ;
1962+
1963+ if (home_directory )
1964+ return home_directory ;
1965+
1966+ home_directory = getenv ("HOME" );
1967+ if (home_directory && * home_directory )
1968+ return home_directory ;
1969+
1970+ strbuf_addf (& buf , "%s/%s" , getenv ("HOMEDRIVE" ), getenv ("HOMEPATH" ));
1971+ home_directory = strbuf_detach (& buf , NULL );
1972+
1973+ return home_directory ;
1974+ }
19021975int xutftowcsn (wchar_t * wcs , const char * utfs , size_t wcslen , int utflen )
19031976{
19041977 int upos = 0 , wpos = 0 ;
@@ -2088,3 +2161,27 @@ void mingw_startup()
20882161 /* initialize Unicode console */
20892162 winansi_init ();
20902163}
2164+
2165+ int mingw_offset_1st_component (const char * path )
2166+ {
2167+ int offset = 0 ;
2168+ if (has_dos_drive_prefix (path ))
2169+ offset = 2 ;
2170+
2171+ /* unc paths */
2172+ else if (is_dir_sep (path [0 ]) && is_dir_sep (path [1 ])) {
2173+
2174+ /* skip server name */
2175+ char * pos = strpbrk (path + 2 , "\\/" );
2176+ if (!pos )
2177+ return 0 ; /* Error: malformed unc path */
2178+
2179+ do {
2180+ pos ++ ;
2181+ } while (* pos && !is_dir_sep (* pos ));
2182+
2183+ offset = pos - path ;
2184+ }
2185+
2186+ return offset + is_dir_sep (path [offset ]);
2187+ }
0 commit comments