Merge branch 'sb/more-repo-in-api'

The in-core repository instances are passed through more codepaths.

* sb/more-repo-in-api: (23 commits)
  t/helper/test-repository: celebrate independence from the_repository
  path.h: make REPO_GIT_PATH_FUNC repository agnostic
  commit: prepare free_commit_buffer and release_commit_memory for any repo
  commit-graph: convert remaining functions to handle any repo
  submodule: don't add submodule as odb for push
  submodule: use submodule repos for object lookup
  pretty: prepare format_commit_message to handle arbitrary repositories
  commit: prepare logmsg_reencode to handle arbitrary repositories
  commit: prepare repo_unuse_commit_buffer to handle any repo
  commit: prepare get_commit_buffer to handle any repo
  commit-reach: prepare in_merge_bases[_many] to handle any repo
  commit-reach: prepare get_merge_bases to handle any repo
  commit-reach.c: allow get_merge_bases_many_0 to handle any repo
  commit-reach.c: allow remove_redundant to handle any repo
  commit-reach.c: allow merge_bases_many to handle any repo
  commit-reach.c: allow paint_down_to_common to handle any repo
  commit: allow parse_commit* to handle any repo
  object: parse_object to honor its repository argument
  object-store: prepare has_{sha1, object}_file to handle any repo
  object-store: prepare read_object_file to deal with any repo
  ...
This commit is contained in:
Junio C Hamano 2019-02-05 14:26:09 -08:00
commit b99a579f8e
20 changed files with 452 additions and 150 deletions

View File

@ -401,7 +401,8 @@ out:
if (obj->type == OBJ_TREE)
free_tree_buffer((struct tree *)obj);
if (obj->type == OBJ_COMMIT)
free_commit_buffer((struct commit *)obj);
free_commit_buffer(the_repository->parsed_objects,
(struct commit *)obj);
return err;
}

View File

