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:
Junio C Hamano 2011-10-06 15:42:04 -07:00
commit 891b8b6e51
5 changed files with 58 additions and 20 deletions

View file

@ -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);

View file

@ -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
View file

@ -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;
}

View file

@ -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

View file

@ -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;