38
static int no_data;
39
static int full_tree;
40
static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
41
+static struct string_list tag_refs = STRING_LIST_INIT_NODUP;
42
static struct refspec refspecs = REFSPEC_INIT_FETCH;
43
static int anonymize;
44
static struct revision_sources revision_sources;
613
export_blob(&diff_queued_diff.queue[i]->two->oid);
614
615
refname = *revision_sources_at(&revision_sources, commit);
616
+ /*
617
+ * FIXME: string_list_remove() below for each ref is overall
618
+ * O(N^2). Compared to a history walk and diffing trees, this is
619
+ * just lost in the noise in practice. However, theoretically a
620
+ * repo may have enough refs for this to become slow.
621
+ */
622
+ string_list_remove(&extra_refs, refname, 0);
623
if (anonymize) {
624
refname = anonymize_refname(refname);
625
anonymize_ident_line(&committer, &committer_end);
823
/* handle nested tags */
824
while (tag && tag->object.type == OBJ_TAG) {
825
parse_object(the_repository, &tag->object.oid);
818
- string_list_append(&extra_refs, full_name)->util = tag;
826
+ string_list_append(&tag_refs, full_name)->util = tag;
827
tag = (struct tag *)tag->tagged;
828
}
829
if (!tag)
882
}
883
884
/*
877
- * This ref will not be updated through a commit, lets make
878
- * sure it gets properly updated eventually.
885
+ * Make sure this ref gets properly updated eventually, whether
886
+ * through a commit or manually at the end.
887
*/
880
- if (*revision_sources_at(&revision_sources, commit) ||
881
- commit->object.flags & SHOWN)
888
+ if (e->item->type != OBJ_TAG)
889
string_list_append(&extra_refs, full_name)->util = commit;
890
+
891
if (!*revision_sources_at(&revision_sources, commit))
892
*revision_sources_at(&revision_sources, commit) = full_name;
893
}
894
+
895
+ string_list_sort(&extra_refs);
896
+ string_list_remove_duplicates(&extra_refs, 0);
897
}
898
888
-static void handle_tags_and_duplicates(void)
899
+static void handle_tags_and_duplicates(struct string_list *extras)
900
{
901
struct commit *commit;
902
int i;
903
893
- for (i = extra_refs.nr - 1; i >= 0; i--) {
894
- const char *name = extra_refs.items[i].string;
895
- struct object *object = extra_refs.items[i].util;
904
+ for (i = extras->nr - 1; i >= 0; i--) {
905
+ const char *name = extras->items[i].string;
906
+ struct object *object = extras->items[i].util;
907
+ int mark;
908
+
909
switch (object->type) {
910
case OBJ_TAG:
911
handle_tag(name, (struct tag *)object);
926
name, oid_to_hex(&null_oid));
927
continue;
928
}
916
- printf("reset %s\nfrom :%d\n\n", name,
917
- get_object_mark(&commit->object));
929
+
930
+ mark = get_object_mark(&commit->object);
931
+ if (!mark) {
932
+ /*
933
+ * Getting here means we have a commit which
934
+ * was excluded by a negative refspec (e.g.
935
+ * fast-export ^master master). If the user
936
+ * wants the branch exported but every commit
937
+ * in its history to be deleted, that sounds
938
+ * like a ref deletion to me.
939
+ */
940
+ printf("reset %s\nfrom %s\n\n",
941
+ name, oid_to_hex(&null_oid));
942
+ continue;
943
+ }
944
+
945
+ printf("reset %s\nfrom :%d\n\n", name, mark
946
+ );
947
show_progress();
948
break;
949
}
1131
}
1132
}
1133
1105
- handle_tags_and_duplicates();
1134
+ handle_tags_and_duplicates(&extra_refs);
1135
+ handle_tags_and_duplicates(&tag_refs);
1136
handle_deletes();
1137
1138
if (export_filename && lastimportid != last_idnum)