Browse Source

Merge branch 'jc/pack'

* jc/pack:
  pack-objects: document --revs, --unpacked and --all.
  pack-objects --unpacked=<existing pack> option.
  pack-objects: further work on internal rev-list logic.
  pack-objects: run rev-list equivalent internally.
  Separate object listing routines out of rev-list
maint
Junio C Hamano 19 years ago
parent
commit
4405fb77f4
  1. 21
      Documentation/git-pack-objects.txt
  2. 4
      Makefile
  3. 2
      builtin-count-objects.c
  4. 182
      builtin-pack-objects.c
  5. 2
      builtin-prune-packed.c
  6. 126
      builtin-rev-list.c
  7. 2
      cache.h
  8. 140
      list-objects.c
  9. 12
      list-objects.h
  10. 24
      revision.c
  11. 6
      revision.h
  12. 26
      sha1_file.c

21
Documentation/git-pack-objects.txt

@ -11,7 +11,7 @@ SYNOPSIS @@ -11,7 +11,7 @@ SYNOPSIS
[verse]
'git-pack-objects' [-q] [--no-reuse-delta] [--non-empty]
[--local] [--incremental] [--window=N] [--depth=N]
{--stdout | base-name} < object-list
[--revs [--unpacked | --all]*] [--stdout | base-name] < object-list


DESCRIPTION
@ -56,6 +56,24 @@ base-name:: @@ -56,6 +56,24 @@ base-name::
Write the pack contents (what would have been written to
.pack file) out to the standard output.

--revs::
Read the revision arguments from the standard input, instead of
individual object names. The revision arguments are processed
the same way as gitlink:git-rev-list[1] with `--objects` flag
uses its `commit` arguments to build the list of objects it
outputs. The objects on the resulting list are packed.

--unpacked::
This implies `--revs`. When processing the list of
revision arguments read from the standard input, limit
the objects packed to those that are not already packed.

--all::
This implies `--revs`. In addition to the list of
revision arguments read from the standard input, pretend
as if all refs under `$GIT_DIR/refs` are specifed to be
included.

--window and --depth::
These two options affects how the objects contained in
the pack are stored using delta compression. The
@ -103,6 +121,7 @@ Documentation by Junio C Hamano @@ -103,6 +121,7 @@ Documentation by Junio C Hamano

See Also
--------
gitlink:git-rev-list[1]
gitlink:git-repack[1]
gitlink:git-prune-packed[1]


4
Makefile

@ -235,7 +235,7 @@ XDIFF_LIB=xdiff/lib.a @@ -235,7 +235,7 @@ XDIFF_LIB=xdiff/lib.a

LIB_H = \
archive.h blob.h cache.h commit.h csum-file.h delta.h \
diff.h object.h pack.h pkt-line.h quote.h refs.h sideband.h \
diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h

@ -252,7 +252,7 @@ LIB_OBJS = \ @@ -252,7 +252,7 @@ LIB_OBJS = \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
write_or_die.o trace.o \
write_or_die.o trace.o list-objects.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o


2
builtin-count-objects.c

@ -62,7 +62,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose, @@ -62,7 +62,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
hex[40] = 0;
if (get_sha1_hex(hex, sha1))
die("internal error");
if (has_sha1_pack(sha1))
if (has_sha1_pack(sha1, NULL))
(*packed_loose)++;
}
}

182
builtin-pack-objects.c

@ -9,10 +9,13 @@ @@ -9,10 +9,13 @@
#include "pack.h"
#include "csum-file.h"
#include "tree-walk.h"
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
#include <sys/time.h>
#include <signal.h>

static const char pack_usage[] = "git-pack-objects [-q] [--no-reuse-delta] [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] {--stdout | base-name} < object-list";
static const char pack_usage[] = "git-pack-objects [-q] [--no-reuse-delta] [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] [--revs [--unpacked | --all]*] [--stdout | base-name] <ref-list | <object-list]";

