Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 65e5f86

Browse files
committed
Merge 'home' into HEAD
2 parents 2a6a5fa + 967d788 commit 65e5f86

File tree

11 files changed

+163
-3
lines changed

11 files changed

+163
-3
lines changed

Documentation/config.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
213213
will probe and set core.fileMode false if appropriate when the
214214
repository is created.
215215

216+
core.hideDotFiles::
217+
(Windows-only) If true (which is the default), mark newly-created
218+
directories and files whose name starts with a dot as hidden.
219+
If 'dotGitOnly', only the .git/ directory is hidden, but no other
220+
files starting with a dot.
221+
216222
core.ignorecase::
217223
If true, this option enables various workarounds to enable
218224
Git to work better on filesystems that are not case sensitive,

builtin/init-db.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ int init_db(const char *template_dir, unsigned int flags)
385385
check_repository_format();
386386

387387
reinit = create_default_files(template_dir);
388+
mark_as_git_dir(get_git_dir());
388389

389390
create_object_directory();
390391

cache.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,13 @@ extern int precomposed_unicode;
594594
*/
595595
extern char comment_line_char;
596596

597+
enum hide_dotfiles_type {
598+
HIDE_DOTFILES_FALSE = 0,
599+
HIDE_DOTFILES_TRUE,
600+
HIDE_DOTFILES_DOTGITONLY,
601+
};
602+
extern enum hide_dotfiles_type hide_dotfiles;
603+
597604
enum branch_track {
598605
BRANCH_TRACK_UNSPECIFIED = -1,
599606
BRANCH_TRACK_NEVER = 0,

compat/mingw.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
#include <wchar.h>
55
#include "../strbuf.h"
66
#include "../run-command.h"
7+
#include "../cache.h"
78

89
static const int delay[] = { 0, 1, 10, 20, 40 };
10+
unsigned int _CRT_fmode = _O_BINARY;
911

1012
int 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+
286309
int 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
348392
FILE *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

361411
FILE *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+
}
19021975
int 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+
}

compat/mingw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,3 +503,6 @@ static int mingw_main(c,v)
503503
* Used by Pthread API implementation for Windows
504504
*/
505505
extern int err_win_to_posix(DWORD winerr);
506+
507+
extern const char *get_windows_home_directory();
508+
#define get_home_directory() get_windows_home_directory()

config.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,15 @@ static int git_default_core_config(const char *var, const char *value)
885885
return 0;
886886
}
887887

888+
if (!strcmp(var, "core.hidedotfiles")) {
889+
if (value && !strcasecmp(value, "dotgitonly")) {
890+
hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
891+
return 0;
892+
}
893+
hide_dotfiles = git_config_bool(var, value);
894+
return 0;
895+
}
896+
888897
/* Add other config variables here and to Documentation/config.txt. */
889898
return 0;
890899
}

environment.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ int merge_log_config = -1;
6363
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
6464
struct startup_info *startup_info;
6565
unsigned long pack_size_limit_cfg;
66+
enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
6667

6768
/*
6869
* The character that begins a commented line in user-editable file

git-compat-util.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,4 +728,12 @@ struct tm *git_gmtime_r(const time_t *, struct tm *);
728728
#define gmtime_r git_gmtime_r
729729
#endif
730730

731+
#ifndef mark_as_git_dir
732+
#define mark_as_git_dir(x) /* noop */
733+
#endif
734+
735+
#ifndef get_home_directory
736+
#define get_home_directory() getenv("HOME")
737+
#endif
738+
731739
#endif

path.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ char *git_path(const char *fmt, ...)
133133
void home_config_paths(char **global, char **xdg, char *file)
134134
{
135135
char *xdg_home = getenv("XDG_CONFIG_HOME");
136-
char *home = getenv("HOME");
136+
const char *home = get_home_directory();
137137
char *to_free = NULL;
138138

139139
if (!home) {
@@ -274,7 +274,7 @@ char *expand_user_path(const char *path)
274274
const char *username = path + 1;
275275
size_t username_len = first_slash - username;
276276
if (username_len == 0) {
277-
const char *home = getenv("HOME");
277+
const char *home = get_home_directory();
278278
if (!home)
279279
goto return_null;
280280
strbuf_add(&user_path, home, strlen(home));

shell.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static char *make_cmd(const char *prog)
5555

5656
static void cd_to_homedir(void)
5757
{
58-
const char *home = getenv("HOME");
58+
const char *home = get_home_directory();
5959
if (!home)
6060
die("could not determine user's home directory; HOME is unset");
6161
if (chdir(home) == -1)

0 commit comments

Comments
 (0)