|
12 | 12 | #include "refs.h"
|
13 | 13 | #include "wildmatch.h"
|
14 | 14 | #include "pathspec.h"
|
| 15 | +#include "varint.h" |
| 16 | +#include "ewah/ewok.h" |
15 | 17 |
|
16 | 18 | struct path_simplify {
|
17 | 19 | int len;
|
@@ -2144,3 +2146,140 @@ void clear_directory(struct dir_struct *dir)
|
2144 | 2146 | }
|
2145 | 2147 | strbuf_release(&dir->basebuf);
|
2146 | 2148 | }
|
| 2149 | + |
| 2150 | +struct ondisk_untracked_cache { |
| 2151 | + struct stat_data info_exclude_stat; |
| 2152 | + struct stat_data excludes_file_stat; |
| 2153 | + uint32_t dir_flags; |
| 2154 | + unsigned char info_exclude_sha1[20]; |
| 2155 | + unsigned char excludes_file_sha1[20]; |
| 2156 | + char exclude_per_dir[FLEX_ARRAY]; |
| 2157 | +}; |
| 2158 | + |
| 2159 | +#define ouc_size(len) (offsetof(struct ondisk_untracked_cache, exclude_per_dir) + len + 1) |
| 2160 | + |
| 2161 | +struct write_data { |
| 2162 | + int index; /* number of written untracked_cache_dir */ |
| 2163 | + struct ewah_bitmap *check_only; /* from untracked_cache_dir */ |
| 2164 | + struct ewah_bitmap *valid; /* from untracked_cache_dir */ |
| 2165 | + struct ewah_bitmap *sha1_valid; /* set if exclude_sha1 is not null */ |
| 2166 | + struct strbuf out; |
| 2167 | + struct strbuf sb_stat; |
| 2168 | + struct strbuf sb_sha1; |
| 2169 | +}; |
| 2170 | + |
| 2171 | +static void stat_data_to_disk(struct stat_data *to, const struct stat_data *from) |
| 2172 | +{ |
| 2173 | + to->sd_ctime.sec = htonl(from->sd_ctime.sec); |
| 2174 | + to->sd_ctime.nsec = htonl(from->sd_ctime.nsec); |
| 2175 | + to->sd_mtime.sec = htonl(from->sd_mtime.sec); |
| 2176 | + to->sd_mtime.nsec = htonl(from->sd_mtime.nsec); |
| 2177 | + to->sd_dev = htonl(from->sd_dev); |
| 2178 | + to->sd_ino = htonl(from->sd_ino); |
| 2179 | + to->sd_uid = htonl(from->sd_uid); |
| 2180 | + to->sd_gid = htonl(from->sd_gid); |
| 2181 | + to->sd_size = htonl(from->sd_size); |
| 2182 | +} |
| 2183 | + |
| 2184 | +static void write_one_dir(struct untracked_cache_dir *untracked, |
| 2185 | + struct write_data *wd) |
| 2186 | +{ |
| 2187 | + struct stat_data stat_data; |
| 2188 | + struct strbuf *out = &wd->out; |
| 2189 | + unsigned char intbuf[16]; |
| 2190 | + unsigned int intlen, value; |
| 2191 | + int i = wd->index++; |
| 2192 | + |
| 2193 | + /* |
| 2194 | + * untracked_nr should be reset whenever valid is clear, but |
| 2195 | + * for safety.. |
| 2196 | + */ |
| 2197 | + if (!untracked->valid) { |
| 2198 | + untracked->untracked_nr = 0; |
| 2199 | + untracked->check_only = 0; |
| 2200 | + } |
| 2201 | + |
| 2202 | + if (untracked->check_only) |
| 2203 | + ewah_set(wd->check_only, i); |
| 2204 | + if (untracked->valid) { |
| 2205 | + ewah_set(wd->valid, i); |
| 2206 | + stat_data_to_disk(&stat_data, &untracked->stat_data); |
| 2207 | + strbuf_add(&wd->sb_stat, &stat_data, sizeof(stat_data)); |
| 2208 | + } |
| 2209 | + if (!is_null_sha1(untracked->exclude_sha1)) { |
| 2210 | + ewah_set(wd->sha1_valid, i); |
| 2211 | + strbuf_add(&wd->sb_sha1, untracked->exclude_sha1, 20); |
| 2212 | + } |
| 2213 | + |
| 2214 | + intlen = encode_varint(untracked->untracked_nr, intbuf); |
| 2215 | + strbuf_add(out, intbuf, intlen); |
| 2216 | + |
| 2217 | + /* skip non-recurse directories */ |
| 2218 | + for (i = 0, value = 0; i < untracked->dirs_nr; i++) |
| 2219 | + if (untracked->dirs[i]->recurse) |
| 2220 | + value++; |
| 2221 | + intlen = encode_varint(value, intbuf); |
| 2222 | + strbuf_add(out, intbuf, intlen); |
| 2223 | + |
| 2224 | + strbuf_add(out, untracked->name, strlen(untracked->name) + 1); |
| 2225 | + |
| 2226 | + for (i = 0; i < untracked->untracked_nr; i++) |
| 2227 | + strbuf_add(out, untracked->untracked[i], |
| 2228 | + strlen(untracked->untracked[i]) + 1); |
| 2229 | + |
| 2230 | + for (i = 0; i < untracked->dirs_nr; i++) |
| 2231 | + if (untracked->dirs[i]->recurse) |
| 2232 | + write_one_dir(untracked->dirs[i], wd); |
| 2233 | +} |
| 2234 | + |
| 2235 | +void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked) |
| 2236 | +{ |
| 2237 | + struct ondisk_untracked_cache *ouc; |
| 2238 | + struct write_data wd; |
| 2239 | + unsigned char varbuf[16]; |
| 2240 | + int len = 0, varint_len; |
| 2241 | + if (untracked->exclude_per_dir) |
| 2242 | + len = strlen(untracked->exclude_per_dir); |
| 2243 | + ouc = xmalloc(sizeof(*ouc) + len + 1); |
| 2244 | + stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat); |
| 2245 | + stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat); |
| 2246 | + hashcpy(ouc->info_exclude_sha1, untracked->ss_info_exclude.sha1); |
| 2247 | + hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.sha1); |
| 2248 | + ouc->dir_flags = htonl(untracked->dir_flags); |
| 2249 | + memcpy(ouc->exclude_per_dir, untracked->exclude_per_dir, len + 1); |
| 2250 | + strbuf_add(out, ouc, ouc_size(len)); |
| 2251 | + free(ouc); |
| 2252 | + ouc = NULL; |
| 2253 | + |
| 2254 | + if (!untracked->root) { |
| 2255 | + varint_len = encode_varint(0, varbuf); |
| 2256 | + strbuf_add(out, varbuf, varint_len); |
| 2257 | + return; |
| 2258 | + } |
| 2259 | + |
| 2260 | + wd.index = 0; |
| 2261 | + wd.check_only = ewah_new(); |
| 2262 | + wd.valid = ewah_new(); |
| 2263 | + wd.sha1_valid = ewah_new(); |
| 2264 | + strbuf_init(&wd.out, 1024); |
| 2265 | + strbuf_init(&wd.sb_stat, 1024); |
| 2266 | + strbuf_init(&wd.sb_sha1, 1024); |
| 2267 | + write_one_dir(untracked->root, &wd); |
| 2268 | + |
| 2269 | + varint_len = encode_varint(wd.index, varbuf); |
| 2270 | + strbuf_add(out, varbuf, varint_len); |
| 2271 | + strbuf_addbuf(out, &wd.out); |
| 2272 | + ewah_serialize_strbuf(wd.valid, out); |
| 2273 | + ewah_serialize_strbuf(wd.check_only, out); |
| 2274 | + ewah_serialize_strbuf(wd.sha1_valid, out); |
| 2275 | + strbuf_addbuf(out, &wd.sb_stat); |
| 2276 | + strbuf_addbuf(out, &wd.sb_sha1); |
| 2277 | + strbuf_addch(out, '\0'); /* safe guard for string lists */ |
| 2278 | + |
| 2279 | + ewah_free(wd.valid); |
| 2280 | + ewah_free(wd.check_only); |
| 2281 | + ewah_free(wd.sha1_valid); |
| 2282 | + strbuf_release(&wd.out); |
| 2283 | + strbuf_release(&wd.sb_stat); |
| 2284 | + strbuf_release(&wd.sb_sha1); |
| 2285 | +} |
0 commit comments