Merge branch 'sb/object-store'
Refactoring the internal global data structure to make it possible to open multiple repositories, work with and then close them. Rerolled by Duy on top of a separate preliminary clean-up topic. The resulting structure of the topics looked very sensible. * sb/object-store: (27 commits) sha1_file: allow sha1_loose_object_info to handle arbitrary repositories sha1_file: allow map_sha1_file to handle arbitrary repositories sha1_file: allow map_sha1_file_1 to handle arbitrary repositories sha1_file: allow open_sha1_file to handle arbitrary repositories sha1_file: allow stat_sha1_file to handle arbitrary repositories sha1_file: allow sha1_file_name to handle arbitrary repositories sha1_file: add repository argument to sha1_loose_object_info sha1_file: add repository argument to map_sha1_file sha1_file: add repository argument to map_sha1_file_1 sha1_file: add repository argument to open_sha1_file sha1_file: add repository argument to stat_sha1_file sha1_file: add repository argument to sha1_file_name sha1_file: allow prepare_alt_odb to handle arbitrary repositories sha1_file: allow link_alt_odb_entries to handle arbitrary repositories sha1_file: add repository argument to prepare_alt_odb sha1_file: add repository argument to link_alt_odb_entries sha1_file: add repository argument to read_info_alternates sha1_file: add repository argument to link_alt_odb_entry sha1_file: add raw_object_store argument to alt_odb_usable pack: move approximate object count to object store ...
This commit is contained in:
commit
cf0b1793ea
@ -1862,7 +1862,7 @@ next:
|
||||
*/
|
||||
if (!state->rebasing) {
|
||||
am_destroy(state);
|
||||
close_all_packs();
|
||||
close_all_packs(the_repository->objects);
|
||||
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "connected.h"
|
||||
#include "packfile.h"
|
||||
#include "list-objects-filter-options.h"
|
||||
#include "object-store.h"
|
||||
|
||||
/*
|
||||
* Overall FIXMEs:
|
||||
@ -1217,7 +1218,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
transport_disconnect(transport);
|
||||
|
||||
if (option_dissociate) {
|
||||
close_all_packs();
|
||||
close_all_packs(the_repository->objects);
|
||||
dissociate_from_references();
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,12 @@
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "dir.h"
|
||||
#include "repository.h"
|
||||
#include "builtin.h"
|
||||
#include "parse-options.h"
|
||||
#include "quote.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static unsigned long garbage;
|
||||
static off_t size_garbage;
|
||||
@ -120,9 +122,9 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
|
||||
struct strbuf loose_buf = STRBUF_INIT;
|
||||
struct strbuf pack_buf = STRBUF_INIT;
|
||||
struct strbuf garbage_buf = STRBUF_INIT;
|
||||
if (!packed_git)
|
||||
if (!get_packed_git(the_repository))
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (!p->pack_local)
|
||||
continue;
|
||||
if (open_pack_index(p))
|
||||
|
@ -1516,7 +1516,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
||||
|
||||
string_list_clear(&list, 0);
|
||||
|
||||
close_all_packs();
|
||||
close_all_packs(the_repository->objects);
|
||||
|
||||
argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
|
||||
if (verbosity < 0)
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "builtin.h"
|
||||
#include "cache.h"
|
||||
#include "repository.h"
|
||||
#include "config.h"
|
||||
#include "commit.h"
|
||||
#include "tree.h"
|
||||
@ -16,6 +17,7 @@
|
||||
#include "streaming.h"
|
||||
#include "decorate.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
#define REACHABLE 0x0001
|
||||
#define SEEN 0x0002
|
||||
@ -719,9 +721,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||
for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
|
||||
for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
|
||||
} else {
|
||||
struct alternate_object_database *alt_odb_list;
|
||||
|
||||
fsck_object_dir(get_object_directory());
|
||||
|
||||
prepare_alt_odb();
|
||||
prepare_alt_odb(the_repository);
|
||||
alt_odb_list = the_repository->objects->alt_odb_list;
|
||||
for (alt = alt_odb_list; alt; alt = alt->next)
|
||||
fsck_object_dir(alt->path);
|
||||
|
||||
@ -733,7 +738,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||
prepare_packed_git();
|
||||
|
||||
if (show_progress) {
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p;
|
||||
p = p->next) {
|
||||
if (open_pack_index(p))
|
||||
continue;
|
||||
total += p->num_objects;
|
||||
@ -741,7 +747,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
||||
|
||||
progress = start_progress(_("Checking objects"), total);
|
||||
}
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p;
|
||||
p = p->next) {
|
||||
/* verify gives error messages itself */
|
||||
if (verify_pack(p, fsck_obj_buffer,
|
||||
progress, count))
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include "builtin.h"
|
||||
#include "repository.h"
|
||||
#include "config.h"
|
||||
#include "tempfile.h"
|
||||
#include "lockfile.h"
|
||||
@ -20,6 +21,7 @@
|
||||
#include "argv-array.h"
|
||||
#include "commit.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
#define FAILED_RUN "failed to run %s"
|
||||
|
||||
@ -173,7 +175,7 @@ static int too_many_packs(void)
|
||||
return 0;
|
||||
|
||||
prepare_packed_git();
|
||||
for (cnt = 0, p = packed_git; p; p = p->next) {
|
||||
for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (!p->pack_local)
|
||||
continue;
|
||||
if (p->pack_keep)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pathspec.h"
|
||||
#include "submodule.h"
|
||||
#include "submodule-config.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static char const * const grep_usage[] = {
|
||||
N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
|
||||
@ -439,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
|
||||
* object.
|
||||
*/
|
||||
grep_read_lock();
|
||||
add_to_alternates_memory(submodule.objectdir);
|
||||
add_to_alternates_memory(submodule.objects->objectdir);
|
||||
grep_read_unlock();
|
||||
|
||||
if (oid) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "streaming.h"
|
||||
#include "thread-utils.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static const char index_pack_usage[] =
|
||||
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
|
||||
|
@ -412,7 +412,7 @@ static void finish(struct commit *head_commit,
|
||||
* We ignore errors in 'gc --auto', since the
|
||||
* user should see them.
|
||||
*/
|
||||
close_all_packs();
|
||||
close_all_packs(the_repository->objects);
|
||||
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "builtin.h"
|
||||
#include "cache.h"
|
||||
#include "repository.h"
|
||||
#include "config.h"
|
||||
#include "attr.h"
|
||||
#include "object.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "argv-array.h"
|
||||
#include "list.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static const char *pack_usage[] = {
|
||||
N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
|
||||
@ -1023,8 +1025,7 @@ static int want_object_in_pack(const struct object_id *oid,
|
||||
if (want != -1)
|
||||
return want;
|
||||
}
|
||||
|
||||
list_for_each(pos, &packed_git_mru) {
|
||||
list_for_each(pos, get_packed_git_mru(the_repository)) {
|
||||
struct packed_git *p = list_entry(pos, struct packed_git, mru);
|
||||
off_t offset;
|
||||
|
||||
@ -1042,7 +1043,8 @@ static int want_object_in_pack(const struct object_id *oid,
|
||||
}
|
||||
want = want_found_object(exclude, p);
|
||||
if (!exclude && want > 0)
|
||||
list_move(&p->mru, &packed_git_mru);
|
||||
list_move(&p->mru,
|
||||
get_packed_git_mru(the_repository));
|
||||
if (want != -1)
|
||||
return want;
|
||||
}
|
||||
@ -2669,7 +2671,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
|
||||
|
||||
memset(&in_pack, 0, sizeof(in_pack));
|
||||
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
struct object_id oid;
|
||||
struct object *o;
|
||||
|
||||
@ -2732,7 +2734,8 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
|
||||
static struct packed_git *last_found = (void *)1;
|
||||
struct packed_git *p;
|
||||
|
||||
p = (last_found != (void *)1) ? last_found : packed_git;
|
||||
p = (last_found != (void *)1) ? last_found :
|
||||
get_packed_git(the_repository);
|
||||
|
||||
while (p) {
|
||||
if ((!p->pack_local || p->pack_keep) &&
|
||||
@ -2741,7 +2744,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
|
||||
return 1;
|
||||
}
|
||||
if (p == last_found)
|
||||
p = packed_git;
|
||||
p = get_packed_git(the_repository);
|
||||
else
|
||||
p = p->next;
|
||||
if (p == last_found)
|
||||
@ -2777,7 +2780,7 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
|
||||
uint32_t i;
|
||||
struct object_id oid;
|
||||
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (!p->pack_local || p->pack_keep)
|
||||
continue;
|
||||
|
||||
@ -3148,7 +3151,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
prepare_packed_git();
|
||||
if (ignore_packed_keep) {
|
||||
struct packed_git *p;
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = get_packed_git(the_repository); p; p = p->next)
|
||||
if (p->pack_local && p->pack_keep)
|
||||
break;
|
||||
if (!p) /* no keep-able packs found */
|
||||
@ -3161,7 +3164,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
||||
* also covers non-local objects
|
||||
*/
|
||||
struct packed_git *p;
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (!p->pack_local) {
|
||||
have_non_local_packs = 1;
|
||||
break;
|
||||
|
@ -7,7 +7,9 @@
|
||||
*/
|
||||
|
||||
#include "builtin.h"
|
||||
#include "repository.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
#define BLKSIZE 512
|
||||
|
||||
@ -571,7 +573,7 @@ static struct pack_list * add_pack(struct packed_git *p)
|
||||
|
||||
static struct pack_list * add_pack_file(const char *filename)
|
||||
{
|
||||
struct packed_git *p = packed_git;
|
||||
struct packed_git *p = get_packed_git(the_repository);
|
||||
|
||||
if (strlen(filename) < 40)
|
||||
die("Bad pack filename: %s", filename);
|
||||
@ -586,7 +588,7 @@ static struct pack_list * add_pack_file(const char *filename)
|
||||
|
||||
static void load_all(void)
|
||||
{
|
||||
struct packed_git *p = packed_git;
|
||||
struct packed_git *p = get_packed_git(the_repository);
|
||||
|
||||
while (p) {
|
||||
add_pack(p);
|
||||
|
@ -2027,7 +2027,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
|
||||
proc.git_cmd = 1;
|
||||
proc.argv = argv_gc_auto;
|
||||
|
||||
close_all_packs();
|
||||
close_all_packs(the_repository->objects);
|
||||
if (!start_command(&proc)) {
|
||||
if (use_sideband)
|
||||
copy_to_sideband(proc.err, -1, NULL);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "revision.h"
|
||||
#include "diffcore.h"
|
||||
#include "diff.h"
|
||||
#include "object-store.h"
|
||||
|
||||
#define OPT_QUIET (1 << 0)
|
||||
#define OPT_CACHED (1 << 1)
|
||||
|
87
cache.h
87
cache.h
@ -940,12 +940,6 @@ extern void check_repository_format(void);
|
||||
#define DATA_CHANGED 0x0020
|
||||
#define TYPE_CHANGED 0x0040
|
||||
|
||||
/*
|
||||
* Put in `buf` the name of the file in the local object database that
|
||||
* would be used to store a loose object with the specified sha1.
|
||||
*/
|
||||
extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1);
|
||||
|
||||
/*
|
||||
* Return an abbreviated sha1 unique within this repository's object database.
|
||||
* The result will be at least `len` characters long, and will be NUL
|
||||
@ -1236,7 +1230,6 @@ extern int force_object_loose(const struct object_id *oid, time_t mtime);
|
||||
|
||||
extern int git_open_cloexec(const char *name, int flags);
|
||||
#define git_open(name) git_open_cloexec(name, O_RDONLY)
|
||||
extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
|
||||
extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
|
||||
extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
|
||||
|
||||
@ -1564,57 +1557,6 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len);
|
||||
extern void schedule_dir_for_removal(const char *name, int len);
|
||||
extern void remove_scheduled_dirs(void);
|
||||
|
||||
extern struct alternate_object_database {
|
||||
struct alternate_object_database *next;
|
||||
|
||||
/* see alt_scratch_buf() */
|
||||
struct strbuf scratch;
|
||||
size_t base_len;
|
||||
|
||||
/*
|
||||
* Used to store the results of readdir(3) calls when searching
|
||||
* for unique abbreviated hashes. This cache is never
|
||||
* invalidated, thus it's racy and not necessarily accurate.
|
||||
* That's fine for its purpose; don't use it for tasks requiring
|
||||
* greater accuracy!
|
||||
*/
|
||||
char loose_objects_subdir_seen[256];
|
||||
struct oid_array loose_objects_cache;
|
||||
|
||||
char path[FLEX_ARRAY];
|
||||
} *alt_odb_list;
|
||||
extern void prepare_alt_odb(void);
|
||||
extern char *compute_alternate_path(const char *path, struct strbuf *err);
|
||||
typedef int alt_odb_fn(struct alternate_object_database *, void *);
|
||||
extern int foreach_alt_odb(alt_odb_fn, void*);
|
||||
|
||||
/*
|
||||
* Allocate a "struct alternate_object_database" but do _not_ actually
|
||||
* add it to the list of alternates.
|
||||
*/
|
||||
struct alternate_object_database *alloc_alt_odb(const char *dir);
|
||||
|
||||
/*
|
||||
* Add the directory to the on-disk alternates file; the new entry will also
|
||||
* take effect in the current process.
|
||||
*/
|
||||
extern void add_to_alternates_file(const char *dir);
|
||||
|
||||
/*
|
||||
* Add the directory to the in-memory list of alternates (along with any
|
||||
* recursive alternates it points to), but do not modify the on-disk alternates
|
||||
* file.
|
||||
*/
|
||||
extern void add_to_alternates_memory(const char *dir);
|
||||
|
||||
/*
|
||||
* Returns a scratch strbuf pre-filled with the alternate object directory,
|
||||
* including a trailing slash, which can be used to access paths in the
|
||||
* alternate. Always use this over direct access to alt->scratch, as it
|
||||
* cleans up any previous use of the scratch buffer.
|
||||
*/
|
||||
extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
|
||||
|
||||
struct pack_window {
|
||||
struct pack_window *next;
|
||||
unsigned char *base;
|
||||
@ -1624,35 +1566,6 @@ struct pack_window {
|
||||
unsigned int inuse_cnt;
|
||||
};
|
||||
|
||||
extern struct packed_git {
|
||||
struct packed_git *next;
|
||||
struct list_head mru;
|
||||
struct pack_window *windows;
|
||||
off_t pack_size;
|
||||
const void *index_data;
|
||||
size_t index_size;
|
||||
uint32_t num_objects;
|
||||
uint32_t num_bad_objects;
|
||||
unsigned char *bad_object_sha1;
|
||||
int index_version;
|
||||
time_t mtime;
|
||||
int pack_fd;
|
||||
unsigned pack_local:1,
|
||||
pack_keep:1,
|
||||
freshened:1,
|
||||
do_not_close:1,
|
||||
pack_promisor:1;
|
||||
unsigned char sha1[20];
|
||||
struct revindex_entry *revindex;
|
||||
/* something like ".git/objects/pack/xxxxx.pack" */
|
||||
char pack_name[FLEX_ARRAY]; /* more */
|
||||
} *packed_git;
|
||||
|
||||
/*
|
||||
* A most-recently-used ordered version of the packed_git list.
|
||||
*/
|
||||
extern struct list_head packed_git_mru;
|
||||
|
||||
struct pack_entry {
|
||||
off_t offset;
|
||||
unsigned char sha1[20];
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "fmt-merge-msg.h"
|
||||
#include "commit.h"
|
||||
#include "argv-array.h"
|
||||
#include "object-store.h"
|
||||
|
||||
int trust_executable_bit = 1;
|
||||
int trust_ctime = 1;
|
||||
@ -270,9 +271,9 @@ const char *get_git_work_tree(void)
|
||||
|
||||
char *get_object_directory(void)
|
||||
{
|
||||
if (!the_repository->objectdir)
|
||||
if (!the_repository->objects->objectdir)
|
||||
BUG("git environment hasn't been setup");
|
||||
return the_repository->objectdir;
|
||||
return the_repository->objects->objectdir;
|
||||
}
|
||||
|
||||
int odb_mkstemp(struct strbuf *temp_filename, const char *pattern)
|
||||
|
@ -154,6 +154,7 @@ Format of STDIN stream:
|
||||
|
||||
#include "builtin.h"
|
||||
#include "cache.h"
|
||||
#include "repository.h"
|
||||
#include "config.h"
|
||||
#include "lockfile.h"
|
||||
#include "object.h"
|
||||
@ -168,6 +169,7 @@ Format of STDIN stream:
|
||||
#include "dir.h"
|
||||
#include "run-command.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
#define PACK_ID_BITS 16
|
||||
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
|
||||
@ -1110,7 +1112,8 @@ static int store_object(
|
||||
if (e->idx.offset) {
|
||||
duplicate_count_by_type[type]++;
|
||||
return 1;
|
||||
} else if (find_sha1_pack(oid.hash, packed_git)) {
|
||||
} else if (find_sha1_pack(oid.hash,
|
||||
get_packed_git(the_repository))) {
|
||||
e->type = type;
|
||||
e->pack_id = MAX_PACK_ID;
|
||||
e->idx.offset = 1; /* just not zero! */
|
||||
@ -1307,7 +1310,8 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
|
||||
duplicate_count_by_type[OBJ_BLOB]++;
|
||||
truncate_pack(&checkpoint);
|
||||
|
||||
} else if (find_sha1_pack(oid.hash, packed_git)) {
|
||||
} else if (find_sha1_pack(oid.hash,
|
||||
get_packed_git(the_repository))) {
|
||||
e->type = OBJ_BLOB;
|
||||
e->pack_id = MAX_PACK_ID;
|
||||
e->idx.offset = 1; /* just not zero! */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "cache.h"
|
||||
#include "config.h"
|
||||
#include "repository.h"
|
||||
#include "refs.h"
|
||||
#include "pkt-line.h"
|
||||
#include "object.h"
|
||||
@ -10,6 +11,7 @@
|
||||
#include "url.h"
|
||||
#include "argv-array.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static const char content_type[] = "Content-Type";
|
||||
static const char content_length[] = "Content-Length";
|
||||
@ -518,13 +520,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)
|
||||
|
||||
select_getanyfile(hdr);
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (p->pack_local)
|
||||
cnt++;
|
||||
}
|
||||
|
||||
strbuf_grow(&buf, cnt * 53 + 2);
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (p->pack_local)
|
||||
strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "sigchain.h"
|
||||
#include "argv-array.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
#ifdef EXPAT_NEEDS_XMLPARSE_H
|
||||
#include <xmlparse.h>
|
||||
|
@ -1,10 +1,12 @@
|
||||
#include "cache.h"
|
||||
#include "repository.h"
|
||||
#include "commit.h"
|
||||
#include "walker.h"
|
||||
#include "http.h"
|
||||
#include "list.h"
|
||||
#include "transport.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
struct alt_base {
|
||||
char *base;
|
||||
@ -545,7 +547,7 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)
|
||||
ret = error("File %s has bad hash", hex);
|
||||
} else if (req->rename < 0) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
sha1_file_name(&buf, req->sha1);
|
||||
sha1_file_name(the_repository, &buf, req->sha1);
|
||||
ret = error("unable to write sha1 filename %s", buf.buf);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
6
http.c
6
http.c
@ -14,6 +14,7 @@
|
||||
#include "packfile.h"
|
||||
#include "protocol.h"
|
||||
#include "string-list.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
|
||||
static int trace_curl_data = 1;
|
||||
@ -2248,7 +2249,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
|
||||
hashcpy(freq->sha1, sha1);
|
||||
freq->localfile = -1;
|
||||
|
||||
sha1_file_name(&filename, sha1);
|
||||
sha1_file_name(the_repository, &filename, sha1);
|
||||
snprintf(freq->tmpfile, sizeof(freq->tmpfile),
|
||||
"%s.temp", filename.buf);
|
||||
|
||||
@ -2397,8 +2398,7 @@ int finish_http_object_request(struct http_object_request *freq)
|
||||
unlink_or_warn(freq->tmpfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sha1_file_name(&filename, freq->sha1);
|
||||
sha1_file_name(the_repository, &filename, freq->sha1);
|
||||
freq->rename = finalize_object_file(freq->tmpfile, filename.buf);
|
||||
strbuf_release(&filename);
|
||||
|
||||
|
132
object-store.h
Normal file
132
object-store.h
Normal file
@ -0,0 +1,132 @@
|
||||
#ifndef OBJECT_STORE_H
|
||||
#define OBJECT_STORE_H
|
||||
|
||||
struct alternate_object_database {
|
||||
struct alternate_object_database *next;
|
||||
|
||||
/* see alt_scratch_buf() */
|
||||
struct strbuf scratch;
|
||||
size_t base_len;
|
||||
|
||||
/*
|
||||
* Used to store the results of readdir(3) calls when searching
|
||||
* for unique abbreviated hashes. This cache is never
|
||||
* invalidated, thus it's racy and not necessarily accurate.
|
||||
* That's fine for its purpose; don't use it for tasks requiring
|
||||
* greater accuracy!
|
||||
*/
|
||||
char loose_objects_subdir_seen[256];
|
||||
struct oid_array loose_objects_cache;
|
||||
|
||||
/*
|
||||
* Path to the alternative object store. If this is a relative path,
|
||||
* it is relative to the current working directory.
|
||||
*/
|
||||
char path[FLEX_ARRAY];
|
||||
};
|
||||
void prepare_alt_odb(struct repository *r);
|
||||
char *compute_alternate_path(const char *path, struct strbuf *err);
|
||||
typedef int alt_odb_fn(struct alternate_object_database *, void *);
|
||||
int foreach_alt_odb(alt_odb_fn, void*);
|
||||
|
||||
/*
|
||||
* Allocate a "struct alternate_object_database" but do _not_ actually
|
||||
* add it to the list of alternates.
|
||||
*/
|
||||
struct alternate_object_database *alloc_alt_odb(const char *dir);
|
||||
|
||||
/*
|
||||
* Add the directory to the on-disk alternates file; the new entry will also
|
||||
* take effect in the current process.
|
||||
*/
|
||||
void add_to_alternates_file(const char *dir);
|
||||
|
||||
/*
|
||||
* Add the directory to the in-memory list of alternates (along with any
|
||||
* recursive alternates it points to), but do not modify the on-disk alternates
|
||||
* file.
|
||||
*/
|
||||
void add_to_alternates_memory(const char *dir);
|
||||
|
||||
/*
|
||||
* Returns a scratch strbuf pre-filled with the alternate object directory,
|
||||
* including a trailing slash, which can be used to access paths in the
|
||||
* alternate. Always use this over direct access to alt->scratch, as it
|
||||
* cleans up any previous use of the scratch buffer.
|
||||
*/
|
||||
struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
|
||||
|
||||
struct packed_git {
|
||||
struct packed_git *next;
|
||||
struct list_head mru;
|
||||
struct pack_window *windows;
|
||||
off_t pack_size;
|
||||
const void *index_data;
|
||||
size_t index_size;
|
||||
uint32_t num_objects;
|
||||
uint32_t num_bad_objects;
|
||||
unsigned char *bad_object_sha1;
|
||||
int index_version;
|
||||
time_t mtime;
|
||||
int pack_fd;
|
||||
unsigned pack_local:1,
|
||||
pack_keep:1,
|
||||
freshened:1,
|
||||
do_not_close:1,
|
||||
pack_promisor:1;
|
||||
unsigned char sha1[20];
|
||||
struct revindex_entry *revindex;
|
||||
/* something like ".git/objects/pack/xxxxx.pack" */
|
||||
char pack_name[FLEX_ARRAY]; /* more */
|
||||
};
|
||||
|
||||
struct raw_object_store {
|
||||
/*
|
||||
* Path to the repository's object store.
|
||||
* Cannot be NULL after initialization.
|
||||
*/
|
||||
char *objectdir;
|
||||
|
||||
/* Path to extra alternate object database if not NULL */
|
||||
char *alternate_db;
|
||||
|
||||
struct alternate_object_database *alt_odb_list;
|
||||
struct alternate_object_database **alt_odb_tail;
|
||||
|
||||
/*
|
||||
* private data
|
||||
*
|
||||
* should only be accessed directly by packfile.c
|
||||
*/
|
||||
|
||||
struct packed_git *packed_git;
|
||||
/* A most-recently-used ordered version of the packed_git list. */
|
||||
struct list_head packed_git_mru;
|
||||
|
||||
/*
|
||||
* A fast, rough count of the number of objects in the repository.
|
||||
* These two fields are not meant for direct access. Use
|
||||
* approximate_object_count() instead.
|
||||
*/
|
||||
unsigned long approximate_object_count;
|
||||
unsigned approximate_object_count_valid : 1;
|
||||
|
||||
/*
|
||||
* Whether packed_git has already been populated with this repository's
|
||||
* packs.
|
||||
*/
|
||||
unsigned packed_git_initialized : 1;
|
||||
};
|
||||
|
||||
struct raw_object_store *raw_object_store_new(void);
|
||||
void raw_object_store_clear(struct raw_object_store *o);
|
||||
|
||||
/*
|
||||
* Put in `buf` the name of the file in the local object database that
|
||||
* would be used to store a loose object with the specified sha1.
|
||||
*/
|
||||
void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
|
||||
|
||||
void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
|
||||
|
||||
#endif /* OBJECT_STORE_H */
|
42
object.c
42
object.c
@ -4,6 +4,8 @@
|
||||
#include "tree.h"
|
||||
#include "commit.h"
|
||||
#include "tag.h"
|
||||
#include "object-store.h"
|
||||
#include "packfile.h"
|
||||
|
||||
static struct object **obj_hash;
|
||||
static int nr_objs, obj_hash_size;
|
||||
@ -445,3 +447,43 @@ void clear_commit_marks_all(unsigned int flags)
|
||||
obj->flags &= ~flags;
|
||||
}
|
||||
}
|
||||
|
||||
struct raw_object_store *raw_object_store_new(void)
|
||||
{
|
||||
struct raw_object_store *o = xmalloc(sizeof(*o));
|
||||
|
||||
memset(o, 0, sizeof(*o));
|
||||
INIT_LIST_HEAD(&o->packed_git_mru);
|
||||
return o;
|
||||
}
|
||||
|
||||
static void free_alt_odb(struct alternate_object_database *alt)
|
||||
{
|
||||
strbuf_release(&alt->scratch);
|
||||
oid_array_clear(&alt->loose_objects_cache);
|
||||
free(alt);
|
||||
}
|
||||
|
||||
static void free_alt_odbs(struct raw_object_store *o)
|
||||
{
|
||||
while (o->alt_odb_list) {
|
||||
struct alternate_object_database *next;
|
||||
|
||||
next = o->alt_odb_list->next;
|
||||
free_alt_odb(o->alt_odb_list);
|
||||
o->alt_odb_list = next;
|
||||
}
|
||||
}
|
||||
|
||||
void raw_object_store_clear(struct raw_object_store *o)
|
||||
{
|
||||
FREE_AND_NULL(o->objectdir);
|
||||
FREE_AND_NULL(o->alternate_db);
|
||||
|
||||
free_alt_odbs(o);
|
||||
o->alt_odb_tail = NULL;
|
||||
|
||||
INIT_LIST_HEAD(&o->packed_git_mru);
|
||||
close_all_packs(o);
|
||||
o->packed_git = NULL;
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "pack-revindex.h"
|
||||
#include "pack-objects.h"
|
||||
#include "packfile.h"
|
||||
#include "repository.h"
|
||||
#include "object-store.h"
|
||||
|
||||
/*
|
||||
* An entry on the bitmap index, representing the bitmap for a given
|
||||
@ -335,7 +337,7 @@ static int open_pack_bitmap(void)
|
||||
assert(!bitmap_git.map && !bitmap_git.loaded);
|
||||
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (open_pack_bitmap_1(p) == 0)
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "pack-revindex.h"
|
||||
#include "progress.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
struct idx_entry {
|
||||
off_t offset;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "cache.h"
|
||||
#include "pack-revindex.h"
|
||||
#include "object-store.h"
|
||||
|
||||
/*
|
||||
* Pack index for existing packs give us easy access to the offsets into
|
||||
|
77
packfile.c
77
packfile.c
@ -1,6 +1,7 @@
|
||||
#include "cache.h"
|
||||
#include "list.h"
|
||||
#include "pack.h"
|
||||
#include "repository.h"
|
||||
#include "dir.h"
|
||||
#include "mergesort.h"
|
||||
#include "packfile.h"
|
||||
@ -13,6 +14,7 @@
|
||||
#include "tag.h"
|
||||
#include "tree-walk.h"
|
||||
#include "tree.h"
|
||||
#include "object-store.h"
|
||||
|
||||
char *odb_pack_name(struct strbuf *buf,
|
||||
const unsigned char *sha1,
|
||||
@ -44,8 +46,6 @@ static unsigned int pack_open_fds;
|
||||
static unsigned int pack_max_fds;
|
||||
static size_t peak_pack_mapped;
|
||||
static size_t pack_mapped;
|
||||
struct packed_git *packed_git;
|
||||
LIST_HEAD(packed_git_mru);
|
||||
|
||||
#define SZ_FMT PRIuMAX
|
||||
static inline uintmax_t sz_fmt(size_t s) { return s; }
|
||||
@ -245,7 +245,7 @@ static int unuse_one_window(struct packed_git *current)
|
||||
|
||||
if (current)
|
||||
scan_windows(current, &lru_p, &lru_w, &lru_l);
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next)
|
||||
scan_windows(p, &lru_p, &lru_w, &lru_l);
|
||||
if (lru_p) {
|
||||
munmap(lru_w->base, lru_w->len);
|
||||
@ -311,11 +311,11 @@ static void close_pack(struct packed_git *p)
|
||||
close_pack_index(p);
|
||||
}
|
||||
|
||||
void close_all_packs(void)
|
||||
void close_all_packs(struct raw_object_store *o)
|
||||
{
|
||||
struct packed_git *p;
|
||||
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = o->packed_git; p; p = p->next)
|
||||
if (p->do_not_close)
|
||||
die("BUG: want to close pack marked 'do-not-close'");
|
||||
else
|
||||
@ -383,7 +383,7 @@ static int close_one_pack(void)
|
||||
struct pack_window *mru_w = NULL;
|
||||
int accept_windows_inuse = 1;
|
||||
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next) {
|
||||
if (p->pack_fd == -1)
|
||||
continue;
|
||||
find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
|
||||
@ -685,8 +685,8 @@ void install_packed_git(struct packed_git *pack)
|
||||
if (pack->pack_fd != -1)
|
||||
pack_open_fds++;
|
||||
|
||||
pack->next = packed_git;
|
||||
packed_git = pack;
|
||||
pack->next = the_repository->objects->packed_git;
|
||||
the_repository->objects->packed_git = pack;
|
||||
}
|
||||
|
||||
void (*report_garbage)(unsigned seen_bits, const char *path);
|
||||
@ -768,7 +768,8 @@ static void prepare_packed_git_one(char *objdir, int local)
|
||||
base_len = path.len;
|
||||
if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
|
||||
/* Don't reopen a pack we already have. */
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p;
|
||||
p = p->next) {
|
||||
size_t len;
|
||||
if (strip_suffix(p->pack_name, ".pack", &len) &&
|
||||
len == base_len &&
|
||||
@ -802,8 +803,6 @@ static void prepare_packed_git_one(char *objdir, int local)
|
||||
strbuf_release(&path);
|
||||
}
|
||||
|
||||
static int approximate_object_count_valid;
|
||||
|
||||
/*
|
||||
* Give a fast, rough count of the number of objects in the repository. This
|
||||
* ignores loose objects completely. If you have a lot of them, then either
|
||||
@ -813,19 +812,20 @@ static int approximate_object_count_valid;
|
||||
*/
|
||||
unsigned long approximate_object_count(void)
|
||||
{
|
||||
static unsigned long count;
|
||||
if (!approximate_object_count_valid) {
|
||||
if (!the_repository->objects->approximate_object_count_valid) {
|
||||
unsigned long count;
|
||||
struct packed_git *p;
|
||||
|
||||
prepare_packed_git();
|
||||
count = 0;
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next) {
|
||||
if (open_pack_index(p))
|
||||
continue;
|
||||
count += p->num_objects;
|
||||
}
|
||||
the_repository->objects->approximate_object_count = count;
|
||||
}
|
||||
return count;
|
||||
return the_repository->objects->approximate_object_count;
|
||||
}
|
||||
|
||||
static void *get_next_packed_git(const void *p)
|
||||
@ -868,43 +868,53 @@ static int sort_pack(const void *a_, const void *b_)
|
||||
|
||||
static void rearrange_packed_git(void)
|
||||
{
|
||||
packed_git = llist_mergesort(packed_git, get_next_packed_git,
|
||||
set_next_packed_git, sort_pack);
|
||||
the_repository->objects->packed_git = llist_mergesort(
|
||||
the_repository->objects->packed_git, get_next_packed_git,
|
||||
set_next_packed_git, sort_pack);
|
||||
}
|
||||
|
||||
static void prepare_packed_git_mru(void)
|
||||
{
|
||||
struct packed_git *p;
|
||||
|
||||
INIT_LIST_HEAD(&packed_git_mru);
|
||||
INIT_LIST_HEAD(&the_repository->objects->packed_git_mru);
|
||||
|
||||
for (p = packed_git; p; p = p->next)
|
||||
list_add_tail(&p->mru, &packed_git_mru);
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next)
|
||||
list_add_tail(&p->mru, &the_repository->objects->packed_git_mru);
|
||||
}
|
||||
|
||||
static int prepare_packed_git_run_once = 0;
|
||||
void prepare_packed_git(void)
|
||||
{
|
||||
struct alternate_object_database *alt;
|
||||
|
||||
if (prepare_packed_git_run_once)
|
||||
if (the_repository->objects->packed_git_initialized)
|
||||
return;
|
||||
prepare_packed_git_one(get_object_directory(), 1);
|
||||
prepare_alt_odb();
|
||||
for (alt = alt_odb_list; alt; alt = alt->next)
|
||||
prepare_alt_odb(the_repository);
|
||||
for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next)
|
||||
prepare_packed_git_one(alt->path, 0);
|
||||
rearrange_packed_git();
|
||||
prepare_packed_git_mru();
|
||||
prepare_packed_git_run_once = 1;
|
||||
the_repository->objects->packed_git_initialized = 1;
|
||||
}
|
||||
|
||||
void reprepare_packed_git(void)
|
||||
{
|
||||
approximate_object_count_valid = 0;
|
||||
prepare_packed_git_run_once = 0;
|
||||
the_repository->objects->approximate_object_count_valid = 0;
|
||||
the_repository->objects->packed_git_initialized = 0;
|
||||
prepare_packed_git();
|
||||
}
|
||||
|
||||
struct packed_git *get_packed_git(struct repository *r)
|
||||
{
|
||||
return r->objects->packed_git;
|
||||
}
|
||||
|
||||
struct list_head *get_packed_git_mru(struct repository *r)
|
||||
{
|
||||
return &r->objects->packed_git_mru;
|
||||
}
|
||||
|
||||
unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
||||
unsigned long len, enum object_type *type, unsigned long *sizep)
|
||||
{
|
||||
@ -1013,7 +1023,7 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
|
||||
struct packed_git *p;
|
||||
unsigned i;
|
||||
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next)
|
||||
for (i = 0; i < p->num_bad_objects; i++)
|
||||
if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
|
||||
return p;
|
||||
@ -1833,13 +1843,14 @@ int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
|
||||
struct list_head *pos;
|
||||
|
||||
prepare_packed_git();
|
||||
if (!packed_git)
|
||||
if (!the_repository->objects->packed_git)
|
||||
return 0;
|
||||
|
||||
list_for_each(pos, &packed_git_mru) {
|
||||
list_for_each(pos, &the_repository->objects->packed_git_mru) {
|
||||
struct packed_git *p = list_entry(pos, struct packed_git, mru);
|
||||
if (fill_pack_entry(sha1, e, p)) {
|
||||
list_move(&p->mru, &packed_git_mru);
|
||||
list_move(&p->mru,
|
||||
&the_repository->objects->packed_git_mru);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -1886,7 +1897,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
|
||||
int pack_errors = 0;
|
||||
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = the_repository->objects->packed_git; p; p = p->next) {
|
||||
if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
|
||||
continue;
|
||||
if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&
|
||||
@ -1917,7 +1928,7 @@ static int add_promisor_object(const struct object_id *oid,
|
||||
|
||||
/*
|
||||
* If this is a tree, commit, or tag, the objects it refers
|
||||
* to are also promisor objects. (Blobs refer to no objects.)
|
||||
* to are also promisor objects. (Blobs refer to no objects->)
|
||||
*/
|
||||
if (obj->type == OBJ_TREE) {
|
||||
struct tree *tree = (struct tree *)obj;
|
||||
|
@ -38,6 +38,9 @@ extern void prepare_packed_git(void);
|
||||
extern void reprepare_packed_git(void);
|
||||
extern void install_packed_git(struct packed_git *pack);
|
||||
|
||||
struct packed_git *get_packed_git(struct repository *r);
|
||||
struct list_head *get_packed_git_mru(struct repository *r);
|
||||
|
||||
/*
|
||||
* Give a rough count of objects in the repository. This sacrifices accuracy
|
||||
* for speed.
|
||||
@ -63,7 +66,7 @@ extern void close_pack_index(struct packed_git *);
|
||||
|
||||
extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
|
||||
extern void close_pack_windows(struct packed_git *);
|
||||
extern void close_all_packs(void);
|
||||
extern void close_all_packs(struct raw_object_store *o);
|
||||
extern void unuse_pack(struct pack_window **);
|
||||
extern void clear_delta_base_cache(void);
|
||||
extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);
|
||||
|
3
path.c
3
path.c
@ -10,6 +10,7 @@
|
||||
#include "submodule-config.h"
|
||||
#include "path.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static int get_st_mode_bits(const char *path, int *mode)
|
||||
{
|
||||
@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo,
|
||||
strbuf_splice(buf, 0, buf->len,
|
||||
repo->index_file, strlen(repo->index_file));
|
||||
else if (dir_prefix(base, "objects"))
|
||||
replace_dir(buf, git_dir_len + 7, repo->objectdir);
|
||||
replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
|
||||
else if (git_hooks_path && dir_prefix(base, "hooks"))
|
||||
replace_dir(buf, git_dir_len + 5, git_hooks_path);
|
||||
else if (repo->different_commondir)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "list-objects.h"
|
||||
#include "packfile.h"
|
||||
#include "worktree.h"
|
||||
#include "object-store.h"
|
||||
|
||||
struct connectivity_progress {
|
||||
struct progress *progress;
|
||||
|
15
repository.c
15
repository.c
@ -1,5 +1,6 @@
|
||||
#include "cache.h"
|
||||
#include "repository.h"
|
||||
#include "object-store.h"
|
||||
#include "config.h"
|
||||
#include "submodule-config.h"
|
||||
|
||||
@ -12,6 +13,7 @@ void initialize_the_repository(void)
|
||||
the_repository = &the_repo;
|
||||
|
||||
the_repo.index = &the_index;
|
||||
the_repo.objects = raw_object_store_new();
|
||||
repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
|
||||
}
|
||||
|
||||
@ -58,10 +60,10 @@ void repo_set_gitdir(struct repository *repo,
|
||||
free(old_gitdir);
|
||||
|
||||
repo_set_commondir(repo, o->commondir);
|
||||
expand_base_dir(&repo->objectdir, o->object_dir,
|
||||
expand_base_dir(&repo->objects->objectdir, o->object_dir,
|
||||
repo->commondir, "objects");
|
||||
free(repo->alternate_db);
|
||||
repo->alternate_db = xstrdup_or_null(o->alternate_db);
|
||||
free(repo->objects->alternate_db);
|
||||
repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
|
||||
expand_base_dir(&repo->graft_file, o->graft_file,
|
||||
repo->commondir, "info/grafts");
|
||||
expand_base_dir(&repo->index_file, o->index_file,
|
||||
@ -140,6 +142,8 @@ static int repo_init(struct repository *repo,
|
||||
struct repository_format format;
|
||||
memset(repo, 0, sizeof(*repo));
|
||||
|
||||
repo->objects = raw_object_store_new();
|
||||
|
||||
if (repo_init_gitdir(repo, gitdir))
|
||||
goto error;
|
||||
|
||||
@ -214,13 +218,14 @@ void repo_clear(struct repository *repo)
|
||||
{
|
||||
FREE_AND_NULL(repo->gitdir);
|
||||
FREE_AND_NULL(repo->commondir);
|
||||
FREE_AND_NULL(repo->objectdir);
|
||||
FREE_AND_NULL(repo->alternate_db);
|
||||
FREE_AND_NULL(repo->graft_file);
|
||||
FREE_AND_NULL(repo->index_file);
|
||||
FREE_AND_NULL(repo->worktree);
|
||||
FREE_AND_NULL(repo->submodule_prefix);
|
||||
|
||||
raw_object_store_clear(repo->objects);
|
||||
FREE_AND_NULL(repo->objects);
|
||||
|
||||
if (repo->config) {
|
||||
git_configset_clear(repo->config);
|
||||
FREE_AND_NULL(repo->config);
|
||||
|
13
repository.h
13
repository.h
@ -2,9 +2,10 @@
|
||||
#define REPOSITORY_H
|
||||
|
||||
struct config_set;
|
||||
struct index_state;
|
||||
struct submodule_cache;
|
||||
struct git_hash_algo;
|
||||
struct index_state;
|
||||
struct raw_object_store;
|
||||
struct submodule_cache;
|
||||
|
||||
struct repository {
|
||||
/* Environment */
|
||||
@ -21,13 +22,9 @@ struct repository {
|
||||
char *commondir;
|
||||
|
||||
/*
|
||||
* Path to the repository's object store.
|
||||
* Cannot be NULL after initialization.
|
||||
* Holds any information related to accessing the raw object content.
|
||||
*/
|
||||
char *objectdir;
|
||||
|
||||
/* Path to extra alternate object database if not NULL */
|
||||
char *alternate_db;
|
||||
struct raw_object_store *objects;
|
||||
|
||||
/*
|
||||
* Path to the repository's graft file.
|
||||
|
@ -1,9 +1,11 @@
|
||||
#include "cache.h"
|
||||
#include "repository.h"
|
||||
#include "refs.h"
|
||||
#include "object.h"
|
||||
#include "commit.h"
|
||||
#include "tag.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
/*
|
||||
* Create the file "path" by writing to a temporary file and renaming
|
||||
@ -200,7 +202,7 @@ static void init_pack_info(const char *infofile, int force)
|
||||
objdirlen = strlen(objdir);
|
||||
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next) {
|
||||
for (p = get_packed_git(the_repository); p; p = p->next) {
|
||||
/* we ignore things on alternate path since they are
|
||||
* not available to the pullers in general.
|
||||
*/
|
||||
@ -210,7 +212,7 @@ static void init_pack_info(const char *infofile, int force)
|
||||
}
|
||||
num_pack = i;
|
||||
info = xcalloc(num_pack, sizeof(struct pack_info *));
|
||||
for (i = 0, p = packed_git; p; p = p->next) {
|
||||
for (i = 0, p = get_packed_git(the_repository); p; p = p->next) {
|
||||
if (!p->pack_local)
|
||||
continue;
|
||||
info[i] = xcalloc(1, sizeof(struct pack_info));
|
||||
|
125
sha1_file.c
125
sha1_file.c
@ -22,6 +22,7 @@
|
||||
#include "pack-revindex.h"
|
||||
#include "sha1-lookup.h"
|
||||
#include "bulk-checkin.h"
|
||||
#include "repository.h"
|
||||
#include "streaming.h"
|
||||
#include "dir.h"
|
||||
#include "list.h"
|
||||
@ -29,6 +30,7 @@
|
||||
#include "quote.h"
|
||||
#include "packfile.h"
|
||||
#include "fetch-object.h"
|
||||
#include "object-store.h"
|
||||
|
||||
/* The maximum size for an object header. */
|
||||
#define MAX_HEADER_LEN 32
|
||||
@ -322,9 +324,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
|
||||
}
|
||||
}
|
||||
|
||||
void sha1_file_name(struct strbuf *buf, const unsigned char *sha1)
|
||||
void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1)
|
||||
{
|
||||
strbuf_addstr(buf, get_object_directory());
|
||||
strbuf_addstr(buf, r->objects->objectdir);
|
||||
strbuf_addch(buf, '/');
|
||||
fill_sha1_path(buf, sha1);
|
||||
}
|
||||
@ -343,13 +345,12 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
struct alternate_object_database *alt_odb_list;
|
||||
static struct alternate_object_database **alt_odb_tail;
|
||||
|
||||
/*
|
||||
* Return non-zero iff the path is usable as an alternate object database.
|
||||
*/
|
||||
static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
|
||||
static int alt_odb_usable(struct raw_object_store *o,
|
||||
struct strbuf *path,
|
||||
const char *normalized_objdir)
|
||||
{
|
||||
struct alternate_object_database *alt;
|
||||
|
||||
@ -365,7 +366,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
|
||||
* Prevent the common mistake of listing the same
|
||||
* thing twice, or object directory itself.
|
||||
*/
|
||||
for (alt = alt_odb_list; alt; alt = alt->next) {
|
||||
for (alt = o->alt_odb_list; alt; alt = alt->next) {
|
||||
if (!fspathcmp(path->buf, alt->path))
|
||||
return 0;
|
||||
}
|
||||
@ -390,9 +391,11 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
|
||||
* SHA1, an extra slash for the first level indirection, and the
|
||||
* terminating NUL.
|
||||
*/
|
||||
static void read_info_alternates(const char * relative_base, int depth);
|
||||
static int link_alt_odb_entry(const char *entry, const char *relative_base,
|
||||
int depth, const char *normalized_objdir)
|
||||
static void read_info_alternates(struct repository *r,
|
||||
const char *relative_base,
|
||||
int depth);
|
||||
static int link_alt_odb_entry(struct repository *r, const char *entry,
|
||||
const char *relative_base, int depth, const char *normalized_objdir)
|
||||
{
|
||||
struct alternate_object_database *ent;
|
||||
struct strbuf pathbuf = STRBUF_INIT;
|
||||
@ -417,7 +420,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
|
||||
while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
|
||||
strbuf_setlen(&pathbuf, pathbuf.len - 1);
|
||||
|
||||
if (!alt_odb_usable(&pathbuf, normalized_objdir)) {
|
||||
if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) {
|
||||
strbuf_release(&pathbuf);
|
||||
return -1;
|
||||
}
|
||||
@ -425,12 +428,12 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
|
||||
ent = alloc_alt_odb(pathbuf.buf);
|
||||
|
||||
/* add the alternate entry */
|
||||
*alt_odb_tail = ent;
|
||||
alt_odb_tail = &(ent->next);
|
||||
*r->objects->alt_odb_tail = ent;
|
||||
r->objects->alt_odb_tail = &(ent->next);
|
||||
ent->next = NULL;
|
||||
|
||||
/* recursively add alternates */
|
||||
read_info_alternates(pathbuf.buf, depth + 1);
|
||||
read_info_alternates(r, pathbuf.buf, depth + 1);
|
||||
|
||||
strbuf_release(&pathbuf);
|
||||
return 0;
|
||||
@ -465,8 +468,8 @@ static const char *parse_alt_odb_entry(const char *string,
|
||||
return end;
|
||||
}
|
||||
|
||||
static void link_alt_odb_entries(const char *alt, int sep,
|
||||
const char *relative_base, int depth)
|
||||
static void link_alt_odb_entries(struct repository *r, const char *alt,
|
||||
int sep, const char *relative_base, int depth)
|
||||
{
|
||||
struct strbuf objdirbuf = STRBUF_INIT;
|
||||
struct strbuf entry = STRBUF_INIT;
|
||||
@ -480,7 +483,7 @@ static void link_alt_odb_entries(const char *alt, int sep,
|
||||
return;
|
||||
}
|
||||
|
||||
strbuf_add_absolute_path(&objdirbuf, get_object_directory());
|
||||
strbuf_add_absolute_path(&objdirbuf, r->objects->objectdir);
|
||||
if (strbuf_normalize_path(&objdirbuf) < 0)
|
||||
die("unable to normalize object directory: %s",
|
||||
objdirbuf.buf);
|
||||
@ -489,13 +492,16 @@ static void link_alt_odb_entries(const char *alt, int sep,
|
||||
alt = parse_alt_odb_entry(alt, sep, &entry);
|
||||
if (!entry.len)
|
||||
continue;
|
||||
link_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf);
|
||||
link_alt_odb_entry(r, entry.buf,
|
||||
relative_base, depth, objdirbuf.buf);
|
||||
}
|
||||
strbuf_release(&entry);
|
||||
strbuf_release(&objdirbuf);
|
||||
}
|
||||
|
||||
static void read_info_alternates(const char * relative_base, int depth)
|
||||
static void read_info_alternates(struct repository *r,
|
||||
const char *relative_base,
|
||||
int depth)
|
||||
{
|
||||
char *path;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
@ -507,7 +513,7 @@ static void read_info_alternates(const char * relative_base, int depth)
|
||||
return;
|
||||
}
|
||||
|
||||
link_alt_odb_entries(buf.buf, '\n', relative_base, depth);
|
||||
link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth);
|
||||
strbuf_release(&buf);
|
||||
free(path);
|
||||
}
|
||||
@ -560,8 +566,9 @@ void add_to_alternates_file(const char *reference)
|
||||
fprintf_or_die(out, "%s\n", reference);
|
||||
if (commit_lock_file(&lock))
|
||||
die_errno("unable to move new alternates file into place");
|
||||
if (alt_odb_tail)
|
||||
link_alt_odb_entries(reference, '\n', NULL, 0);
|
||||
if (the_repository->objects->alt_odb_tail)
|
||||
link_alt_odb_entries(the_repository, reference,
|
||||
'\n', NULL, 0);
|
||||
}
|
||||
free(alts);
|
||||
}
|
||||
@ -572,9 +579,10 @@ void add_to_alternates_memory(const char *reference)
|
||||
* Make sure alternates are initialized, or else our entry may be
|
||||
* overwritten when they are.
|
||||
*/
|
||||
prepare_alt_odb();
|
||||
prepare_alt_odb(the_repository);
|
||||
|
||||
link_alt_odb_entries(reference, '\n', NULL, 0);
|
||||
link_alt_odb_entries(the_repository, reference,
|
||||
'\n', NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -657,8 +665,8 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
|
||||
struct alternate_object_database *ent;
|
||||
int r = 0;
|
||||
|
||||
prepare_alt_odb();
|
||||
for (ent = alt_odb_list; ent; ent = ent->next) {
|
||||
prepare_alt_odb(the_repository);
|
||||
for (ent = the_repository->objects->alt_odb_list; ent; ent = ent->next) {
|
||||
r = fn(ent, cb);
|
||||
if (r)
|
||||
break;
|
||||
@ -666,15 +674,15 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
|
||||
return r;
|
||||
}
|
||||
|
||||
void prepare_alt_odb(void)
|
||||
void prepare_alt_odb(struct repository *r)
|
||||
{
|
||||
if (alt_odb_tail)
|
||||
if (r->objects->alt_odb_tail)
|
||||
return;
|
||||
|
||||
alt_odb_tail = &alt_odb_list;
|
||||
link_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);
|
||||
r->objects->alt_odb_tail = &r->objects->alt_odb_list;
|
||||
link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0);
|
||||
|
||||
read_info_alternates(get_object_directory(), 0);
|
||||
read_info_alternates(r, r->objects->objectdir, 0);
|
||||
}
|
||||
|
||||
/* Returns 1 if we have successfully freshened the file, 0 otherwise. */
|
||||
@ -706,7 +714,7 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)
|
||||
static struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
strbuf_reset(&buf);
|
||||
sha1_file_name(&buf, sha1);
|
||||
sha1_file_name(the_repository, &buf, sha1);
|
||||
|
||||
return check_and_freshen_file(buf.buf, freshen);
|
||||
}
|
||||
@ -714,8 +722,8 @@ static int check_and_freshen_local(const unsigned char *sha1, int freshen)
|
||||
static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
|
||||
{
|
||||
struct alternate_object_database *alt;
|
||||
prepare_alt_odb();
|
||||
for (alt = alt_odb_list; alt; alt = alt->next) {
|
||||
prepare_alt_odb(the_repository);
|
||||
for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) {
|
||||
const char *path = alt_sha1_path(alt, sha1);
|
||||
if (check_and_freshen_file(path, freshen))
|
||||
return 1;
|
||||
@ -860,22 +868,22 @@ int git_open_cloexec(const char *name, int flags)
|
||||
* Note that it may point to static storage and is only valid until another
|
||||
* call to sha1_file_name(), etc.
|
||||
*/
|
||||
static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
|
||||
const char **path)
|
||||
static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
|
||||
struct stat *st, const char **path)
|
||||
{
|
||||
struct alternate_object_database *alt;
|
||||
static struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
strbuf_reset(&buf);
|
||||
sha1_file_name(&buf, sha1);
|
||||
sha1_file_name(r, &buf, sha1);
|
||||
*path = buf.buf;
|
||||
|
||||
if (!lstat(*path, st))
|
||||
return 0;
|
||||
|
||||
prepare_alt_odb();
|
||||
prepare_alt_odb(r);
|
||||
errno = ENOENT;
|
||||
for (alt = alt_odb_list; alt; alt = alt->next) {
|
||||
for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
|
||||
*path = alt_sha1_path(alt, sha1);
|
||||
if (!lstat(*path, st))
|
||||
return 0;
|
||||
@ -888,7 +896,8 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
|
||||
* Like stat_sha1_file(), but actually open the object and return the
|
||||
* descriptor. See the caveats on the "path" parameter above.
|
||||
*/
|
||||
static int open_sha1_file(const unsigned char *sha1, const char **path)
|
||||
static int open_sha1_file(struct repository *r,
|
||||
const unsigned char *sha1, const char **path)
|
||||
{
|
||||
int fd;
|
||||
struct alternate_object_database *alt;
|
||||
@ -896,7 +905,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
|
||||
static struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
strbuf_reset(&buf);
|
||||
sha1_file_name(&buf, sha1);
|
||||
sha1_file_name(r, &buf, sha1);
|
||||
*path = buf.buf;
|
||||
|
||||
fd = git_open(*path);
|
||||
@ -904,8 +913,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
|
||||
return fd;
|
||||
most_interesting_errno = errno;
|
||||
|
||||
prepare_alt_odb();
|
||||
for (alt = alt_odb_list; alt; alt = alt->next) {
|
||||
prepare_alt_odb(r);
|
||||
for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
|
||||
*path = alt_sha1_path(alt, sha1);
|
||||
fd = git_open(*path);
|
||||
if (fd >= 0)
|
||||
@ -921,9 +930,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
|
||||
* Map the loose object at "path" if it is not NULL, or the path found by
|
||||
* searching for a loose object named "sha1".
|
||||
*/
|
||||
static void *map_sha1_file_1(const char *path,
|
||||
const unsigned char *sha1,
|
||||
unsigned long *size)
|
||||
static void *map_sha1_file_1(struct repository *r, const char *path,
|
||||
const unsigned char *sha1, unsigned long *size)
|
||||
{
|
||||
void *map;
|
||||
int fd;
|
||||
@ -931,7 +939,7 @@ static void *map_sha1_file_1(const char *path,
|
||||
if (path)
|
||||
fd = git_open(path);
|
||||
else
|
||||
fd = open_sha1_file(sha1, &path);
|
||||
fd = open_sha1_file(r, sha1, &path);
|
||||
map = NULL;
|
||||
if (fd >= 0) {
|
||||
struct stat st;
|
||||
@ -950,9 +958,10 @@ static void *map_sha1_file_1(const char *path,
|
||||
return map;
|
||||
}
|
||||
|
||||
void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
|
||||
void *map_sha1_file(struct repository *r,
|
||||
const unsigned char *sha1, unsigned long *size)
|
||||
{
|
||||
return map_sha1_file_1(NULL, sha1, size);
|
||||
return map_sha1_file_1(r, NULL, sha1, size);
|
||||
}
|
||||
|
||||
static int unpack_sha1_short_header(git_zstream *stream,
|
||||
@ -1141,9 +1150,9 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
|
||||
return parse_sha1_header_extended(hdr, &oi, 0);
|
||||
}
|
||||
|
||||
static int sha1_loose_object_info(const unsigned char *sha1,
|
||||
struct object_info *oi,
|
||||
int flags)
|
||||
static int sha1_loose_object_info(struct repository *r,
|
||||
const unsigned char *sha1,
|
||||
struct object_info *oi, int flags)
|
||||
{
|
||||
int status = 0;
|
||||
unsigned long mapsize;
|
||||
@ -1167,14 +1176,14 @@ static int sha1_loose_object_info(const unsigned char *sha1,
|
||||
if (!oi->typep && !oi->type_name && !oi->sizep && !oi->contentp) {
|
||||
const char *path;
|
||||
struct stat st;
|
||||
if (stat_sha1_file(sha1, &st, &path) < 0)
|
||||
if (stat_sha1_file(r, sha1, &st, &path) < 0)
|
||||
return -1;
|
||||
if (oi->disk_sizep)
|
||||
*oi->disk_sizep = st.st_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
map = map_sha1_file(sha1, &mapsize);
|
||||
map = map_sha1_file(r, sha1, &mapsize);
|
||||
if (!map)
|
||||
return -1;
|
||||
|
||||
@ -1266,7 +1275,7 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
|
||||
return -1;
|
||||
|
||||
/* Most likely it's a loose object. */
|
||||
if (!sha1_loose_object_info(real->hash, oi, flags))
|
||||
if (!sha1_loose_object_info(the_repository, real->hash, oi, flags))
|
||||
return 0;
|
||||
|
||||
/* Not a loose object; someone else may have just packed it. */
|
||||
@ -1390,7 +1399,7 @@ void *read_object_file_extended(const struct object_id *oid,
|
||||
die("replacement %s not found for %s",
|
||||
oid_to_hex(repl), oid_to_hex(oid));
|
||||
|
||||
if (!stat_sha1_file(repl->hash, &st, &path))
|
||||
if (!stat_sha1_file(the_repository, repl->hash, &st, &path))
|
||||
die("loose object %s (stored in %s) is corrupt",
|
||||
oid_to_hex(repl), path);
|
||||
|
||||
@ -1591,7 +1600,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
|
||||
static struct strbuf filename = STRBUF_INIT;
|
||||
|
||||
strbuf_reset(&filename);
|
||||
sha1_file_name(&filename, oid->hash);
|
||||
sha1_file_name(the_repository, &filename, oid->hash);
|
||||
|
||||
fd = create_tmpfile(&tmp_file, filename.buf);
|
||||
if (fd < 0) {
|
||||
@ -2199,7 +2208,7 @@ int read_loose_object(const char *path,
|
||||
|
||||
*contents = NULL;
|
||||
|
||||
map = map_sha1_file_1(path, NULL, &mapsize);
|
||||
map = map_sha1_file_1(the_repository, path, NULL, &mapsize);
|
||||
if (!map) {
|
||||
error_errno("unable to mmap %s", path);
|
||||
goto out;
|
||||
|
11
sha1_name.c
11
sha1_name.c
@ -10,6 +10,8 @@
|
||||
#include "dir.h"
|
||||
#include "sha1-array.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
#include "repository.h"
|
||||
|
||||
static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
|
||||
|
||||
@ -104,7 +106,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)
|
||||
*/
|
||||
fakeent = alloc_alt_odb(get_object_directory());
|
||||
}
|
||||
fakeent->next = alt_odb_list;
|
||||
fakeent->next = the_repository->objects->alt_odb_list;
|
||||
|
||||
for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
|
||||
int pos;
|
||||
@ -178,7 +180,8 @@ static void find_short_packed_object(struct disambiguate_state *ds)
|
||||
struct packed_git *p;
|
||||
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p && !ds->ambiguous; p = p->next)
|
||||
for (p = get_packed_git(the_repository); p && !ds->ambiguous;
|
||||
p = p->next)
|
||||
unique_in_pack(p, ds);
|
||||
}
|
||||
|
||||
@ -334,7 +337,7 @@ static int init_object_disambiguation(const char *name, int len,
|
||||
|
||||
ds->len = len;
|
||||
ds->hex_pfx[len] = '\0';
|
||||
prepare_alt_odb();
|
||||
prepare_alt_odb(the_repository);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -532,7 +535,7 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)
|
||||
struct packed_git *p;
|
||||
|
||||
prepare_packed_git();
|
||||
for (p = packed_git; p; p = p->next)
|
||||
for (p = get_packed_git(the_repository); p; p = p->next)
|
||||
find_abbrev_len_for_pack(p, mad);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
*/
|
||||
#include "cache.h"
|
||||
#include "streaming.h"
|
||||
#include "repository.h"
|
||||
#include "object-store.h"
|
||||
#include "packfile.h"
|
||||
|
||||
enum input_source {
|
||||
@ -335,7 +337,8 @@ static struct stream_vtbl loose_vtbl = {
|
||||
|
||||
static open_method_decl(loose)
|
||||
{
|
||||
st->u.loose.mapped = map_sha1_file(oid->hash, &st->u.loose.mapsize);
|
||||
st->u.loose.mapped = map_sha1_file(the_repository,
|
||||
oid->hash, &st->u.loose.mapsize);
|
||||
if (!st->u.loose.mapped)
|
||||
return -1;
|
||||
if ((unpack_sha1_header(&st->z,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "remote.h"
|
||||
#include "worktree.h"
|
||||
#include "parse-options.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
|
||||
static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "cache.h"
|
||||
#include "refs.h"
|
||||
#include "worktree.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static const char *notnull(const char *arg, const char *name)
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "strbuf.h"
|
||||
#include "argv-array.h"
|
||||
#include "quote.h"
|
||||
#include "object-store.h"
|
||||
|
||||
struct tmp_objdir {
|
||||
struct strbuf path;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "sha1-array.h"
|
||||
#include "sigchain.h"
|
||||
#include "transport-internal.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static void set_upstreams(struct transport *transport, struct ref *refs,
|
||||
int pretend)
|
||||
|
Loading…
Reference in New Issue
Block a user