@ -397,7 +397,8 @@ static int cmd_log_walk(struct rev_info *rev)
* We may show a given commit multiple times when
* walking the reflogs.
*/
free_commit_buffer(commit);
free_commit_buffer(the_repository->parsed_objects,
commit);
free_commit_list(commit->parents);
commit->parents = NULL;
}
@ -1940,7 +1941,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
die(_("Failed to create output files"));
shown = log_tree_commit(&rev, commit);
free_commit_buffer(commit);
free_commit_buffer(the_repository->parsed_objects,
commit);
/* We put one extra blank line between formatted
* patches and this flag is used by log-tree code

View File

@ -197,7 +197,8 @@ static void finish_commit(struct commit *commit, void *data)
free_commit_list(commit->parents);
commit->parents = NULL;
}
free_commit_buffer(commit);
free_commit_buffer(the_repository->parsed_objects,
commit);
}
static inline void finish_object__ma(struct object *obj)

View File

@ -288,7 +288,8 @@ static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t
g->chunk_oid_lookup, g->hash_len, pos);
}
static struct commit_list **insert_parent_or_die(struct commit_graph *g,
static struct commit_list **insert_parent_or_die(struct repository *r,
struct commit_graph *g,
uint64_t pos,
struct commit_list **pptr)
{
@ -299,7 +300,7 @@ static struct commit_list **insert_parent_or_die(struct commit_graph *g,
die("invalid parent position %"PRIu64, pos);
hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * pos);
c = lookup_commit(the_repository, &oid);
c = lookup_commit(r, &oid);
if (!c)
die(_("could not find commit %s"), oid_to_hex(&oid));
c->graph_pos = pos;
@ -313,7 +314,9 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
item->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
}
static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uint32_t pos)
static int fill_commit_in_graph(struct repository *r,
struct commit *item,
struct commit_graph *g, uint32_t pos)
{
uint32_t edge_value;
uint32_t *parent_data_ptr;
@ -337,13 +340,13 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin
edge_value = get_be32(commit_data + g->hash_len);
if (edge_value == GRAPH_PARENT_NONE)
return 1;
pptr = insert_parent_or_die(g, edge_value, pptr);
pptr = insert_parent_or_die(r, g, edge_value, pptr);
edge_value = get_be32(commit_data + g->hash_len + 4);
if (edge_value == GRAPH_PARENT_NONE)
return 1;
if (!(edge_value & GRAPH_OCTOPUS_EDGES_NEEDED)) {
pptr = insert_parent_or_die(g, edge_value, pptr);
pptr = insert_parent_or_die(r, g, edge_value, pptr);
return 1;
}
@ -351,7 +354,7 @@ static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uin
4 * (uint64_t)(edge_value & GRAPH_EDGE_LAST_MASK));
do {
edge_value = get_be32(parent_data_ptr);
pptr = insert_parent_or_die(g,
pptr = insert_parent_or_die(r, g,
edge_value & GRAPH_EDGE_LAST_MASK,
pptr);
parent_data_ptr++;
@ -370,7 +373,9 @@ static int find_commit_in_graph(struct commit *item, struct commit_graph *g, uin
}
}
static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item)
static int parse_commit_in_graph_one(struct repository *r,
struct commit_graph *g,
struct commit *item)
{
uint32_t pos;
@ -378,7 +383,7 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
return 1;
if (find_commit_in_graph(item, g, &pos))
return fill_commit_in_graph(item, g, pos);
return fill_commit_in_graph(r, item, g, pos);
return 0;
}
@ -387,7 +392,7 @@ int parse_commit_in_graph(struct repository *r, struct commit *item)
{
if (!prepare_commit_graph(r))
return 0;
return parse_commit_in_graph_one(r->objects->commit_graph, item);
return parse_commit_in_graph_one(r, r->objects->commit_graph, item);
}
void load_commit_graph_info(struct repository *r, struct commit *item)
@ -399,19 +404,22 @@ void load_commit_graph_info(struct repository *r, struct commit *item)
fill_commit_graph_info(item, r->objects->commit_graph, pos);
}
static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)
static struct tree *load_tree_for_commit(struct repository *r,
struct commit_graph *g,
struct commit *c)
{
struct object_id oid;
const unsigned char *commit_data = g->chunk_commit_data +
GRAPH_DATA_WIDTH * (c->graph_pos);
hashcpy(oid.hash, commit_data);
c->maybe_tree = lookup_tree(the_repository, &oid);
c->maybe_tree = lookup_tree(r, &oid);
return c->maybe_tree;
}
static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
static struct tree *get_commit_tree_in_graph_one(struct repository *r,
struct commit_graph *g,
const struct commit *c)
{
if (c->maybe_tree)
@ -419,12 +427,12 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
if (c->graph_pos == COMMIT_NOT_FROM_GRAPH)
BUG("get_commit_tree_in_graph_one called from non-commit-graph commit");
return load_tree_for_commit(g, (struct commit *)c);
return load_tree_for_commit(r, g, (struct commit *)c);
}
struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
{
return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
return get_commit_tree_in_graph_one(r, r->objects->commit_graph, c);
}
static void write_graph_chunk_fanout(struct hashfile *f,
@ -1035,7 +1043,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
}
graph_commit = lookup_commit(r, &cur_oid);
if (!parse_commit_in_graph_one(g, graph_commit))
if (!parse_commit_in_graph_one(r, g, graph_commit))
graph_report("failed to parse %s from commit-graph",
oid_to_hex(&cur_oid));
}
@ -1071,7 +1079,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g)
continue;
}
if (!oideq(&get_commit_tree_in_graph_one(g, graph_commit)->object.oid,
if (!oideq(&get_commit_tree_in_graph_one(r, g, graph_commit)->object.oid,
get_commit_tree_oid(odb_commit)))
graph_report("root tree OID for commit %s in commit-graph is %s != %s",
oid_to_hex(&cur_oid),

View File

@ -30,7 +30,8 @@ static int queue_has_nonstale(struct prio_queue *queue)
}
/* all input commits in one and twos[] must have been parsed! */
static struct commit_list *paint_down_to_common(struct commit *one, int n,
static struct commit_list *paint_down_to_common(struct repository *r,
struct commit *one, int n,
struct commit **twos,
int min_generation)
{
@ -83,7 +84,7 @@ static struct commit_list *paint_down_to_common(struct commit *one, int n,
parents = parents->next;
if ((p->object.flags & flags) == flags)
continue;
if (parse_commit(p))
if (repo_parse_commit(r, p))
return NULL;
p->object.flags |= flags;
prio_queue_put(&queue, p);
@ -94,7 +95,9 @@ static struct commit_list *paint_down_to_common(struct commit *one, int n,
return result;
}
static struct commit_list *merge_bases_many(struct commit *one, int n, struct commit **twos)
static struct commit_list *merge_bases_many(struct repository *r,
struct commit *one, int n,
struct commit **twos)
{
struct commit_list *list = NULL;
struct commit_list *result = NULL;
@ -109,14 +112,14 @@ static struct commit_list *merge_bases_many(struct commit *one, int n, struct co
return commit_list_insert(one, &result);
}
if (parse_commit(one))
if (repo_parse_commit(r, one))
return NULL;
for (i = 0; i < n; i++) {
if (parse_commit(twos[i]))
if (repo_parse_commit(r, twos[i]))
return NULL;
}
list = paint_down_to_common(one, n, twos, 0);
list = paint_down_to_common(r, one, n, twos, 0);
while (list) {
struct commit *commit = pop_commit(&list);
@ -153,7 +156,7 @@ struct commit_list *get_octopus_merge_bases(struct commit_list *in)
return ret;
}
static int remove_redundant(struct commit **array, int cnt)
static int remove_redundant(struct repository *r, struct commit **array, int cnt)
{
/*
* Some commit in the array may be an ancestor of
@ -171,7 +174,7 @@ static int remove_redundant(struct commit **array, int cnt)
ALLOC_ARRAY(filled_index, cnt - 1);
for (i = 0; i < cnt; i++)
parse_commit(array[i]);
repo_parse_commit(r, array[i]);
for (i = 0; i < cnt; i++) {
struct commit_list *common;
uint32_t min_generation = array[i]->generation;
@ -187,8 +190,8 @@ static int remove_redundant(struct commit **array, int cnt)
if (array[j]->generation < min_generation)
min_generation = array[j]->generation;
}
common = paint_down_to_common(array[i], filled, work,
min_generation);
common = paint_down_to_common(r, array[i], filled,
work, min_generation);
if (array[i]->object.flags & PARENT2)
redundant[i] = 1;
for (j = 0; j < filled; j++)
@ -213,7 +216,8 @@ static int remove_redundant(struct commit **array, int cnt)
return filled;
}
static struct commit_list *get_merge_bases_many_0(struct commit *one,
static struct commit_list *get_merge_bases_many_0(struct repository *r,
struct commit *one,
int n,
struct commit **twos,
int cleanup)
@ -223,7 +227,7 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,
struct commit_list *result;
int cnt, i;
result = merge_bases_many(one, n, twos);
result = merge_bases_many(r, one, n, twos);
for (i = 0; i < n; i++) {
if (one == twos[i])
return result;
@ -246,7 +250,7 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,
clear_commit_marks(one, all_flags);
clear_commit_marks_many(n, twos, all_flags);
cnt = remove_redundant(rslt, cnt);
cnt = remove_redundant(r, rslt, cnt);
result = NULL;
for (i = 0; i < cnt; i++)
commit_list_insert_by_date(rslt[i], &result);
@ -254,23 +258,27 @@ static struct commit_list *get_merge_bases_many_0(struct commit *one,
return result;
}
struct commit_list *get_merge_bases_many(struct commit *one,
int n,
struct commit **twos)
struct commit_list *repo_get_merge_bases_many(struct repository *r,
struct commit *one,
int n,
struct commit **twos)
{
return get_merge_bases_many_0(one, n, twos, 1);
return get_merge_bases_many_0(r, one, n, twos, 1);
}
struct commit_list *get_merge_bases_many_dirty(struct commit *one,
int n,
struct commit **twos)
struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
struct commit *one,
int n,
struct commit **twos)
{
return get_merge_bases_many_0(one, n, twos, 0);
return get_merge_bases_many_0(r, one, n, twos, 0);
}
struct commit_list *get_merge_bases(struct commit *one, struct commit *two)
struct commit_list *repo_get_merge_bases(struct repository *r,
struct commit *one,
struct commit *two)
{
return get_merge_bases_many_0(one, 1, &two, 1);
return get_merge_bases_many_0(r, one, 1, &two, 1);
}
/*
@ -304,16 +312,17 @@ int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
/*
* Is "commit" an ancestor of one of the "references"?
*/
int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference)
int repo_in_merge_bases_many(struct repository *r, struct commit *commit,
int nr_reference, struct commit **reference)
{
struct commit_list *bases;
int ret = 0, i;
uint32_t min_generation = GENERATION_NUMBER_INFINITY;
if (parse_commit(commit))
if (repo_parse_commit(r, commit))
return ret;
for (i = 0; i < nr_reference; i++) {
if (parse_commit(reference[i]))
if (repo_parse_commit(r, reference[i]))
return ret;
if (reference[i]->generation < min_generation)
min_generation = reference[i]->generation;
@ -322,7 +331,9 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *
if (commit->generation > min_generation)
return ret;
bases = paint_down_to_common(commit, nr_reference, reference, commit->generation);
bases = paint_down_to_common(r, commit,
nr_reference, reference,
commit->generation);
if (commit->object.flags & PARENT2)
ret = 1;
clear_commit_marks(commit, all_flags);
@ -334,9 +345,11 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *
/*
* Is "commit" an ancestor of (i.e. reachable from) the "reference"?
*/
int in_merge_bases(struct commit *commit, struct commit *reference)
int repo_in_merge_bases(struct repository *r,
struct commit *commit,
struct commit *reference)
{
return in_merge_bases_many(commit, 1, &reference);
return repo_in_merge_bases_many(r, commit, 1, &reference);
}
struct commit_list *reduce_heads(struct commit_list *heads)
@ -365,7 +378,7 @@ struct commit_list *reduce_heads(struct commit_list *heads)
p->item->object.flags &= ~STALE;
}
}
num_head = remove_redundant(array, num_head);
num_head = remove_redundant(the_repository, array, num_head);
for (i = 0; i < num_head; i++)
tail = &commit_list_insert(array[i], tail)->next;
free(array);

View File

@ -9,21 +9,35 @@ struct ref_filter;
struct object_id;
struct object_array;
struct commit_list *get_merge_bases_many(struct commit *one,
int n,
struct commit **twos);
struct commit_list *get_merge_bases_many_dirty(struct commit *one,
int n,
struct commit **twos);
struct commit_list *get_merge_bases(struct commit *one, struct commit *two);
struct commit_list *repo_get_merge_bases(struct repository *r,
struct commit *rev1,
struct commit *rev2);
struct commit_list *repo_get_merge_bases_many(struct repository *r,
struct commit *one, int n,
struct commit **twos);
/* To be used only when object flags after this call no longer matter */
struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
struct commit *one, int n,
struct commit **twos);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define get_merge_bases(r1, r2) repo_get_merge_bases(the_repository, r1, r2)
#define get_merge_bases_many(one, n, two) repo_get_merge_bases_many(the_repository, one, n, two)
#define get_merge_bases_many_dirty(one, n, twos) repo_get_merge_bases_many_dirty(the_repository, one, n, twos)
#endif
struct commit_list *get_octopus_merge_bases(struct commit_list *in);
/* To be used only when object flags after this call no longer matter */
struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);
int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
int in_merge_bases(struct commit *commit, struct commit *reference);
int repo_in_merge_bases(struct repository *r,
struct commit *commit,
struct commit *reference);
int repo_in_merge_bases_many(struct repository *r,
struct commit *commit,
int nr_reference, struct commit **reference);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define in_merge_bases(c1, c2) repo_in_merge_bases(the_repository, c1, c2)
#define in_merge_bases_many(c1, n, cs) repo_in_merge_bases_many(the_repository, c1, n, cs)
#endif
/*
* Takes a list of commits and returns a new list where those

View File

@ -299,13 +299,15 @@ const void *get_cached_commit_buffer(struct repository *r, const struct commit *
return v->buffer;
}
const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
const void *repo_get_commit_buffer(struct repository *r,
const struct commit *commit,
unsigned long *sizep)
{
const void *ret = get_cached_commit_buffer(the_repository, commit, sizep);
const void *ret = get_cached_commit_buffer(r, commit, sizep);
if (!ret) {
enum object_type type;
unsigned long size;
ret = read_object_file(&commit->object.oid, &type, &size);
ret = repo_read_object_file(r, &commit->object.oid, &type, &size);
if (!ret)
die("cannot read commit object %s",
oid_to_hex(&commit->object.oid));
@ -318,18 +320,20 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
return ret;
}
void unuse_commit_buffer(const struct commit *commit, const void *buffer)
void repo_unuse_commit_buffer(struct repository *r,
const struct commit *commit,
const void *buffer)
{
struct commit_buffer *v = buffer_slab_peek(
the_repository->parsed_objects->buffer_slab, commit);
r->parsed_objects->buffer_slab, commit);
if (!(v && v->buffer == buffer))
free((void *)buffer);
}
void free_commit_buffer(struct commit *commit)
void free_commit_buffer(struct parsed_object_pool *pool, struct commit *commit)
{
struct commit_buffer *v = buffer_slab_peek(
the_repository->parsed_objects->buffer_slab, commit);
pool->buffer_slab, commit);
if (v) {
FREE_AND_NULL(v->buffer);
v->size = 0;
@ -352,13 +356,12 @@ struct object_id *get_commit_tree_oid(const struct commit *commit)
return &get_commit_tree(commit)->object.oid;
}
void release_commit_memory(struct commit *c)
void release_commit_memory(struct parsed_object_pool *pool, struct commit *c)
{
c->maybe_tree = NULL;
c->index = 0;
free_commit_buffer(c);
free_commit_buffer(pool, c);
free_commit_list(c->parents);
/* TODO: what about commit->util? */
c->object.parsed = 0;
}
@ -445,7 +448,10 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b
return 0;
}
int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_commit_graph)
int repo_parse_commit_internal(struct repository *r,
struct commit *item,
int quiet_on_missing,
int use_commit_graph)
{
enum object_type type;
void *buffer;
@ -456,9 +462,9 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com
return -1;
if (item->object.parsed)
return 0;
if (use_commit_graph && parse_commit_in_graph(the_repository, item))
if (use_commit_graph && parse_commit_in_graph(r, item))
return 0;
buffer = read_object_file(&item->object.oid, &type, &size);
buffer = repo_read_object_file(r, &item->object.oid, &type, &size);
if (!buffer)
return quiet_on_missing ? -1 :
error("Could not read %s",
@ -469,18 +475,19 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com
oid_to_hex(&item->object.oid));
}
ret = parse_commit_buffer(the_repository, item, buffer, size, 0);
ret = parse_commit_buffer(r, item, buffer, size, 0);
if (save_commit_buffer && !ret) {
set_commit_buffer(the_repository, item, buffer, size);
set_commit_buffer(r, item, buffer, size);
return 0;
}
free(buffer);
return ret;
}
int parse_commit_gently(struct commit *item, int quiet_on_missing)
int repo_parse_commit_gently(struct repository *r,
struct commit *item, int quiet_on_missing)
{
return parse_commit_internal(item, quiet_on_missing, 1);
return repo_parse_commit_internal(r, item, quiet_on_missing, 1);
}
void parse_commit_or_die(struct commit *item)

