284
static struct oidset excluded_by_config;
285
static int name_hash_version = -1;
286
287
+enum stdin_packs_mode {
288
+ STDIN_PACKS_MODE_NONE,
289
+ STDIN_PACKS_MODE_STANDARD,
290
+ STDIN_PACKS_MODE_FOLLOW,
291
+};
292
+
293
/**
294
* Check whether the name_hash_version chosen by user input is appropriate,
295
* and also validate whether it is compatible with other features.
3755
}
3756
3757
static void show_object_pack_hint(struct object *object, const char *name,
3752
- void *data UNUSED)
3758
+ void *data)
3759
{
3754
- struct object_entry *oe = packlist_find(&to_pack, &object->oid);
3755
- if (!oe)
3756
- return;
3760
+ enum stdin_packs_mode mode = *(enum stdin_packs_mode *)data;
3761
+ if (mode == STDIN_PACKS_MODE_FOLLOW) {
3762
+ if (object->type == OBJ_BLOB &&
3763
+ !has_object(the_repository, &object->oid, 0))
3764
+ return;
3765
+ add_object_entry(&object->oid, object->type, name, 0);
3766
+ } else {
3767
+ struct object_entry *oe = packlist_find(&to_pack, &object->oid);
3768
+ if (!oe)
3769
+ return;
3770
3758
- /*
3759
- * Our 'to_pack' list was constructed by iterating all objects packed in
3760
- * included packs, and so doesn't have a non-zero hash field that you
3761
- * would typically pick up during a reachability traversal.
3762
- *
3763
- * Make a best-effort attempt to fill in the ->hash and ->no_try_delta
3764
- * fields here in order to perhaps improve the delta selection
3765
- * process.
3766
- */
3767
- oe->hash = pack_name_hash_fn(name);
3768
- oe->no_try_delta = name && no_try_delta(name);
3771
+ /*
3772
+ * Our 'to_pack' list was constructed by iterating all
3773
+ * objects packed in included packs, and so doesn't have
3774
+ * a non-zero hash field that you would typically pick
3775
+ * up during a reachability traversal.
3776
+ *
3777
+ * Make a best-effort attempt to fill in the ->hash and
3778
+ * ->no_try_delta fields here in order to perhaps
3779
+ * improve the delta selection process.
3780
+ */
3781
+ oe->hash = pack_name_hash_fn(name);
3782
+ oe->no_try_delta = name && no_try_delta(name);
3783
3770
- stdin_packs_hints_nr++;
3784
+ stdin_packs_hints_nr++;
3785
+ }
3786
}
3787
3773
-static void show_commit_pack_hint(struct commit *commit UNUSED,
3774
- void *data UNUSED)
3788
+static void show_commit_pack_hint(struct commit *commit, void *data)
3789
{
3790
+ enum stdin_packs_mode mode = *(enum stdin_packs_mode *)data;
3791
+
3792
+ if (mode == STDIN_PACKS_MODE_FOLLOW) {
3793
+ show_object_pack_hint((struct object *)commit, "", data);
3794
+ return;
3795
+ }
3796
+
3797
/* nothing to do; commits don't have a namehash */
3798
+
3799
}
3800
3801
static int pack_mtime_cmp(const void *_a, const void *_b)
3903
3904
static void add_unreachable_loose_objects(struct rev_info *revs);
3905
3884
-static void read_stdin_packs(int rev_list_unpacked)
3906
+static void read_stdin_packs(enum stdin_packs_mode mode, int rev_list_unpacked)
3907
{
3908
struct rev_info revs;
3909
3935
traverse_commit_list(&revs,
3936
show_commit_pack_hint,
3937
show_object_pack_hint,
3916
- NULL);
3938
+ &mode);
3939
3940
trace2_data_intmax("pack-objects", the_repository, "stdin_packs_found",
3941
stdin_packs_found_nr);
4817
return is_not_in_promisor_pack_obj((struct object *) commit, data);
4818
}
4819
4820
+static int parse_stdin_packs_mode(const struct option *opt, const char *arg,
4821
+ int unset)
4822
+{
4823
+ enum stdin_packs_mode *mode = opt->value;
4824
+
4825
+ if (unset)
4826
+ *mode = STDIN_PACKS_MODE_NONE;
4827
+ else if (!arg || !*arg)
4828
+ *mode = STDIN_PACKS_MODE_STANDARD;
4829
+ else if (!strcmp(arg, "follow"))
4830
+ *mode = STDIN_PACKS_MODE_FOLLOW;
4831
+ else
4832
+ die(_("invalid value for '%s': '%s'"), opt->long_name, arg);
4833
+
4834
+ return 0;
4835
+}
4836
+
4837
int cmd_pack_objects(int argc,
4838
const char **argv,
4839
const char *prefix,
4844
struct strvec rp = STRVEC_INIT;
4845
int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0;
4846
int rev_list_index = 0;
4808
- int stdin_packs = 0;
4847
+ enum stdin_packs_mode stdin_packs = STDIN_PACKS_MODE_NONE;
4848
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
4849
struct list_objects_filter_options filter_options =
4850
LIST_OBJECTS_FILTER_INIT;
4899
OPT_SET_INT_F(0, "indexed-objects", &rev_list_index,
4900
N_("include objects referred to by the index"),
4901
1, PARSE_OPT_NONEG),
4902
+ OPT_CALLBACK_F(0, "stdin-packs", &stdin_packs, N_("mode"),
4903
+ N_("read packs from stdin"),
4904
+ PARSE_OPT_OPTARG, parse_stdin_packs_mode),
4905
OPT_BOOL(0, "stdin-packs", &stdin_packs,
4906
N_("read packs from stdin")),
4907
OPT_BOOL(0, "stdout", &pack_to_stdout,
5192
progress_state = start_progress(the_repository,
5193
_("Enumerating objects"), 0);
5194
if (stdin_packs) {
5153
- read_stdin_packs(rev_list_unpacked);
5195
+ read_stdin_packs(stdin_packs, rev_list_unpacked);
5196
} else if (cruft) {
5197
read_cruft_objects();
5198
} else if (!use_internal_rev_list) {