struct object_entry {
unsigned char sha1[20];
@ -66,6 +69,7 @@ static int progress = 1; @@ -66,6 +69,7 @@ static int progress = 1;
static volatile sig_atomic_t progress_update;
static int window = 10;
static int pack_to_stdout;
static int num_preferred_base;

/*
* The object names in objects array are hashed with this hashtable,
@ -838,7 +842,7 @@ static int check_pbase_path(unsigned hash) @@ -838,7 +842,7 @@ static int check_pbase_path(unsigned hash)
return 0;
}

static void add_preferred_base_object(char *name, unsigned hash)
static void add_preferred_base_object(const char *name, unsigned hash)
{
struct pbase_tree *it;
int cmplen = name_cmp_len(name);
@ -867,6 +871,9 @@ static void add_preferred_base(unsigned char *sha1) @@ -867,6 +871,9 @@ static void add_preferred_base(unsigned char *sha1)
unsigned long size;
unsigned char tree_sha1[20];

if (window <= num_preferred_base++)
return;

data = read_object_with_reference(sha1, tree_type, &size, tree_sha1);
if (!data)
return;
@ -1326,14 +1333,105 @@ static int git_pack_config(const char *k, const char *v) @@ -1326,14 +1333,105 @@ static int git_pack_config(const char *k, const char *v)
return git_default_config(k, v);
}

static void read_object_list_from_stdin(void)
{
char line[40 + 1 + PATH_MAX + 2];
unsigned char sha1[20];
unsigned hash;

for (;;) {
if (!fgets(line, sizeof(line), stdin)) {
if (feof(stdin))
break;
if (!ferror(stdin))
die("fgets returned NULL, not EOF, not error!");
if (errno != EINTR)
die("fgets: %s", strerror(errno));
clearerr(stdin);
continue;
}
if (line[0] == '-') {
if (get_sha1_hex(line+1, sha1))
die("expected edge sha1, got garbage:\n %s",
line);
add_preferred_base(sha1);
continue;
}
if (get_sha1_hex(line, sha1))
die("expected sha1, got garbage:\n %s", line);

hash = name_hash(line+41);
add_preferred_base_object(line+41, hash);
add_object_entry(sha1, hash, 0);
}
}

static void show_commit(struct commit *commit)
{
unsigned hash = name_hash("");
add_preferred_base_object("", hash);
add_object_entry(commit->object.sha1, hash, 0);
}

static void show_object(struct object_array_entry *p)
{
unsigned hash = name_hash(p->name);
add_preferred_base_object(p->name, hash);
add_object_entry(p->item->sha1, hash, 0);
}

static void show_edge(struct commit *commit)
{
add_preferred_base(commit->object.sha1);
}

static void get_object_list(int ac, const char **av)
{
struct rev_info revs;
char line[1000];
int flags = 0;

init_revisions(&revs, NULL);
save_commit_buffer = 0;
track_object_refs = 0;
setup_revisions(ac, av, &revs, NULL);

while (fgets(line, sizeof(line), stdin) != NULL) {
int len = strlen(line);
if (line[len - 1] == '\n')
line[--len] = 0;
if (!len)
break;
if (*line == '-') {
if (!strcmp(line, "--not")) {
flags ^= UNINTERESTING;
continue;
}
die("not a rev '%s'", line);
}
if (handle_revision_arg(line, &revs, flags, 1))
die("bad revision '%s'", line);
}

prepare_revision_walk(&revs);
mark_edges_uninteresting(revs.commits, &revs, show_edge);
traverse_commit_list(&revs, show_commit, show_object);
}

int cmd_pack_objects(int argc, const char **argv, const char *prefix)
{
SHA_CTX ctx;
char line[40 + 1 + PATH_MAX + 2];
int depth = 10;
struct object_entry **list;
int num_preferred_base = 0;
int use_internal_rev_list = 0;
int thin = 0;
int i;
const char *rp_av[64];
int rp_ac;

rp_av[0] = "pack-objects";
rp_av[1] = "--objects"; /* --thin will make it --objects-edge */
rp_ac = 2;

git_config(git_pack_config);

@ -1341,7 +1439,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) @@ -1341,7 +1439,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
for (i = 1; i < argc; i++) {
const char *arg = argv[i];

if (*arg == '-') {
if (*arg != '-')
break;

if (!strcmp("--non-empty", arg)) {
non_empty = 1;
continue;
@ -1388,16 +1488,50 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) @@ -1388,16 +1488,50 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
pack_to_stdout = 1;
continue;
}
usage(pack_usage);
if (!strcmp("--revs", arg)) {
use_internal_rev_list = 1;
continue;
}
if (!strcmp("--unpacked", arg) ||
!strncmp("--unpacked=", arg, 11) ||
!strcmp("--all", arg)) {
use_internal_rev_list = 1;
if (ARRAY_SIZE(rp_av) - 1 <= rp_ac)
die("too many internal rev-list options");
rp_av[rp_ac++] = arg;
continue;
}
if (!strcmp("--thin", arg)) {
use_internal_rev_list = 1;
thin = 1;
rp_av[1] = "--objects-edge";
continue;
}
if (base_name)
usage(pack_usage);
base_name = arg;
}

/* Traditionally "pack-objects [options] base extra" failed;
* we would however want to take refs parameter that would
* have been given to upstream rev-list ourselves, which means
* we somehow want to say what the base name is. So the
* syntax would be:
*
* pack-objects [options] base <refs...>
*
* in other words, we would treat the first non-option as the
* base_name and send everything else to the internal revision
* walker.
*/

if (!pack_to_stdout)
base_name = argv[i++];

if (pack_to_stdout != !base_name)
usage(pack_usage);

if (!pack_to_stdout && thin)
die("--thin cannot be used to build an indexable pack.");

prepare_packed_git();

if (progress) {
@ -1405,35 +1539,13 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) @@ -1405,35 +1539,13 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
setup_progress_signal();
}

for (;;) {
unsigned char sha1[20];
unsigned hash;

if (!fgets(line, sizeof(line), stdin)) {
if (feof(stdin))
break;
if (!ferror(stdin))
die("fgets returned NULL, not EOF, not error!");
if (errno != EINTR)
die("fgets: %s", strerror(errno));
clearerr(stdin);
continue;
if (!use_internal_rev_list)
read_object_list_from_stdin();
else {
rp_av[rp_ac] = NULL;
get_object_list(rp_ac, rp_av);
}

if (line[0] == '-') {
if (get_sha1_hex(line+1, sha1))
die("expected edge sha1, got garbage:\n %s",
line+1);
if (num_preferred_base++ < window)
add_preferred_base(sha1);
continue;
}
if (get_sha1_hex(line, sha1))
die("expected sha1, got garbage:\n %s", line);
hash = name_hash(line+41);
add_preferred_base_object(line+41, hash);
add_object_entry(sha1, hash, 0);
}
if (progress)
fprintf(stderr, "Done counting %d objects.\n", nr_objects);
sorted_by_sha = create_final_object_list();

2
builtin-prune-packed.c

@ -19,7 +19,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len) @@ -19,7 +19,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len)
memcpy(hex+2, de->d_name, 38);
if (get_sha1_hex(hex, sha1))
continue;
if (!has_sha1_pack(sha1))
if (!has_sha1_pack(sha1, NULL))
continue;
memcpy(pathname + len, de->d_name, 38);
if (dryrun)

126
builtin-rev-list.c

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
#include "tree-walk.h"
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
#include "builtin.h"

/* bits #0-15 in revision.h */
@ -98,92 +99,8 @@ static void show_commit(struct commit *commit) @@ -98,92 +99,8 @@ static void show_commit(struct commit *commit)
commit->buffer = NULL;
}

static void process_blob(struct blob *blob,
struct object_array *p,
struct name_path *path,
const char *name)
static void show_object(struct object_array_entry *p)
{
struct object *obj = &blob->object;

if (!revs.blob_objects)
return;
if (obj->flags & (UNINTERESTING | SEEN))
return;
obj->flags |= SEEN;
name = xstrdup(name);
add_object(obj, p, path, name);
}

static void process_tree(struct tree *tree,
struct object_array *p,
struct name_path *path,
const char *name)
{
struct object *obj = &tree->object;
struct tree_desc desc;
struct name_entry entry;
struct name_path me;

if (!revs.tree_objects)
return;
if (obj->flags & (UNINTERESTING | SEEN))
return;
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
name = xstrdup(name);
add_object(obj, p, path, name);
me.up = path;
me.elem = name;
me.elem_len = strlen(name);

desc.buf = tree->buffer;
desc.size = tree->size;

while (tree_entry(&desc, &entry)) {
if (S_ISDIR(entry.mode))
process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
else
process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
}
free(tree->buffer);
tree->buffer = NULL;
}

static void show_commit_list(struct rev_info *revs)
{
int i;
struct commit *commit;
struct object_array objects = { 0, 0, NULL };

while ((commit = get_revision(revs)) != NULL) {
process_tree(commit->tree, &objects, NULL, "");
show_commit(commit);
}
for (i = 0; i < revs->pending.nr; i++) {
struct object_array_entry *pending = revs->pending.objects + i;
struct object *obj = pending->item;
const char *name = pending->name;
if (obj->flags & (UNINTERESTING | SEEN))
continue;
if (obj->type == OBJ_TAG) {
obj->flags |= SEEN;
add_object_array(obj, name, &objects);
continue;
}
if (obj->type == OBJ_TREE) {
process_tree((struct tree *)obj, &objects, NULL, name);
continue;
}
if (obj->type == OBJ_BLOB) {
process_blob((struct blob *)obj, &objects, NULL, name);
continue;
}
die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
}
for (i = 0; i < objects.nr; i++) {
struct object_array_entry *p = objects.objects + i;

/* An object with name "foo\n0000000..." can be used to
* confuse downstream git-pack-objects very badly.
*/
@ -195,7 +112,11 @@ static void show_commit_list(struct rev_info *revs) @@ -195,7 +112,11 @@ static void show_commit_list(struct rev_info *revs)
}
else
printf("%s %s\n", sha1_to_hex(p->item->sha1), p->name);
}
}

static void show_edge(struct commit *commit)
{
printf("-%s\n", sha1_to_hex(commit->object.sha1));
}

