#include "cache.h"
+#include "lockfile.h"
#include "tree.h"
#include "tree-walk.h"
#include "cache-tree.h"
struct strbuf buffer;
int missing_ok = flags & WRITE_TREE_MISSING_OK;
int dryrun = flags & WRITE_TREE_DRY_RUN;
+ int repair = flags & WRITE_TREE_REPAIR;
int to_invalidate = 0;
int i;
+ assert(!(dryrun && repair));
+
*skip_count = 0;
if (0 <= it->entry_count && has_sha1_file(it->sha1))
flags);
if (subcnt < 0)
return subcnt;
+ if (!subcnt)
+ die("index cache-tree records empty sub-tree");
i += subcnt;
sub->count = subcnt; /* to be used in the next loop */
*skip_count += subskip;
int pathlen, entlen;
const unsigned char *sha1;
unsigned mode;
+ int expected_missing = 0;
path = ce->name;
pathlen = ce_namelen(ce);
i += sub->count;
sha1 = sub->cache_tree->sha1;
mode = S_IFDIR;
- if (sub->cache_tree->entry_count < 0)
+ if (sub->cache_tree->entry_count < 0) {
to_invalidate = 1;
+ expected_missing = 1;
+ }
}
else {
sha1 = ce->sha1;
}
if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1)) {
strbuf_release(&buffer);
+ if (expected_missing)
+ return -1;
return error("invalid object %06o %s for '%.*s'",
mode, sha1_to_hex(sha1), entlen+baselen, path);
}
#endif
}
- if (dryrun)
+ if (repair) {
+ unsigned char sha1[20];
+ hash_sha1_file(buffer.buf, buffer.len, tree_type, sha1);
+ if (has_sha1_file(sha1))
+ hashcpy(it->sha1, sha1);
+ else
+ to_invalidate = 1;
+ } else if (dryrun)
hash_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1);
else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1)) {
strbuf_release(&buffer);