Skip to content

Commit

Permalink
Merge pull request #2504 from dscho/access-repo-via-junction
Browse files Browse the repository at this point in the history
Handle `git add <file>` where <file> traverses an NTFS junction
  • Loading branch information
dscho authored Feb 1, 2020
2 parents 5f4dea1 + 100d194 commit 89a5bbf
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 0 deletions.
3 changes: 3 additions & 0 deletions abspath.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
goto error_out;
}

if (platform_strbuf_realpath(resolved, path))
return resolved->buf;

strbuf_addstr(&remaining, path);
get_root_part(resolved, &remaining);

Expand Down
31 changes: 31 additions & 0 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,37 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
return NULL;
}

char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path)
{
wchar_t wpath[MAX_PATH];
HANDLE h;
DWORD ret;
int len;

if (xutftowcs_path(wpath, path) < 0)
return NULL;

h = CreateFileW(wpath, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
return NULL;

ret = GetFinalPathNameByHandleW(h, wpath, ARRAY_SIZE(wpath), 0);
CloseHandle(h);
if (!ret || ret >= ARRAY_SIZE(wpath))
return NULL;

len = wcslen(wpath) * 3;
strbuf_grow(resolved, len);
len = xwcstoutf(resolved->buf, normalize_ntpath(wpath), len);
if (len < 0)
return NULL;
resolved->len = len;
return resolved->buf;

}

char *mingw_getcwd(char *pointer, int len)
{
wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
Expand Down
2 changes: 2 additions & 0 deletions compat/mingw.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ extern int (*win32_is_mount_point)(struct strbuf *path);
#define PATH_SEP ';'
char *mingw_query_user_email(void);
#define query_user_email mingw_query_user_email
char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path);
#define platform_strbuf_realpath mingw_strbuf_realpath
#if !defined(__MINGW64_VERSION_MAJOR) && (!defined(_MSC_VER) || _MSC_VER < 1800)
#define PRIuMAX "I64u"
#define PRId64 "I64d"
Expand Down
4 changes: 4 additions & 0 deletions git-compat-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ static inline int git_create_symlink(struct index_state *index, const char *targ
#define query_user_email() NULL
#endif

#ifndef platform_strbuf_realpath
#define platform_strbuf_realpath(resolved, path) NULL
#endif

#ifdef __TANDEM
#include <floss.h(floss_execl,floss_execlp,floss_execv,floss_execvp)>
#include <floss.h(floss_getpwuid)>
Expand Down
11 changes: 11 additions & 0 deletions t/t3700-add.sh
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,15 @@ test_expect_success CASE_INSENSITIVE_FS 'path is case-insensitive' '
git add "$downcased"
'

test_expect_success MINGW 'can add files via NTFS junctions' '
test_when_finished "cmd //c rmdir junction && rm -rf target" &&
test_create_repo target &&
cmd //c "mklink /j junction target" &&
>target/via-junction &&
git -C junction add "$(pwd)/junction/via-junction" &&
echo via-junction >expect &&
git -C target diff --cached --name-only >actual &&
test_cmp expect actual
'

test_done

0 comments on commit 89a5bbf

Please sign in to comment.