mirror of
https://github.com/git/git.git
synced 2026-04-02 04:50:12 +02:00
Merge branch 'master' of git://repo.or.cz/alt-git
This commit is contained in:
@@ -14,6 +14,7 @@ SYNOPSIS
|
||||
[ \--max-age=timestamp ]
|
||||
[ \--min-age=timestamp ]
|
||||
[ \--sparse ]
|
||||
[ \--merges ]
|
||||
[ \--no-merges ]
|
||||
[ \--first-parent ]
|
||||
[ \--remove-empty ]
|
||||
|
||||
@@ -201,6 +201,10 @@ endif::git-rev-list[]
|
||||
|
||||
Stop when a given path disappears from the tree.
|
||||
|
||||
--merges::
|
||||
|
||||
Print only merge commits.
|
||||
|
||||
--no-merges::
|
||||
|
||||
Do not print commits with more than one parent.
|
||||
|
||||
35
Makefile
35
Makefile
@@ -61,6 +61,8 @@ all::
|
||||
#
|
||||
# Define NO_LIBGEN_H if you don't have libgen.h.
|
||||
#
|
||||
# Define NEEDS_LIBGEN if your libgen needs -lgen when linking
|
||||
#
|
||||
# Define NO_SYS_SELECT_H if you don't have sys/select.h.
|
||||
#
|
||||
# Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link.
|
||||
@@ -828,18 +830,31 @@ ifeq ($(uname_S),GNU)
|
||||
NO_STRLCPY=YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),IRIX)
|
||||
NO_SETENV = YesPlease
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_STRCASESTR = YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MMAP = YesPlease
|
||||
NO_EXTERNAL_GREP = UnfortunatelyYes
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
SHELL_PATH = /usr/gnu/bin/bash
|
||||
NEEDS_LIBGEN = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),IRIX64)
|
||||
NO_IPV6=YesPlease
|
||||
NO_SETENV=YesPlease
|
||||
NO_UNSETENV = YesPlease
|
||||
NO_STRCASESTR=YesPlease
|
||||
NO_MEMMEM = YesPlease
|
||||
NO_MKSTEMPS = YesPlease
|
||||
NO_STRLCPY = YesPlease
|
||||
NO_SOCKADDR_STORAGE=YesPlease
|
||||
NO_MKDTEMP = YesPlease
|
||||
NO_MMAP = YesPlease
|
||||
NO_EXTERNAL_GREP = UnfortunatelyYes
|
||||
SNPRINTF_RETURNS_BOGUS = YesPlease
|
||||
SHELL_PATH=/usr/gnu/bin/bash
|
||||
BASIC_CFLAGS += -DPATH_MAX=1024
|
||||
# for now, build 32-bit version
|
||||
BASIC_LDFLAGS += -L/usr/lib32
|
||||
NEEDS_LIBGEN = YesPlease
|
||||
endif
|
||||
ifeq ($(uname_S),HP-UX)
|
||||
NO_IPV6=YesPlease
|
||||
@@ -1019,6 +1034,9 @@ ifdef NEEDS_LIBICONV
|
||||
endif
|
||||
EXTLIBS += $(ICONV_LINK) -liconv
|
||||
endif
|
||||
ifdef NEEDS_LIBGEN
|
||||
EXTLIBS += -lgen
|
||||
endif
|
||||
ifdef NEEDS_SOCKET
|
||||
EXTLIBS += -lsocket
|
||||
endif
|
||||
@@ -1641,10 +1659,11 @@ ifneq (,$X)
|
||||
endif
|
||||
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
|
||||
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
|
||||
{ $(RM) "$$execdir/git$X" && \
|
||||
{ test "$$bindir/" = "$$execdir/" || \
|
||||
{ $(RM) "$$execdir/git$X" && \
|
||||
test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
|
||||
ln "$$bindir/git$X" "$$execdir/git$X" 2>/dev/null || \
|
||||
cp "$$bindir/git$X" "$$execdir/git$X"; } && \
|
||||
cp "$$bindir/git$X" "$$execdir/git$X"; } ; } && \
|
||||
{ for p in $(BUILT_INS); do \
|
||||
$(RM) "$$execdir/$$p" && \
|
||||
ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
|
||||
|
||||
@@ -97,35 +97,6 @@ static void treat_gitlinks(const char **pathspec)
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_directory(struct dir_struct *dir, const char **pathspec,
|
||||
int ignored_too)
|
||||
{
|
||||
const char *path, *base;
|
||||
int baselen;
|
||||
|
||||
/* Set up the default git porcelain excludes */
|
||||
memset(dir, 0, sizeof(*dir));
|
||||
if (!ignored_too) {
|
||||
dir->flags |= DIR_COLLECT_IGNORED;
|
||||
setup_standard_excludes(dir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
* use that to optimize the directory walk
|
||||
*/
|
||||
baselen = common_prefix(pathspec);
|
||||
path = ".";
|
||||
base = "";
|
||||
if (baselen)
|
||||
path = base = xmemdupz(*pathspec, baselen);
|
||||
|
||||
/* Read the directory and prune it */
|
||||
read_directory(dir, path, base, baselen, pathspec);
|
||||
if (pathspec)
|
||||
prune_directory(dir, pathspec, baselen);
|
||||
}
|
||||
|
||||
static void refresh(int verbose, const char **pathspec)
|
||||
{
|
||||
char *seen;
|
||||
@@ -343,9 +314,21 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
die("index file corrupt");
|
||||
treat_gitlinks(pathspec);
|
||||
|
||||
if (add_new_files)
|
||||
if (add_new_files) {
|
||||
int baselen;
|
||||
|
||||
/* Set up the default git porcelain excludes */
|
||||
memset(&dir, 0, sizeof(dir));
|
||||
if (!ignored_too) {
|
||||
dir.flags |= DIR_COLLECT_IGNORED;
|
||||
setup_standard_excludes(&dir);
|
||||
}
|
||||
|
||||
/* This picks up the paths that are not tracked */
|
||||
fill_directory(&dir, pathspec, ignored_too);
|
||||
baselen = fill_directory(&dir, pathspec);
|
||||
if (pathspec)
|
||||
prune_directory(&dir, pathspec, baselen);
|
||||
}
|
||||
|
||||
if (refresh_only) {
|
||||
refresh(verbose, pathspec);
|
||||
|
||||
@@ -33,7 +33,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
int ignored_only = 0, baselen = 0, config_set = 0, errors = 0;
|
||||
struct strbuf directory = STRBUF_INIT;
|
||||
struct dir_struct dir;
|
||||
const char *path, *base;
|
||||
static const char **pathspec;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *qname;
|
||||
@@ -78,16 +77,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
||||
pathspec = get_pathspec(prefix, argv);
|
||||
read_cache();
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
* use that to optimize the directory walk
|
||||
*/
|
||||
baselen = common_prefix(pathspec);
|
||||
path = ".";
|
||||
base = "";
|
||||
if (baselen)
|
||||
path = base = xmemdupz(*pathspec, baselen);
|
||||
read_directory(&dir, path, base, baselen, pathspec);
|
||||
fill_directory(&dir, pathspec);
|
||||
|
||||
if (pathspec)
|
||||
seen = xmalloc(argc > 0 ? argc : 1);
|
||||
|
||||
@@ -400,14 +400,14 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
|
||||
/*
|
||||
* We would want to bypass the object transfer altogether if
|
||||
* everything we are going to fetch already exists and connected
|
||||
* everything we are going to fetch already exists and is connected
|
||||
* locally.
|
||||
*
|
||||
* The refs we are going to fetch are in to_fetch (nr_heads in
|
||||
* total). If running
|
||||
* The refs we are going to fetch are in ref_map. If running
|
||||
*
|
||||
* $ git rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
|
||||
* $ git rev-list --objects --stdin --not --all
|
||||
*
|
||||
* (feeding all the refs in ref_map on its standard input)
|
||||
* does not error out, that means everything reachable from the
|
||||
* refs we are going to fetch exists and is connected to some of
|
||||
* our existing refs.
|
||||
@@ -416,8 +416,9 @@ static int quickfetch(struct ref *ref_map)
|
||||
{
|
||||
struct child_process revlist;
|
||||
struct ref *ref;
|
||||
char **argv;
|
||||
int i, err;
|
||||
int err;
|
||||
const char *argv[] = {"rev-list",
|
||||
"--quiet", "--objects", "--stdin", "--not", "--all", NULL};
|
||||
|
||||
/*
|
||||
* If we are deepening a shallow clone we already have these
|
||||
@@ -429,34 +430,46 @@ static int quickfetch(struct ref *ref_map)
|
||||
if (depth)
|
||||
return -1;
|
||||
|
||||
for (i = 0, ref = ref_map; ref; ref = ref->next)
|
||||
i++;
|
||||
if (!i)
|
||||
if (!ref_map)
|
||||
return 0;
|
||||
|
||||
argv = xmalloc(sizeof(*argv) * (i + 6));
|
||||
i = 0;
|
||||
argv[i++] = xstrdup("rev-list");
|
||||
argv[i++] = xstrdup("--quiet");
|
||||
argv[i++] = xstrdup("--objects");
|
||||
for (ref = ref_map; ref; ref = ref->next)
|
||||
argv[i++] = xstrdup(sha1_to_hex(ref->old_sha1));
|
||||
argv[i++] = xstrdup("--not");
|
||||
argv[i++] = xstrdup("--all");
|
||||
argv[i++] = NULL;
|
||||
|
||||
memset(&revlist, 0, sizeof(revlist));
|
||||
revlist.argv = (const char**)argv;
|
||||
revlist.argv = argv;
|
||||
revlist.git_cmd = 1;
|
||||
revlist.no_stdin = 1;
|
||||
revlist.no_stdout = 1;
|
||||
revlist.no_stderr = 1;
|
||||
err = run_command(&revlist);
|
||||
revlist.in = -1;
|
||||
|
||||
for (i = 0; argv[i]; i++)
|
||||
free(argv[i]);
|
||||
free(argv);
|
||||
return err;
|
||||
err = start_command(&revlist);
|
||||
if (err) {
|
||||
error("could not run rev-list");
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If rev-list --stdin encounters an unknown commit, it terminates,
|
||||
* which will cause SIGPIPE in the write loop below.
|
||||
*/
|
||||
sigchain_push(SIGPIPE, SIG_IGN);
|
||||
|
||||
for (ref = ref_map; ref; ref = ref->next) {
|
||||
if (write_in_full(revlist.in, sha1_to_hex(ref->old_sha1), 40) < 0 ||
|
||||
write_in_full(revlist.in, "\n", 1) < 0) {
|
||||
if (errno != EPIPE && errno != EINVAL)
|
||||
error("failed write to rev-list: %s", strerror(errno));
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (close(revlist.in)) {
|
||||
error("failed to close rev-list's stdin: %s", strerror(errno));
|
||||
err = -1;
|
||||
}
|
||||
|
||||
sigchain_pop(SIGPIPE);
|
||||
|
||||
return finish_command(&revlist) || err;
|
||||
}
|
||||
|
||||
static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
||||
|
||||
@@ -161,12 +161,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
|
||||
|
||||
/* For cached/deleted files we don't need to even do the readdir */
|
||||
if (show_others || show_killed) {
|
||||
const char *path = ".", *base = "";
|
||||
int baselen = prefix_len;
|
||||
|
||||
if (baselen)
|
||||
path = base = prefix;
|
||||
read_directory(dir, path, base, baselen, pathspec);
|
||||
fill_directory(dir, pathspec);
|
||||
if (show_others)
|
||||
show_other_files(dir);
|
||||
if (show_killed)
|
||||
|
||||
@@ -329,7 +329,8 @@ static int update_one(struct cache_tree *it,
|
||||
entlen = pathlen - baselen;
|
||||
}
|
||||
if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))
|
||||
return error("invalid object %s", sha1_to_hex(sha1));
|
||||
return error("invalid object %06o %s for '%.*s'",
|
||||
mode, sha1_to_hex(sha1), entlen+baselen, path);
|
||||
|
||||
if (ce->ce_flags & CE_REMOVE)
|
||||
continue; /* entry being removed */
|
||||
|
||||
10
cache.h
10
cache.h
@@ -744,7 +744,17 @@ struct checkout {
|
||||
};
|
||||
|
||||
extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath);
|
||||
|
||||
struct cache_def {
|
||||
char path[PATH_MAX + 1];
|
||||
int len;
|
||||
int flags;
|
||||
int track_flags;
|
||||
int prefix_len_stat_func;
|
||||
};
|
||||
|
||||
extern int has_symlink_leading_path(const char *name, int len);
|
||||
extern int threaded_has_symlink_leading_path(struct cache_def *, const char *, int);
|
||||
extern int has_symlink_or_noent_leading_path(const char *name, int len);
|
||||
extern int has_dirs_only_path(const char *name, int len, int prefix_len);
|
||||
extern void invalidate_lstat_cache(const char *name, int len);
|
||||
|
||||
@@ -485,6 +485,12 @@ AC_CHECK_LIB([resolv], [hstrerror],
|
||||
AC_SUBST(NEEDS_RESOLV)
|
||||
test -n "$NEEDS_RESOLV" && LIBS="$LIBS -lresolv"
|
||||
|
||||
AC_CHECK_LIB([gen], [basename],
|
||||
[NEEDS_LIBGEN=],
|
||||
[NEEDS_LIBGEN=YesPlease])
|
||||
AC_SUBST(NEEDS_LIBGEN)
|
||||
test -n "$NEEDS_LIBGEN" && LIBS="$LIBS -lgen"
|
||||
|
||||
## Checks for header files.
|
||||
AC_MSG_NOTICE([CHECKS for header files])
|
||||
#
|
||||
|
||||
@@ -1114,7 +1114,7 @@ _git_ls_tree ()
|
||||
__git_log_common_options="
|
||||
--not --all
|
||||
--branches --tags --remotes
|
||||
--first-parent --no-merges
|
||||
--first-parent --merges --no-merges
|
||||
--max-count=
|
||||
--max-age= --since= --after=
|
||||
--min-age= --until= --before=
|
||||
|
||||
111
dir.c
111
dir.c
@@ -14,12 +14,11 @@ struct path_simplify {
|
||||
const char *path;
|
||||
};
|
||||
|
||||
static int read_directory_recursive(struct dir_struct *dir,
|
||||
const char *path, const char *base, int baselen,
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, int len,
|
||||
int check_only, const struct path_simplify *simplify);
|
||||
static int get_dtype(struct dirent *de, const char *path);
|
||||
static int get_dtype(struct dirent *de, const char *path, int len);
|
||||
|
||||
int common_prefix(const char **pathspec)
|
||||
static int common_prefix(const char **pathspec)
|
||||
{
|
||||
const char *path, *slash, *next;
|
||||
int prefix;
|
||||
@@ -52,6 +51,26 @@ int common_prefix(const char **pathspec)
|
||||
return prefix;
|
||||
}
|
||||
|
||||
int fill_directory(struct dir_struct *dir, const char **pathspec)
|
||||
{
|
||||
const char *path;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Calculate common prefix for the pathspec, and
|
||||
* use that to optimize the directory walk
|
||||
*/
|
||||
len = common_prefix(pathspec);
|
||||
path = "";
|
||||
|
||||
if (len)
|
||||
path = xmemdupz(*pathspec, len);
|
||||
|
||||
/* Read the directory and prune it */
|
||||
read_directory(dir, path, len, pathspec);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does 'match' match the given name?
|
||||
* A match is found if
|
||||
@@ -307,7 +326,7 @@ static int excluded_1(const char *pathname,
|
||||
|
||||
if (x->flags & EXC_FLAG_MUSTBEDIR) {
|
||||
if (*dtype == DT_UNKNOWN)
|
||||
*dtype = get_dtype(NULL, pathname);
|
||||
*dtype = get_dtype(NULL, pathname, pathlen);
|
||||
if (*dtype != DT_DIR)
|
||||
continue;
|
||||
}
|
||||
@@ -505,7 +524,7 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
|
||||
/* This is the "show_other_directories" case */
|
||||
if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
|
||||
return show_directory;
|
||||
if (!read_directory_recursive(dir, dirname, dirname, len, 1, simplify))
|
||||
if (!read_directory_recursive(dir, dirname, len, 1, simplify))
|
||||
return ignore_directory;
|
||||
return show_directory;
|
||||
}
|
||||
@@ -547,11 +566,52 @@ static int in_pathspec(const char *path, int len, const struct path_simplify *si
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_dtype(struct dirent *de, const char *path)
|
||||
static int get_index_dtype(const char *path, int len)
|
||||
{
|
||||
int pos;
|
||||
struct cache_entry *ce;
|
||||
|
||||
ce = cache_name_exists(path, len, 0);
|
||||
if (ce) {
|
||||
if (!ce_uptodate(ce))
|
||||
return DT_UNKNOWN;
|
||||
if (S_ISGITLINK(ce->ce_mode))
|
||||
return DT_DIR;
|
||||
/*
|
||||
* Nobody actually cares about the
|
||||
* difference between DT_LNK and DT_REG
|
||||
*/
|
||||
return DT_REG;
|
||||
}
|
||||
|
||||
/* Try to look it up as a directory */
|
||||
pos = cache_name_pos(path, len);
|
||||
if (pos >= 0)
|
||||
return DT_UNKNOWN;
|
||||
pos = -pos-1;
|
||||
while (pos < active_nr) {
|
||||
ce = active_cache[pos++];
|
||||
if (strncmp(ce->name, path, len))
|
||||
break;
|
||||
if (ce->name[len] > '/')
|
||||
break;
|
||||
if (ce->name[len] < '/')
|
||||
continue;
|
||||
if (!ce_uptodate(ce))
|
||||
break; /* continue? */
|
||||
return DT_DIR;
|
||||
}
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
|
||||
static int get_dtype(struct dirent *de, const char *path, int len)
|
||||
{
|
||||
int dtype = de ? DTYPE(de) : DT_UNKNOWN;
|
||||
struct stat st;
|
||||
|
||||
if (dtype != DT_UNKNOWN)
|
||||
return dtype;
|
||||
dtype = get_index_dtype(path, len);
|
||||
if (dtype != DT_UNKNOWN)
|
||||
return dtype;
|
||||
if (lstat(path, &st))
|
||||
@@ -574,15 +634,15 @@ static int get_dtype(struct dirent *de, const char *path)
|
||||
* Also, we ignore the name ".git" (even if it is not a directory).
|
||||
* That likely will not change.
|
||||
*/
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
|
||||
static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify)
|
||||
{
|
||||
DIR *fdir = opendir(*path ? path : ".");
|
||||
DIR *fdir = opendir(*base ? base : ".");
|
||||
int contents = 0;
|
||||
|
||||
if (fdir) {
|
||||
struct dirent *de;
|
||||
char fullname[PATH_MAX + 1];
|
||||
memcpy(fullname, base, baselen);
|
||||
char path[PATH_MAX + 1];
|
||||
memcpy(path, base, baselen);
|
||||
|
||||
while ((de = readdir(fdir)) != NULL) {
|
||||
int len, dtype;
|
||||
@@ -593,17 +653,18 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
continue;
|
||||
len = strlen(de->d_name);
|
||||
/* Ignore overly long pathnames! */
|
||||
if (len + baselen + 8 > sizeof(fullname))
|
||||
if (len + baselen + 8 > sizeof(path))
|
||||
continue;
|
||||
memcpy(fullname + baselen, de->d_name, len+1);
|
||||
if (simplify_away(fullname, baselen + len, simplify))
|
||||
memcpy(path + baselen, de->d_name, len+1);
|
||||
len = baselen + len;
|
||||
if (simplify_away(path, len, simplify))
|
||||
continue;
|
||||
|
||||
dtype = DTYPE(de);
|
||||
exclude = excluded(dir, fullname, &dtype);
|
||||
exclude = excluded(dir, path, &dtype);
|
||||
if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
|
||||
&& in_pathspec(fullname, baselen + len, simplify))
|
||||
dir_add_ignored(dir, fullname, baselen + len);
|
||||
&& in_pathspec(path, len, simplify))
|
||||
dir_add_ignored(dir, path,len);
|
||||
|
||||
/*
|
||||
* Excluded? If we don't explicitly want to show
|
||||
@@ -613,7 +674,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
continue;
|
||||
|
||||
if (dtype == DT_UNKNOWN)
|
||||
dtype = get_dtype(de, fullname);
|
||||
dtype = get_dtype(de, path, len);
|
||||
|
||||
/*
|
||||
* Do we want to see just the ignored files?
|
||||
@@ -630,9 +691,9 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
default:
|
||||
continue;
|
||||
case DT_DIR:
|
||||
memcpy(fullname + baselen + len, "/", 2);
|
||||
memcpy(path + len, "/", 2);
|
||||
len++;
|
||||
switch (treat_directory(dir, fullname, baselen + len, simplify)) {
|
||||
switch (treat_directory(dir, path, len, simplify)) {
|
||||
case show_directory:
|
||||
if (exclude != !!(dir->flags
|
||||
& DIR_SHOW_IGNORED))
|
||||
@@ -640,7 +701,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
break;
|
||||
case recurse_into_directory:
|
||||
contents += read_directory_recursive(dir,
|
||||
fullname, fullname, baselen + len, 0, simplify);
|
||||
path, len, 0, simplify);
|
||||
continue;
|
||||
case ignore_directory:
|
||||
continue;
|
||||
@@ -654,7 +715,7 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
|
||||
if (check_only)
|
||||
goto exit_early;
|
||||
else
|
||||
dir_add_name(dir, fullname, baselen + len);
|
||||
dir_add_name(dir, path, len);
|
||||
}
|
||||
exit_early:
|
||||
closedir(fdir);
|
||||
@@ -717,15 +778,15 @@ static void free_simplify(struct path_simplify *simplify)
|
||||
free(simplify);
|
||||
}
|
||||
|
||||
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
|
||||
int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)
|
||||
{
|
||||
struct path_simplify *simplify;
|
||||
|
||||
if (has_symlink_leading_path(path, strlen(path)))
|
||||
if (has_symlink_leading_path(path, len))
|
||||
return dir->nr;
|
||||
|
||||
simplify = create_simplify(pathspec);
|
||||
read_directory_recursive(dir, path, base, baselen, 0, simplify);
|
||||
read_directory_recursive(dir, path, len, 0, simplify);
|
||||
free_simplify(simplify);
|
||||
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
|
||||
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
|
||||
|
||||
5
dir.h
5
dir.h
@@ -61,14 +61,13 @@ struct dir_struct {
|
||||
char basebuf[PATH_MAX];
|
||||
};
|
||||
|
||||
extern int common_prefix(const char **pathspec);
|
||||
|
||||
#define MATCHED_RECURSIVELY 1
|
||||
#define MATCHED_FNMATCH 2
|
||||
#define MATCHED_EXACTLY 3
|
||||
extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
|
||||
|
||||
extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen, const char **pathspec);
|
||||
extern int fill_directory(struct dir_struct *dir, const char **pathspec);
|
||||
extern int read_directory(struct dir_struct *, const char *path, int len, const char **pathspec);
|
||||
|
||||
extern int excluded(struct dir_struct *, const char *, int *);
|
||||
extern void add_excludes_from_file(struct dir_struct *, const char *fname);
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
# else
|
||||
# define _XOPEN_SOURCE 500
|
||||
# endif
|
||||
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX)
|
||||
#elif !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__USLC__) && !defined(_M_UNIX) && !defined(sgi)
|
||||
#define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
|
||||
#ifndef __sun__
|
||||
#define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
|
||||
@@ -62,6 +62,7 @@
|
||||
#define _GNU_SOURCE 1
|
||||
#define _BSD_SOURCE 1
|
||||
#define _NETBSD_SOURCE 1
|
||||
#define _SGI_SOURCE 1
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
98
git-svn.perl
98
git-svn.perl
@@ -876,10 +876,6 @@ sub cmd_multi_init {
|
||||
usage(1);
|
||||
}
|
||||
|
||||
# there are currently some bugs that prevent multi-init/multi-fetch
|
||||
# setups from working well without this.
|
||||
$Git::SVN::_minimize_url = 1;
|
||||
|
||||
$_prefix = '' unless defined $_prefix;
|
||||
if (defined $url) {
|
||||
$url = canonicalize_url($url);
|
||||
@@ -1180,7 +1176,7 @@ sub complete_url_ls_init {
|
||||
"wanted to set to: $gs->{url}\n";
|
||||
}
|
||||
command_oneline('config', $k, $gs->{url}) unless $orig_url;
|
||||
my $remote_path = "$ra->{svn_path}/$repo_path";
|
||||
my $remote_path = "$gs->{path}/$repo_path";
|
||||
$remote_path =~ s#/+#/#g;
|
||||
$remote_path =~ s#^/##g;
|
||||
$remote_path .= "/*" if $remote_path !~ /\*/;
|
||||
@@ -1363,11 +1359,11 @@ sub read_repo_config {
|
||||
sub extract_metadata {
|
||||
my $id = shift or return (undef, undef, undef);
|
||||
my ($url, $rev, $uuid) = ($id =~ /^\s*git-svn-id:\s+(.*)\@(\d+)
|
||||
\s([a-f\d\-]+)$/x);
|
||||
\s([a-f\d\-]+)$/ix);
|
||||
if (!defined $rev || !$uuid || !$url) {
|
||||
# some of the original repositories I made had
|
||||
# identifiers like this:
|
||||
($rev, $uuid) = ($id =~/^\s*git-svn-id:\s(\d+)\@([a-f\d\-]+)/);
|
||||
($rev, $uuid) = ($id =~/^\s*git-svn-id:\s(\d+)\@([a-f\d\-]+)/i);
|
||||
}
|
||||
return ($url, $rev, $uuid);
|
||||
}
|
||||
@@ -2014,7 +2010,7 @@ sub _set_svm_vars {
|
||||
|
||||
chomp($src, $uuid);
|
||||
|
||||
$uuid =~ m{^[0-9a-f\-]{30,}$}
|
||||
$uuid =~ m{^[0-9a-f\-]{30,}$}i
|
||||
or die "doesn't look right - svm:uuid is '$uuid'\n";
|
||||
|
||||
# the '!' is used to mark the repos_root!/relative/path
|
||||
@@ -2100,7 +2096,7 @@ sub svnsync {
|
||||
die "doesn't look right - svn:sync-from-url is '$url'\n";
|
||||
|
||||
my $uuid = tmp_config('--get', "$section.svnsync-uuid");
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}) or
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
|
||||
die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
|
||||
|
||||
$svnsync = { url => $url, uuid => $uuid }
|
||||
@@ -2118,7 +2114,7 @@ sub svnsync {
|
||||
die "doesn't look right - svn:sync-from-url is '$url'\n";
|
||||
|
||||
my $uuid = $rp->{'svn:sync-from-uuid'} or die $err . "uuid\n";
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}) or
|
||||
($uuid) = ($uuid =~ m{^([0-9a-f\-]{30,})$}i) or
|
||||
die "doesn't look right - svn:sync-from-uuid is '$uuid'\n";
|
||||
|
||||
my $section = "svn-remote.$self->{repo_id}";
|
||||
@@ -2134,7 +2130,7 @@ sub ra_uuid {
|
||||
unless ($self->{ra_uuid}) {
|
||||
my $key = "svn-remote.$self->{repo_id}.uuid";
|
||||
my $uuid = eval { tmp_config('--get', $key) };
|
||||
if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/) {
|
||||
if (!$@ && $uuid && $uuid =~ /^([a-f\d\-]{30,})$/i) {
|
||||
$self->{ra_uuid} = $uuid;
|
||||
} else {
|
||||
die "ra_uuid called without URL\n" unless $self->{url};
|
||||
@@ -2177,16 +2173,6 @@ sub ra {
|
||||
$ra;
|
||||
}
|
||||
|
||||
sub rel_path {
|
||||
my ($self) = @_;
|
||||
my $repos_root = $self->ra->{repos_root};
|
||||
return $self->{path} if ($self->{url} eq $repos_root);
|
||||
my $url = $self->{url} .
|
||||
(length $self->{path} ? "/$self->{path}" : $self->{path});
|
||||
$url =~ s!^\Q$repos_root\E(?:/+|$)!!g;
|
||||
$url;
|
||||
}
|
||||
|
||||
# prop_walk(PATH, REV, SUB)
|
||||
# -------------------------
|
||||
# Recursively traverse PATH at revision REV and invoke SUB for each
|
||||
@@ -2512,10 +2498,7 @@ sub match_paths {
|
||||
if (my $path = $paths->{"/$self->{path}"}) {
|
||||
return ($path->{action} eq 'D') ? 0 : 1;
|
||||
}
|
||||
my $repos_root = $self->ra->{repos_root};
|
||||
my $extended_path = $self->{url} . '/' . $self->{path};
|
||||
$extended_path =~ s#^\Q$repos_root\E(/|$)##;
|
||||
$self->{path_regex} ||= qr/^\/\Q$extended_path\E\//;
|
||||
$self->{path_regex} ||= qr/^\/\Q$self->{path}\E\//;
|
||||
if (grep /$self->{path_regex}/, keys %$paths) {
|
||||
return 1;
|
||||
}
|
||||
@@ -2538,15 +2521,14 @@ sub find_parent_branch {
|
||||
unless (defined $paths) {
|
||||
my $err_handler = $SVN::Error::handler;
|
||||
$SVN::Error::handler = \&Git::SVN::Ra::skip_unknown_revs;
|
||||
$self->ra->get_log([$self->{path}], $rev, $rev, 0, 1, 1, sub {
|
||||
$paths =
|
||||
Git::SVN::Ra::dup_changed_paths($_[0]) });
|
||||
$self->ra->get_log([$self->{path}], $rev, $rev, 0, 1, 1,
|
||||
sub { $paths = $_[0] });
|
||||
$SVN::Error::handler = $err_handler;
|
||||
}
|
||||
return undef unless defined $paths;
|
||||
|
||||
# look for a parent from another branch:
|
||||
my @b_path_components = split m#/#, $self->rel_path;
|
||||
my @b_path_components = split m#/#, $self->{path};
|
||||
my @a_path_components;
|
||||
my $i;
|
||||
while (@b_path_components) {
|
||||
@@ -2564,11 +2546,11 @@ sub find_parent_branch {
|
||||
my $r = $i->{copyfrom_rev};
|
||||
my $repos_root = $self->ra->{repos_root};
|
||||
my $url = $self->ra->{url};
|
||||
my $new_url = $repos_root . $branch_from;
|
||||
my $new_url = $url . $branch_from;
|
||||
print STDERR "Found possible branch point: ",
|
||||
"$new_url => ", $self->full_url, ", $r\n";
|
||||
$branch_from =~ s#^/##;
|
||||
my $gs = $self->other_gs($new_url, $url, $repos_root,
|
||||
my $gs = $self->other_gs($new_url, $url,
|
||||
$branch_from, $r, $self->{ref_id});
|
||||
my ($r0, $parent) = $gs->find_rev_before($r, 1);
|
||||
{
|
||||
@@ -2753,9 +2735,9 @@ sub parse_svn_date {
|
||||
}
|
||||
|
||||
sub other_gs {
|
||||
my ($self, $new_url, $url, $repos_root,
|
||||
my ($self, $new_url, $url,
|
||||
$branch_from, $r, $old_ref_id) = @_;
|
||||
my $gs = Git::SVN->find_by_url($new_url, $repos_root, $branch_from);
|
||||
my $gs = Git::SVN->find_by_url($new_url, $url, $branch_from);
|
||||
unless ($gs) {
|
||||
my $ref_id = $old_ref_id;
|
||||
$ref_id =~ s/\@\d+$//;
|
||||
@@ -2866,7 +2848,7 @@ sub make_log_entry {
|
||||
die "Can't have both 'useSvmProps' and 'rewriteRoot' ",
|
||||
"options set!\n";
|
||||
}
|
||||
my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$};
|
||||
my ($uuid, $r) = $headrev =~ m{^([a-f\d\-]{30,}):(\d+)$}i;
|
||||
# we don't want "SVM: initializing mirror for junk" ...
|
||||
return undef if $r == 0;
|
||||
my $svm = $self->svm;
|
||||
@@ -4431,6 +4413,34 @@ sub get_log {
|
||||
my ($self, @args) = @_;
|
||||
my $pool = SVN::Pool->new;
|
||||
|
||||
# svn_log_changed_path_t objects passed to get_log are likely to be
|
||||
# overwritten even if only the refs are copied to an external variable,
|
||||
# so we should dup the structures in their entirety. Using an
|
||||
# externally passed pool (instead of our temporary and quickly cleared
|
||||
# pool in Git::SVN::Ra) does not help matters at all...
|
||||
my $receiver = pop @args;
|
||||
my $prefix = "/".$self->{svn_path};
|
||||
$prefix =~ s#/+($)##;
|
||||
my $prefix_regex = qr#^\Q$prefix\E#;
|
||||
push(@args, sub {
|
||||
my ($paths) = $_[0];
|
||||
return &$receiver(@_) unless $paths;
|
||||
$_[0] = ();
|
||||
foreach my $p (keys %$paths) {
|
||||
my $i = $paths->{$p};
|
||||
# Make path relative to our url, not repos_root
|
||||
$p =~ s/$prefix_regex//;
|
||||
my %s = map { $_ => $i->$_; }
|
||||
qw/copyfrom_path copyfrom_rev action/;
|
||||
if ($s{'copyfrom_path'}) {
|
||||
$s{'copyfrom_path'} =~ s/$prefix_regex//;
|
||||
}
|
||||
$_[0]{$p} = \%s;
|
||||
}
|
||||
&$receiver(@_);
|
||||
});
|
||||
|
||||
|
||||
# the limit parameter was not supported in SVN 1.1.x, so we
|
||||
# drop it. Therefore, the receiver callback passed to it
|
||||
# is made aware of this limitation by being wrapped if
|
||||
@@ -4600,7 +4610,7 @@ sub gs_fetch_loop_common {
|
||||
};
|
||||
sub _cb {
|
||||
my ($paths, $r, $author, $date, $log) = @_;
|
||||
[ dup_changed_paths($paths),
|
||||
[ $paths,
|
||||
{ author => $author, date => $date, log => $log } ];
|
||||
}
|
||||
$self->get_log([$longest_path], $min, $max, 0, 1, 1,
|
||||
@@ -4823,24 +4833,6 @@ sub skip_unknown_revs {
|
||||
die "Error from SVN, ($errno): ", $err->expanded_message,"\n";
|
||||
}
|
||||
|
||||
# svn_log_changed_path_t objects passed to get_log are likely to be
|
||||
# overwritten even if only the refs are copied to an external variable,
|
||||
# so we should dup the structures in their entirety. Using an externally
|
||||
# passed pool (instead of our temporary and quickly cleared pool in
|
||||
# Git::SVN::Ra) does not help matters at all...
|
||||
sub dup_changed_paths {
|
||||
my ($paths) = @_;
|
||||
return undef unless $paths;
|
||||
my %ret;
|
||||
foreach my $p (keys %$paths) {
|
||||
my $i = $paths->{$p};
|
||||
my %s = map { $_ => $i->$_ }
|
||||
qw/copyfrom_path copyfrom_rev action/;
|
||||
$ret{$p} = \%s;
|
||||
}
|
||||
\%ret;
|
||||
}
|
||||
|
||||
package Git::SVN::Log;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@@ -94,7 +94,7 @@ our $favicon = "++GITWEB_FAVICON++";
|
||||
# URI and label (title) of GIT logo link
|
||||
#our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/";
|
||||
#our $logo_label = "git documentation";
|
||||
our $logo_url = "http://git.or.cz/";
|
||||
our $logo_url = "http://git-scm.com/";
|
||||
our $logo_label = "git homepage";
|
||||
|
||||
# source of projects list
|
||||
|
||||
@@ -34,7 +34,9 @@ static void *preload_thread(void *_data)
|
||||
struct thread_data *p = _data;
|
||||
struct index_state *index = p->index;
|
||||
struct cache_entry **cep = index->cache + p->offset;
|
||||
struct cache_def cache;
|
||||
|
||||
memset(&cache, 0, sizeof(cache));
|
||||
nr = p->nr;
|
||||
if (nr + p->offset > index->cache_nr)
|
||||
nr = index->cache_nr - p->offset;
|
||||
@@ -49,6 +51,8 @@ static void *preload_thread(void *_data)
|
||||
continue;
|
||||
if (!ce_path_match(ce, p->pathspec))
|
||||
continue;
|
||||
if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
|
||||
continue;
|
||||
if (lstat(ce->name, &st))
|
||||
continue;
|
||||
if (ie_match_stat(index, ce, &st, CE_MATCH_RACY_IS_DIRTY))
|
||||
|
||||
@@ -133,7 +133,7 @@ void mark_parents_uninteresting(struct commit *commit)
|
||||
static void add_pending_object_with_mode(struct rev_info *revs, struct object *obj, const char *name, unsigned mode)
|
||||
{
|
||||
if (revs->no_walk && (obj->flags & UNINTERESTING))
|
||||
die("object ranges do not make sense when not walking revisions");
|
||||
revs->no_walk = 0;
|
||||
if (revs->reflog_info && obj->type == OBJ_COMMIT &&
|
||||
add_reflog_for_walk(revs->reflog_info,
|
||||
(struct commit *)obj, name))
|
||||
|
||||
90
symlinks.c
90
symlinks.c
@@ -32,19 +32,13 @@ static int longest_path_match(const char *name_a, int len_a,
|
||||
return match_len;
|
||||
}
|
||||
|
||||
static struct cache_def {
|
||||
char path[PATH_MAX + 1];
|
||||
int len;
|
||||
int flags;
|
||||
int track_flags;
|
||||
int prefix_len_stat_func;
|
||||
} cache;
|
||||
static struct cache_def default_cache;
|
||||
|
||||
static inline void reset_lstat_cache(void)
|
||||
static inline void reset_lstat_cache(struct cache_def *cache)
|
||||
{
|
||||
cache.path[0] = '\0';
|
||||
cache.len = 0;
|
||||
cache.flags = 0;
|
||||
cache->path[0] = '\0';
|
||||
cache->len = 0;
|
||||
cache->flags = 0;
|
||||
/*
|
||||
* The track_flags and prefix_len_stat_func members is only
|
||||
* set by the safeguard rule inside lstat_cache()
|
||||
@@ -70,23 +64,23 @@ static inline void reset_lstat_cache(void)
|
||||
* of the prefix, where the cache should use the stat() function
|
||||
* instead of the lstat() function to test each path component.
|
||||
*/
|
||||
static int lstat_cache(const char *name, int len,
|
||||
static int lstat_cache(struct cache_def *cache, const char *name, int len,
|
||||
int track_flags, int prefix_len_stat_func)
|
||||
{
|
||||
int match_len, last_slash, last_slash_dir, previous_slash;
|
||||
int match_flags, ret_flags, save_flags, max_len, ret;
|
||||
struct stat st;
|
||||
|
||||
if (cache.track_flags != track_flags ||
|
||||
cache.prefix_len_stat_func != prefix_len_stat_func) {
|
||||
if (cache->track_flags != track_flags ||
|
||||
cache->prefix_len_stat_func != prefix_len_stat_func) {
|
||||
/*
|
||||
* As a safeguard rule we clear the cache if the
|
||||
* values of track_flags and/or prefix_len_stat_func
|
||||
* does not match with the last supplied values.
|
||||
*/
|
||||
reset_lstat_cache();
|
||||
cache.track_flags = track_flags;
|
||||
cache.prefix_len_stat_func = prefix_len_stat_func;
|
||||
reset_lstat_cache(cache);
|
||||
cache->track_flags = track_flags;
|
||||
cache->prefix_len_stat_func = prefix_len_stat_func;
|
||||
match_len = last_slash = 0;
|
||||
} else {
|
||||
/*
|
||||
@@ -94,10 +88,10 @@ static int lstat_cache(const char *name, int len,
|
||||
* the 2 "excluding" path types.
|
||||
*/
|
||||
match_len = last_slash =
|
||||
longest_path_match(name, len, cache.path, cache.len,
|
||||
longest_path_match(name, len, cache->path, cache->len,
|
||||
&previous_slash);
|
||||
match_flags = cache.flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||
if (match_flags && match_len == cache.len)
|
||||
match_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||
if (match_flags && match_len == cache->len)
|
||||
return match_flags;
|
||||
/*
|
||||
* If we now have match_len > 0, we would know that
|
||||
@@ -121,18 +115,18 @@ static int lstat_cache(const char *name, int len,
|
||||
max_len = len < PATH_MAX ? len : PATH_MAX;
|
||||
while (match_len < max_len) {
|
||||
do {
|
||||
cache.path[match_len] = name[match_len];
|
||||
cache->path[match_len] = name[match_len];
|
||||
match_len++;
|
||||
} while (match_len < max_len && name[match_len] != '/');
|
||||
if (match_len >= max_len && !(track_flags & FL_FULLPATH))
|
||||
break;
|
||||
last_slash = match_len;
|
||||
cache.path[last_slash] = '\0';
|
||||
cache->path[last_slash] = '\0';
|
||||
|
||||
if (last_slash <= prefix_len_stat_func)
|
||||
ret = stat(cache.path, &st);
|
||||
ret = stat(cache->path, &st);
|
||||
else
|
||||
ret = lstat(cache.path, &st);
|
||||
ret = lstat(cache->path, &st);
|
||||
|
||||
if (ret) {
|
||||
ret_flags = FL_LSTATERR;
|
||||
@@ -156,9 +150,9 @@ static int lstat_cache(const char *name, int len,
|
||||
*/
|
||||
save_flags = ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
|
||||
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
|
||||
cache.path[last_slash] = '\0';
|
||||
cache.len = last_slash;
|
||||
cache.flags = save_flags;
|
||||
cache->path[last_slash] = '\0';
|
||||
cache->len = last_slash;
|
||||
cache->flags = save_flags;
|
||||
} else if ((track_flags & FL_DIR) &&
|
||||
last_slash_dir > 0 && last_slash_dir <= PATH_MAX) {
|
||||
/*
|
||||
@@ -172,11 +166,11 @@ static int lstat_cache(const char *name, int len,
|
||||
* can still cache the path components before the last
|
||||
* one (the found symlink or non-existing component).
|
||||
*/
|
||||
cache.path[last_slash_dir] = '\0';
|
||||
cache.len = last_slash_dir;
|
||||
cache.flags = FL_DIR;
|
||||
cache->path[last_slash_dir] = '\0';
|
||||
cache->len = last_slash_dir;
|
||||
cache->flags = FL_DIR;
|
||||
} else {
|
||||
reset_lstat_cache();
|
||||
reset_lstat_cache(cache);
|
||||
}
|
||||
return ret_flags;
|
||||
}
|
||||
@@ -188,16 +182,17 @@ static int lstat_cache(const char *name, int len,
|
||||
void invalidate_lstat_cache(const char *name, int len)
|
||||
{
|
||||
int match_len, previous_slash;
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
|
||||
match_len = longest_path_match(name, len, cache.path, cache.len,
|
||||
match_len = longest_path_match(name, len, cache->path, cache->len,
|
||||
&previous_slash);
|
||||
if (len == match_len) {
|
||||
if ((cache.track_flags & FL_DIR) && previous_slash > 0) {
|
||||
cache.path[previous_slash] = '\0';
|
||||
cache.len = previous_slash;
|
||||
cache.flags = FL_DIR;
|
||||
if ((cache->track_flags & FL_DIR) && previous_slash > 0) {
|
||||
cache->path[previous_slash] = '\0';
|
||||
cache->len = previous_slash;
|
||||
cache->flags = FL_DIR;
|
||||
} else {
|
||||
reset_lstat_cache();
|
||||
reset_lstat_cache(cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,19 +202,26 @@ void invalidate_lstat_cache(const char *name, int len)
|
||||
*/
|
||||
void clear_lstat_cache(void)
|
||||
{
|
||||
reset_lstat_cache();
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
reset_lstat_cache(cache);
|
||||
}
|
||||
|
||||
#define USE_ONLY_LSTAT 0
|
||||
|
||||
/*
|
||||
* Return non-zero if path 'name' has a leading symlink component
|
||||
*/
|
||||
int threaded_has_symlink_leading_path(struct cache_def *cache, const char *name, int len)
|
||||
{
|
||||
return lstat_cache(cache, name, len, FL_SYMLINK|FL_DIR, USE_ONLY_LSTAT) & FL_SYMLINK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return non-zero if path 'name' has a leading symlink component
|
||||
*/
|
||||
int has_symlink_leading_path(const char *name, int len)
|
||||
{
|
||||
return lstat_cache(name, len,
|
||||
FL_SYMLINK|FL_DIR, USE_ONLY_LSTAT) &
|
||||
FL_SYMLINK;
|
||||
return threaded_has_symlink_leading_path(&default_cache, name, len);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -228,7 +230,8 @@ int has_symlink_leading_path(const char *name, int len)
|
||||
*/
|
||||
int has_symlink_or_noent_leading_path(const char *name, int len)
|
||||
{
|
||||
return lstat_cache(name, len,
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
return lstat_cache(cache, name, len,
|
||||
FL_SYMLINK|FL_NOENT|FL_DIR, USE_ONLY_LSTAT) &
|
||||
(FL_SYMLINK|FL_NOENT);
|
||||
}
|
||||
@@ -242,7 +245,8 @@ int has_symlink_or_noent_leading_path(const char *name, int len)
|
||||
*/
|
||||
int has_dirs_only_path(const char *name, int len, int prefix_len)
|
||||
{
|
||||
return lstat_cache(name, len,
|
||||
struct cache_def *cache = &default_cache; /* FIXME */
|
||||
return lstat_cache(cache, name, len,
|
||||
FL_DIR|FL_FULLPATH, prefix_len) &
|
||||
FL_DIR;
|
||||
}
|
||||
|
||||
@@ -119,4 +119,24 @@ test_expect_success 'quickfetch should not copy from alternate' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'quickfetch should handle ~1000 refs (on Windows)' '
|
||||
|
||||
git gc &&
|
||||
head=$(git rev-parse HEAD) &&
|
||||
branchprefix="$head refs/heads/branch" &&
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for j in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for k in 0 1 2 3 4 5 6 7 8 9; do
|
||||
echo "$branchprefix$i$j$k" >> .git/packed-refs
|
||||
done
|
||||
done
|
||||
done &&
|
||||
(
|
||||
cd cloned &&
|
||||
git fetch &&
|
||||
git fetch
|
||||
)
|
||||
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -99,22 +99,22 @@ test_expect_success 'Multiple branch or tag paths require -d' '
|
||||
|
||||
test_expect_success 'create new branches and tags' '
|
||||
( cd git_project &&
|
||||
git svn branch -m "New branch 1" -d project/b_one New1 ) &&
|
||||
git svn branch -m "New branch 1" -d b_one New1 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e b_one/New1/a.file ) &&
|
||||
|
||||
( cd git_project &&
|
||||
git svn branch -m "New branch 2" -d project/b_two New2 ) &&
|
||||
git svn branch -m "New branch 2" -d b_two New2 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e b_two/New2/a.file ) &&
|
||||
|
||||
( cd git_project &&
|
||||
git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) &&
|
||||
git svn branch -t -m "New tag 1" -d tags_A Tag1 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e tags_A/Tag1/a.file ) &&
|
||||
|
||||
( cd git_project &&
|
||||
git svn tag -m "New tag 2" -d project/tags_B Tag2 ) &&
|
||||
git svn tag -m "New tag 2" -d tags_B Tag2 ) &&
|
||||
( cd svn_project &&
|
||||
svn_cmd up && test -e tags_B/Tag2/a.file )
|
||||
'
|
||||
|
||||
@@ -128,7 +128,7 @@ static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_o
|
||||
|
||||
static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_options *o)
|
||||
{
|
||||
struct cache_entry *src[5] = { ce, };
|
||||
struct cache_entry *src[5] = { ce, NULL, };
|
||||
|
||||
o->pos++;
|
||||
if (ce_stage(ce)) {
|
||||
@@ -551,7 +551,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
|
||||
memset(&d, 0, sizeof(d));
|
||||
if (o->dir)
|
||||
d.exclude_per_dir = o->dir->exclude_per_dir;
|
||||
i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);
|
||||
i = read_directory(&d, pathbuf, namelen+1, NULL);
|
||||
if (i)
|
||||
return o->gently ? -1 :
|
||||
error(ERRORMSG(o, not_uptodate_dir), ce->name);
|
||||
@@ -1004,7 +1004,7 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
|
||||
|
||||
if (old && same(old, a)) {
|
||||
int update = 0;
|
||||
if (o->reset) {
|
||||
if (o->reset && !ce_uptodate(old)) {
|
||||
struct stat st;
|
||||
if (lstat(old->name, &st) ||
|
||||
ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID))
|
||||
|
||||
@@ -255,7 +255,7 @@ static void wt_status_print_untracked(struct wt_status *s)
|
||||
DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
|
||||
setup_standard_excludes(&dir);
|
||||
|
||||
read_directory(&dir, ".", "", 0, NULL);
|
||||
fill_directory(&dir, NULL);
|
||||
for(i = 0; i < dir.nr; i++) {
|
||||
struct dir_entry *ent = dir.entries[i];
|
||||
if (!cache_name_is_other(ent->name, ent->len))
|
||||
|
||||
Reference in New Issue
Block a user