mirror of
https://github.com/git/git
synced 2024-08-27 11:39:22 +00:00
Merge branch 'ph/transport-with-gitfile' into next
* ph/transport-with-gitfile: Add test showing git-fetch groks gitfiles Teach transport about the gitfile mechanism Learn to handle gitfiles in enter_repo enter_repo: do not modify input
This commit is contained in:
commit
891b8b6e51
2
cache.h
2
cache.h
|
@ -734,7 +734,7 @@ int safe_create_leading_directories(char *path);
|
|||
int safe_create_leading_directories_const(const char *path);
|
||||
int mkdir_in_gitdir(const char *path);
|
||||
extern char *expand_user_path(const char *path);
|
||||
char *enter_repo(char *path, int strict);
|
||||
const char *enter_repo(const char *path, int strict);
|
||||
static inline int is_absolute_path(const char *path)
|
||||
{
|
||||
return is_dir_sep(path[0]) || has_dos_drive_prefix(path);
|
||||
|
|
4
daemon.c
4
daemon.c
|
@ -108,11 +108,11 @@ static void NORETURN daemon_die(const char *err, va_list params)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static char *path_ok(char *directory)
|
||||
static const char *path_ok(char *directory)
|
||||
{
|
||||
static char rpath[PATH_MAX];
|
||||
static char interp_path[PATH_MAX];
|
||||
char *path;
|
||||
const char *path;
|
||||
char *dir;
|
||||
|
||||
dir = directory;
|
||||
|
|
34
path.c
34
path.c
|
@ -283,7 +283,7 @@ char *expand_user_path(const char *path)
|
|||
* links. User relative paths are also returned as they are given,
|
||||
* except DWIM suffixing.
|
||||
*/
|
||||
char *enter_repo(char *path, int strict)
|
||||
const char *enter_repo(const char *path, int strict)
|
||||
{
|
||||
static char used_path[PATH_MAX];
|
||||
static char validated_path[PATH_MAX];
|
||||
|
@ -295,16 +295,19 @@ char *enter_repo(char *path, int strict)
|
|||
static const char *suffix[] = {
|
||||
".git/.git", "/.git", ".git", "", NULL,
|
||||
};
|
||||
const char *gitfile;
|
||||
int len = strlen(path);
|
||||
int i;
|
||||
while ((1 < len) && (path[len-1] == '/')) {
|
||||
path[len-1] = 0;
|
||||
while ((1 < len) && (path[len-1] == '/'))
|
||||
len--;
|
||||
}
|
||||
|
||||
if (PATH_MAX <= len)
|
||||
return NULL;
|
||||
if (path[0] == '~') {
|
||||
char *newpath = expand_user_path(path);
|
||||
strncpy(used_path, path, len); used_path[len] = 0 ;
|
||||
strcpy(validated_path, used_path);
|
||||
|
||||
if (used_path[0] == '~') {
|
||||
char *newpath = expand_user_path(used_path);
|
||||
if (!newpath || (PATH_MAX - 10 < strlen(newpath))) {
|
||||
free(newpath);
|
||||
return NULL;
|
||||
|
@ -316,24 +319,23 @@ char *enter_repo(char *path, int strict)
|
|||
* anyway.
|
||||
*/
|
||||
strcpy(used_path, newpath); free(newpath);
|
||||
strcpy(validated_path, path);
|
||||
path = used_path;
|
||||
}
|
||||
else if (PATH_MAX - 10 < len)
|
||||
return NULL;
|
||||
else {
|
||||
path = strcpy(used_path, path);
|
||||
strcpy(validated_path, path);
|
||||
}
|
||||
len = strlen(path);
|
||||
len = strlen(used_path);
|
||||
for (i = 0; suffix[i]; i++) {
|
||||
strcpy(path + len, suffix[i]);
|
||||
if (!access(path, F_OK)) {
|
||||
strcpy(used_path + len, suffix[i]);
|
||||
if (!access(used_path, F_OK)) {
|
||||
strcat(validated_path, suffix[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!suffix[i] || chdir(path))
|
||||
if (!suffix[i])
|
||||
return NULL;
|
||||
gitfile = read_gitfile(used_path) ;
|
||||
if (gitfile)
|
||||
strcpy(used_path, gitfile);
|
||||
if (chdir(used_path))
|
||||
return NULL;
|
||||
path = validated_path;
|
||||
}
|
||||
|
|
|
@ -206,6 +206,20 @@ test_expect_success 'clone from .git file' '
|
|||
git clone dst/.git dst2
|
||||
'
|
||||
|
||||
test_expect_success 'fetch from .git gitfile' '
|
||||
(
|
||||
cd dst2 &&
|
||||
git fetch ../dst/.git
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'fetch from gitfile parent' '
|
||||
(
|
||||
cd dst2 &&
|
||||
git fetch ../dst
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'clone separate gitdir where target already exists' '
|
||||
rm -rf dst &&
|
||||
test_must_fail git clone --separate-git-dir realgitdir src dst
|
||||
|
|
24
transport.c
24
transport.c
|
@ -859,6 +859,28 @@ static int is_local(const char *url)
|
|||
has_dos_drive_prefix(url);
|
||||
}
|
||||
|
||||
static int is_gitfile(const char *url)
|
||||
{
|
||||
struct stat st;
|
||||
char buf[9];
|
||||
int fd, len;
|
||||
if (stat(url, &st))
|
||||
return 0;
|
||||
if (!S_ISREG(st.st_mode))
|
||||
return 0;
|
||||
if (st.st_size < 10 || st.st_size > PATH_MAX)
|
||||
return 1;
|
||||
|
||||
fd = open(url, O_RDONLY);
|
||||
if (fd < 0)
|
||||
die_errno("Error opening '%s'", url);
|
||||
len = read_in_full(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
if (len != sizeof(buf))
|
||||
die("Error reading %s", url);
|
||||
return !prefixcmp(buf, "gitdir: ");
|
||||
}
|
||||
|
||||
static int is_file(const char *url)
|
||||
{
|
||||
struct stat buf;
|
||||
|
@ -907,7 +929,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
|
|||
ret->fetch = fetch_objs_via_rsync;
|
||||
ret->push = rsync_transport_push;
|
||||
ret->smart_options = NULL;
|
||||
} else if (is_local(url) && is_file(url)) {
|
||||
} else if (is_local(url) && is_file(url) && !is_gitfile(url)) {
|
||||
struct bundle_transport_data *data = xcalloc(1, sizeof(*data));
|
||||
ret->data = data;
|
||||
ret->get_refs_list = get_refs_from_bundle;
|
||||
|
|
Loading…
Reference in a new issue