mirror of
https://github.com/git/git
synced 2024-10-30 04:01:21 +00:00
Merge branch 'sb/object-store-replace'
The effort to pass the repository in-core structure throughout the API continues. This round deals with the code that implements the refs/replace/ mechanism. * sb/object-store-replace: replace-object: allow lookup_replace_object to handle arbitrary repositories replace-object: allow do_lookup_replace_object to handle arbitrary repositories replace-object: allow prepare_replace_object to handle arbitrary repositories refs: allow for_each_replace_ref to handle arbitrary repositories refs: store the main ref store inside the repository struct replace-object: add repository argument to lookup_replace_object replace-object: add repository argument to do_lookup_replace_object replace-object: add repository argument to prepare_replace_object refs: add repository argument to for_each_replace_ref refs: add repository argument to get_main_ref_store replace-object: check_replace_refs is safe in multi repo environment replace-object: eliminate replace objects prepared flag object-store: move lookup_replace_object to replace-object.h replace-object: move replace_map to object store replace_object: use oidmap
This commit is contained in:
commit
174774cd51
17 changed files with 134 additions and 150 deletions
|
@ -1,5 +1,6 @@
|
|||
#include "builtin.h"
|
||||
#include "tag.h"
|
||||
#include "replace-object.h"
|
||||
|
||||
/*
|
||||
* A signature file has a very simple fixed format: four lines
|
||||
|
@ -24,7 +25,7 @@ static int verify_object(const struct object_id *oid, const char *expected_type)
|
|||
enum object_type type;
|
||||
unsigned long size;
|
||||
void *buffer = read_object_file(oid, &type, &size);
|
||||
const struct object_id *repl = lookup_replace_object(oid);
|
||||
const struct object_id *repl = lookup_replace_object(the_repository, oid);
|
||||
|
||||
if (buffer) {
|
||||
if (type == type_from_string(expected_type))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "builtin.h"
|
||||
#include "parse-options.h"
|
||||
#include "refs.h"
|
||||
#include "repository.h"
|
||||
|
||||
static char const * const pack_refs_usage[] = {
|
||||
N_("git pack-refs [<options>]"),
|
||||
|
@ -17,5 +18,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
|
|||
};
|
||||
if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
|
||||
usage_with_options(pack_refs_usage, opts);
|
||||
return refs_pack_refs(get_main_ref_store(), flags);
|
||||
return refs_pack_refs(get_main_ref_store(the_repository), flags);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "refs.h"
|
||||
#include "parse-options.h"
|
||||
#include "run-command.h"
|
||||
#include "object-store.h"
|
||||
#include "repository.h"
|
||||
#include "tag.h"
|
||||
|
||||
static const char * const git_replace_usage[] = {
|
||||
|
@ -83,7 +85,7 @@ static int list_replace_refs(const char *pattern, const char *format)
|
|||
"valid formats are 'short', 'medium' and 'long'\n",
|
||||
format);
|
||||
|
||||
for_each_replace_ref(show_reference, (void *)&data);
|
||||
for_each_replace_ref(the_repository, show_reference, (void *)&data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
19
cache.h
19
cache.h
|
@ -1193,25 +1193,6 @@ static inline void *read_object_file(const struct object_id *oid, enum object_ty
|
|||
return read_object_file_extended(oid, type, size, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This internal function is only declared here for the benefit of
|
||||
* lookup_replace_object(). Please do not call it directly.
|
||||
*/
|
||||
extern const struct object_id *do_lookup_replace_object(const struct object_id *oid);
|
||||
|
||||
/*
|
||||
* If object sha1 should be replaced, return the replacement object's
|
||||
* name (replaced recursively, if necessary). The return value is
|
||||
* either sha1 or a pointer to a permanently-allocated value. When
|
||||
* object replacement is suppressed, always return sha1.
|
||||
*/
|
||||
static inline const struct object_id *lookup_replace_object(const struct object_id *oid)
|
||||
{
|
||||
if (!check_replace_refs)
|
||||
return oid;
|
||||
return do_lookup_replace_object(oid);
|
||||
}
|
||||
|
||||
/* Read and unpack an object file into memory, write memory to an object file */
|
||||
extern int oid_object_info(const struct object_id *, unsigned long *);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ const char *editor_program;
|
|||
const char *askpass_program;
|
||||
const char *excludes_file;
|
||||
enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
|
||||
int check_replace_refs = 1;
|
||||
int check_replace_refs = 1; /* NEEDSWORK: rename to read_replace_refs */
|
||||
char *git_replace_ref_base;
|
||||
enum eol core_eol = EOL_UNSET;
|
||||
int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef OBJECT_STORE_H
|
||||
#define OBJECT_STORE_H
|
||||
|
||||
#include "oidmap.h"
|
||||
|
||||
struct alternate_object_database {
|
||||
struct alternate_object_database *next;
|
||||
|
||||
|
@ -93,6 +95,12 @@ struct raw_object_store {
|
|||
struct alternate_object_database *alt_odb_list;
|
||||
struct alternate_object_database **alt_odb_tail;
|
||||
|
||||
/*
|
||||
* Objects that should be substituted by other objects
|
||||
* (see git-replace(1)).
|
||||
*/
|
||||
struct oidmap *replace_map;
|
||||
|
||||
/*
|
||||
* private data
|
||||
*
|
||||
|
|
3
object.c
3
object.c
|
@ -1,5 +1,6 @@
|
|||
#include "cache.h"
|
||||
#include "object.h"
|
||||
#include "replace-object.h"
|
||||
#include "blob.h"
|
||||
#include "tree.h"
|
||||
#include "commit.h"
|
||||
|
@ -246,7 +247,7 @@ struct object *parse_object(const struct object_id *oid)
|
|||
unsigned long size;
|
||||
enum object_type type;
|
||||
int eaten;
|
||||
const struct object_id *repl = lookup_replace_object(oid);
|
||||
const struct object_id *repl = lookup_replace_object(the_repository, oid);
|
||||
void *buffer;
|
||||
struct object *obj;
|
||||
|
||||
|
|
80
refs.c
80
refs.c
|
@ -14,6 +14,7 @@
|
|||
#include "submodule.h"
|
||||
#include "worktree.h"
|
||||
#include "argv-array.h"
|
||||
#include "repository.h"
|
||||
|
||||
/*
|
||||
* List of all available backends
|
||||
|
@ -207,7 +208,7 @@ char *refs_resolve_refdup(struct ref_store *refs,
|
|||
char *resolve_refdup(const char *refname, int resolve_flags,
|
||||
struct object_id *oid, int *flags)
|
||||
{
|
||||
return refs_resolve_refdup(get_main_ref_store(),
|
||||
return refs_resolve_refdup(get_main_ref_store(the_repository),
|
||||
refname, resolve_flags,
|
||||
oid, flags);
|
||||
}
|
||||
|
@ -229,7 +230,7 @@ int refs_read_ref_full(struct ref_store *refs, const char *refname,
|
|||
|
||||
int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, int *flags)
|
||||
{
|
||||
return refs_read_ref_full(get_main_ref_store(), refname,
|
||||
return refs_read_ref_full(get_main_ref_store(the_repository), refname,
|
||||
resolve_flags, oid, flags);
|
||||
}
|
||||
|
||||
|
@ -376,7 +377,7 @@ int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
|||
|
||||
int for_each_tag_ref(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_tag_ref(get_main_ref_store(), fn, cb_data);
|
||||
return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
||||
|
@ -386,7 +387,7 @@ int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da
|
|||
|
||||
int for_each_branch_ref(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_branch_ref(get_main_ref_store(), fn, cb_data);
|
||||
return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
||||
|
@ -396,7 +397,7 @@ int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da
|
|||
|
||||
int for_each_remote_ref(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_remote_ref(get_main_ref_store(), fn, cb_data);
|
||||
return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
int head_ref_namespaced(each_ref_fn fn, void *cb_data)
|
||||
|
@ -744,7 +745,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg,
|
|||
struct strbuf err = STRBUF_INIT;
|
||||
|
||||
if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
|
||||
assert(refs == get_main_ref_store());
|
||||
assert(refs == get_main_ref_store(the_repository));
|
||||
return delete_pseudoref(refname, old_oid);
|
||||
}
|
||||
|
||||
|
@ -766,7 +767,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg,
|
|||
int delete_ref(const char *msg, const char *refname,
|
||||
const struct object_id *old_oid, unsigned int flags)
|
||||
{
|
||||
return refs_delete_ref(get_main_ref_store(), msg, refname,
|
||||
return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
|
||||
old_oid, flags);
|
||||
}
|
||||
|
||||
|
@ -942,7 +943,7 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
|
|||
|
||||
struct ref_transaction *ref_transaction_begin(struct strbuf *err)
|
||||
{
|
||||
return ref_store_transaction_begin(get_main_ref_store(), err);
|
||||
return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
|
||||
}
|
||||
|
||||
void ref_transaction_free(struct ref_transaction *transaction)
|
||||
|
@ -1074,7 +1075,7 @@ int refs_update_ref(struct ref_store *refs, const char *msg,
|
|||
int ret = 0;
|
||||
|
||||
if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
|
||||
assert(refs == get_main_ref_store());
|
||||
assert(refs == get_main_ref_store(the_repository));
|
||||
ret = write_pseudoref(refname, new_oid, old_oid, &err);
|
||||
} else {
|
||||
t = ref_store_transaction_begin(refs, &err);
|
||||
|
@ -1113,7 +1114,7 @@ int update_ref(const char *msg, const char *refname,
|
|||
const struct object_id *old_oid,
|
||||
unsigned int flags, enum action_on_err onerr)
|
||||
{
|
||||
return refs_update_ref(get_main_ref_store(), msg, refname, new_oid,
|
||||
return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
|
||||
old_oid, flags, onerr);
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1335,7 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
|||
|
||||
int head_ref(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_head_ref(get_main_ref_store(), fn, cb_data);
|
||||
return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
struct ref_iterator *refs_ref_iterator_begin(
|
||||
|
@ -1393,7 +1394,7 @@ int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
|||
|
||||
int for_each_ref(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_ref(get_main_ref_store(), fn, cb_data);
|
||||
return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
|
||||
|
@ -1404,7 +1405,7 @@ int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
|
|||
|
||||
int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_ref_in(get_main_ref_store(), prefix, fn, cb_data);
|
||||
return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
|
||||
}
|
||||
|
||||
int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
|
||||
|
@ -1413,7 +1414,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsig
|
|||
|
||||
if (broken)
|
||||
flag = DO_FOR_EACH_INCLUDE_BROKEN;
|
||||
return do_for_each_ref(get_main_ref_store(),
|
||||
return do_for_each_ref(get_main_ref_store(the_repository),
|
||||
prefix, fn, 0, flag, cb_data);
|
||||
}
|
||||
|
||||
|
@ -1428,9 +1429,9 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
|
|||
return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data);
|
||||
}
|
||||
|
||||
int for_each_replace_ref(each_ref_fn fn, void *cb_data)
|
||||
int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return do_for_each_ref(get_main_ref_store(),
|
||||
return do_for_each_ref(get_main_ref_store(r),
|
||||
git_replace_ref_base, fn,
|
||||
strlen(git_replace_ref_base),
|
||||
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
|
||||
|
@ -1441,7 +1442,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
|
|||
struct strbuf buf = STRBUF_INIT;
|
||||
int ret;
|
||||
strbuf_addf(&buf, "%srefs/", get_git_namespace());
|
||||
ret = do_for_each_ref(get_main_ref_store(),
|
||||
ret = do_for_each_ref(get_main_ref_store(the_repository),
|
||||
buf.buf, fn, 0, 0, cb_data);
|
||||
strbuf_release(&buf);
|
||||
return ret;
|
||||
|
@ -1455,7 +1456,7 @@ int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
|||
|
||||
int for_each_rawref(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_rawref(get_main_ref_store(), fn, cb_data);
|
||||
return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
int refs_read_raw_ref(struct ref_store *ref_store,
|
||||
|
@ -1561,7 +1562,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
|
|||
/* backend functions */
|
||||
int refs_init_db(struct strbuf *err)
|
||||
{
|
||||
struct ref_store *refs = get_main_ref_store();
|
||||
struct ref_store *refs = get_main_ref_store(the_repository);
|
||||
|
||||
return refs->be->init_db(refs, err);
|
||||
}
|
||||
|
@ -1569,7 +1570,7 @@ int refs_init_db(struct strbuf *err)
|
|||
const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
|
||||
struct object_id *oid, int *flags)
|
||||
{
|
||||
return refs_resolve_ref_unsafe(get_main_ref_store(), refname,
|
||||
return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
|
||||
resolve_flags, oid, flags);
|
||||
}
|
||||
|
||||
|
@ -1621,9 +1622,6 @@ static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
|
|||
return entry;
|
||||
}
|
||||
|
||||
/* A pointer to the ref_store for the main repository: */
|
||||
static struct ref_store *main_ref_store;
|
||||
|
||||
/* A hashmap of ref_stores, stored by submodule name: */
|
||||
static struct hashmap submodule_ref_stores;
|
||||
|
||||
|
@ -1665,13 +1663,13 @@ static struct ref_store *ref_store_init(const char *gitdir,
|
|||
return refs;
|
||||
}
|
||||
|
||||
struct ref_store *get_main_ref_store(void)
|
||||
struct ref_store *get_main_ref_store(struct repository *r)
|
||||
{
|
||||
if (main_ref_store)
|
||||
return main_ref_store;
|
||||
if (r->refs)
|
||||
return r->refs;
|
||||
|
||||
main_ref_store = ref_store_init(get_git_dir(), REF_STORE_ALL_CAPS);
|
||||
return main_ref_store;
|
||||
r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
|
||||
return r->refs;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1740,7 +1738,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
|
|||
const char *id;
|
||||
|
||||
if (wt->is_current)
|
||||
return get_main_ref_store();
|
||||
return get_main_ref_store(the_repository);
|
||||
|
||||
id = wt->id ? wt->id : "/";
|
||||
refs = lookup_ref_store_map(&worktree_ref_stores, id);
|
||||
|
@ -1796,7 +1794,7 @@ int refs_peel_ref(struct ref_store *refs, const char *refname,
|
|||
|
||||
int peel_ref(const char *refname, struct object_id *oid)
|
||||
{
|
||||
return refs_peel_ref(get_main_ref_store(), refname, oid);
|
||||
return refs_peel_ref(get_main_ref_store(the_repository), refname, oid);
|
||||
}
|
||||
|
||||
int refs_create_symref(struct ref_store *refs,
|
||||
|
@ -1812,7 +1810,7 @@ int refs_create_symref(struct ref_store *refs,
|
|||
int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
const char *logmsg)
|
||||
{
|
||||
return refs_create_symref(get_main_ref_store(), ref_target,
|
||||
return refs_create_symref(get_main_ref_store(the_repository), ref_target,
|
||||
refs_heads_master, logmsg);
|
||||
}
|
||||
|
||||
|
@ -2020,7 +2018,7 @@ int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
|
|||
|
||||
int for_each_reflog(each_ref_fn fn, void *cb_data)
|
||||
{
|
||||
return refs_for_each_reflog(get_main_ref_store(), fn, cb_data);
|
||||
return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
|
||||
}
|
||||
|
||||
int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
|
||||
|
@ -2035,7 +2033,7 @@ int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
|
|||
int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
|
||||
void *cb_data)
|
||||
{
|
||||
return refs_for_each_reflog_ent_reverse(get_main_ref_store(),
|
||||
return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository),
|
||||
refname, fn, cb_data);
|
||||
}
|
||||
|
||||
|
@ -2048,7 +2046,7 @@ int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
|
|||
int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
|
||||
void *cb_data)
|
||||
{
|
||||
return refs_for_each_reflog_ent(get_main_ref_store(), refname,
|
||||
return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname,
|
||||
fn, cb_data);
|
||||
}
|
||||
|
||||
|
@ -2059,7 +2057,7 @@ int refs_reflog_exists(struct ref_store *refs, const char *refname)
|
|||
|
||||
int reflog_exists(const char *refname)
|
||||
{
|
||||
return refs_reflog_exists(get_main_ref_store(), refname);
|
||||
return refs_reflog_exists(get_main_ref_store(the_repository), refname);
|
||||
}
|
||||
|
||||
int refs_create_reflog(struct ref_store *refs, const char *refname,
|
||||
|
@ -2071,7 +2069,7 @@ int refs_create_reflog(struct ref_store *refs, const char *refname,
|
|||
int safe_create_reflog(const char *refname, int force_create,
|
||||
struct strbuf *err)
|
||||
{
|
||||
return refs_create_reflog(get_main_ref_store(), refname,
|
||||
return refs_create_reflog(get_main_ref_store(the_repository), refname,
|
||||
force_create, err);
|
||||
}
|
||||
|
||||
|
@ -2082,7 +2080,7 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname)
|
|||
|
||||
int delete_reflog(const char *refname)
|
||||
{
|
||||
return refs_delete_reflog(get_main_ref_store(), refname);
|
||||
return refs_delete_reflog(get_main_ref_store(the_repository), refname);
|
||||
}
|
||||
|
||||
int refs_reflog_expire(struct ref_store *refs,
|
||||
|
@ -2105,7 +2103,7 @@ int reflog_expire(const char *refname, const struct object_id *oid,
|
|||
reflog_expiry_cleanup_fn cleanup_fn,
|
||||
void *policy_cb_data)
|
||||
{
|
||||
return refs_reflog_expire(get_main_ref_store(),
|
||||
return refs_reflog_expire(get_main_ref_store(the_repository),
|
||||
refname, oid, flags,
|
||||
prepare_fn, should_prune_fn,
|
||||
cleanup_fn, policy_cb_data);
|
||||
|
@ -2128,7 +2126,7 @@ int refs_delete_refs(struct ref_store *refs, const char *msg,
|
|||
int delete_refs(const char *msg, struct string_list *refnames,
|
||||
unsigned int flags)
|
||||
{
|
||||
return refs_delete_refs(get_main_ref_store(), msg, refnames, flags);
|
||||
return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags);
|
||||
}
|
||||
|
||||
int refs_rename_ref(struct ref_store *refs, const char *oldref,
|
||||
|
@ -2139,7 +2137,7 @@ int refs_rename_ref(struct ref_store *refs, const char *oldref,
|
|||
|
||||
int rename_ref(const char *oldref, const char *newref, const char *logmsg)
|
||||
{
|
||||
return refs_rename_ref(get_main_ref_store(), oldref, newref, logmsg);
|
||||
return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
|
||||
}
|
||||
|
||||
int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
|
||||
|
@ -2150,5 +2148,5 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
|
|||
|
||||
int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
|
||||
{
|
||||
return refs_copy_existing_ref(get_main_ref_store(), oldref, newref, logmsg);
|
||||
return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
|
||||
}
|
||||
|
|
4
refs.h
4
refs.h
|
@ -307,7 +307,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data,
|
|||
int for_each_tag_ref(each_ref_fn fn, void *cb_data);
|
||||
int for_each_branch_ref(each_ref_fn fn, void *cb_data);
|
||||
int for_each_remote_ref(each_ref_fn fn, void *cb_data);
|
||||
int for_each_replace_ref(each_ref_fn fn, void *cb_data);
|
||||
int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data);
|
||||
int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data);
|
||||
int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
|
||||
const char *prefix, void *cb_data);
|
||||
|
@ -765,7 +765,7 @@ int reflog_expire(const char *refname, const struct object_id *oid,
|
|||
|
||||
int ref_storage_backend_exists(const char *name);
|
||||
|
||||
struct ref_store *get_main_ref_store(void);
|
||||
struct ref_store *get_main_ref_store(struct repository *r);
|
||||
/*
|
||||
* Return the ref_store instance for the specified submodule. For the
|
||||
* main repository, use submodule==NULL; such a call cannot fail. For
|
||||
|
|
|
@ -62,10 +62,6 @@ struct ref_lock {
|
|||
struct object_id old_oid;
|
||||
};
|
||||
|
||||
/*
|
||||
* Future: need to be in "struct repository"
|
||||
* when doing a full libification.
|
||||
*/
|
||||
struct files_ref_store {
|
||||
struct ref_store base;
|
||||
unsigned int store_flags;
|
||||
|
|
|
@ -1,55 +1,11 @@
|
|||
#include "cache.h"
|
||||
#include "sha1-lookup.h"
|
||||
#include "oidmap.h"
|
||||
#include "object-store.h"
|
||||
#include "replace-object.h"
|
||||
#include "refs.h"
|
||||
#include "repository.h"
|
||||
#include "commit.h"
|
||||
|
||||
/*
|
||||
* An array of replacements. The array is kept sorted by the original
|
||||
* sha1.
|
||||
*/
|
||||
static struct replace_object {
|
||||
struct object_id original;
|
||||
struct object_id replacement;
|
||||
} **replace_object;
|
||||
|
||||
static int replace_object_alloc, replace_object_nr;
|
||||
|
||||
static const unsigned char *replace_sha1_access(size_t index, void *table)
|
||||
{
|
||||
struct replace_object **replace = table;
|
||||
return replace[index]->original.hash;
|
||||
}
|
||||
|
||||
static int replace_object_pos(const unsigned char *sha1)
|
||||
{
|
||||
return sha1_pos(sha1, replace_object, replace_object_nr,
|
||||
replace_sha1_access);
|
||||
}
|
||||
|
||||
static int register_replace_object(struct replace_object *replace,
|
||||
int ignore_dups)
|
||||
{
|
||||
int pos = replace_object_pos(replace->original.hash);
|
||||
|
||||
if (0 <= pos) {
|
||||
if (ignore_dups)
|
||||
free(replace);
|
||||
else {
|
||||
free(replace_object[pos]);
|
||||
replace_object[pos] = replace;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
pos = -pos - 1;
|
||||
ALLOC_GROW(replace_object, replace_object_nr + 1, replace_object_alloc);
|
||||
replace_object_nr++;
|
||||
if (pos < replace_object_nr)
|
||||
MOVE_ARRAY(replace_object + pos + 1, replace_object + pos,
|
||||
replace_object_nr - pos - 1);
|
||||
replace_object[pos] = replace;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int register_replace_ref(const char *refname,
|
||||
const struct object_id *oid,
|
||||
int flag, void *cb_data)
|
||||
|
@ -59,7 +15,7 @@ static int register_replace_ref(const char *refname,
|
|||
const char *hash = slash ? slash + 1 : refname;
|
||||
struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
|
||||
|
||||
if (get_oid_hex(hash, &repl_obj->original)) {
|
||||
if (get_oid_hex(hash, &repl_obj->original.oid)) {
|
||||
free(repl_obj);
|
||||
warning("bad replace ref name: %s", refname);
|
||||
return 0;
|
||||
|
@ -69,23 +25,22 @@ static int register_replace_ref(const char *refname,
|
|||
oidcpy(&repl_obj->replacement, oid);
|
||||
|
||||
/* Register new object */
|
||||
if (register_replace_object(repl_obj, 1))
|
||||
if (oidmap_put(the_repository->objects->replace_map, repl_obj))
|
||||
die("duplicate replace ref: %s", refname);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void prepare_replace_object(void)
|
||||
static void prepare_replace_object(struct repository *r)
|
||||
{
|
||||
static int replace_object_prepared;
|
||||
|
||||
if (replace_object_prepared)
|
||||
if (r->objects->replace_map)
|
||||
return;
|
||||
|
||||
for_each_replace_ref(register_replace_ref, NULL);
|
||||
replace_object_prepared = 1;
|
||||
if (!replace_object_nr)
|
||||
check_replace_refs = 0;
|
||||
r->objects->replace_map =
|
||||
xmalloc(sizeof(*the_repository->objects->replace_map));
|
||||
oidmap_init(r->objects->replace_map, 0);
|
||||
|
||||
for_each_replace_ref(r, register_replace_ref, NULL);
|
||||
}
|
||||
|
||||
/* We allow "recursive" replacement. Only within reason, though */
|
||||
|
@ -98,23 +53,21 @@ static void prepare_replace_object(void)
|
|||
* permanently-allocated value. This function always respects replace
|
||||
* references, regardless of the value of check_replace_refs.
|
||||
*/
|
||||
const struct object_id *do_lookup_replace_object(const struct object_id *oid)
|
||||
const struct object_id *do_lookup_replace_object(struct repository *r,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
int pos, depth = MAXREPLACEDEPTH;
|
||||
int depth = MAXREPLACEDEPTH;
|
||||
const struct object_id *cur = oid;
|
||||
|
||||
prepare_replace_object();
|
||||
prepare_replace_object(r);
|
||||
|
||||
/* Try to recursively replace the object */
|
||||
do {
|
||||
if (--depth < 0)
|
||||
die("replace depth too high for object %s",
|
||||
oid_to_hex(oid));
|
||||
|
||||
pos = replace_object_pos(cur->hash);
|
||||
if (0 <= pos)
|
||||
cur = &replace_object[pos]->replacement;
|
||||
} while (0 <= pos);
|
||||
|
||||
return cur;
|
||||
while (depth-- > 0) {
|
||||
struct replace_object *repl_obj =
|
||||
oidmap_get(r->objects->replace_map, cur);
|
||||
if (!repl_obj)
|
||||
return cur;
|
||||
cur = &repl_obj->replacement;
|
||||
}
|
||||
die("replace depth too high for object %s", oid_to_hex(oid));
|
||||
}
|
||||
|
|
36
replace-object.h
Normal file
36
replace-object.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef REPLACE_OBJECT_H
|
||||
#define REPLACE_OBJECT_H
|
||||
|
||||
#include "oidmap.h"
|
||||
#include "repository.h"
|
||||
#include "object-store.h"
|
||||
|
||||
struct replace_object {
|
||||
struct oidmap_entry original;
|
||||
struct object_id replacement;
|
||||
};
|
||||
|
||||
/*
|
||||
* This internal function is only declared here for the benefit of
|
||||
* lookup_replace_object(). Please do not call it directly.
|
||||
*/
|
||||
extern const struct object_id *do_lookup_replace_object(struct repository *r,
|
||||
const struct object_id *oid);
|
||||
|
||||
/*
|
||||
* If object sha1 should be replaced, return the replacement object's
|
||||
* name (replaced recursively, if necessary). The return value is
|
||||
* either sha1 or a pointer to a permanently-allocated value. When
|
||||
* object replacement is suppressed, always return sha1.
|
||||
*/
|
||||
static inline const struct object_id *lookup_replace_object(struct repository *r,
|
||||
const struct object_id *oid)
|
||||
{
|
||||
if (!check_replace_refs ||
|
||||
(r->objects->replace_map &&
|
||||
r->objects->replace_map->map.tablesize == 0))
|
||||
return oid;
|
||||
return do_lookup_replace_object(r, oid);
|
||||
}
|
||||
|
||||
#endif /* REPLACE_OBJECT_H */
|
|
@ -26,6 +26,9 @@ struct repository {
|
|||
*/
|
||||
struct raw_object_store *objects;
|
||||
|
||||
/* The store in which the refs are held. */
|
||||
struct ref_store *refs;
|
||||
|
||||
/*
|
||||
* Path to the repository's graft file.
|
||||
* Cannot be NULL after initialization.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "diff.h"
|
||||
#include "refs.h"
|
||||
#include "revision.h"
|
||||
#include "repository.h"
|
||||
#include "graph.h"
|
||||
#include "grep.h"
|
||||
#include "reflog-walk.h"
|
||||
|
@ -1285,7 +1286,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
|
|||
|
||||
cb.all_revs = revs;
|
||||
cb.all_flags = flags;
|
||||
cb.refs = get_main_ref_store();
|
||||
cb.refs = get_main_ref_store(the_repository);
|
||||
for_each_reflog(handle_one_reflog, &cb);
|
||||
|
||||
if (!revs->single_worktree)
|
||||
|
@ -2176,7 +2177,7 @@ static int handle_revision_pseudo_opt(const char *submodule,
|
|||
die("BUG: --single-worktree cannot be used together with submodule");
|
||||
refs = get_submodule_ref_store(submodule);
|
||||
} else
|
||||
refs = get_main_ref_store();
|
||||
refs = get_main_ref_store(the_repository);
|
||||
|
||||
/*
|
||||
* NOTE!
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "sha1-lookup.h"
|
||||
#include "bulk-checkin.h"
|
||||
#include "repository.h"
|
||||
#include "replace-object.h"
|
||||
#include "streaming.h"
|
||||
#include "dir.h"
|
||||
#include "list.h"
|
||||
|
@ -1239,7 +1240,7 @@ int oid_object_info_extended(const struct object_id *oid, struct object_info *oi
|
|||
int already_retried = 0;
|
||||
|
||||
if (flags & OBJECT_INFO_LOOKUP_REPLACE)
|
||||
real = lookup_replace_object(oid);
|
||||
real = lookup_replace_object(the_repository, oid);
|
||||
|
||||
if (is_null_oid(real))
|
||||
return -1;
|
||||
|
@ -1383,8 +1384,8 @@ void *read_object_file_extended(const struct object_id *oid,
|
|||
const struct packed_git *p;
|
||||
const char *path;
|
||||
struct stat st;
|
||||
const struct object_id *repl = lookup_replace ? lookup_replace_object(oid)
|
||||
: oid;
|
||||
const struct object_id *repl = lookup_replace ?
|
||||
lookup_replace_object(the_repository, oid) : oid;
|
||||
|
||||
errno = 0;
|
||||
data = read_object(repl->hash, type, size);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "streaming.h"
|
||||
#include "repository.h"
|
||||
#include "object-store.h"
|
||||
#include "replace-object.h"
|
||||
#include "packfile.h"
|
||||
|
||||
enum input_source {
|
||||
|
@ -139,7 +140,7 @@ struct git_istream *open_istream(const struct object_id *oid,
|
|||
{
|
||||
struct git_istream *st;
|
||||
struct object_info oi = OBJECT_INFO_INIT;
|
||||
const struct object_id *real = lookup_replace_object(oid);
|
||||
const struct object_id *real = lookup_replace_object(the_repository, oid);
|
||||
enum input_source src = istream_source(real, type, &oi);
|
||||
|
||||
if (src < 0)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "refs.h"
|
||||
#include "worktree.h"
|
||||
#include "object-store.h"
|
||||
#include "repository.h"
|
||||
|
||||
static const char *notnull(const char *arg, const char *name)
|
||||
{
|
||||
|
@ -23,7 +24,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
|
|||
if (!argv[0]) {
|
||||
die("ref store required");
|
||||
} else if (!strcmp(argv[0], "main")) {
|
||||
*refs = get_main_ref_store();
|
||||
*refs = get_main_ref_store(the_repository);
|
||||
} else if (skip_prefix(argv[0], "submodule:", &gitdir)) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
int ret;
|
||||
|
|
Loading…
Reference in a new issue