From: Thomas Gummerer <t.gummerer@gmail.com>
To: git@vger.kernel.org
Cc: trast@inf.ethz.ch, mhagger@alum.mit.edu, gitster@pobox.com,
pclouds@gmail.com, robin.rosenberg@dewire.com,
t.gummerer@gmail.com
Subject: [PATCH 11/22] ls-files.c: use the index api
Date: Sun, 7 Jul 2013 10:11:49 +0200 [thread overview]
Message-ID: <1373184720-29767-12-git-send-email-t.gummerer@gmail.com> (raw)
In-Reply-To: <1373184720-29767-1-git-send-email-t.gummerer@gmail.com>
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
---
builtin/ls-files.c | 213 +++++++++++++++++++++++++----------------------------
1 file changed, 100 insertions(+), 113 deletions(-)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 08d9786..82857d4 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -88,36 +88,35 @@ static void show_killed_files(struct dir_struct *dir)
for (i = 0; i < dir->nr; i++) {
struct dir_entry *ent = dir->entries[i];
char *cp, *sp;
- int pos, len, killed = 0;
+ int len, killed = 0;
for (cp = ent->name; cp - ent->name < ent->len; cp = sp + 1) {
+ struct cache_entry *ce;
+
sp = strchr(cp, '/');
if (!sp) {
/* If ent->name is prefix of an entry in the
* cache, it will be killed.
*/
- pos = cache_name_pos(ent->name, ent->len);
- if (0 <= pos)
+ if (get_cache_entry_by_name(ent->name, ent->len, &ce))
die("bug in show-killed-files");
- pos = -pos - 1;
- while (pos < active_nr &&
- ce_stage(active_cache[pos]))
- pos++; /* skip unmerged */
- if (active_nr <= pos)
+ while (ce && ce_stage(ce))
+ ce = next_cache_entry(ce);
+ if (!ce)
break;
/* pos points at a name immediately after
* ent->name in the cache. Does it expect
* ent->name to be a directory?
*/
- len = ce_namelen(active_cache[pos]);
+ len = ce_namelen(ce);
if ((ent->len < len) &&
- !strncmp(active_cache[pos]->name,
+ !strncmp(ce->name,
ent->name, ent->len) &&
- active_cache[pos]->name[ent->len] == '/')
+ ce->name[ent->len] == '/')
killed = 1;
break;
}
- if (0 <= cache_name_pos(ent->name, sp - ent->name)) {
+ if (get_cache_entry_by_name(ent->name, sp - ent->name, &ce)) {
/* If any of the leading directories in
* ent->name is registered in the cache,
* ent->name will be killed.
@@ -213,10 +212,43 @@ static int ce_excluded(struct dir_struct *dir, struct cache_entry *ce)
return is_excluded(dir, ce->name, &dtype);
}
-static void show_files(struct dir_struct *dir)
+static int show_cached_stage(struct cache_entry *ce, void *cb_data)
{
- int i;
+ struct dir_struct *dir = cb_data;
+
+ if ((dir->flags & DIR_SHOW_IGNORED) && !ce_excluded(dir, ce))
+ return 0;
+ if (show_unmerged && !ce_stage(ce))
+ return 0;
+ if (ce->ce_flags & CE_UPDATE)
+ return 0;
+ show_ce_entry(ce_stage(ce) ? tag_unmerged :
+ (ce_skip_worktree(ce) ? tag_skip_worktree : tag_cached), ce);
+ return 0;
+}
+static int show_deleted_modified(struct cache_entry *ce, void *cb_data)
+{
+ struct stat st;
+ int err;
+ struct dir_struct *dir = cb_data;
+
+ if ((dir->flags & DIR_SHOW_IGNORED) && !ce_excluded(dir, ce))
+ return 0;
+ if (ce->ce_flags & CE_UPDATE)
+ return 0;
+ if (ce_skip_worktree(ce))
+ return 0;
+ err = lstat(ce->name, &st);
+ if (show_deleted && err)
+ show_ce_entry(tag_removed, ce);
+ if (show_modified && ce_modified(ce, &st, 0))
+ show_ce_entry(tag_modified, ce);
+ return 0;
+}
+
+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);
@@ -225,66 +257,18 @@ static void show_files(struct dir_struct *dir)
if (show_killed)
show_killed_files(dir);
}
- if (show_cached || show_stage) {
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- if ((dir->flags & DIR_SHOW_IGNORED) &&
- !ce_excluded(dir, ce))
- continue;
- if (show_unmerged && !ce_stage(ce))
- continue;
- if (ce->ce_flags & CE_UPDATE)
- continue;
- show_ce_entry(ce_stage(ce) ? tag_unmerged :
- (ce_skip_worktree(ce) ? tag_skip_worktree : tag_cached), ce);
- }
- }
- if (show_deleted || show_modified) {
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- struct stat st;
- int err;
- if ((dir->flags & DIR_SHOW_IGNORED) &&
- !ce_excluded(dir, ce))
- continue;
- if (ce->ce_flags & CE_UPDATE)
- continue;
- if (ce_skip_worktree(ce))
- continue;
- err = lstat(ce->name, &st);
- if (show_deleted && err)
- show_ce_entry(tag_removed, ce);
- if (show_modified && ce_modified(ce, &st, 0))
- show_ce_entry(tag_modified, ce);
- }
- }
+ if (show_cached | show_stage)
+ for_each_cache_entry(show_cached_stage, dir);
+ if (show_deleted | show_modified)
+ for_each_cache_entry(show_deleted_modified, dir);
}
-/*
- * Prune the index to only contain stuff starting with "prefix"
- */
-static void prune_cache(const char *prefix)
+static int hoist_unmerged(struct cache_entry *ce, void *cb_data)
{
- int pos = cache_name_pos(prefix, max_prefix_len);
- unsigned int first, last;
-
- if (pos < 0)
- pos = -pos-1;
- memmove(active_cache, active_cache + pos,
- (active_nr - pos) * sizeof(struct cache_entry *));
- active_nr -= pos;
- first = 0;
- last = active_nr;
- while (last > first) {
- int next = (last + first) >> 1;
- struct cache_entry *ce = active_cache[next];
- if (!strncmp(ce->name, prefix, max_prefix_len)) {
- first = next+1;
- continue;
- }
- last = next;
- }
- active_nr = last;
+ if (!ce_stage(ce))
+ return 0;
+ ce->ce_flags |= CE_STAGEMASK;
+ return 0;
}
static void strip_trailing_slash_from_submodules(void)
@@ -292,16 +276,38 @@ static void strip_trailing_slash_from_submodules(void)
const char **p;
for (p = pathspec; *p != NULL; p++) {
- int len = strlen(*p), pos;
+ int len = strlen(*p);
+ struct cache_entry *ce;
if (len < 1 || (*p)[len - 1] != '/')
continue;
- pos = cache_name_pos(*p, len - 1);
- if (pos >= 0 && S_ISGITLINK(active_cache[pos]->ce_mode))
+ if (get_cache_entry_by_name(*p, len - 1, &ce) && S_ISGITLINK(ce->ce_mode))
*p = xstrndup(*p, len - 1);
}
}
+int mark_entry_to_show(struct cache_entry *ce, void *cb_data)
+{
+ struct cache_entry *last_stage0 = cb_data;
+ switch (ce_stage(ce)) {
+ case 0:
+ last_stage0 = ce;
+ /* fallthru */
+ default:
+ return 0;
+ case 1:
+ /*
+ * If there is stage #0 entry for this, we do not
+ * need to show it. We use CE_UPDATE bit to mark
+ * such an entry.
+ */
+ if (last_stage0 &&
+ !strcmp(last_stage0->name, ce->name))
+ ce->ce_flags |= CE_UPDATE;
+ }
+ return 0;
+}
+
/*
* Read the tree specified with --with-tree option
* (typically, HEAD) into stage #1 and then
@@ -316,7 +322,6 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
unsigned char sha1[20];
struct pathspec pathspec;
struct cache_entry *last_stage0 = NULL;
- int i;
if (get_sha1(tree_name, sha1))
die("tree-ish %s not found.", tree_name);
@@ -325,12 +330,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
die("bad tree-ish %s", tree_name);
/* Hoist the unmerged entries up to stage #3 to make room */
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- if (!ce_stage(ce))
- continue;
- ce->ce_flags |= CE_STAGEMASK;
- }
+ for_each_cache_entry(hoist_unmerged, NULL);
if (prefix) {
static const char *(matchbuf[2]);
@@ -343,25 +343,7 @@ void overlay_tree_on_cache(const char *tree_name, const char *prefix)
if (read_tree(tree, 1, &pathspec))
die("unable to read tree entries %s", tree_name);
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- switch (ce_stage(ce)) {
- case 0:
- last_stage0 = ce;
- /* fallthru */
- default:
- continue;
- case 1:
- /*
- * If there is stage #0 entry for this, we do not
- * need to show it. We use CE_UPDATE bit to mark
- * such an entry.
- */
- if (last_stage0 &&
- !strcmp(last_stage0->name, ce->name))
- ce->ce_flags |= CE_UPDATE;
- }
- }
+ for_each_cache_entry(mark_entry_to_show, last_stage0);
}
int report_path_error(const char *ps_matched, const char **pathspec, const char *prefix)
@@ -457,6 +439,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
struct dir_struct dir;
struct exclude_list *el;
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
+ struct filter_opts *opts = xmalloc(sizeof(*opts));
struct option builtin_ls_files_options[] = {
{ OPTION_CALLBACK, 'z', NULL, NULL, NULL,
N_("paths are separated with NUL character"),
@@ -522,9 +505,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
prefix_len = strlen(prefix);
git_config(git_default_config, NULL);
- if (read_cache() < 0)
- die("index file corrupt");
-
argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
ls_files_usage, 0);
el = add_exclude_list(&dir, EXC_CMDL, "--exclude option");
@@ -557,14 +537,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
pathspec = get_pathspec(prefix, argv);
- /* be nice with submodule paths ending in a slash */
- if (pathspec)
- strip_trailing_slash_from_submodules();
-
- /* Find common prefix for all pathspec's */
- max_prefix = common_prefix(pathspec);
- max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
-
/* Treat unmatching pathspec elements as errors */
if (pathspec && error_unmatch) {
int num;
@@ -573,6 +545,23 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
ps_matched = xcalloc(1, num);
}
+ memset(opts, 0, sizeof(*opts));
+ opts->pathspec = pathspec;
+ opts->read_staged = 1;
+ if (show_resolve_undo)
+ opts->read_resolve_undo = 1;
+ read_cache_filtered(opts);
+
+ if (pathspec) {
+ strip_trailing_slash_from_submodules();
+ opts->pathspec = pathspec;
+ cache_change_filter_opts(opts);
+ }
+
+ /* Find common prefix for all pathspec's */
+ max_prefix = opts->max_prefix;
+ max_prefix_len = opts->max_prefix_len;
+
if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
die("ls-files --ignored needs some exclude pattern");
@@ -581,8 +570,6 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
show_killed || show_modified || show_resolve_undo))
show_cached = 1;
- if (max_prefix)
- prune_cache(max_prefix);
if (with_tree) {
/*
* Basic sanity check; show-stages and show-unmerged
--
1.8.3.453.g1dfc63d
next prev parent reply other threads:[~2013-07-07 8:13 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-07 8:11 [PATCH 00/22] Index v5 Thomas Gummerer
2013-07-07 8:11 ` [PATCH 01/22] t2104: Don't fail for index versions other than [23] Thomas Gummerer
2013-07-07 8:11 ` [PATCH 02/22] read-cache: split index file version specific functionality Thomas Gummerer
2013-07-07 8:11 ` [PATCH 03/22] read-cache: move index v2 specific functions to their own file Thomas Gummerer
2013-07-07 8:11 ` [PATCH 04/22] read-cache: Re-read index if index file changed Thomas Gummerer
2013-07-07 8:11 ` [PATCH 05/22] read-cache: add index reading api Thomas Gummerer
2013-07-08 2:01 ` Duy Nguyen
2013-07-08 11:40 ` Thomas Gummerer
2013-07-08 2:19 ` Duy Nguyen
2013-07-08 11:20 ` Thomas Gummerer
2013-07-08 12:45 ` Duy Nguyen
2013-07-08 13:37 ` Thomas Gummerer
2013-07-08 20:54 ` [PATCH 5.5/22] Add documentation for the index api Thomas Gummerer
2013-07-09 15:42 ` Duy Nguyen
2013-07-09 20:10 ` Thomas Gummerer
2013-07-10 5:28 ` Duy Nguyen
2013-07-11 11:30 ` Thomas Gummerer
2013-07-11 11:42 ` Duy Nguyen
2013-07-11 12:27 ` Duy Nguyen
2013-07-08 16:36 ` [PATCH 05/22] read-cache: add index reading api Junio C Hamano
2013-07-08 20:10 ` Thomas Gummerer
2013-07-08 23:09 ` Junio C Hamano
2013-07-09 20:13 ` Thomas Gummerer
2013-07-07 8:11 ` [PATCH 06/22] make sure partially read index is not changed Thomas Gummerer
2013-07-08 16:31 ` Junio C Hamano
2013-07-08 18:33 ` Thomas Gummerer
2013-07-07 8:11 ` [PATCH 07/22] dir.c: use index api Thomas Gummerer
2013-07-07 8:11 ` [PATCH 08/22] tree.c: " Thomas Gummerer
2013-07-07 8:11 ` [PATCH 09/22] name-hash.c: " Thomas Gummerer
2013-07-07 8:11 ` [PATCH 10/22] grep.c: Use " Thomas Gummerer
2013-07-07 8:11 ` Thomas Gummerer [this message]
2013-07-07 8:11 ` [PATCH 12/22] read-cache: make read_blob_data_from_index use " Thomas Gummerer
2013-07-07 8:11 ` [PATCH 13/22] documentation: add documentation of the index-v5 file format Thomas Gummerer
2013-07-11 10:39 ` Duy Nguyen
2013-07-11 11:39 ` Thomas Gummerer
2013-07-11 11:47 ` Duy Nguyen
2013-07-11 12:26 ` Thomas Gummerer
2013-07-11 12:50 ` Duy Nguyen
2013-07-07 8:11 ` [PATCH 14/22] read-cache: make in-memory format aware of stat_crc Thomas Gummerer
2013-07-07 8:11 ` [PATCH 15/22] read-cache: read index-v5 Thomas Gummerer
2013-07-07 20:18 ` Eric Sunshine
2013-07-08 11:40 ` Thomas Gummerer
2013-07-07 8:11 ` [PATCH 16/22] read-cache: read resolve-undo data Thomas Gummerer
2013-07-07 8:11 ` [PATCH 17/22] read-cache: read cache-tree in index-v5 Thomas Gummerer
2013-07-07 20:41 ` Eric Sunshine
2013-07-07 8:11 ` [PATCH 18/22] read-cache: write index-v5 Thomas Gummerer
2013-07-07 20:43 ` Eric Sunshine
2013-07-07 8:11 ` [PATCH 19/22] read-cache: write index-v5 cache-tree data Thomas Gummerer
2013-07-07 8:11 ` [PATCH 20/22] read-cache: write resolve-undo data for index-v5 Thomas Gummerer
2013-07-07 8:11 ` [PATCH 21/22] update-index.c: rewrite index when index-version is given Thomas Gummerer
2013-07-07 8:12 ` [PATCH 22/22] p0003-index.sh: add perf test for the index formats Thomas Gummerer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1373184720-29767-12-git-send-email-t.gummerer@gmail.com \
--to=t.gummerer@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mhagger@alum.mit.edu \
--cc=pclouds@gmail.com \
--cc=robin.rosenberg@dewire.com \
--cc=trast@inf.ethz.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).