From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 11/20] untracked cache: save to an index extension
Date: Wed, 7 May 2014 21:51:51 +0700 [thread overview]
Message-ID: <1399474320-6840-12-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1399474320-6840-1-git-send-email-pclouds@gmail.com>
FIXME: save check_only
---
cache.h | 3 ++
dir.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dir.h | 1 +
read-cache.c | 12 ++++++++
4 files changed, 107 insertions(+)
diff --git a/cache.h b/cache.h
index 107ac61..06fcb6b 100644
--- a/cache.h
+++ b/cache.h
@@ -268,6 +268,8 @@ static inline unsigned int canon_mode(unsigned int mode)
#define cache_entry_size(len) (offsetof(struct cache_entry,name) + (len) + 1)
+
+struct untracked_cache;
struct index_state {
struct cache_entry **cache;
unsigned int version;
@@ -279,6 +281,7 @@ struct index_state {
initialized : 1;
struct hashmap name_hash;
struct hashmap dir_hash;
+ struct untracked_cache *untracked;
};
extern struct index_state the_index;
diff --git a/dir.c b/dir.c
index b5bfda8..b7d394a 100644
--- a/dir.c
+++ b/dir.c
@@ -12,6 +12,7 @@
#include "refs.h"
#include "wildmatch.h"
#include "pathspec.h"
+#include "varint.h"
struct path_simplify {
int len;
@@ -2165,3 +2166,93 @@ void clear_directory(struct dir_struct *dir)
}
strbuf_release(&dir->basebuf);
}
+
+struct ondisk_untracked_cache {
+ struct stat_data info_exclude_stat;
+ struct stat_data excludes_file_stat;
+ uint32_t dir_flags;
+ unsigned char info_exclude_sha1[20];
+ unsigned char excludes_file_sha1[20];
+ char exclude_per_dir[1];
+};
+
+static void stat_data_to_disk(struct stat_data *to, const struct stat_data *from)
+{
+ to->sd_ctime.sec = htonl(from->sd_ctime.sec);
+ to->sd_ctime.nsec = htonl(from->sd_ctime.nsec);
+ to->sd_mtime.sec = htonl(from->sd_mtime.sec);
+ to->sd_mtime.nsec = htonl(from->sd_mtime.nsec);
+ to->sd_dev = htonl(from->sd_dev);
+ to->sd_ino = htonl(from->sd_ino);
+ to->sd_uid = htonl(from->sd_uid);
+ to->sd_gid = htonl(from->sd_gid);
+ to->sd_size = htonl(from->sd_size);
+}
+
+static void write_one_dir(struct strbuf *out, struct untracked_cache_dir *untracked)
+{
+ struct stat_data stat_data;
+ unsigned char intbuf[16];
+ unsigned int intlen, value;
+ int i;
+
+ stat_data_to_disk(&stat_data, &untracked->stat_data);
+ strbuf_add(out, &stat_data, sizeof(stat_data));
+ strbuf_add(out, untracked->exclude_sha1, 20);
+
+ /*
+ * untracked_nr should be reset whenever valid is clear, but
+ * for safety..
+ */
+ if (!untracked->valid) {
+ untracked->untracked_nr = 0;
+ untracked->check_only = 0;
+ }
+
+ /*
+ * encode_varint does not deal with signed integers. Use the
+ * lowest bit to store the sign.
+ */
+ value = untracked->untracked_nr << 2;
+ if (untracked->valid)
+ value |= 1;
+ if (untracked->check_only)
+ value |= 2;
+ intlen = encode_varint(value, intbuf);
+ strbuf_add(out, intbuf, intlen);
+
+ /* skip non-recurse directories */
+ for (i = 0, value = 0; i < untracked->dirs_nr; i++)
+ if (untracked->dirs[i]->recurse)
+ value++;
+ intlen = encode_varint(value, intbuf);
+ strbuf_add(out, intbuf, intlen);
+
+ strbuf_add(out, untracked->name, strlen(untracked->name) + 1);
+
+ for (i = 0; i < untracked->untracked_nr; i++)
+ strbuf_add(out, untracked->untracked[i],
+ strlen(untracked->untracked[i]) + 1);
+
+ for (i = 0; i < untracked->dirs_nr; i++)
+ if (untracked->dirs[i]->recurse)
+ write_one_dir(out, untracked->dirs[i]);
+}
+
+void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked)
+{
+ struct ondisk_untracked_cache *ouc;
+ int len = 0;
+ if (untracked->exclude_per_dir)
+ len = strlen(untracked->exclude_per_dir);
+ ouc = xmalloc(sizeof(*ouc) + len);
+ stat_data_to_disk(&ouc->info_exclude_stat, &untracked->info_exclude_stat);
+ stat_data_to_disk(&ouc->excludes_file_stat, &untracked->excludes_file_stat);
+ hashcpy(ouc->info_exclude_sha1, untracked->info_exclude_sha1);
+ hashcpy(ouc->excludes_file_sha1, untracked->excludes_file_sha1);
+ ouc->dir_flags = htonl(untracked->dir_flags);
+ memcpy(ouc->exclude_per_dir, untracked->exclude_per_dir, len + 1);
+ strbuf_add(out, ouc, sizeof(*ouc) + len);
+ if (untracked->root)
+ write_one_dir(out, untracked->root);
+}
diff --git a/dir.h b/dir.h
index 5dde37b..e520d58 100644
--- a/dir.h
+++ b/dir.h
@@ -295,4 +295,5 @@ static inline int dir_path_match(const struct dir_entry *ent,
has_trailing_dir);
}
+void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);
#endif
diff --git a/read-cache.c b/read-cache.c
index ba13353..a619666 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -34,6 +34,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
#define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) )
#define CACHE_EXT_TREE 0x54524545 /* "TREE" */
#define CACHE_EXT_RESOLVE_UNDO 0x52455543 /* "REUC" */
+#define CACHE_EXT_UNTRACKED 0x554E5452 /* "UNTR" */
struct index_state the_index;
@@ -1869,6 +1870,17 @@ int write_index(struct index_state *istate, int newfd)
if (err)
return -1;
}
+ if (istate->untracked) {
+ struct strbuf sb = STRBUF_INIT;
+
+ write_untracked_extension(&sb, istate->untracked);
+ err = write_index_ext_header(&c, newfd, CACHE_EXT_UNTRACKED,
+ sb.len) < 0 ||
+ ce_write(&c, newfd, sb.buf, sb.len) < 0;
+ strbuf_release(&sb);
+ if (err)
+ return -1;
+ }
if (ce_flush(&c, newfd) || fstat(newfd, &st))
return -1;
--
1.9.1.346.ga2b5940
next prev parent reply other threads:[~2014-05-07 14:53 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-07 14:51 [PATCH 00/20] Untracked cache to speed up "git status" Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 01/20] dir.c: coding style fix Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 02/20] dir.h: move struct exclude declaration to top level Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 03/20] prep_exclude: remove the artificial PATH_MAX limit Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 04/20] dir.c: optionally compute sha-1 of a .gitignore file Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 05/20] untracked cache: record .gitignore information and dir hierarchy Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 06/20] untracked cache: initial untracked cache validation Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 07/20] untracked cache: invalidate dirs recursively if .gitignore changes Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 08/20] untracked cache: record/validate dir mtime and reuse cached output Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 09/20] untracked cache: mark what dirs should be recursed/saved Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 10/20] untracked cache: don't open non-existent .gitignore Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` Nguyễn Thái Ngọc Duy [this message]
2014-05-07 14:51 ` [PATCH 12/20] untracked cache: load from UNTR index extension Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 13/20] untracked cache: invalidate at index addition or removal Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 14/20] untracked cache: print untracked statistics with $GIT_TRACE_UNTRACKED Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 15/20] read-cache.c: split racy stat test to a separate function Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 16/20] untracked cache: avoid racy timestamps Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 17/20] status: support untracked cache Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 18/20] update-index: manually enable or disable " Nguyễn Thái Ngọc Duy
2014-05-07 14:51 ` [PATCH 19/20] update-index: test the system before enabling " Nguyễn Thái Ngọc Duy
2014-05-07 14:52 ` [PATCH 20/20] t7063: tests for " Nguyễn Thái Ngọc Duy
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=1399474320-6840-12-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.