View File

@ -80,12 +80,21 @@ struct commit *lookup_commit_reference_by_name(const char *name);
struct commit *lookup_commit_or_die(const struct object_id *oid, const char *ref_name);
int parse_commit_buffer(struct repository *r, struct commit *item, const void *buffer, unsigned long size, int check_graph);
int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_commit_graph);
int parse_commit_gently(struct commit *item, int quiet_on_missing);
static inline int parse_commit(struct commit *item)
int repo_parse_commit_internal(struct repository *r, struct commit *item,
int quiet_on_missing, int use_commit_graph);
int repo_parse_commit_gently(struct repository *r,
struct commit *item,
int quiet_on_missing);
static inline int repo_parse_commit(struct repository *r, struct commit *item)
{
return parse_commit_gently(item, 0);
return repo_parse_commit_gently(r, item, 0);
}
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define parse_commit_internal(item, quiet, use) repo_parse_commit_internal(the_repository, item, quiet, use)
#define parse_commit_gently(item, quiet) repo_parse_commit_gently(the_repository, item, quiet)
#define parse_commit(item) repo_parse_commit(the_repository, item)
#endif
void parse_commit_or_die(struct commit *item);
struct buffer_slab;
@ -109,7 +118,12 @@ const void *get_cached_commit_buffer(struct repository *, const struct commit *,
* from disk. The resulting memory should not be modified, and must be given
* to unuse_commit_buffer when the caller is done.
*/
const void *get_commit_buffer(const struct commit *, unsigned long *size);
const void *repo_get_commit_buffer(struct repository *r,
const struct commit *,
unsigned long *size);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define get_commit_buffer(c, s) repo_get_commit_buffer(the_repository, c, s)
#endif
/*
* Tell the commit subsytem that we are done with a particular commit buffer.
@ -117,12 +131,17 @@ const void *get_commit_buffer(const struct commit *, unsigned long *size);
* from an earlier call to get_commit_buffer. The buffer may or may not be
* freed by this call; callers should not access the memory afterwards.
*/
void unuse_commit_buffer(const struct commit *, const void *buffer);
void repo_unuse_commit_buffer(struct repository *r,
const struct commit *,
const void *buffer);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define unuse_commit_buffer(c, b) repo_unuse_commit_buffer(the_repository, c, b)
#endif
/*
* Free any cached object buffer associated with the commit.
*/
void free_commit_buffer(struct commit *);
void free_commit_buffer(struct parsed_object_pool *pool, struct commit *);
struct tree *get_commit_tree(const struct commit *);
struct object_id *get_commit_tree_oid(const struct commit *);
@ -131,7 +150,7 @@ struct object_id *get_commit_tree_oid(const struct commit *);
* Release memory related to a commit, including the parent list and
* any cached object buffer.
*/
void release_commit_memory(struct commit *c);
void release_commit_memory(struct parsed_object_pool *pool, struct commit *c);
/*
* Disassociate any cached object buffer from the commit, but do not free it.
@ -162,6 +181,14 @@ extern int has_non_ascii(const char *text);
extern const char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding);
const char *repo_logmsg_reencode(struct repository *r,
const struct commit *commit,
char **commit_encoding,
const char *output_encoding);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define logmsg_reencode(c, enc, out) repo_logmsg_reencode(the_repository, c, enc, out)
#endif
extern const char *skip_blank_lines(const char *msg);
/** Removes the first commit from a list sorted by date, and adds all

View File

@ -0,0 +1,144 @@
// This file is used for the ongoing refactoring of
// bringing the index or repository struct in all of
// our code base.
@@
expression E;
expression F;
expression G;
@@
- read_object_file(
+ repo_read_object_file(the_repository,
E, F, G)
@@
expression E;
@@
- has_sha1_file(
+ repo_has_sha1_file(the_repository,
E)
@@
expression E;
expression F;
@@
- has_sha1_file_with_flags(
+ repo_has_sha1_file_with_flags(the_repository,
E)
@@
expression E;
@@
- has_object_file(
+ repo_has_object_file(the_repository,
E)
@@
expression E;
expression F;
@@
- has_object_file_with_flags(
+ repo_has_object_file_with_flags(the_repository,
E)
@@
expression E;
expression F;
expression G;
@@
- parse_commit_internal(
+ repo_parse_commit_internal(the_repository,
E, F, G)
@@
expression E;
expression F;
@@
- parse_commit_gently(
+ repo_parse_commit_gently(the_repository,
E, F)
@@
expression E;
@@
- parse_commit(
+ repo_parse_commit(the_repository,
E)
@@
expression E;
expression F;
@@
- get_merge_bases(
+ repo_get_merge_bases(the_repository,
E, F);
@@
expression E;
expression F;
expression G;
@@
- get_merge_bases_many(
+ repo_get_merge_bases_many(the_repository,
E, F, G);
@@
expression E;
expression F;
expression G;
@@
- get_merge_bases_many_dirty(
+ repo_get_merge_bases_many_dirty(the_repository,
E, F, G);
@@
expression E;
expression F;
@@
- in_merge_bases(
+ repo_in_merge_bases(the_repository,
E, F);
@@
expression E;
expression F;
expression G;
@@
- in_merge_bases_many(
+ repo_in_merge_bases_many(the_repository,
E, F, G);
@@
expression E;
expression F;
@@
- get_commit_buffer(
+ repo_get_commit_buffer(the_repository,
E, F);
@@
expression E;
expression F;
@@
- unuse_commit_buffer(
+ repo_unuse_commit_buffer(the_repository,
E, F);
@@
expression E;
expression F;
expression G;
@@
- logmsg_reencode(
+ repo_logmsg_reencode(the_repository,
E, F, G);
@@
expression E;
expression F;
expression G;
expression H;
@@
- format_commit_message(
+ repo_format_commit_message(the_repository,
E, F, G, H);

View File

@ -160,13 +160,20 @@ const char *loose_object_path(struct repository *r, struct strbuf *buf, const un
void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
extern void *read_object_file_extended(const struct object_id *oid,
extern void *read_object_file_extended(struct repository *r,
const struct object_id *oid,
enum object_type *type,
unsigned long *size, int lookup_replace);
static inline void *read_object_file(const struct object_id *oid, enum object_type *type, unsigned long *size)
static inline void *repo_read_object_file(struct repository *r,
const struct object_id *oid,
enum object_type *type,
unsigned long *size)
{
return read_object_file_extended(oid, type, size, 1);
return read_object_file_extended(r, oid, type, size, 1);
}
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define read_object_file(oid, type, size) repo_read_object_file(the_repository, oid, type, size)
#endif
/* Read and unpack an object file into memory, write memory to an object file */
int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
@ -204,15 +211,27 @@ int read_loose_object(const char *path,
* object_info. OBJECT_INFO_SKIP_CACHED is automatically set; pass
* nonzero flags to also set other flags.
*/
extern int has_sha1_file_with_flags(const unsigned char *sha1, int flags);
static inline int has_sha1_file(const unsigned char *sha1)
int repo_has_sha1_file_with_flags(struct repository *r,
const unsigned char *sha1, int flags);
static inline int repo_has_sha1_file(struct repository *r,
const unsigned char *sha1)
{
return has_sha1_file_with_flags(sha1, 0);
return repo_has_sha1_file_with_flags(r, sha1, 0);
}
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define has_sha1_file_with_flags(sha1, flags) repo_has_sha1_file_with_flags(the_repository, sha1, flags)
#define has_sha1_file(sha1) repo_has_sha1_file(the_repository, sha1)
#endif
/* Same as the above, except for struct object_id. */
extern int has_object_file(const struct object_id *oid);
extern int has_object_file_with_flags(const struct object_id *oid, int flags);
int repo_has_object_file(struct repository *r, const struct object_id *oid);
int repo_has_object_file_with_flags(struct repository *r,
const struct object_id *oid, int flags);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define has_object_file(oid) repo_has_object_file(the_repository, oid)
#define has_object_file_with_flags(oid, flags) repo_has_object_file_with_flags(the_repository, oid, flags)
#endif
/*
* Return true iff an alternate object database has a loose object

View File

@ -259,8 +259,8 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
if (obj && obj->parsed)
return obj;
if ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) ||
(!obj && has_object_file(oid) &&
if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
(!obj && repo_has_object_file(r, oid) &&
oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
if (check_object_signature(repl, NULL, 0, NULL) < 0) {
error(_("sha1 mismatch %s"), oid_to_hex(oid));
@ -270,7 +270,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid)
return lookup_object(r, oid->hash);
}
buffer = read_object_file(oid, &type, &size);
buffer = repo_read_object_file(r, oid, &type, &size);
if (buffer) {
if (check_object_signature(repl, buffer, size, type_name(type)) < 0) {
free(buffer);
@ -540,7 +540,7 @@ void parsed_object_pool_clear(struct parsed_object_pool *o)
if (obj->type == OBJ_TREE)
free_tree_buffer((struct tree*)obj);
else if (obj->type == OBJ_COMMIT)
release_commit_memory((struct commit*)obj);
release_commit_memory(o, (struct commit*)obj);
else if (obj->type == OBJ_TAG)
release_tag_memory((struct tag*)obj);
}

View File

@ -1148,12 +1148,13 @@ void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1)
p->num_bad_objects++;
}
const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
const struct packed_git *has_packed_and_bad(struct repository *r,
const unsigned char *sha1)
{
struct packed_git *p;
unsigned i;
for (p = the_repository->objects->packed_git; p; p = p->next)
for (p = r->objects->packed_git; p; p = p->next)
for (i = 0; i < p->num_bad_objects; i++)
if (hasheq(sha1,
p->bad_object_sha1 + the_hash_algo->rawsz * i))

View File

@ -146,7 +146,7 @@ extern int packed_object_info(struct repository *r,
off_t offset, struct object_info *);
extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);
extern const struct packed_git *has_packed_and_bad(struct repository *r, const unsigned char *sha1);
/*
* Iff a pack file in the given repository contains the object named by sha1,

2
path.h
View File

@ -165,7 +165,7 @@ extern void report_linked_checkout_garbage(void);
const char *git_path_##var(struct repository *r) \
{ \
if (!r->cached_paths.var) \
r->cached_paths.var = git_pathdup(filename); \
r->cached_paths.var = repo_git_path(r, filename); \
return r->cached_paths.var; \
}

View File

@ -595,14 +595,15 @@ static char *replace_encoding_header(char *buf, const char *encoding)
return strbuf_detach(&tmp, NULL);
}
const char *logmsg_reencode(const struct commit *commit,
char **commit_encoding,
const char *output_encoding)
const char *repo_logmsg_reencode(struct repository *r,
const struct commit *commit,
char **commit_encoding,
const char *output_encoding)
{
static const char *utf8 = "UTF-8";
const char *use_encoding;
char *encoding;
const char *msg = get_commit_buffer(commit, NULL);
const char *msg = repo_get_commit_buffer(r, commit, NULL);
char *out;
if (!output_encoding || !*output_encoding) {
@ -630,7 +631,7 @@ const char *logmsg_reencode(const struct commit *commit,
* the cached copy from get_commit_buffer, we need to duplicate it
* to avoid munging the cached copy.
*/
if (msg == get_cached_commit_buffer(the_repository, commit, NULL))
if (msg == get_cached_commit_buffer(r, commit, NULL))
out = xstrdup(msg);
else
out = (char *)msg;
@ -644,7 +645,7 @@ const char *logmsg_reencode(const struct commit *commit,
*/
out = reencode_string(msg, output_encoding, use_encoding);
if (out)
unuse_commit_buffer(commit, msg);
repo_unuse_commit_buffer(r, commit, msg);
}
/*
@ -1527,9 +1528,10 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w)
strbuf_release(&dummy);
}
void format_commit_message(const struct commit *commit,
const char *format, struct strbuf *sb,
const struct pretty_print_context *pretty_ctx)
void repo_format_commit_message(struct repository *r,
const struct commit *commit,
const char *format, struct strbuf *sb,
const struct pretty_print_context *pretty_ctx)
{
struct format_commit_context context;
const char *output_enc = pretty_ctx->output_encoding;
@ -1543,9 +1545,9 @@ void format_commit_message(const struct commit *commit,
* convert a commit message to UTF-8 first
* as far as 'format_commit_item' assumes it in UTF-8
*/
context.message = logmsg_reencode(commit,
&context.commit_encoding,
utf8);
context.message = repo_logmsg_reencode(r, commit,
&context.commit_encoding,
utf8);
strbuf_expand(sb, format, format_commit_item, &context);
rewrap_message_tail(sb, &context, 0, 0, 0);
@ -1569,7 +1571,7 @@ void format_commit_message(const struct commit *commit,
}
free(context.commit_encoding);
unuse_commit_buffer(commit, context.message);
repo_unuse_commit_buffer(r, commit, context.message);
}
static void pp_header(struct pretty_print_context *pp,

View File

@ -104,9 +104,14 @@ void pp_remainder(struct pretty_print_context *pp, const char **msg_p,
* Put the result to "sb".
* Please use this function for custom formats.
*/
void format_commit_message(const struct commit *commit,
void repo_format_commit_message(struct repository *r,
const struct commit *commit,
const char *format, struct strbuf *sb,
const struct pretty_print_context *context);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define format_commit_message(c, f, s, con) \
repo_format_commit_message(the_repository, c, f, s, con)
#endif
/*
* Parse given arguments from "arg", check it for correctness and

View File

@ -1421,7 +1421,9 @@ int oid_object_info(struct repository *r,
return type;
}
static void *read_object(const unsigned char *sha1, enum object_type *type,
static void *read_object(struct repository *r,
const unsigned char *sha1,
enum object_type *type,
unsigned long *size)
{
struct object_id oid;
@ -1433,7 +1435,7 @@ static void *read_object(const unsigned char *sha1, enum object_type *type,
hashcpy(oid.hash, sha1);
if (oid_object_info_extended(the_repository, &oid, &oi, 0) < 0)
if (oid_object_info_extended(r, &oid, &oi, 0) < 0)
return NULL;
return content;
}
@ -1461,7 +1463,8 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
* deal with them should arrange to call read_object() and give error
* messages themselves.
*/
void *read_object_file_extended(const struct object_id *oid,
void *read_object_file_extended(struct repository *r,
const struct object_id *oid,
enum object_type *type,
unsigned long *size,
int lookup_replace)
@ -1471,10 +1474,10 @@ void *read_object_file_extended(const struct object_id *oid,
const char *path;
struct stat st;
const struct object_id *repl = lookup_replace ?
lookup_replace_object(the_repository, oid) : oid;
lookup_replace_object(r, oid) : oid;
errno = 0;
data = read_object(repl->hash, type, size);
data = read_object(r, repl->hash, type, size);
if (data)
return data;
@ -1486,11 +1489,11 @@ 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(the_repository, repl->hash, &st, &path))
if (!stat_sha1_file(r, repl->hash, &st, &path))
die(_("loose object %s (stored in %s) is corrupt"),
oid_to_hex(repl), path);
if ((p = has_packed_and_bad(repl->hash)) != NULL)
if ((p = has_packed_and_bad(r, repl->hash)) != NULL)
die(_("packed object %s (stored in %s) is corrupt"),
oid_to_hex(repl), p->pack_name);
@ -1814,7 +1817,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
if (has_loose_object(oid))
return 0;
buf = read_object(oid->hash, &type, &len);
buf = read_object(the_repository, oid->hash, &type, &len);
if (!buf)
return error(_("cannot read sha1_file for %s"), oid_to_hex(oid));
hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
@ -1824,24 +1827,27 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
return ret;
}
int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
int repo_has_sha1_file_with_flags(struct repository *r,
const unsigned char *sha1, int flags)
{
struct object_id oid;
if (!startup_info->have_repository)
return 0;
hashcpy(oid.hash, sha1);
return oid_object_info_extended(the_repository, &oid, NULL,
return oid_object_info_extended(r, &oid, NULL,
flags | OBJECT_INFO_SKIP_CACHED) >= 0;
}
int has_object_file(const struct object_id *oid)
int repo_has_object_file(struct repository *r,
const struct object_id *oid)
{
return has_sha1_file(oid->hash);
return repo_has_sha1_file(r, oid->hash);
}
int has_object_file_with_flags(const struct object_id *oid, int flags)
int repo_has_object_file_with_flags(struct repository *r,
const struct object_id *oid, int flags)
{
return has_sha1_file_with_flags(oid->hash, flags);
return repo_has_sha1_file_with_flags(r, oid->hash, flags);
}
static void check_tree(const void *buf, size_t size)

View File

@ -499,7 +499,7 @@ static struct stream_vtbl incore_vtbl = {
static open_method_decl(incore)
{
st->u.incore.buf = read_object_file_extended(oid, type, &st->size, 0);
st->u.incore.buf = read_object_file_extended(the_repository, oid, type, &st->size, 0);
st->u.incore.read_ptr = 0;
st->vtbl = &incore_vtbl;

View File

@ -456,7 +456,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
return prepare_revision_walk(rev);
}
static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
{
static const char format[] = " %m %s";
struct strbuf sb = STRBUF_INIT;
@ -467,7 +467,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
ctx.date_mode = rev->date_mode;
ctx.output_encoding = get_log_output_encoding();
strbuf_setlen(&sb, 0);
format_commit_message(commit, format, &sb, &ctx);
repo_format_commit_message(r, commit, format, &sb,
&ctx);
strbuf_addch(&sb, '\n');
if (commit->object.flags & SYMMETRIC_LEFT)
diff_emit_submodule_del(o, sb.buf);
@ -500,14 +501,46 @@ static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
}
/* Helper function to display the submodule header line prior to the full
* summary output. If it can locate the submodule objects directory it will
* attempt to lookup both the left and right commits and put them into the
* left and right pointers.
/*
* Initialize a repository struct for a submodule based on the provided 'path'.
*
* Unlike repo_submodule_init, this tolerates submodules not present
* in .gitmodules. This function exists only to preserve historical behavior,
*
* Returns the repository struct on success,
* NULL when the submodule is not present.
*/
static void show_submodule_header(struct diff_options *o, const char *path,
static struct repository *open_submodule(const char *path)
{
struct strbuf sb = STRBUF_INIT;
struct repository *out = xmalloc(sizeof(*out));
if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
strbuf_release(&sb);
free(out);
return NULL;
}
/* Mark it as a submodule */
out->submodule_prefix = xstrdup(path);
strbuf_release(&sb);
return out;
}
/*
* Helper function to display the submodule header line prior to the full
* summary output.
*
* If it can locate the submodule git directory it will create a repository
* handle for the submodule and lookup both the left and right commits and
* put them into the left and right pointers.
*/
static void show_submodule_header(struct diff_options *o,
const char *path,
struct object_id *one, struct object_id *two,
unsigned dirty_submodule,
struct repository *sub,
struct commit **left, struct commit **right,
struct commit_list **merge_bases)
{
@ -526,7 +559,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
else if (is_null_oid(two))
message = "(submodule deleted)";
if (add_submodule_odb(path)) {
if (!sub) {
if (!message)
message = "(commits not present)";
goto output_header;
@ -536,8 +569,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
* Attempt to lookup the commit references, and determine if this is
* a fast forward or fast backwards update.
*/
*left = lookup_commit_reference(the_repository, one);
*right = lookup_commit_reference(the_repository, two);
*left = lookup_commit_reference(sub, one);
*right = lookup_commit_reference(sub, two);
/*
* Warn about missing commits in the submodule project, but only if
@ -547,7 +580,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
(!is_null_oid(two) && !*right))
message = "(commits not present)";
*merge_bases = get_merge_bases(*left, *right);
*merge_bases = repo_get_merge_bases(sub, *left, *right);
if (*merge_bases) {
if ((*merge_bases)->item == *left)
fast_forward = 1;
@ -581,16 +614,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
struct rev_info rev;
struct commit *left = NULL, *right = NULL;
struct commit_list *merge_bases = NULL;
struct repository *sub;
sub = open_submodule(path);
show_submodule_header(o, path, one, two, dirty_submodule,
&left, &right, &merge_bases);
sub, &left, &right, &merge_bases);
/*
* If we don't have both a left and a right pointer, there is no
* reason to try and display a summary. The header line should contain
* all the information the user needs.
*/
if (!left || !right)
if (!left || !right || !sub)
goto out;
/* Treat revision walker failure the same as missing commits */
@ -599,13 +634,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
goto out;
}
print_submodule_summary(&rev, o);
print_submodule_summary(sub, &rev, o);
out:
if (merge_bases)
free_commit_list(merge_bases);
clear_commit_marks(left, ~0);
clear_commit_marks(right, ~0);
if (sub) {
repo_clear(sub);
free(sub);
}
}
void show_submodule_inline_diff(struct diff_options *o, const char *path,
@ -617,9 +656,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
struct commit_list *merge_bases = NULL;
struct child_process cp = CHILD_PROCESS_INIT;
struct strbuf sb = STRBUF_INIT;
struct repository *sub;
sub = open_submodule(path);
show_submodule_header(o, path, one, two, dirty_submodule,
&left, &right, &merge_bases);
sub, &left, &right, &merge_bases);
/* We need a valid left and right commit to display a difference */
if (!(left || is_null_oid(one)) ||
@ -680,6 +721,10 @@ done:
clear_commit_marks(left, ~0);
if (right)
clear_commit_marks(right, ~0);
if (sub) {
repo_clear(sub);
free(sub);
}
}
int should_update_submodules(void)
@ -1004,9 +1049,6 @@ static int push_submodule(const char *path,
const struct string_list *push_options,
int dry_run)
{
if (add_submodule_odb(path))
return 1;
if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
struct child_process cp = CHILD_PROCESS_INIT;
argv_array_push(&cp.args, "push");

View File

@ -17,6 +17,11 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
setup_git_env(gitdir);
memset(the_repository, 0, sizeof(*the_repository));
/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");
@ -43,6 +48,11 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
setup_git_env(gitdir);
memset(the_repository, 0, sizeof(*the_repository));
/* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
if (repo_init(&r, gitdir, worktree))
die("Couldn't init repo");