* [PATCH v2 14/21] Convert unmerge_cache to take struct pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/checkout.c | 2 +-
rerere.c | 2 +-
resolve-undo.c | 4 ++--
resolve-undo.h | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 00910dc..aa399d6 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -281,7 +281,7 @@ static int checkout_paths(const struct checkout_opts *opts,
/* "checkout -m path" to recreate conflicted state */
if (opts->merge)
- unmerge_cache(opts->pathspec.raw);
+ unmerge_cache(&opts->pathspec);
/* Any unmerged paths? */
for (pos = 0; pos < active_nr; pos++) {
diff --git a/rerere.c b/rerere.c
index f8ddf85..9d149fa 100644
--- a/rerere.c
+++ b/rerere.c
@@ -666,7 +666,7 @@ int rerere_forget(struct pathspec *pathspec)
fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
- unmerge_cache(pathspec->raw);
+ unmerge_cache(pathspec);
find_conflict(&conflict);
for (i = 0; i < conflict.nr; i++) {
struct string_list_item *it = &conflict.items[i];
diff --git a/resolve-undo.c b/resolve-undo.c
index 72b4612..1bfece2 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -156,7 +156,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
return unmerge_index_entry_at(istate, pos);
}
-void unmerge_index(struct index_state *istate, const char **pathspec)
+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
{
int i;
@@ -165,7 +165,7 @@ void unmerge_index(struct index_state *istate, const char **pathspec)
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
- if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+ if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))
continue;
i = unmerge_index_entry_at(istate, i);
}
diff --git a/resolve-undo.h b/resolve-undo.h
index 8458769..81e8803 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -11,6 +11,6 @@ extern void resolve_undo_write(struct strbuf *, struct string_list *);
extern struct string_list *resolve_undo_read(const char *, unsigned long);
extern void resolve_undo_clear_index(struct index_state *);
extern int unmerge_index_entry_at(struct index_state *, int);
-extern void unmerge_index(struct index_state *, const char **);
+extern void unmerge_index(struct index_state *, const struct pathspec *);
#endif
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 13/21] Convert read_cache_preload() to take struct pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/checkout.c | 2 +-
builtin/commit.c | 4 ++--
builtin/diff-files.c | 2 +-
builtin/diff-index.c | 2 +-
builtin/diff.c | 4 ++--
cache.h | 4 +++-
preload-index.c | 20 +++++++++++---------
7 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index da25298..00910dc 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -261,7 +261,7 @@ static int checkout_paths(const struct checkout_opts *opts,
lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_locked_index(lock_file, 1);
- if (read_cache_preload(opts->pathspec.raw) < 0)
+ if (read_cache_preload(&opts->pathspec) < 0)
return error(_("corrupt index file"));
if (opts->source_tree)
diff --git a/builtin/commit.c b/builtin/commit.c
index 196dfab..069d853 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -287,7 +287,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
PATHSPEC_EMPTY_MATCH_ALL,
prefix, argv);
- if (read_cache_preload(pathspec.raw) < 0)
+ if (read_cache_preload(&pathspec) < 0)
die(_("index file corrupt"));
if (interactive) {
@@ -1209,7 +1209,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
PATHSPEC_EMPTY_MATCH_ALL,
prefix, argv);
- read_cache_preload(s.pathspec.raw);
+ read_cache_preload(&s.pathspec);
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);
fd = hold_locked_index(&index_lock, 0);
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 46085f8..9200069 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
(rev.diffopt.output_format & DIFF_FORMAT_PATCH))
rev.combine_merges = rev.dense_combined_merges = 1;
- if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+ if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
perror("read_cache_preload");
return -1;
}
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 1c737f7..ce15b23 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -43,7 +43,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
usage(diff_cache_usage);
if (!cached) {
setup_work_tree();
- if (read_cache_preload(rev.diffopt.pathspec.raw) < 0) {
+ if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
perror("read_cache_preload");
return -1;
}
diff --git a/builtin/diff.c b/builtin/diff.c
index 8c2af6c..62bdc4d 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -140,7 +140,7 @@ static int builtin_diff_index(struct rev_info *revs,
usage(builtin_diff_usage);
if (!cached) {
setup_work_tree();
- if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+ if (read_cache_preload(&revs->diffopt.pathspec) < 0) {
perror("read_cache_preload");
return -1;
}
@@ -240,7 +240,7 @@ static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv
revs->combine_merges = revs->dense_combined_merges = 1;
setup_work_tree();
- if (read_cache_preload(revs->diffopt.pathspec.raw) < 0) {
+ if (read_cache_preload(&revs->diffopt.pathspec) < 0) {
perror("read_cache_preload");
return -1;
}
diff --git a/cache.h b/cache.h
index af96376..c594ded 100644
--- a/cache.h
+++ b/cache.h
@@ -182,6 +182,8 @@ struct cache_entry {
#error "CE_EXTENDED_FLAGS out of range"
#endif
+struct pathspec;
+
/*
* Copy the sha1 and stat state of a cache entry from one to
* another. But we never change the name, or the hash state!
@@ -433,7 +435,7 @@ extern int init_db(const char *template_dir, unsigned int flags);
/* Initialize and use the cache information */
extern int read_index(struct index_state *);
-extern int read_index_preload(struct index_state *, const char **pathspec);
+extern int read_index_preload(struct index_state *, const struct pathspec *pathspec);
extern int read_index_from(struct index_state *, const char *path);
extern int is_index_unborn(struct index_state *);
extern int read_index_unmerged(struct index_state *);
diff --git a/preload-index.c b/preload-index.c
index 49cb08d..91f27f7 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -4,7 +4,8 @@
#include "cache.h"
#ifdef NO_PTHREADS
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+ const struct pathspec *pathspec)
{
; /* nothing */
}
@@ -24,7 +25,7 @@ static void preload_index(struct index_state *index, const char **pathspec)
struct thread_data {
pthread_t pthread;
struct index_state *index;
- const char **pathspec;
+ struct pathspec pathspec;
int offset, nr;
};
@@ -35,9 +36,7 @@ static void *preload_thread(void *_data)
struct index_state *index = p->index;
struct cache_entry **cep = index->cache + p->offset;
struct cache_def cache;
- struct pathspec pathspec;
- init_pathspec(&pathspec, p->pathspec);
memset(&cache, 0, sizeof(cache));
nr = p->nr;
if (nr + p->offset > index->cache_nr)
@@ -53,7 +52,7 @@ static void *preload_thread(void *_data)
continue;
if (ce_uptodate(ce))
continue;
- if (!ce_path_match(ce, &pathspec))
+ if (!ce_path_match(ce, &p->pathspec))
continue;
if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
continue;
@@ -63,11 +62,11 @@ static void *preload_thread(void *_data)
continue;
ce_mark_uptodate(ce);
} while (--nr > 0);
- free_pathspec(&pathspec);
return NULL;
}
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+ const struct pathspec *pathspec)
{
int threads, i, work, offset;
struct thread_data data[MAX_PARALLEL];
@@ -82,10 +81,12 @@ static void preload_index(struct index_state *index, const char **pathspec)
threads = MAX_PARALLEL;
offset = 0;
work = DIV_ROUND_UP(index->cache_nr, threads);
+ memset(&data, 0, sizeof(data));
for (i = 0; i < threads; i++) {
struct thread_data *p = data+i;
p->index = index;
- p->pathspec = pathspec;
+ if (pathspec)
+ p->pathspec = *pathspec;
p->offset = offset;
p->nr = work;
offset += work;
@@ -100,7 +101,8 @@ static void preload_index(struct index_state *index, const char **pathspec)
}
#endif
-int read_index_preload(struct index_state *index, const char **pathspec)
+int read_index_preload(struct index_state *index,
+ const struct pathspec *pathspec)
{
int retval = read_index(index);
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 12/21] add: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
treat_gitlinks() modifies pathspec and is moved to dir.c, close to
other pathspec code. It'll be removed later when parse_pathspec()
learns to take over its job. Note that treat_gitlinks() and
strip_trailing_slash_from_submodules() do not perform exactly the same
thing. But that does not matter for now.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/add.c | 84 ++++++++++++++++++++---------------------------------------
cache.h | 1 +
dir.c | 32 +++++++++++++++++++++++
3 files changed, 61 insertions(+), 56 deletions(-)
diff --git a/builtin/add.c b/builtin/add.c
index e664100..c8592fe 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -153,33 +153,6 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, int
return seen;
}
-static void treat_gitlinks(const char **pathspec)
-{
- int i;
-
- if (!pathspec || !*pathspec)
- return;
-
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- if (S_ISGITLINK(ce->ce_mode)) {
- int len = ce_namelen(ce), j;
- for (j = 0; pathspec[j]; j++) {
- int len2 = strlen(pathspec[j]);
- if (len2 <= len || pathspec[j][len] != '/' ||
- memcmp(ce->name, pathspec[j], len))
- continue;
- if (len2 == len + 1)
- /* strip trailing slash */
- pathspec[j] = xstrndup(ce->name, len);
- else
- die (_("Path '%s' is in submodule '%.*s'"),
- pathspec[j], len, ce->name);
- }
- }
- }
-}
-
static void refresh(int verbose, const char **pathspec)
{
char *seen;
@@ -197,21 +170,18 @@ static void refresh(int verbose, const char **pathspec)
free(seen);
}
-static const char **validate_pathspec(int argc, const char **argv, const char *prefix)
+static void validate_pathspec(const char **pathspec, const char *prefix)
{
- const char **pathspec = get_pathspec(prefix, argv);
-
- if (pathspec) {
- const char **p;
- for (p = pathspec; *p; p++) {
- if (has_symlink_leading_path(*p, strlen(*p))) {
- int len = prefix ? strlen(prefix) : 0;
- die(_("'%s' is beyond a symbolic link"), *p + len);
- }
+ const char **p;
+ if (!pathspec)
+ return;
+
+ for (p = pathspec; *p; p++) {
+ if (has_symlink_leading_path(*p, strlen(*p))) {
+ int len = prefix ? strlen(prefix) : 0;
+ die(_("'%s' is beyond a symbolic link"), *p + len);
}
}
-
- return pathspec;
}
int run_add_interactive(const char *revision, const char *patch_mode,
@@ -248,7 +218,8 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
const char **pathspec = NULL;
if (argc) {
- pathspec = validate_pathspec(argc, argv, prefix);
+ pathspec = get_pathspec(prefix, argv);
+ validate_pathspec(pathspec, prefix);
if (!pathspec)
return -1;
}
@@ -367,7 +338,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
{
int exit_status = 0;
int newfd;
- const char **pathspec;
+ struct pathspec pathspec;
struct dir_struct dir;
int flags;
int add_new_files;
@@ -415,11 +386,12 @@ int cmd_add(int argc, const char **argv, const char *prefix)
fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
return 0;
}
- pathspec = validate_pathspec(argc, argv, prefix);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+ validate_pathspec(pathspec.raw, prefix);
if (read_cache() < 0)
die(_("index file corrupt"));
- treat_gitlinks(pathspec);
+ treat_gitlinks(&pathspec);
if (add_new_files) {
int baselen;
@@ -432,33 +404,33 @@ int cmd_add(int argc, const char **argv, const char *prefix)
}
/* This picks up the paths that are not tracked */
- baselen = fill_directory(&dir, pathspec);
- if (pathspec)
- seen = prune_directory(&dir, pathspec, baselen);
+ baselen = fill_directory(&dir, pathspec.raw);
+ if (pathspec.nr)
+ seen = prune_directory(&dir, pathspec.raw, baselen);
}
if (refresh_only) {
- refresh(verbose, pathspec);
+ refresh(verbose, pathspec.raw);
goto finish;
}
- if (pathspec) {
+ if (pathspec.nr) {
int i;
struct path_exclude_check check;
path_exclude_check_init(&check, &dir);
if (!seen)
- seen = find_used_pathspec(pathspec);
- for (i = 0; pathspec[i]; i++) {
- if (!seen[i] && pathspec[i][0]
- && !file_exists(pathspec[i])) {
+ seen = find_used_pathspec(pathspec.raw);
+ for (i = 0; pathspec.raw[i]; i++) {
+ if (!seen[i] && pathspec.raw[i][0]
+ && !file_exists(pathspec.raw[i])) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
- if (path_excluded(&check, pathspec[i], -1, &dtype))
- dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i]));
+ if (path_excluded(&check, pathspec.raw[i], -1, &dtype))
+ dir_add_ignored(&dir, pathspec.raw[i], strlen(pathspec.raw[i]));
} else
die(_("pathspec '%s' did not match any files"),
- pathspec[i]);
+ pathspec.raw[i]);
}
}
free(seen);
@@ -467,7 +439,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
plug_bulk_checkin();
- exit_status |= add_files_to_cache(prefix, pathspec, flags);
+ exit_status |= add_files_to_cache(prefix, pathspec.raw, flags);
if (add_new_files)
exit_status |= add_files(&dir, flags);
diff --git a/cache.h b/cache.h
index 62eefb1..af96376 100644
--- a/cache.h
+++ b/cache.h
@@ -497,6 +497,7 @@ extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,
unsigned flags, const char *prefix,
const char **args);
void strip_trailing_slash_from_submodules(struct pathspec *pathspec);
+void treat_gitlinks(struct pathspec *pathspec);
extern void free_pathspec(struct pathspec *);
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
diff --git a/dir.c b/dir.c
index 4be3ca1..4d1f71c 100644
--- a/dir.c
+++ b/dir.c
@@ -1460,6 +1460,38 @@ void strip_trailing_slash_from_submodules(struct pathspec *pathspec)
}
}
+void treat_gitlinks(struct pathspec *pathspec)
+{
+ int i;
+
+ for (i = 0; i < active_nr; i++) {
+ struct cache_entry *ce = active_cache[i];
+ int len = ce_namelen(ce), j;
+
+ if (!S_ISGITLINK(ce->ce_mode))
+ continue;
+
+ for (j = 0; j < pathspec->nr; j++) {
+ int len2 = strlen(pathspec->raw[j]);
+ if (len2 <= len || pathspec->raw[j][len] != '/' ||
+ memcmp(ce->name, pathspec->raw[j], len))
+ continue;
+ if (len2 == len + 1) {
+ /* strip trailing slash */
+ char *path = xstrndup(ce->name, len);
+ pathspec->raw[j] = path;
+ pathspec->items[j].match = path;
+ pathspec->items[j].len = len;
+ pathspec->items[j].nowildcard_len = simple_length(path);
+ } else
+ die (_("Path '%s' is in submodule '%.*s'"),
+ pathspec->raw[j], len, ce->name);
+ }
+ }
+}
+
+
+
void free_pathspec(struct pathspec *pathspec)
{
free(pathspec->items);
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 11/21] archive: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
archive.c | 10 ++++------
archive.h | 2 +-
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/archive.c b/archive.c
index 4666404..530badb 100644
--- a/archive.c
+++ b/archive.c
@@ -150,7 +150,6 @@ int write_archive_entries(struct archiver_args *args,
struct archiver_context context;
struct unpack_trees_options opts;
struct tree_desc t;
- struct pathspec pathspec;
int err;
if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -185,10 +184,8 @@ int write_archive_entries(struct archiver_args *args,
git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
}
- init_pathspec(&pathspec, args->pathspec);
- err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
+ err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
write_archive_entry, &context);
- free_pathspec(&pathspec);
if (err == READ_TREE_RECURSIVE)
err = 0;
return err;
@@ -230,8 +227,9 @@ static int path_exists(struct tree *tree, const char *path)
static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
{
- ar_args->pathspec = pathspec = get_pathspec("", pathspec);
- if (pathspec) {
+ parse_pathspec(&ar_args->pathspec, PATHSPEC_FROMTOP, 0, "", pathspec);
+ if (ar_args->pathspec.nr) {
+ pathspec = ar_args->pathspec.raw;
while (*pathspec) {
if (!path_exists(ar_args->tree, *pathspec))
die("path not found: %s", *pathspec);
diff --git a/archive.h b/archive.h
index 895afcd..a98c49e 100644
--- a/archive.h
+++ b/archive.h
@@ -8,7 +8,7 @@ struct archiver_args {
const unsigned char *commit_sha1;
const struct commit *commit;
time_t time;
- const char **pathspec;
+ struct pathspec pathspec;
unsigned int verbose : 1;
unsigned int worktree_attributes : 1;
unsigned int convert : 1;
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* parsecvs has been salvaged
From: Eric S. Raymond @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Bart Massey, Keith Packard
Since Heiko Voigt and others were concerned about this, I report that
I have successfully salvaged the parsecvs code. I now have it emitting
a correct-looking fast-import stream for my main test repository.
I'm not ready to ship it yet because there are several features I
think it ought to have before I do. An -R option like cvsps's;
correct interpretation of a third timezone field as in cvsps; and,
most significantly, I want to make sure it emits warnings for important
error and problem conditions like unresolvable tags and absence of
commitids.
But these are all relatively minor issues. It is likely I will be able
to ship early next week, at which point I will add support for
parsecvs as a third engine in new cvsimport.
This next step in the larger program will be factoring out the cvsps
test suite and applying it to all three of cvsps, cvs2git, and
parsecvs so I can compare results.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
Americans have the right and advantage of being armed - unlike the citizens
of other countries whose governments are afraid to trust the people with arms.
-- James Madison, The Federalist Papers
^ permalink raw reply
* [PATCH v2 10/21] ls-files: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
strip_trailing_slash_from_submodules() modifies pathspec and is moved
to dir.c, close to other pathspec code. It'll be removed later when
parse_pathspec() learns to take over its job.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/ls-files.c | 42 +++++++++++-------------------------------
cache.h | 1 +
dir.c | 20 ++++++++++++++++++++
3 files changed, 32 insertions(+), 31 deletions(-)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 4a9ee69..9336abd 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -30,7 +30,7 @@ static int debug_mode;
static const char *prefix;
static int max_prefix_len;
static int prefix_len;
-static const char **pathspec;
+static struct pathspec pathspec;
static int error_unmatch;
static char *ps_matched;
static const char *with_tree;
@@ -58,7 +58,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
if (len >= ent->len)
die("git ls-files: internal error - directory entry not superset of prefix");
- if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))
+ if (!match_pathspec_depth(&pathspec, ent->name, ent->len, len, ps_matched))
return;
fputs(tag, stdout);
@@ -133,7 +133,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
if (len >= ce_namelen(ce))
die("git ls-files: internal error - cache entry not superset of prefix");
- if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched))
+ if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), len, ps_matched))
return;
if (tag && *tag && show_valid_bit &&
@@ -187,7 +187,7 @@ static void show_ru_info(void)
len = strlen(path);
if (len < max_prefix_len)
continue; /* outside of the prefix */
- if (!match_pathspec(pathspec, path, len, max_prefix_len, ps_matched))
+ if (!match_pathspec_depth(&pathspec, path, len, max_prefix_len, ps_matched))
continue; /* uninterested */
for (i = 0; i < 3; i++) {
if (!ui->mode[i])
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)
/* For cached/deleted files we don't need to even do the readdir */
if (show_others || show_killed) {
- fill_directory(dir, pathspec);
+ fill_directory(dir, pathspec.raw);
if (show_others)
show_other_files(dir);
if (show_killed)
@@ -287,21 +287,6 @@ static void prune_cache(const char *prefix)
active_nr = last;
}
-static void strip_trailing_slash_from_submodules(void)
-{
- const char **p;
-
- for (p = pathspec; *p != NULL; p++) {
- int len = strlen(*p), pos;
-
- if (len < 1 || (*p)[len - 1] != '/')
- continue;
- pos = cache_name_pos(*p, len - 1);
- if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode))
- *p = xstrndup(*p, len - 1);
- }
-}
-
/*
* Read the tree specified with --with-tree option
* (typically, HEAD) into stage #1 and then
@@ -549,23 +534,18 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
if (require_work_tree && !is_inside_work_tree())
setup_work_tree();
- pathspec = get_pathspec(prefix, argv);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
/* be nice with submodule paths ending in a slash */
- if (pathspec)
- strip_trailing_slash_from_submodules();
+ strip_trailing_slash_from_submodules(&pathspec);
/* Find common prefix for all pathspec's */
- max_prefix = common_prefix(pathspec);
+ max_prefix = common_prefix(pathspec.raw);
max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
/* Treat unmatching pathspec elements as errors */
- if (pathspec && error_unmatch) {
- int num;
- for (num = 0; pathspec[num]; num++)
- ;
- ps_matched = xcalloc(1, num);
- }
+ if (pathspec.nr && error_unmatch)
+ ps_matched = xcalloc(1, pathspec.nr);
if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
die("ls-files --ignored needs some exclude pattern");
@@ -592,7 +572,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
if (ps_matched) {
int bad;
- bad = report_path_error(ps_matched, pathspec, prefix);
+ bad = report_path_error(ps_matched, pathspec.raw, prefix);
if (bad)
fprintf(stderr, "Did you forget to 'git add'?\n");
diff --git a/cache.h b/cache.h
index a3c316f..62eefb1 100644
--- a/cache.h
+++ b/cache.h
@@ -496,6 +496,7 @@ extern int init_pathspec(struct pathspec *, const char **);
extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,
unsigned flags, const char *prefix,
const char **args);
+void strip_trailing_slash_from_submodules(struct pathspec *pathspec);
extern void free_pathspec(struct pathspec *);
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
diff --git a/dir.c b/dir.c
index 31f0995..4be3ca1 100644
--- a/dir.c
+++ b/dir.c
@@ -1440,6 +1440,26 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
return 0;
}
+void strip_trailing_slash_from_submodules(struct pathspec *pathspec)
+{
+ int i;
+ for (i = 0; i < pathspec->nr; i++) {
+ const char *p = pathspec->raw[i];
+ int len = strlen(p), pos;
+
+ if (len < 1 || p[len - 1] != '/')
+ continue;
+ pos = cache_name_pos(p, len - 1);
+ if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode)) {
+ char *path = xstrndup(p, len - 1);
+ pathspec->raw[i] = path;
+ pathspec->items[i].match = path;
+ pathspec->items[i].len = len - 1;
+ pathspec->items[i].nowildcard_len = simple_length(path);
+ }
+ }
+}
+
void free_pathspec(struct pathspec *pathspec)
{
free(pathspec->items);
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 09/21] rm: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/rm.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/builtin/rm.c b/builtin/rm.c
index dabfcf6..d719d95 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -216,7 +216,7 @@ static struct option builtin_rm_options[] = {
int cmd_rm(int argc, const char **argv, const char *prefix)
{
int i, newfd;
- const char **pathspec;
+ struct pathspec pathspec;
char *seen;
git_config(git_default_config, NULL);
@@ -249,27 +249,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
}
}
- pathspec = get_pathspec(prefix, argv);
- refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+ refresh_index(&the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);
seen = NULL;
- for (i = 0; pathspec[i] ; i++)
- /* nothing */;
- seen = xcalloc(i, 1);
+ seen = xcalloc(pathspec.nr, 1);
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
- if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen))
+ if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))
continue;
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
list.entry[list.nr].name = ce->name;
list.entry[list.nr++].is_submodule = S_ISGITLINK(ce->ce_mode);
}
- if (pathspec) {
+ if (pathspec.nr) {
const char *match;
int seen_any = 0;
- for (i = 0; (match = pathspec[i]) != NULL ; i++) {
+ for (i = 0; (match = pathspec.raw[i]) != NULL ; i++) {
if (!seen[i]) {
if (!ignore_unmatch) {
die(_("pathspec '%s' did not match any files"),
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 08/21] checkout: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/checkout.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index a9c1b5a..da25298 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -45,7 +45,7 @@ struct checkout_opts {
int branch_exists;
const char *prefix;
- const char **pathspec;
+ struct pathspec pathspec;
struct tree *source_tree;
};
@@ -256,39 +256,37 @@ static int checkout_paths(const struct checkout_opts *opts,
if (opts->patch_mode)
return run_add_interactive(revision, "--patch=checkout",
- opts->pathspec);
+ opts->pathspec.raw);
lock_file = xcalloc(1, sizeof(struct lock_file));
newfd = hold_locked_index(lock_file, 1);
- if (read_cache_preload(opts->pathspec) < 0)
+ if (read_cache_preload(opts->pathspec.raw) < 0)
return error(_("corrupt index file"));
if (opts->source_tree)
- read_tree_some(opts->source_tree, opts->pathspec);
+ read_tree_some(opts->source_tree, opts->pathspec.raw);
- for (pos = 0; opts->pathspec[pos]; pos++)
- ;
- ps_matched = xcalloc(1, pos);
+ ps_matched = xcalloc(1, opts->pathspec.nr);
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
continue;
- match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
+ match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched);
}
- if (report_path_error(ps_matched, opts->pathspec, opts->prefix))
+ if (report_path_error(ps_matched, opts->pathspec.raw, opts->prefix))
return 1;
/* "checkout -m path" to recreate conflicted state */
if (opts->merge)
- unmerge_cache(opts->pathspec);
+ unmerge_cache(opts->pathspec.raw);
/* Any unmerged paths? */
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
- if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
+ if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce))
continue;
if (opts->force) {
@@ -315,7 +313,7 @@ static int checkout_paths(const struct checkout_opts *opts,
struct cache_entry *ce = active_cache[pos];
if (opts->source_tree && !(ce->ce_flags & CE_UPDATE))
continue;
- if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
+ if (match_pathspec_depth(&opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) {
if (!ce_stage(ce)) {
errs |= checkout_entry(ce, &state, NULL);
continue;
@@ -960,7 +958,7 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts)
static int checkout_branch(struct checkout_opts *opts,
struct branch_info *new)
{
- if (opts->pathspec)
+ if (opts->pathspec.nr)
die(_("paths cannot be used with switching branches"));
if (opts->patch_mode)
@@ -1110,9 +1108,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
}
if (argc) {
- opts.pathspec = get_pathspec(prefix, argv);
+ parse_pathspec(&opts.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
- if (!opts.pathspec)
+ if (!opts.pathspec.nr)
die(_("invalid path specification"));
/*
@@ -1144,7 +1142,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
strbuf_release(&buf);
}
- if (opts.patch_mode || opts.pathspec)
+ if (opts.patch_mode || opts.pathspec.nr)
return checkout_paths(&opts, new.name);
else
return checkout_branch(&opts, &new);
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 07/21] rerere: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/rerere.c | 6 +++---
rerere.c | 8 ++++----
rerere.h | 4 +++-
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/builtin/rerere.c b/builtin/rerere.c
index dc1708e..a573c4a 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -68,11 +68,11 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
return rerere(flags);
if (!strcmp(argv[0], "forget")) {
- const char **pathspec;
+ struct pathspec pathspec;
if (argc < 2)
warning("'git rerere forget' without paths is deprecated");
- pathspec = get_pathspec(prefix, argv + 1);
- return rerere_forget(pathspec);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
+ return rerere_forget(&pathspec);
}
fd = setup_rerere(&merge_rr, flags);
diff --git a/rerere.c b/rerere.c
index a6a5cd5..f8ddf85 100644
--- a/rerere.c
+++ b/rerere.c
@@ -655,7 +655,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
return 0;
}
-int rerere_forget(const char **pathspec)
+int rerere_forget(struct pathspec *pathspec)
{
int i, fd;
struct string_list conflict = STRING_LIST_INIT_DUP;
@@ -666,12 +666,12 @@ int rerere_forget(const char **pathspec)
fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
- unmerge_cache(pathspec);
+ unmerge_cache(pathspec->raw);
find_conflict(&conflict);
for (i = 0; i < conflict.nr; i++) {
struct string_list_item *it = &conflict.items[i];
- if (!match_pathspec(pathspec, it->string, strlen(it->string),
- 0, NULL))
+ if (!match_pathspec_depth(pathspec, it->string, strlen(it->string),
+ 0, NULL))
continue;
rerere_forget_one_path(it->string, &merge_rr);
}
diff --git a/rerere.h b/rerere.h
index 156d2aa..4aa06c9 100644
--- a/rerere.h
+++ b/rerere.h
@@ -3,6 +3,8 @@
#include "string-list.h"
+struct pathspec;
+
#define RERERE_AUTOUPDATE 01
#define RERERE_NOAUTOUPDATE 02
@@ -16,7 +18,7 @@ extern void *RERERE_RESOLVED;
extern int setup_rerere(struct string_list *, int);
extern int rerere(int);
extern const char *rerere_path(const char *hex, const char *file);
-extern int rerere_forget(const char **);
+extern int rerere_forget(struct pathspec *);
extern int rerere_remaining(struct string_list *);
extern void rerere_clear(struct string_list *);
extern void rerere_gc(struct string_list *);
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 06/21] status: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:21 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/commit.c | 9 +++++----
wt-status.c | 17 +++++++----------
wt-status.h | 2 +-
3 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index 444ae1d..196dfab 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1205,11 +1205,12 @@ int cmd_status(int argc, const char **argv, const char *prefix)
handle_untracked_files_arg(&s);
if (show_ignored_in_status)
s.show_ignored_files = 1;
- if (*argv)
- s.pathspec = get_pathspec(prefix, argv);
+ parse_pathspec(&s.pathspec, PATHSPEC_FROMTOP,
+ PATHSPEC_EMPTY_MATCH_ALL,
+ prefix, argv);
- read_cache_preload(s.pathspec);
- refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, NULL, NULL);
+ read_cache_preload(s.pathspec.raw);
+ refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec.raw, NULL, NULL);
fd = hold_locked_index(&index_lock, 0);
if (0 <= fd)
diff --git a/wt-status.c b/wt-status.c
index 2a9658b..13e6aba 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -434,7 +434,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
}
rev.diffopt.format_callback = wt_status_collect_changed_cb;
rev.diffopt.format_callback_data = s;
- init_pathspec(&rev.prune_data, s->pathspec);
+ rev.prune_data = s->pathspec;
run_diff_files(&rev, 0);
}
@@ -459,22 +459,20 @@ static void wt_status_collect_changes_index(struct wt_status *s)
rev.diffopt.detect_rename = 1;
rev.diffopt.rename_limit = 200;
rev.diffopt.break_opt = 0;
- init_pathspec(&rev.prune_data, s->pathspec);
+ rev.prune_data = s->pathspec;
run_diff_index(&rev, 1);
}
static void wt_status_collect_changes_initial(struct wt_status *s)
{
- struct pathspec pathspec;
int i;
- init_pathspec(&pathspec, s->pathspec);
for (i = 0; i < active_nr; i++) {
struct string_list_item *it;
struct wt_status_change_data *d;
struct cache_entry *ce = active_cache[i];
- if (!ce_path_match(ce, &pathspec))
+ if (!ce_path_match(ce, &s->pathspec))
continue;
it = string_list_insert(&s->change, ce->name);
d = it->util;
@@ -489,7 +487,6 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
else
d->index_status = DIFF_STATUS_ADDED;
}
- free_pathspec(&pathspec);
}
static void wt_status_collect_untracked(struct wt_status *s)
@@ -505,11 +502,11 @@ static void wt_status_collect_untracked(struct wt_status *s)
DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
setup_standard_excludes(&dir);
- fill_directory(&dir, s->pathspec);
+ fill_directory(&dir, s->pathspec.raw);
for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent->name, ent->len) &&
- match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
+ match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))
string_list_insert(&s->untracked, ent->name);
free(ent);
}
@@ -517,11 +514,11 @@ static void wt_status_collect_untracked(struct wt_status *s)
if (s->show_ignored_files) {
dir.nr = 0;
dir.flags = DIR_SHOW_IGNORED | DIR_SHOW_OTHER_DIRECTORIES;
- fill_directory(&dir, s->pathspec);
+ fill_directory(&dir, s->pathspec.raw);
for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent->name, ent->len) &&
- match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL))
+ match_pathspec_depth(&s->pathspec, ent->name, ent->len, 0, NULL))
string_list_insert(&s->ignored, ent->name);
free(ent);
}
diff --git a/wt-status.h b/wt-status.h
index 236b41f..dd8df41 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -44,7 +44,7 @@ struct wt_status {
int is_initial;
char *branch;
const char *reference;
- const char **pathspec;
+ struct pathspec pathspec;
int verbose;
int amend;
enum commit_whence whence;
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 05/21] commit: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:20 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/commit.c | 18 +++++++++---------
cache.h | 3 +++
setup.c | 3 +++
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index d6dd3df..444ae1d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -277,17 +277,17 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
{
int fd;
struct string_list partial;
- const char **pathspec = NULL;
+ struct pathspec pathspec;
char *old_index_env = NULL;
int refresh_flags = REFRESH_QUIET;
if (is_status)
refresh_flags |= REFRESH_UNMERGED;
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP,
+ PATHSPEC_EMPTY_MATCH_ALL,
+ prefix, argv);
- if (*argv)
- pathspec = get_pathspec(prefix, argv);
-
- if (read_cache_preload(pathspec) < 0)
+ if (read_cache_preload(pathspec.raw) < 0)
die(_("index file corrupt"));
if (interactive) {
@@ -329,9 +329,9 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
* (A) if all goes well, commit the real index;
* (B) on failure, rollback the real index.
*/
- if (all || (also && pathspec && *pathspec)) {
+ if (all || (also && pathspec.nr)) {
fd = hold_locked_index(&index_lock, 1);
- add_files_to_cache(also ? prefix : NULL, pathspec, 0);
+ add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
if (write_cache(fd, active_cache, active_nr) ||
@@ -350,7 +350,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
* and create commit from the_index.
* We still need to refresh the index here.
*/
- if (!only && (!pathspec || !*pathspec)) {
+ if (!only && !pathspec.nr) {
fd = hold_locked_index(&index_lock, 1);
refresh_cache_or_die(refresh_flags);
if (active_cache_changed) {
@@ -395,7 +395,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
memset(&partial, 0, sizeof(partial));
partial.strdup_strings = 1;
- if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec))
+ if (list_paths(&partial, !current_head ? NULL : "HEAD", prefix, pathspec.raw))
exit(1);
discard_cache();
diff --git a/cache.h b/cache.h
index e52365d..a3c316f 100644
--- a/cache.h
+++ b/cache.h
@@ -476,6 +476,9 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
/* Pathspec magic */
#define PATHSPEC_FROMTOP (1<<0)
+/* Pathspec flags */
+#define PATHSPEC_EMPTY_MATCH_ALL (1<<0) /* No args means match everything */
+
struct pathspec {
const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
int nr;
diff --git a/setup.c b/setup.c
index 6e960b9..a26b6c0 100644
--- a/setup.c
+++ b/setup.c
@@ -280,6 +280,9 @@ void parse_pathspec(struct pathspec *pathspec,
if (!entry && !prefix)
return;
+ if (!*argv && (flags & PATHSPEC_EMPTY_MATCH_ALL))
+ return;
+
/* No arguments with prefix -> prefix pathspec */
if (!entry) {
static const char *raw[2];
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 03/21] Export parse_pathspec() and convert some get_pathspec() calls
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:20 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
These call sites follow the pattern:
paths = get_pathspec(prefix, argv);
init_pathspec(&pathspec, paths);
which can be converted into a single parse_pathspec() call.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/grep.c | 4 +---
builtin/ls-tree.c | 2 +-
builtin/update-index.c | 3 +--
cache.h | 6 ++++++
revision.c | 4 ++--
setup.c | 6 +++---
6 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/builtin/grep.c b/builtin/grep.c
index 0e1b6c8..705f9ff 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -630,7 +630,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
const char *show_in_pager = NULL, *default_pager = "dummy";
struct grep_opt opt;
struct object_array list = OBJECT_ARRAY_INIT;
- const char **paths = NULL;
struct pathspec pathspec;
struct string_list path_list = STRING_LIST_INIT_NODUP;
int i;
@@ -857,8 +856,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
verify_filename(prefix, argv[j], j == i);
}
- paths = get_pathspec(prefix, argv + i);
- init_pathspec(&pathspec, paths);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + i);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index fb76e38..a78ba53 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -166,7 +166,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
if (get_sha1(argv[0], sha1))
die("Not a valid object name %s", argv[0]);
- init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
for (i = 0; i < pathspec.nr; i++)
pathspec.items[i].nowildcard_len = pathspec.items[i].len;
pathspec.has_wildcard = 0;
diff --git a/builtin/update-index.c b/builtin/update-index.c
index ada1dff..6728e59 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -546,10 +546,9 @@ static int do_reupdate(int ac, const char **av,
*/
int pos;
int has_head = 1;
- const char **paths = get_pathspec(prefix, av + 1);
struct pathspec pathspec;
- init_pathspec(&pathspec, paths);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, av + 1);
if (read_ref("HEAD", head_sha1))
/* If there is no HEAD, that means it is an initial
diff --git a/cache.h b/cache.h
index 9304d91..e52365d 100644
--- a/cache.h
+++ b/cache.h
@@ -473,6 +473,9 @@ extern int index_name_is_other(const struct index_state *, const char *, int);
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+/* Pathspec magic */
+#define PATHSPEC_FROMTOP (1<<0)
+
struct pathspec {
const char **raw; /* get_pathspec() result, not freed by free_pathspec() */
int nr;
@@ -487,6 +490,9 @@ struct pathspec {
};
extern int init_pathspec(struct pathspec *, const char **);
+extern void parse_pathspec(struct pathspec *pathspec, unsigned magic,
+ unsigned flags, const char *prefix,
+ const char **args);
extern void free_pathspec(struct pathspec *);
extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
diff --git a/revision.c b/revision.c
index 95d21e6..a044242 100644
--- a/revision.c
+++ b/revision.c
@@ -1851,8 +1851,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
*/
ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
prune_data.path[prune_data.nr++] = NULL;
- init_pathspec(&revs->prune_data,
- get_pathspec(revs->prefix, prune_data.path));
+ parse_pathspec(&revs->prune_data, PATHSPEC_FROMTOP, 0,
+ revs->prefix, prune_data.path);
}
if (revs->def == NULL)
diff --git a/setup.c b/setup.c
index 4fcdae6..6e960b9 100644
--- a/setup.c
+++ b/setup.c
@@ -266,9 +266,9 @@ static int pathspec_item_cmp(const void *a_, const void *b_)
* Given command line arguments and a prefix, convert the input to
* pathspec. die() if any magic other than ones in magic_mask.
*/
-static void parse_pathspec(struct pathspec *pathspec,
- unsigned magic_mask, unsigned flags,
- const char *prefix, const char **argv)
+void parse_pathspec(struct pathspec *pathspec,
+ unsigned magic_mask, unsigned flags,
+ const char *prefix, const char **argv)
{
struct pathspec_item *item;
const char *entry = *argv;
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 04/21] clean: convert to use parse_pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:20 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/clean.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/builtin/clean.c b/builtin/clean.c
index 69c1cda..788ad8c 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -42,7 +42,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
struct strbuf directory = STRBUF_INIT;
struct dir_struct dir;
- static const char **pathspec;
+ struct pathspec pathspec;
struct strbuf buf = STRBUF_INIT;
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
const char *qname;
@@ -101,12 +101,12 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
add_exclude(exclude_list.items[i].string, "", 0,
&dir.exclude_list[EXC_CMDL]);
- pathspec = get_pathspec(prefix, argv);
+ parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
- fill_directory(&dir, pathspec);
+ fill_directory(&dir, pathspec.raw);
- if (pathspec)
- seen = xmalloc(argc > 0 ? argc : 1);
+ if (pathspec.nr)
+ seen = xmalloc(pathspec.nr);
for (i = 0; i < dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
@@ -141,10 +141,10 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
if (lstat(ent->name, &st))
continue;
- if (pathspec) {
- memset(seen, 0, argc > 0 ? argc : 1);
- matches = match_pathspec(pathspec, ent->name, len,
- 0, seen);
+ if (pathspec.nr) {
+ memset(seen, 0, pathspec.nr);
+ matches = match_pathspec_depth(&pathspec, ent->name, len,
+ 0, seen);
}
if (S_ISDIR(st.st_mode)) {
@@ -169,7 +169,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
}
strbuf_reset(&directory);
} else {
- if (pathspec && !matches)
+ if (pathspec.nr && !matches)
continue;
qname = quote_path_relative(ent->name, -1, &buf, prefix);
if (show_only) {
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 01/21] pathspec: save the non-wildcard length part
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:20 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
We mark pathspec with wildcards with the field use_wildcard. We
could do better by saving the length of the non-wildcard part, which
can be used for optimizations such as f9f6e2c (exclude: do strcmp as
much as possible before fnmatch - 2012-06-07).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
builtin/ls-files.c | 2 +-
builtin/ls-tree.c | 2 +-
cache.h | 2 +-
dir.c | 6 +++---
tree-walk.c | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b5434af..4a9ee69 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -337,7 +337,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
matchbuf[0] = prefix;
matchbuf[1] = NULL;
init_pathspec(&pathspec, matchbuf);
- pathspec.items[0].use_wildcard = 0;
+ pathspec.items[0].nowildcard_len = pathspec.items[0].len;
} else
init_pathspec(&pathspec, NULL);
if (read_tree(tree, 1, &pathspec))
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 235c17c..fb76e38 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -168,7 +168,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
init_pathspec(&pathspec, get_pathspec(prefix, argv + 1));
for (i = 0; i < pathspec.nr; i++)
- pathspec.items[i].use_wildcard = 0;
+ pathspec.items[i].nowildcard_len = pathspec.items[i].len;
pathspec.has_wildcard = 0;
tree = parse_tree_indirect(sha1);
if (!tree)
diff --git a/cache.h b/cache.h
index 2b192d2..9304d91 100644
--- a/cache.h
+++ b/cache.h
@@ -482,7 +482,7 @@ struct pathspec {
struct pathspec_item {
const char *match;
int len;
- unsigned int use_wildcard:1;
+ int nowildcard_len;
} *items;
};
diff --git a/dir.c b/dir.c
index 5a83aa7..c391d46 100644
--- a/dir.c
+++ b/dir.c
@@ -230,7 +230,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
return MATCHED_RECURSIVELY;
}
- if (item->use_wildcard && !fnmatch(match, name, 0))
+ if (item->nowildcard_len < item->len && !fnmatch(match, name, 0))
return MATCHED_FNMATCH;
return 0;
@@ -1429,8 +1429,8 @@ int init_pathspec(struct pathspec *pathspec, const char **paths)
item->match = path;
item->len = strlen(path);
- item->use_wildcard = !no_wildcard(path);
- if (item->use_wildcard)
+ item->nowildcard_len = simple_length(path);
+ if (item->nowildcard_len < item->len)
pathspec->has_wildcard = 1;
}
diff --git a/tree-walk.c b/tree-walk.c
index 3f54c02..af871c5 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -626,7 +626,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
&never_interesting))
return entry_interesting;
- if (item->use_wildcard) {
+ if (item->nowildcard_len < item->len) {
if (!fnmatch(match + baselen, entry->path, 0))
return entry_interesting;
@@ -642,7 +642,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
}
match_wildcards:
- if (!item->use_wildcard)
+ if (item->nowildcard_len == item->len)
continue;
/*
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 02/21] Add parse_pathspec() that converts cmdline args to struct pathspec
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:20 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357903275-16804-1-git-send-email-pclouds@gmail.com>
Currently to fill a struct pathspec, we do:
const char **paths;
paths = get_pathspec(prefix, argv);
...
init_pathspec(&pathspec, paths);
"paths" can only carry bare strings, which loses information from
command line arguments such as pathspec magic or the prefix part's
length for each argument.
parse_pathspec() is introduced to combine the two calls into one. The
plan is gradually replace all get_pathspec() and init_pathspec() with
parse_pathspec(). get_pathspec() now becomes a thin wrapper of
parse_pathspec().
parse_pathspec() allows the caller to reject the pathspec magics that
it does not support. When a new pathspec magic is introduced, we can
enable it per command after making sure that all underlying code has no
problem with the new magic.
"flags" parameter is currently unused. But it would allow callers to
pass certain instructions to parse_pathspec, for example forcing
literal pathspec when no magic is used.
With the introduction of parse_pathspec, there are now two functions
that can initialize struct pathspec: init_pathspec and
parse_pathspec. Any semantic changes in struct pathspec must be
reflected in both functions. init_pathspec() will be phased out in
favor of parse_pathspec().
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
dir.c | 2 +-
dir.h | 1 +
setup.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++----------------
3 files changed, 77 insertions(+), 25 deletions(-)
diff --git a/dir.c b/dir.c
index c391d46..31f0995 100644
--- a/dir.c
+++ b/dir.c
@@ -291,7 +291,7 @@ int match_pathspec_depth(const struct pathspec *ps,
/*
* Return the length of the "simple" part of a path match limiter.
*/
-static int simple_length(const char *match)
+int simple_length(const char *match)
{
int len = -1;
diff --git a/dir.h b/dir.h
index f5c89e3..1d4888b 100644
--- a/dir.h
+++ b/dir.h
@@ -66,6 +66,7 @@ struct dir_struct {
#define MATCHED_RECURSIVELY 1
#define MATCHED_FNMATCH 2
#define MATCHED_EXACTLY 3
+extern int simple_length(const char *match);
extern char *common_prefix(const char **pathspec);
extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
extern int match_pathspec_depth(const struct pathspec *pathspec,
diff --git a/setup.c b/setup.c
index f108c4b..4fcdae6 100644
--- a/setup.c
+++ b/setup.c
@@ -174,7 +174,7 @@ static struct pathspec_magic {
/*
* Take an element of a pathspec and check for magic signatures.
- * Append the result to the prefix.
+ * Append the result to the prefix. Return the magic bitmap.
*
* For now, we only parse the syntax and throw out anything other than
* "top" magic.
@@ -185,7 +185,10 @@ static struct pathspec_magic {
* the prefix part must always match literally, and a single stupid
* string cannot express such a case.
*/
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const char *elt)
+static unsigned prefix_pathspec(struct pathspec_item *item,
+ const char **raw,
+ const char *prefix, int prefixlen,
+ const char *elt)
{
unsigned magic = 0;
const char *copyfrom = elt;
@@ -241,39 +244,87 @@ static const char *prefix_pathspec(const char *prefix, int prefixlen, const char
}
if (magic & PATHSPEC_FROMTOP)
- return xstrdup(copyfrom);
+ item->match = xstrdup(copyfrom);
else
- return prefix_path(prefix, prefixlen, copyfrom);
+ item->match = prefix_path(prefix, prefixlen, copyfrom);
+ *raw = item->match;
+ item->len = strlen(item->match);
+ item->nowildcard_len = simple_length(item->match);
+ return magic;
}
-const char **get_pathspec(const char *prefix, const char **pathspec)
+static int pathspec_item_cmp(const void *a_, const void *b_)
{
- const char *entry = *pathspec;
- const char **src, **dst;
- int prefixlen;
+ struct pathspec_item *a, *b;
- if (!prefix && !entry)
- return NULL;
+ a = (struct pathspec_item *)a_;
+ b = (struct pathspec_item *)b_;
+ return strcmp(a->match, b->match);
+}
+
+/*
+ * Given command line arguments and a prefix, convert the input to
+ * pathspec. die() if any magic other than ones in magic_mask.
+ */
+static void parse_pathspec(struct pathspec *pathspec,
+ unsigned magic_mask, unsigned flags,
+ const char *prefix, const char **argv)
+{
+ struct pathspec_item *item;
+ const char *entry = *argv;
+ int i, n, prefixlen;
+
+ memset(pathspec, 0, sizeof(*pathspec));
+
+ /* No arguments, no prefix -> no pathspec */
+ if (!entry && !prefix)
+ return;
+ /* No arguments with prefix -> prefix pathspec */
if (!entry) {
- static const char *spec[2];
- spec[0] = prefix;
- spec[1] = NULL;
- return spec;
+ static const char *raw[2];
+
+ pathspec->items = item = xmalloc(sizeof(*item));
+ item->match = prefix;
+ item->nowildcard_len = item->len = strlen(prefix);
+ raw[0] = prefix;
+ raw[1] = NULL;
+ pathspec->nr = 1;
+ pathspec->raw = raw;
+ return;
}
- /* Otherwise we have to re-write the entries.. */
- src = pathspec;
- dst = pathspec;
+ n = 0;
+ while (argv[n])
+ n++;
+
+ pathspec->nr = n;
+ pathspec->items = item = xmalloc(sizeof(*item) * n);
+ pathspec->raw = argv;
prefixlen = prefix ? strlen(prefix) : 0;
- while (*src) {
- *(dst++) = prefix_pathspec(prefix, prefixlen, *src);
- src++;
+
+ for (i = 0; i < n; i++) {
+ unsigned applied_magic;
+ const char *arg = argv[i];
+
+ applied_magic = prefix_pathspec(item + i, argv + i,
+ prefix, prefixlen, arg);
+ if (applied_magic & ~magic_mask)
+ die(_("pathspec magic in '%s' is not supported"
+ " by this command"), arg);
+ if (item[i].nowildcard_len < item[i].len)
+ pathspec->has_wildcard = 1;
}
- *dst = NULL;
- if (!*pathspec)
- return NULL;
- return pathspec;
+
+ qsort(pathspec->items, pathspec->nr,
+ sizeof(struct pathspec_item), pathspec_item_cmp);
+}
+
+const char **get_pathspec(const char *prefix, const char **pathspec)
+{
+ struct pathspec ps;
+ parse_pathspec(&ps, PATHSPEC_FROMTOP, 0, prefix, pathspec);
+ return ps.raw;
}
/*
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 00/21] nd/parse-pathspec reroll
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 11:20 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Nguyễn Thái Ngọc Duy
Changes:
- The incorrect patch 'pathspec: make sure the prefix part is
wildcard-clean' is removed. I want to keep this series simple.
Complex pathspec manipulation will have its own series later.
- Fix t7400.38 failure when core.ignorecase is on. We should exercise
core.ignorecase codepath more in the test suite, but that should be
in a separate series.
- parse_pathspec() learns PATHSPEC_EMPTY_MATCH_ALL flag to support
"no pathspec means match everything", which is used by some commands
like commit/status
- rename 'raw' to '_raw' to catch new access sites
I also checked if we still have similar faults to t7400.38 (modifying
pathspec directly leading to inconsistencies) and I think we're safe.
Nguyễn Thái Ngọc Duy (21):
pathspec: save the non-wildcard length part
Add parse_pathspec() that converts cmdline args to struct pathspec
Export parse_pathspec() and convert some get_pathspec() calls
clean: convert to use parse_pathspec
commit: convert to use parse_pathspec
status: convert to use parse_pathspec
rerere: convert to use parse_pathspec
checkout: convert to use parse_pathspec
rm: convert to use parse_pathspec
ls-files: convert to use parse_pathspec
archive: convert to use parse_pathspec
add: convert to use parse_pathspec
Convert read_cache_preload() to take struct pathspec
Convert unmerge_cache to take struct pathspec
checkout: convert read_tree_some to take struct pathspec
Convert report_path_error to take struct pathspec
Convert refresh_index to take struct pathspec
Convert {read,fill}_directory to take struct pathspec
Convert add_files_to_cache to take struct pathspec
Convert more init_pathspec() to parse_pathspec()
Rename field "raw" to "_raw" in struct pathspec
archive.c | 12 +++---
archive.h | 2 +-
builtin/add.c | 102 ++++++++++++++++++-------------------------------
builtin/checkout.c | 37 ++++++++----------
builtin/clean.c | 20 +++++-----
builtin/commit.c | 39 +++++++++----------
builtin/diff-files.c | 2 +-
builtin/diff-index.c | 2 +-
builtin/diff.c | 4 +-
builtin/grep.c | 6 +--
builtin/log.c | 2 +-
builtin/ls-files.c | 64 +++++++++++--------------------
builtin/ls-tree.c | 6 +--
builtin/rerere.c | 6 +--
builtin/rm.c | 16 ++++----
builtin/update-index.c | 3 +-
cache.h | 25 +++++++++---
diff-lib.c | 2 +-
dir.c | 72 +++++++++++++++++++++++++++++-----
dir.h | 5 ++-
merge-recursive.c | 2 +-
preload-index.c | 20 +++++-----
read-cache.c | 5 ++-
rerere.c | 6 +--
rerere.h | 4 +-
resolve-undo.c | 4 +-
resolve-undo.h | 2 +-
revision.c | 8 ++--
setup.c | 102 +++++++++++++++++++++++++++++++++++++------------
tree-diff.c | 8 ++--
tree-walk.c | 4 +-
tree.c | 4 +-
tree.h | 2 +-
wt-status.c | 17 ++++-----
wt-status.h | 2 +-
35 files changed, 339 insertions(+), 278 deletions(-)
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply
* missing objects -- prevention
From: Sitaram Chamarty @ 2013-01-11 11:10 UTC (permalink / raw)
To: Git Mailing List
Hi all,
I find a lot of info on how to recover from and/or repair a repo that
has missing (or corrupted) objects.
What I need is info on common reasons (other than disk errors -- we've
checked for those) for such errors to occur, any preventive measures
we can take, and so on. For example, can *any* type of network error
or race condition cause this? (Say, can one push writes an object,
then fails an update check, and a later push succeeds and races
against a gc that removes the unreachable object?) Or... the repo is
pretty large -- about 6-7 GB, so could size cause a race that would
not show up on a smaller repo?
Anything else I can watch out for or caution the team about?
The symptom is usually a disk space crunch caused by tmp_pack_* files
left around by auto-gc. Presumably the missing objects failed the gc
and so it left the files around, and they eventually accumulate enough
to cause disk full errors. (If a gc ever succeeded, I suspect these
files would go away, but that requires manual intervention).
I would appreciate any thoughts... Thanks!
--
Sitaram
^ permalink raw reply
* Re: [PATCH 03/19] reset.c: pass pathspec around instead of (prefix, argv) pair
From: Duy Nguyen @ 2013-01-11 11:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Martin von Zweigbergk, git
In-Reply-To: <7vfw28eiu3.fsf@alter.siamese.dyndns.org>
On Fri, Jan 11, 2013 at 6:09 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Or I could hold off nd/parse-pathspec if this series has a better
>> chance of graduation first. Decision?
>
> I am greedy and want to have both ;-)
Apparently I have no problems with your being greedy.
> There is no textual conflict between the two topics at the moment,
> but because the ultimate goal of your series is to remove all uses
> of the pathspec.raw[] field outside the implementation of pathspec
> matching, it might help to rename the field to _private_raw (or
> remove it), and either make get_pathspec() private or disappear, to
> ensure that the compiler will help us catching semantic conflicts
> with new users of it at a late stage of your series.
There are still some uses for get_pathspec() and new call sites won't
cause big problems because they would need init_pathspec() to convert
get_pathspec() results to struct pathspec. I will rename raw[] though.
--
Duy
^ permalink raw reply
* Re: t7400 broken on pu (Mac OS X)
From: Duy Nguyen @ 2013-01-11 11:03 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Torsten Bögershausen, git
In-Reply-To: <7v38y83ooo.fsf@alter.siamese.dyndns.org>
On Fri, Jan 11, 2013 at 12:58 AM, Junio C Hamano <gitster@pobox.com> wrote:
> I can see why it is wrong to let pathspec.raw be rewritten without
> making matching change to the containing pathspec, but I find it
> strange why it matters only on case-insensitive codepath.
Yeah, I don't get it either. I can see that core.ignorecase exercises
some more code, but still fail to see the link. I should get to the
bottom of this and write some tests to for core.ignorecase-only code.
--
Duy
^ permalink raw reply
* Re: git checkout bug on Win7 x64
From: Konstantin Khomoutov @ 2013-01-11 9:54 UTC (permalink / raw)
To: Ishayahu Lastov
Cc: git-u79uwXL29TY76Z2rM5mHXA, git-users-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <CAJ52sWnm23pLibG24PZm0UB=_tk7JahNx0c53E1udJG4D3yvvQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, 11 Jan 2013 11:30:01 +0400
Ishayahu Lastov <meoc-it-JGs/UdohzUI@public.gmane.org> wrote:
[...]
> As I understand after last "git checkout" in "git status" I should see
> that I gave no changes. It looks like an bug, isn't it?
Looks like an EOL-conversion problem rather typical to Windows, see
http://stackoverflow.com/a/2016426/720999
--
^ permalink raw reply
* [PATCH v2 3/3] fetch: elaborate --depth action
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 9:05 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Stefan Beller, Jonathan Nieder, schlotter,
Ralf.Wildenhues, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357895148-30909-1-git-send-email-pclouds@gmail.com>
--depth is explained as deepen, but the way it's applied, it can
shorten the history as well. Keen users may have noticed the
implication by the phrase "the specified number of commits from the
tip of each remote branch". Put "shorten" in the description to make
it clearer.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/fetch-options.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 8a0449c..fb92b02 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -8,7 +8,7 @@
option old data in `.git/FETCH_HEAD` will be overwritten.
--depth=<depth>::
- Deepen the history of a 'shallow' repository created by
+ Deepen or shorten the history of a 'shallow' repository created by
`git clone` with `--depth=<depth>` option (see linkgit:git-clone[1])
to the specified number of commits from the tip of each remote
branch history. Tags for the deepened commits are not fetched.
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 2/3] upload-pack: fix off-by-one depth calculation in shallow clone
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 9:05 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Stefan Beller, Jonathan Nieder, schlotter,
Ralf.Wildenhues, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357895148-30909-1-git-send-email-pclouds@gmail.com>
get_shallow_commits() is used to determine the cut points at a given
depth (i.e. the number of commits in a chain that the user likes to
get). However we count current depth up to the commit "commit" but we
do the cutting at its parents (i.e. current depth + 1). This makes
upload-pack always return one commit more than requested. This patch
fixes it.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Fixed the && command chain in t5500.
shallow.c | 8 +++++++-
t/t5500-fetch-pack.sh | 25 +++++++++++++++++++------
2 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/shallow.c b/shallow.c
index a0363de..6be915f 100644
--- a/shallow.c
+++ b/shallow.c
@@ -72,8 +72,14 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
}
if (parse_commit(commit))
die("invalid commit");
- commit->object.flags |= not_shallow_flag;
cur_depth++;
+ if (cur_depth >= depth) {
+ commit_list_insert(commit, &result);
+ commit->object.flags |= shallow_flag;
+ commit = NULL;
+ continue;
+ }
+ commit->object.flags |= not_shallow_flag;
for (p = commit->parents, commit = NULL; p; p = p->next) {
if (!p->item->util) {
int *pointer = xmalloc(sizeof(int));
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 426027e..354d32c 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -130,16 +130,25 @@ test_expect_success 'single given branch clone' '
test_must_fail git --git-dir=branch-a/.git rev-parse origin/B
'
+test_expect_success 'clone shallow depth 1' '
+ git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0 &&
+ test "`git --git-dir=shallow0/.git rev-list --count HEAD`" = 1
+'
+
test_expect_success 'clone shallow' '
git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
'
+test_expect_success 'clone shallow depth count' '
+ test "`git --git-dir=shallow/.git rev-list --count HEAD`" = 2
+'
+
test_expect_success 'clone shallow object count' '
(
cd shallow &&
git count-objects -v
) > count.shallow &&
- grep "^in-pack: 18" count.shallow
+ grep "^in-pack: 12" count.shallow
'
test_expect_success 'clone shallow object count (part 2)' '
@@ -256,12 +265,16 @@ test_expect_success 'additional simple shallow deepenings' '
)
'
+test_expect_success 'clone shallow depth count' '
+ test "`git --git-dir=shallow/.git rev-list --count HEAD`" = 11
+'
+
test_expect_success 'clone shallow object count' '
(
cd shallow &&
git count-objects -v
) > count.shallow &&
- grep "^count: 52" count.shallow
+ grep "^count: 55" count.shallow
'
test_expect_success 'fetch --no-shallow on full repo' '
@@ -293,7 +306,7 @@ test_expect_success 'clone shallow object count' '
cd shallow2 &&
git count-objects -v
) > count.shallow2 &&
- grep "^in-pack: 6" count.shallow2
+ grep "^in-pack: 3" count.shallow2
'
test_expect_success 'clone shallow with --branch' '
@@ -301,7 +314,7 @@ test_expect_success 'clone shallow with --branch' '
'
test_expect_success 'clone shallow object count' '
- echo "in-pack: 6" > count3.expected &&
+ echo "in-pack: 3" > count3.expected &&
GIT_DIR=shallow3/.git git count-objects -v |
grep "^in-pack" > count3.actual &&
test_cmp count3.expected count3.actual
@@ -330,7 +343,7 @@ EOF
GIT_DIR=shallow6/.git git tag -l >taglist.actual &&
test_cmp taglist.expected taglist.actual &&
- echo "in-pack: 7" > count6.expected &&
+ echo "in-pack: 4" > count6.expected &&
GIT_DIR=shallow6/.git git count-objects -v |
grep "^in-pack" > count6.actual &&
test_cmp count6.expected count6.actual
@@ -345,7 +358,7 @@ EOF
GIT_DIR=shallow7/.git git tag -l >taglist.actual &&
test_cmp taglist.expected taglist.actual &&
- echo "in-pack: 7" > count7.expected &&
+ echo "in-pack: 4" > count7.expected &&
GIT_DIR=shallow7/.git git count-objects -v |
grep "^in-pack" > count7.actual &&
test_cmp count7.expected count7.actual
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH v2 1/3] fetch: add --unshallow for turning shallow repo into complete one
From: Nguyễn Thái Ngọc Duy @ 2013-01-11 9:05 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Stefan Beller, Jonathan Nieder, schlotter,
Ralf.Wildenhues, Nguyễn Thái Ngọc Duy
In-Reply-To: <1357875005-21956-1-git-send-email-pclouds@gmail.com>
The user can do --depth=2147483647 (*) for restoring complete repo
now. But it's hard to remember. Any other numbers larger than the
longest commit chain in the repository would also do, but some
guessing may be involved. Make easy-to-remember --unshallow an alias
for --depth=2147483647.
Make upload-pack recognize this special number as infinite depth. The
effect is essentially the same as before, except that upload-pack is
more efficient because it does not have to traverse to the bottom
anymore.
The chance of a user actually wanting exactly 2147483647 commits
depth, not infinite, on a repository with a history that long, is
probably too small to consider. The client can learn to add or
subtract one commit to avoid the special treatment when that actually
happens.
(*) This is the largest positive number a 32-bit signed integer can
contain. JGit and older C Git store depth as "int" so both are OK
with this number. Dulwich does not support shallow clone.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
On Fri, Jan 11, 2013 at 10:55 AM, Junio C Hamano <gitster@pobox.com> wrote:
> I think "no shallow" makes sense in a much more important way than
> "infinite depth", and this patch is a good idea for a reason
> entirely different from the justification your log message makes ;-)
> [snip]
> Calling the option "--no-shallow" (or even better, "--unshallow",
> meaning "make it a repository that is no longer shallow") makes it
> crystal clear that the option is about wiping away the shallowness.
> Of course, the result has to contain an untruncted history, but that
> is a mere side effect and an implementation detail from the end
> user's point of view.
Very well said. --unshallow it is.
Documentation/fetch-options.txt | 4 ++++
Documentation/git-fetch-pack.txt | 2 ++
Documentation/technical/shallow.txt | 3 +++
builtin/fetch.c | 17 ++++++++++++++++-
commit.h | 3 +++
t/t5500-fetch-pack.sh | 20 ++++++++++++++++++++
upload-pack.c | 13 ++++++++++---
7 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt
index 6e98bdf..8a0449c 100644
--- a/Documentation/fetch-options.txt
+++ b/Documentation/fetch-options.txt
@@ -13,6 +13,10 @@
to the specified number of commits from the tip of each remote
branch history. Tags for the deepened commits are not fetched.
+--unshallow::
+ Convert a shallow repository to a complete one, removing all
+ the limitations imposed by shallow repositories.
+
ifndef::git-pull[]
--dry-run::
Show what would be done, without making any changes.
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
index 8c75120..b81e90d 100644
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -84,6 +84,8 @@ be in a separate packet, and the list must end with a flush packet.
--depth=<n>::
Limit fetching to ancestor-chains not longer than n.
+ 'git-upload-pack' treats the special depth 2147483647 as
+ infinite even if there is an ancestor-chain that long.
--no-progress::
Do not show the progress.
diff --git a/Documentation/technical/shallow.txt b/Documentation/technical/shallow.txt
index 0502a54..ea2f69f 100644
--- a/Documentation/technical/shallow.txt
+++ b/Documentation/technical/shallow.txt
@@ -53,3 +53,6 @@ It also writes an appropriate $GIT_DIR/shallow.
You can deepen a shallow repository with "git-fetch --depth 20
repo branch", which will fetch branch from repo, but stop at depth
20, updating $GIT_DIR/shallow.
+
+The special depth 2147483647 (or 0x7fffffff, the largest positive
+number a signed 32-bit integer can contain) means infinite depth.
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 4b5a898..2b15ced 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -32,7 +32,7 @@ enum {
static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
-static int tags = TAGS_DEFAULT;
+static int tags = TAGS_DEFAULT, unshallow;
static const char *depth;
static const char *upload_pack;
static struct strbuf default_rla = STRBUF_INIT;
@@ -82,6 +82,9 @@ static struct option builtin_fetch_options[] = {
OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
OPT_STRING(0, "depth", &depth, N_("depth"),
N_("deepen history of shallow clone")),
+ { OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
+ N_("convert to a complete repository"),
+ PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
{ OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
{ OPTION_STRING, 0, "recurse-submodules-default",
@@ -970,6 +973,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
argc = parse_options(argc, argv, prefix,
builtin_fetch_options, builtin_fetch_usage, 0);
+ if (unshallow) {
+ if (depth)
+ die(_("--depth and --unshallow cannot be used together"));
+ else if (!is_repository_shallow())
+ die(_("--unshallow on a complete repository does not make sense"));
+ else {
+ static char inf_depth[12];
+ sprintf(inf_depth, "%d", INFINITE_DEPTH);
+ depth = inf_depth;
+ }
+ }
+
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
if (recurse_submodules_default) {
int arg = parse_fetch_recurse_submodules_arg("--recurse-submodules-default", recurse_submodules_default);
diff --git a/commit.h b/commit.h
index 0f469e5..fbde106 100644
--- a/commit.h
+++ b/commit.h
@@ -162,6 +162,9 @@ extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *r
extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos, int cleanup);
extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
+/* largest postive number a signed 32-bit integer can contain */
+#define INFINITE_DEPTH 0x7fffffff
+
extern int register_shallow(const unsigned char *sha1);
extern int unregister_shallow(const unsigned char *sha1);
extern int for_each_commit_graft(each_commit_graft_fn, void *);
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 6322e8a..426027e 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -264,6 +264,26 @@ test_expect_success 'clone shallow object count' '
grep "^count: 52" count.shallow
'
+test_expect_success 'fetch --no-shallow on full repo' '
+ test_must_fail git fetch --noshallow
+'
+
+test_expect_success 'fetch --depth --no-shallow' '
+ (
+ cd shallow &&
+ test_must_fail git fetch --depth=1 --noshallow
+ )
+'
+
+test_expect_success 'turn shallow to complete repository' '
+ (
+ cd shallow &&
+ git fetch --unshallow &&
+ ! test -f .git/shallow &&
+ git fsck --full
+ )
+'
+
test_expect_success 'clone shallow without --no-single-branch' '
git clone --depth 1 "file://$(pwd)/." shallow2
'
diff --git a/upload-pack.c b/upload-pack.c
index 6142421..88f0029 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -670,10 +670,17 @@ static void receive_needs(void)
if (depth == 0 && shallows.nr == 0)
return;
if (depth > 0) {
- struct commit_list *result, *backup;
+ struct commit_list *result = NULL, *backup = NULL;
int i;
- backup = result = get_shallow_commits(&want_obj, depth,
- SHALLOW, NOT_SHALLOW);
+ if (depth == INFINITE_DEPTH)
+ for (i = 0; i < shallows.nr; i++) {
+ struct object *object = shallows.objects[i].item;
+ object->flags |= NOT_SHALLOW;
+ }
+ else
+ backup = result =
+ get_shallow_commits(&want_obj, depth,
+ SHALLOW, NOT_SHALLOW);
while (result) {
struct object *object = &result->item->object;
if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
--
1.8.0.rc2.23.g1fb49df
^ permalink raw reply related
* [PATCH] git-completion.bash: Silence not a valid object errors
From: Dylan Smith @ 2013-01-11 8:06 UTC (permalink / raw)
To: git
Trying to complete the command
git show master:./file
would cause a "Not a valid object name" error to be output on standard
error. Silence the error so it won't appear on the command line.
Signed-off-by: Dylan Smith <dylan.ah.smith@gmail.com>
---
contrib/completion/git-completion.bash | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 0b77eb1..d4c7bfe 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -397,7 +397,7 @@ __git_complete_revlist_file ()
*) pfx="$ref:$pfx" ;;
esac
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
+ __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \
| sed '/^100... blob /{
s,^.* ,,
s,$, ,
--
1.7.9.5
^ permalink raw reply related
* git checkout bug on Win7 x64
From: Ishayahu Lastov @ 2013-01-11 7:30 UTC (permalink / raw)
To: git
This is my session on Win7 x64:
Microsoft Windows [Version 6.1.7601]
(c) Корпорация Майкрософт (Microsoft Corp.), 2009. Все права защищены.
C:\Dropbox\Dropbox\Wesnoth\Apocryphs>cd Apokryphs.Orks
C:\Dropbox\Dropbox\Wesnoth\Apocryphs\Apokryphs.Orks>git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: scenarios/01_NothernVillage.cfg
#
no changes added to commit (use "git add" and/or "git commit -a")
C:\Dropbox\Dropbox\Wesnoth\Apocryphs\Apokryphs.Orks>cd scenarios
C:\Dropbox\Dropbox\Wesnoth\Apocryphs\Apokryphs.Orks\scenarios>git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: 01_NothernVillage.cfg
#
no changes added to commit (use "git add" and/or "git commit -a")
C:\Dropbox\Dropbox\Wesnoth\Apocryphs\Apokryphs.Orks\scenarios>git checkout -- 01
_NothernVillage.cfg
C:\Dropbox\Dropbox\Wesnoth\Apocryphs\Apokryphs.Orks\scenarios>git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: 01_NothernVillage.cfg
#
no changes added to commit (use "git add" and/or "git commit -a")
C:\Dropbox\Dropbox\Wesnoth\Apocryphs\Apokryphs.Orks\scenarios>
As I understand after last "git checkout" in "git status" I should see
that I gave no changes. It looks like an bug, isn't it?
--
сохраняйте, пожалуйста, при ответе исходный текст письма
С уважением,
начальник отдела технической поддержки
Московского Еврейского Общинного Центра
Ишаяу Ластов
телефон: +7-495-645-05-16
моб : +7-901-569-81-86
с 12 до 18, с воскресенья по четверг
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox