summaryrefslogtreecommitdiff
path: root/builtin/fast-export.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/fast-export.c')
-rw-r--r--builtin/fast-export.c125
1 files changed, 64 insertions, 61 deletions
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 796d0cd66c..9bd8a14b57 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -7,6 +7,8 @@
#include "cache.h"
#include "config.h"
#include "refs.h"
+#include "refspec.h"
+#include "object-store.h"
#include "commit.h"
#include "object.h"
#include "tag.h"
@@ -21,6 +23,7 @@
#include "quote.h"
#include "remote.h"
#include "blob.h"
+#include "commit-slab.h"
static const char *fast_export_usage[] = {
N_("git fast-export [rev-list-opts]"),
@@ -35,9 +38,9 @@ static int use_done_feature;
static int no_data;
static int full_tree;
static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
-static struct refspec *refspecs;
-static int refspecs_nr;
+static struct refspec refspecs = REFSPEC_INIT_FETCH;
static int anonymize;
+static struct revision_sources revision_sources;
static int parse_opt_signed_tag_mode(const struct option *opt,
const char *arg, int unset)
@@ -156,15 +159,14 @@ static void anonymize_path(struct strbuf *out, const char *path,
}
}
-/* Since intptr_t is C99, we do not use it here */
-static inline uint32_t *mark_to_ptr(uint32_t mark)
+static inline void *mark_to_ptr(uint32_t mark)
{
- return ((uint32_t *)NULL) + mark;
+ return (void *)(uintptr_t)mark;
}
static inline uint32_t ptr_to_mark(void * mark)
{
- return (uint32_t *)mark - (uint32_t *)NULL;
+ return (uint32_t)(uintptr_t)mark;
}
static inline void mark_object(struct object *object, uint32_t mark)
@@ -228,21 +230,22 @@ static void export_blob(const struct object_id *oid)
if (is_null_oid(oid))
return;
- object = lookup_object(oid->hash);
+ object = lookup_object(the_repository, oid->hash);
if (object && object->flags & SHOWN)
return;
if (anonymize) {
buf = anonymize_blob(&size);
- object = (struct object *)lookup_blob(oid);
+ object = (struct object *)lookup_blob(the_repository, oid);
eaten = 0;
} else {
- buf = read_sha1_file(oid->hash, &type, &size);
+ buf = read_object_file(oid, &type, &size);
if (!buf)
- die ("Could not read blob %s", oid_to_hex(oid));
- if (check_sha1_signature(oid->hash, buf, size, typename(type)) < 0)
+ die("could not read blob %s", oid_to_hex(oid));
+ if (check_object_signature(oid, buf, size, type_name(type)) < 0)
die("sha1 mismatch in blob %s", oid_to_hex(oid));
- object = parse_object_buffer(oid, type, size, buf, &eaten);
+ object = parse_object_buffer(the_repository, oid, type,
+ size, buf, &eaten);
}
if (!object)
@@ -252,7 +255,7 @@ static void export_blob(const struct object_id *oid)
printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
if (size && fwrite(buf, size, 1, stdout) != 1)
- die_errno ("Could not write blob '%s'", oid_to_hex(oid));
+ die_errno("could not write blob '%s'", oid_to_hex(oid));
printf("\n");
show_progress();
@@ -400,7 +403,8 @@ static void show_filemodify(struct diff_queue_struct *q,
anonymize_sha1(&spec->oid) :
spec->oid.hash));
else {
- struct object *object = lookup_object(spec->oid.hash);
+ struct object *object = lookup_object(the_repository,
+ spec->oid.hash);
printf("M %06o :%d ", spec->mode,
get_object_mark(object));
}
@@ -517,7 +521,7 @@ static void anonymize_ident_line(const char **beg, const char **end)
/* skip "committer", "author", "tagger", etc */
end_of_header = strchr(*beg, ' ');
if (!end_of_header)
- die("BUG: malformed line fed to anonymize_ident_line: %.*s",
+ BUG("malformed line fed to anonymize_ident_line: %.*s",
(int)(*end - *beg), *beg);
end_of_header++;
strbuf_add(out, *beg, end_of_header - *beg);
@@ -559,14 +563,14 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
commit_buffer = get_commit_buffer(commit, NULL);
author = strstr(commit_buffer, "\nauthor ");
if (!author)
- die ("Could not find author in commit %s",
- oid_to_hex(&commit->object.oid));
+ die("could not find author in commit %s",
+ oid_to_hex(&commit->object.oid));
author++;
author_end = strchrnul(author, '\n');
committer = strstr(author_end, "\ncommitter ");
if (!committer)
- die ("Could not find committer in commit %s",
- oid_to_hex(&commit->object.oid));
+ die("could not find committer in commit %s",
+ oid_to_hex(&commit->object.oid));
committer++;
committer_end = strchrnul(committer, '\n');
message = strstr(committer_end, "\n\n");
@@ -578,11 +582,11 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
get_object_mark(&commit->parents->item->object) != 0 &&
!full_tree) {
parse_commit_or_die(commit->parents->item);
- diff_tree_oid(&commit->parents->item->tree->object.oid,
- &commit->tree->object.oid, "", &rev->diffopt);
+ diff_tree_oid(get_commit_tree_oid(commit->parents->item),
+ get_commit_tree_oid(commit), "", &rev->diffopt);
}
else
- diff_root_tree_oid(&commit->tree->object.oid,
+ diff_root_tree_oid(get_commit_tree_oid(commit),
"", &rev->diffopt);
/* Export the referenced blobs, and remember the marks. */
@@ -590,7 +594,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode))
export_blob(&diff_queued_diff.queue[i]->two->oid);
- refname = commit->util;
+ refname = *revision_sources_at(&revision_sources, commit);
if (anonymize) {
refname = anonymize_refname(refname);
anonymize_ident_line(&committer, &committer_end);
@@ -651,8 +655,11 @@ static void handle_tail(struct object_array *commits, struct rev_info *revs,
struct commit *commit;
while (commits->nr) {
commit = (struct commit *)object_array_pop(commits);
- if (has_unshown_parent(commit))
+ if (has_unshown_parent(commit)) {
+ /* Queue again, to be handled later */
+ add_object_array(&commit->object, NULL, commits);
return;
+ }
handle_commit(commit, revs, paths_of_changed_objects);
}
}
@@ -682,9 +689,9 @@ static void handle_tag(const char *name, struct tag *tag)
return;
}
- buf = read_sha1_file(tag->object.oid.hash, &type, &size);
+ buf = read_object_file(&tag->object.oid, &type, &size);
if (!buf)
- die ("Could not read tag %s", oid_to_hex(&tag->object.oid));
+ die("could not read tag %s", oid_to_hex(&tag->object.oid));
message = memmem(buf, size, "\n\n", 2);
if (message) {
message += 2;
@@ -721,18 +728,18 @@ static void handle_tag(const char *name, struct tag *tag)
if (signature)
switch(signed_tag_mode) {
case ABORT:
- die ("Encountered signed tag %s; use "
- "--signed-tags=<mode> to handle it.",
- oid_to_hex(&tag->object.oid));
+ die("encountered signed tag %s; use "
+ "--signed-tags=<mode> to handle it",
+ oid_to_hex(&tag->object.oid));
case WARN:
- warning ("Exporting signed tag %s",
- oid_to_hex(&tag->object.oid));
+ warning("exporting signed tag %s",
+ oid_to_hex(&tag->object.oid));
/* fallthru */
case VERBATIM:
break;
case WARN_STRIP:
- warning ("Stripping signature from tag %s",
- oid_to_hex(&tag->object.oid));
+ warning("stripping signature from tag %s",
+ oid_to_hex(&tag->object.oid));
/* fallthru */
case STRIP:
message_size = signature + 1 - message;
@@ -746,18 +753,18 @@ static void handle_tag(const char *name, struct tag *tag)
if (!tagged_mark) {
switch(tag_of_filtered_mode) {
case ABORT:
- die ("Tag %s tags unexported object; use "
- "--tag-of-filtered-object=<mode> to handle it.",
- oid_to_hex(&tag->object.oid));
+ die("tag %s tags unexported object; use "
+ "--tag-of-filtered-object=<mode> to handle it",
+ oid_to_hex(&tag->object.oid));
case DROP:
/* Ignore this tag altogether */
free(buf);
return;
case REWRITE:
if (tagged->type != OBJ_COMMIT) {
- die ("Tag %s tags unexported %s!",
- oid_to_hex(&tag->object.oid),
- typename(tagged->type));
+ die("tag %s tags unexported %s!",
+ oid_to_hex(&tag->object.oid),
+ type_name(tagged->type));
}
p = (struct commit *)tagged;
for (;;) {
@@ -768,7 +775,7 @@ static void handle_tag(const char *name, struct tag *tag)
if (!(p->object.flags & TREESAME))
break;
if (!p->parents)
- die ("Can't find replacement commit for tag %s\n",
+ die("can't find replacement commit for tag %s",
oid_to_hex(&tag->object.oid));
p = p->parents->item;
}
@@ -796,7 +803,7 @@ static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
/* handle nested tags */
while (tag && tag->object.type == OBJ_TAG) {
- parse_object(&tag->object.oid);
+ parse_object(the_repository, &tag->object.oid);
string_list_append(&extra_refs, full_name)->util = tag;
tag = (struct tag *)tag->tagged;
}
@@ -826,9 +833,9 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
if (dwim_ref(e->name, strlen(e->name), &oid, &full_name) != 1)
continue;
- if (refspecs) {
+ if (refspecs.nr) {
char *private;
- private = apply_refspecs(refspecs, refspecs_nr, full_name);
+ private = apply_refspecs(&refspecs, full_name);
if (private) {
free(full_name);
full_name = private;
@@ -839,7 +846,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
if (!commit) {
warning("%s: Unexpected object of type %s, skipping.",
e->name,
- typename(e->item->type));
+ type_name(e->item->type));
continue;
}
@@ -851,7 +858,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
continue;
default: /* OBJ_TAG (nested tags) is already handled */
warning("Tag points to object of unexpected type %s, skipping.",
- typename(commit->object.type));
+ type_name(commit->object.type));
continue;
}
@@ -859,10 +866,11 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
* This ref will not be updated through a commit, lets make
* sure it gets properly updated eventually.
*/
- if (commit->util || commit->object.flags & SHOWN)
+ if (*revision_sources_at(&revision_sources, commit) ||
+ commit->object.flags & SHOWN)
string_list_append(&extra_refs, full_name)->util = commit;
- if (!commit->util)
- commit->util = full_name;
+ if (!*revision_sources_at(&revision_sources, commit))
+ *revision_sources_at(&revision_sources, commit) = full_name;
}
}
@@ -947,7 +955,7 @@ static void import_marks(char *input_file)
if (last_idnum < mark)
last_idnum = mark;
- type = sha1_object_info(oid.hash, NULL);
+ type = oid_object_info(the_repository, &oid, NULL);
if (type < 0)
die("object not found: %s", oid_to_hex(&oid));
@@ -955,7 +963,7 @@ static void import_marks(char *input_file)
/* only commits */
continue;
- commit = lookup_commit(&oid);
+ commit = lookup_commit(the_repository, &oid);
if (!commit)
die("not a commit? can't happen: %s", oid_to_hex(&oid));
@@ -974,8 +982,8 @@ static void import_marks(char *input_file)
static void handle_deletes(void)
{
int i;
- for (i = 0; i < refspecs_nr; i++) {
- struct refspec *refspec = &refspecs[i];
+ for (i = 0; i < refspecs.nr; i++) {
+ struct refspec_item *refspec = &refspecs.items[i];
if (*refspec->src)
continue;
@@ -1026,8 +1034,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
git_config(git_default_config, NULL);
init_revisions(&revs, prefix);
+ init_revision_sources(&revision_sources);
revs.topo_order = 1;
- revs.show_source = 1;
+ revs.sources = &revision_sources;
revs.rewrite_parents = 1;
argc = parse_options(argc, argv, prefix, options, fast_export_usage,
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
@@ -1036,18 +1045,12 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
usage_with_options (fast_export_usage, options);
if (refspecs_list.nr) {
- const char **refspecs_str;
int i;
- ALLOC_ARRAY(refspecs_str, refspecs_list.nr);
for (i = 0; i < refspecs_list.nr; i++)
- refspecs_str[i] = refspecs_list.items[i].string;
-
- refspecs_nr = refspecs_list.nr;
- refspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);
+ refspec_append(&refspecs, refspecs_list.items[i].string);
string_list_clear(&refspecs_list, 1);
- free(refspecs_str);
}
if (use_done_feature)
@@ -1086,7 +1089,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
if (use_done_feature)
printf("done\n");
- free_refspec(refspecs_nr, refspecs);
+ refspec_clear(&refspecs);
return 0;
}