/*
@ -276,35 +197,6 @@ static struct commit_list *find_bisection(struct commit_list *list) @@ -276,35 +197,6 @@ static struct commit_list *find_bisection(struct commit_list *list)
return best;
}

static void mark_edge_parents_uninteresting(struct commit *commit)
{
struct commit_list *parents;

for (parents = commit->parents; parents; parents = parents->next) {
struct commit *parent = parents->item;
if (!(parent->object.flags & UNINTERESTING))
continue;
mark_tree_uninteresting(parent->tree);
if (revs.edge_hint && !(parent->object.flags & SHOWN)) {
parent->object.flags |= SHOWN;
printf("-%s\n", sha1_to_hex(parent->object.sha1));
}
}
}

static void mark_edges_uninteresting(struct commit_list *list)
{
for ( ; list; list = list->next) {
struct commit *commit = list->item;

if (commit->object.flags & UNINTERESTING) {
mark_tree_uninteresting(commit->tree);
continue;
}
mark_edge_parents_uninteresting(commit);
}
}

static void read_revisions_from_stdin(struct rev_info *revs)
{
char line[1000];
@ -384,12 +276,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) @@ -384,12 +276,12 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)

prepare_revision_walk(&revs);
if (revs.tree_objects)
mark_edges_uninteresting(revs.commits);
mark_edges_uninteresting(revs.commits, &revs, show_edge);

if (bisect_list)
revs.commits = find_bisection(revs.commits);

show_commit_list(&revs);
traverse_commit_list(&revs, show_commit, show_object);

return 0;
}

2
cache.h

@ -259,7 +259,7 @@ extern int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer, @@ -259,7 +259,7 @@ extern int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer,
extern int write_sha1_to_fd(int fd, const unsigned char *sha1);
extern int move_temp_to_file(const char *tmpfile, const char *filename);

extern int has_sha1_pack(const unsigned char *sha1);
extern int has_sha1_pack(const unsigned char *sha1, const char **ignore);
extern int has_sha1_file(const unsigned char *sha1);
extern void *map_sha1_file(const unsigned char *sha1, unsigned long *);
extern int legacy_loose_object(unsigned char *);

140
list-objects.c

@ -0,0 +1,140 @@ @@ -0,0 +1,140 @@
#include "cache.h"
#include "tag.h"
#include "commit.h"
#include "tree.h"
#include "blob.h"
#include "diff.h"
#include "tree-walk.h"
#include "revision.h"
#include "list-objects.h"

static void process_blob(struct rev_info *revs,
struct blob *blob,
struct object_array *p,
struct name_path *path,
const char *name)
{
struct object *obj = &blob->object;

if (!revs->blob_objects)
return;
if (obj->flags & (UNINTERESTING | SEEN))
return;
obj->flags |= SEEN;
name = xstrdup(name);
add_object(obj, p, path, name);
}

static void process_tree(struct rev_info *revs,
struct tree *tree,
struct object_array *p,
struct name_path *path,
const char *name)
{
struct object *obj = &tree->object;
struct tree_desc desc;
struct name_entry entry;
struct name_path me;

if (!revs->tree_objects)
return;
if (obj->flags & (UNINTERESTING | SEEN))
return;
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
name = xstrdup(name);
add_object(obj, p, path, name);
me.up = path;
me.elem = name;
me.elem_len = strlen(name);

desc.buf = tree->buffer;
desc.size = tree->size;

while (tree_entry(&desc, &entry)) {
if (S_ISDIR(entry.mode))
process_tree(revs,
lookup_tree(entry.sha1),
p, &me, entry.path);
else
process_blob(revs,
lookup_blob(entry.sha1),
p, &me, entry.path);
}
free(tree->buffer);
tree->buffer = NULL;
}

static void mark_edge_parents_uninteresting(struct commit *commit,
struct rev_info *revs,
show_edge_fn show_edge)
{
struct commit_list *parents;

for (parents = commit->parents; parents; parents = parents->next) {
struct commit *parent = parents->item;
if (!(parent->object.flags & UNINTERESTING))
continue;
mark_tree_uninteresting(parent->tree);
if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
parent->object.flags |= SHOWN;
show_edge(parent);
}
}
}

void mark_edges_uninteresting(struct commit_list *list,
struct rev_info *revs,
show_edge_fn show_edge)
{
for ( ; list; list = list->next) {
struct commit *commit = list->item;

if (commit->object.flags & UNINTERESTING) {
mark_tree_uninteresting(commit->tree);
continue;
}
mark_edge_parents_uninteresting(commit, revs, show_edge);
}
}

void traverse_commit_list(struct rev_info *revs,
void (*show_commit)(struct commit *),
void (*show_object)(struct object_array_entry *))
{
int i;
struct commit *commit;
struct object_array objects = { 0, 0, NULL };

while ((commit = get_revision(revs)) != NULL) {
process_tree(revs, commit->tree, &objects, NULL, "");
show_commit(commit);
}
for (i = 0; i < revs->pending.nr; i++) {
struct object_array_entry *pending = revs->pending.objects + i;
struct object *obj = pending->item;
const char *name = pending->name;
if (obj->flags & (UNINTERESTING | SEEN))
continue;
if (obj->type == OBJ_TAG) {
obj->flags |= SEEN;
add_object_array(obj, name, &objects);
continue;
}
if (obj->type == OBJ_TREE) {
process_tree(revs, (struct tree *)obj, &objects,
NULL, name);
continue;
}
if (obj->type == OBJ_BLOB) {
process_blob(revs, (struct blob *)obj, &objects,
NULL, name);
continue;
}
die("unknown pending object %s (%s)",
sha1_to_hex(obj->sha1), name);
}
for (i = 0; i < objects.nr; i++)
show_object(&objects.objects[i]);
}

12
list-objects.h

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
#ifndef LIST_OBJECTS_H
#define LIST_OBJECTS_H

typedef void (*show_commit_fn)(struct commit *);
typedef void (*show_object_fn)(struct object_array_entry *);
typedef void (*show_edge_fn)(struct commit *);

void traverse_commit_list(struct rev_info *revs, show_commit_fn, show_object_fn);

void mark_edges_uninteresting(struct commit_list *, struct rev_info *, show_edge_fn);

#endif

24
revision.c

@ -416,7 +416,8 @@ static void limit_list(struct rev_info *revs) @@ -416,7 +416,8 @@ static void limit_list(struct rev_info *revs)

if (revs->max_age != -1 && (commit->date < revs->max_age))
obj->flags |= UNINTERESTING;
if (revs->unpacked && has_sha1_pack(obj->sha1))
if (revs->unpacked &&
has_sha1_pack(obj->sha1, revs->ignore_packed))
obj->flags |= UNINTERESTING;
add_parents_to_list(revs, commit, &list);
if (obj->flags & UNINTERESTING) {
@ -671,6 +672,16 @@ int handle_revision_arg(const char *arg, struct rev_info *revs, @@ -671,6 +672,16 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
return 0;
}

static void add_ignore_packed(struct rev_info *revs, const char *name)
{
int num = ++revs->num_ignore_packed;

revs->ignore_packed = xrealloc(revs->ignore_packed,
sizeof(const char **) * (num + 1));
revs->ignore_packed[num-1] = name;
revs->ignore_packed[num] = NULL;
}

/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
@ -811,6 +822,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch @@ -811,6 +822,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
}
if (!strcmp(arg, "--unpacked")) {
revs->unpacked = 1;
free(revs->ignore_packed);
revs->ignore_packed = NULL;
revs->num_ignore_packed = 0;
continue;
}
if (!strncmp(arg, "--unpacked=", 11)) {
revs->unpacked = 1;
add_ignore_packed(revs, arg+11);
continue;
}
if (!strcmp(arg, "-r")) {
@ -1057,7 +1076,8 @@ struct commit *get_revision(struct rev_info *revs) @@ -1057,7 +1076,8 @@ struct commit *get_revision(struct rev_info *revs)
*/
if (!revs->limited) {
if ((revs->unpacked &&
has_sha1_pack(commit->object.sha1)) ||
has_sha1_pack(commit->object.sha1,
revs->ignore_packed)) ||
(revs->max_age != -1 &&
(commit->date < revs->max_age)))
continue;

