mirror of
https://github.com/git/git.git
synced 2026-02-05 07:23:13 +00:00
Merge 'home' into HEAD
This commit is contained in:
@@ -212,6 +212,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.ignorecase::
|
||||
If true, this option enables various workarounds to enable
|
||||
Git to work better on filesystems that are not case sensitive,
|
||||
|
||||
@@ -385,6 +385,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();
|
||||
|
||||
|
||||
7
cache.h
7
cache.h
@@ -603,6 +603,13 @@ extern int precomposed_unicode;
|
||||
*/
|
||||
extern char comment_line_char;
|
||||
|
||||
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,
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#include <wchar.h>
|
||||
#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)
|
||||
{
|
||||
@@ -283,6 +285,27 @@ int mingw_rmdir(const char *pathname)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int make_hidden(const wchar_t *path)
|
||||
{
|
||||
DWORD attribs = GetFileAttributesW(path);
|
||||
if (SetFileAttributesW(path, FILE_ATTRIBUTE_HIDDEN | attribs))
|
||||
return 0;
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
void mingw_mark_as_git_dir(const char *dir)
|
||||
{
|
||||
wchar_t wdir[MAX_PATH];
|
||||
if (hide_dotfiles != HIDE_DOTFILES_FALSE && !is_bare_repository())
|
||||
if (xutftowcs_path(wdir, dir) < 0 || make_hidden(wdir))
|
||||
warning("Failed to make '%s' hidden", dir);
|
||||
git_config_set("core.hideDotFiles",
|
||||
hide_dotfiles == HIDE_DOTFILES_FALSE ? "false" :
|
||||
(hide_dotfiles == HIDE_DOTFILES_DOTGITONLY ?
|
||||
"dotGitOnly" : "true"));
|
||||
}
|
||||
|
||||
int mingw_mkdir(const char *path, int mode)
|
||||
{
|
||||
int ret;
|
||||
@@ -290,6 +313,16 @@ int mingw_mkdir(const char *path, int mode)
|
||||
if (xutftowcs_path(wpath, path) < 0)
|
||||
return -1;
|
||||
ret = _wmkdir(wpath);
|
||||
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(wpath);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -316,6 +349,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(wfilename))
|
||||
warning("Could not mark '%s' as hidden.", filename);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
@@ -347,27 +391,39 @@ int mingw_fgetc(FILE *stream)
|
||||
#undef fopen
|
||||
FILE *mingw_fopen (const char *filename, const char *otype)
|
||||
{
|
||||
int hide = 0;
|
||||
FILE *file;
|
||||
wchar_t wfilename[MAX_PATH], wotype[4];
|
||||
if (hide_dotfiles == HIDE_DOTFILES_TRUE &&
|
||||
basename((char*)filename)[0] == '.')
|
||||
hide = access(filename, F_OK);
|
||||
if (filename && !strcmp(filename, "/dev/null"))
|
||||
filename = "nul";
|
||||
if (xutftowcs_path(wfilename, filename) < 0 ||
|
||||
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
|
||||
return NULL;
|
||||
file = _wfopen(wfilename, wotype);
|
||||
if (file && hide && make_hidden(wfilename))
|
||||
warning("Could not mark '%s' as hidden.", filename);
|
||||
return file;
|
||||
}
|
||||
|
||||
FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
|
||||
{
|
||||
int hide = 0;
|
||||
FILE *file;
|
||||
wchar_t wfilename[MAX_PATH], wotype[4];
|
||||
if (hide_dotfiles == HIDE_DOTFILES_TRUE &&
|
||||
basename((char*)filename)[0] == '.')
|
||||
hide = access(filename, F_OK);
|
||||
if (filename && !strcmp(filename, "/dev/null"))
|
||||
filename = "nul";
|
||||
if (xutftowcs_path(wfilename, filename) < 0 ||
|
||||
xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0)
|
||||
return NULL;
|
||||
file = _wfreopen(wfilename, wotype, stream);
|
||||
if (file && hide && make_hidden(wfilename))
|
||||
warning("Could not mark '%s' as hidden.", filename);
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -1899,6 +1955,23 @@ pid_t waitpid(pid_t pid, int *status, int options)
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *get_windows_home_directory(void)
|
||||
{
|
||||
static const char *home_directory = NULL;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
if (home_directory)
|
||||
return home_directory;
|
||||
|
||||
home_directory = getenv("HOME");
|
||||
if (home_directory && *home_directory)
|
||||
return home_directory;
|
||||
|
||||
strbuf_addf(&buf, "%s/%s", getenv("HOMEDRIVE"), getenv("HOMEPATH"));
|
||||
home_directory = strbuf_detach(&buf, NULL);
|
||||
|
||||
return home_directory;
|
||||
}
|
||||
int xutftowcsn(wchar_t *wcs, const char *utfs, size_t wcslen, int utflen)
|
||||
{
|
||||
int upos = 0, wpos = 0;
|
||||
@@ -2088,3 +2161,27 @@ void mingw_startup()
|
||||
/* initialize Unicode console */
|
||||
winansi_init();
|
||||
}
|
||||
|
||||
int mingw_offset_1st_component(const char *path)
|
||||
{
|
||||
int offset = 0;
|
||||
if (has_dos_drive_prefix(path))
|
||||
offset = 2;
|
||||
|
||||
/* unc paths */
|
||||
else if (is_dir_sep(path[0]) && is_dir_sep(path[1])) {
|
||||
|
||||
/* skip server name */
|
||||
char *pos = strpbrk(path + 2, "\\/");
|
||||
if (!pos)
|
||||
return 0; /* Error: malformed unc path */
|
||||
|
||||
do {
|
||||
pos++;
|
||||
} while (*pos && !is_dir_sep(*pos));
|
||||
|
||||
offset = pos - path;
|
||||
}
|
||||
|
||||
return offset + is_dir_sep(path[offset]);
|
||||
}
|
||||
|
||||
@@ -503,3 +503,6 @@ static int mingw_main(c,v)
|
||||
* Used by Pthread API implementation for Windows
|
||||
*/
|
||||
extern int err_win_to_posix(DWORD winerr);
|
||||
|
||||
extern const char *get_windows_home_directory();
|
||||
#define get_home_directory() get_windows_home_directory()
|
||||
|
||||
9
config.c
9
config.c
@@ -874,6 +874,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;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ int merge_log_config = -1;
|
||||
int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
|
||||
struct startup_info *startup_info;
|
||||
unsigned long pack_size_limit_cfg;
|
||||
enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY;
|
||||
|
||||
/*
|
||||
* The character that begins a commented line in user-editable file
|
||||
|
||||
@@ -723,4 +723,12 @@ struct tm *git_gmtime_r(const time_t *, struct tm *);
|
||||
#define gmtime_r git_gmtime_r
|
||||
#endif
|
||||
|
||||
#ifndef mark_as_git_dir
|
||||
#define mark_as_git_dir(x) /* noop */
|
||||
#endif
|
||||
|
||||
#ifndef get_home_directory
|
||||
#define get_home_directory() getenv("HOME")
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
4
path.c
4
path.c
@@ -133,7 +133,7 @@ char *git_path(const char *fmt, ...)
|
||||
void home_config_paths(char **global, char **xdg, char *file)
|
||||
{
|
||||
char *xdg_home = getenv("XDG_CONFIG_HOME");
|
||||
char *home = getenv("HOME");
|
||||
const char *home = get_home_directory();
|
||||
char *to_free = NULL;
|
||||
|
||||
if (!home) {
|
||||
@@ -274,7 +274,7 @@ char *expand_user_path(const char *path)
|
||||
const char *username = path + 1;
|
||||
size_t username_len = first_slash - username;
|
||||
if (username_len == 0) {
|
||||
const char *home = getenv("HOME");
|
||||
const char *home = get_home_directory();
|
||||
if (!home)
|
||||
goto return_null;
|
||||
strbuf_add(&user_path, home, strlen(home));
|
||||
|
||||
2
shell.c
2
shell.c
@@ -55,7 +55,7 @@ static char *make_cmd(const char *prog)
|
||||
|
||||
static void cd_to_homedir(void)
|
||||
{
|
||||
const char *home = getenv("HOME");
|
||||
const char *home = get_home_directory();
|
||||
if (!home)
|
||||
die("could not determine user's home directory; HOME is unset");
|
||||
if (chdir(home) == -1)
|
||||
|
||||
@@ -332,4 +332,32 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' '
|
||||
test_path_is_dir realgitdir/refs
|
||||
'
|
||||
|
||||
# Tests for the hidden file attribute on windows
|
||||
is_hidden () {
|
||||
test "1" -eq "$(echo puts [file attributes $1 -hidden]|tclsh)"
|
||||
}
|
||||
|
||||
test_expect_success MINGW 'plain hidden' '
|
||||
rm -rf newdir &&
|
||||
(
|
||||
unset GIT_DIR GIT_WORK_TREE
|
||||
mkdir newdir &&
|
||||
cd newdir &&
|
||||
git init &&
|
||||
is_hidden .git
|
||||
) &&
|
||||
check_config newdir/.git false unset
|
||||
'
|
||||
|
||||
test_expect_success MINGW 'plain bare not hidden' '
|
||||
rm -rf newdir
|
||||
(
|
||||
unset GIT_DIR GIT_WORK_TREE GIT_CONFIG
|
||||
mkdir newdir &&
|
||||
cd newdir &&
|
||||
git --bare init
|
||||
) &&
|
||||
! is_hidden newdir
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
Reference in New Issue
Block a user