static int queue_or_write_archive_entry(const unsigned char *sha1, struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { struct archiver_context *c = context; while (c->bottom && !(base->len >= c->bottom->len && !strncmp(base->buf, c->bottom->path, c->bottom->len))) { struct directory *next = c->bottom->up; free(c->bottom); c->bottom = next; } if (S_ISDIR(mode)) { queue_directory(sha1, base, filename, mode, stage, c); return READ_TREE_RECURSIVE; } if (write_directory(c)) return -1; return write_archive_entry(sha1, base->buf, base->len, filename, mode, stage, context); }
static int write_archive_entry_buf(const unsigned char *sha1, struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { return write_archive_entry(sha1, base->buf, base->len, filename, mode, stage, context); }
static int write_directory(struct archiver_context *c) { struct directory *d = c->bottom; int ret; if (!d) return 0; c->bottom = d->up; d->path[d->len - 1] = '\0'; /* no trailing slash */ ret = write_directory(c) || write_archive_entry(&d->oid, d->path, d->baselen, d->path + d->baselen, d->mode, d->stage, c) != READ_TREE_RECURSIVE; free(d); return ret ? -1 : 0; }
static int queue_or_write_archive_entry(const struct object_id *oid, struct strbuf *base, const char *filename, unsigned mode, int stage, void *context) { struct archiver_context *c = context; while (c->bottom && !(base->len >= c->bottom->len && !strncmp(base->buf, c->bottom->path, c->bottom->len))) { struct directory *next = c->bottom->up; free(c->bottom); c->bottom = next; } if (S_ISDIR(mode)) { size_t baselen = base->len; const struct attr_check *check; /* Borrow base, but restore its original value when done. */ strbuf_addstr(base, filename); strbuf_addch(base, '/'); check = get_archive_attrs(c->args->repo->index, base->buf); strbuf_setlen(base, baselen); if (check_attr_export_ignore(check)) return 0; queue_directory(oid->hash, base, filename, mode, stage, c); return READ_TREE_RECURSIVE; } if (write_directory(c)) return -1; return write_archive_entry(oid, base->buf, base->len, filename, mode, stage, context); }