6
revision.h

@ -38,7 +38,7 @@ struct rev_info { @@ -38,7 +38,7 @@ struct rev_info {
blob_objects:1,
edge_hint:1,
limited:1,
unpacked:1,
unpacked:1, /* see also ignore_packed below */
boundary:1,
parents:1;

@ -57,6 +57,10 @@ struct rev_info { @@ -57,6 +57,10 @@ struct rev_info {
unsigned int shown_one:1,
abbrev_commit:1,
relative_date:1;

const char **ignore_packed; /* pretend objects in these are unpacked */
int num_ignore_packed;

unsigned int abbrev;
enum cmit_fmt commit_format;
struct log_info *loginfo;

26
sha1_file.c

@ -1217,12 +1217,20 @@ int find_pack_entry_one(const unsigned char *sha1, @@ -1217,12 +1217,20 @@ int find_pack_entry_one(const unsigned char *sha1,
return 0;
}

static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed)
{
struct packed_git *p;
prepare_packed_git();

for (p = packed_git; p; p = p->next) {
if (ignore_packed) {
const char **ig;
for (ig = ignore_packed; *ig; ig++)
if (!strcmp(p->pack_name, *ig))
break;
if (*ig)
continue;
}
if (find_pack_entry_one(sha1, e, p))
return 1;
}
@ -1255,10 +1263,10 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep @@ -1255,10 +1263,10 @@ int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep
if (!map) {
struct pack_entry e;

if (find_pack_entry(sha1, &e))
if (find_pack_entry(sha1, &e, NULL))
return packed_object_info(&e, type, sizep);
reprepare_packed_git();
if (find_pack_entry(sha1, &e))
if (find_pack_entry(sha1, &e, NULL))
return packed_object_info(&e, type, sizep);
return error("unable to find %s", sha1_to_hex(sha1));
}
@ -1281,7 +1289,7 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo @@ -1281,7 +1289,7 @@ static void *read_packed_sha1(const unsigned char *sha1, char *type, unsigned lo
{
struct pack_entry e;

if (!find_pack_entry(sha1, &e)) {
if (!find_pack_entry(sha1, &e, NULL)) {
error("cannot read sha1_file for %s", sha1_to_hex(sha1));
return NULL;
}
@ -1294,7 +1302,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size @@ -1294,7 +1302,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
void *map, *buf;
struct pack_entry e;

if (find_pack_entry(sha1, &e))
if (find_pack_entry(sha1, &e, NULL))
return read_packed_sha1(sha1, type, size);
map = map_sha1_file(sha1, &mapsize);
if (map) {
@ -1303,7 +1311,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size @@ -1303,7 +1311,7 @@ void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size
return buf;
}
reprepare_packed_git();
if (find_pack_entry(sha1, &e))
if (find_pack_entry(sha1, &e, NULL))
return read_packed_sha1(sha1, type, size);
return NULL;
}
@ -1735,10 +1743,10 @@ int has_pack_file(const unsigned char *sha1) @@ -1735,10 +1743,10 @@ int has_pack_file(const unsigned char *sha1)
return 1;
}

int has_sha1_pack(const unsigned char *sha1)
int has_sha1_pack(const unsigned char *sha1, const char **ignore_packed)
{
struct pack_entry e;
return find_pack_entry(sha1, &e);
return find_pack_entry(sha1, &e, ignore_packed);
}

int has_sha1_file(const unsigned char *sha1)
@ -1746,7 +1754,7 @@ int has_sha1_file(const unsigned char *sha1) @@ -1746,7 +1754,7 @@ int has_sha1_file(const unsigned char *sha1)
struct stat st;
struct pack_entry e;

if (find_pack_entry(sha1, &e))
if (find_pack_entry(sha1, &e, NULL))
return 1;
return find_sha1_file(sha1, &st) ? 1 : 0;
}

Loading…
Cancel
Save