22
#include "progress.h"
23
#include "reflog-walk.h"
24
#include "oidset.h"
25
+#include "oidmap.h"
26
#include "packfile.h"
27
+#include "quote.h"
28
+#include "strbuf.h"
29
30
static const char rev_list_usage[] =
31
"git rev-list [<options>] <commit>... [--] [<path>...]\n"
76
static struct oidset omitted_objects;
77
static int arg_print_omitted; /* print objects omitted by filter */
78
76
-static struct oidset missing_objects;
79
+struct missing_objects_map_entry {
80
+ struct oidmap_entry entry;
81
+ const char *path;
82
+};
83
+static struct oidmap missing_objects;
84
enum missing_action {
85
MA_ERROR = 0, /* fail if any missing objects are encountered */
86
MA_ALLOW_ANY, /* silently allow ALL missing objects */
87
MA_PRINT, /* print ALL missing objects in special section */
88
+ MA_PRINT_INFO, /* same as MA_PRINT but also prints missing object info */
89
MA_ALLOW_PROMISOR, /* silently allow all missing PROMISOR objects */
90
};
91
static enum missing_action arg_missing_action;
109
return size;
110
}
111
104
-static inline void finish_object__ma(struct object *obj)
112
+static void add_missing_object_entry(struct object_id *oid, const char *path)
113
+{
114
+ struct missing_objects_map_entry *entry;
115
+
116
+ if (oidmap_get(&missing_objects, oid))
117
+ return;
118
+
119
+ CALLOC_ARRAY(entry, 1);
120
+ entry->entry.oid = *oid;
121
+ if (path)
122
+ entry->path = xstrdup(path);
123
+ oidmap_put(&missing_objects, entry);
124
+}
125
+
126
+static void print_missing_object(struct missing_objects_map_entry *entry,
127
+ int print_missing_info)
128
+{
129
+ struct strbuf sb = STRBUF_INIT;
130
+
131
+ if (!print_missing_info) {
132
+ printf("?%s\n", oid_to_hex(&entry->entry.oid));
133
+ return;
134
+ }
135
+
136
+ if (entry->path && *entry->path) {
137
+ struct strbuf path = STRBUF_INIT;
138
+
139
+ strbuf_addstr(&sb, " path=");
140
+ quote_path(entry->path, NULL, &path, QUOTE_PATH_QUOTE_SP);
141
+ strbuf_addbuf(&sb, &path);
142
+
143
+ strbuf_release(&path);
144
+ }
145
+
146
+ printf("?%s%s\n", oid_to_hex(&entry->entry.oid), sb.buf);
147
+ strbuf_release(&sb);
148
+}
149
+
150
+static inline void finish_object__ma(struct object *obj, const char *name)
151
{
152
/*
153
* Whether or not we try to dynamically fetch missing objects
165
return;
166
167
case MA_PRINT:
122
- oidset_insert(&missing_objects, &obj->oid);
168
+ case MA_PRINT_INFO:
169
+ add_missing_object_entry(&obj->oid, name);
170
return;
171
172
case MA_ALLOW_PROMISOR:
199
200
if (revs->do_not_die_on_missing_objects &&
201
oidset_contains(&revs->missing_commits, &commit->object.oid)) {
155
- finish_object__ma(&commit->object);
202
+ finish_object__ma(&commit->object, NULL);
203
return;
204
}
205
315
finish_commit(commit);
316
}
317
271
-static int finish_object(struct object *obj, const char *name UNUSED,
272
- void *cb_data)
318
+static int finish_object(struct object *obj, const char *name, void *cb_data)
319
{
320
struct rev_list_info *info = cb_data;
321
if (oid_object_info_extended(the_repository, &obj->oid, NULL, 0) < 0) {
276
- finish_object__ma(obj);
322
+ finish_object__ma(obj, name);
323
return 1;
324
}
325
if (info->revs->verify_objects && !obj->parsed && obj->type != OBJ_COMMIT)
460
return 1;
461
}
462
463
+ if (!strcmp(value, "print-info")) {
464
+ arg_missing_action = MA_PRINT_INFO;
465
+ fetch_if_missing = 0;
466
+ return 1;
467
+ }
468
+
469
if (!strcmp(value, "allow-promisor")) {
470
arg_missing_action = MA_ALLOW_PROMISOR;
471
fetch_if_missing = 0;
833
834
if (arg_print_omitted)
835
oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE);
784
- if (arg_missing_action == MA_PRINT) {
785
- oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE);
836
+ if (arg_missing_action == MA_PRINT ||
837
+ arg_missing_action == MA_PRINT_INFO) {
838
+ struct oidset_iter iter;
839
+ struct object_id *oid;
840
+
841
+ oidmap_init(&missing_objects, DEFAULT_OIDSET_SIZE);
842
+ oidset_iter_init(&revs.missing_commits, &iter);
843
+
844
/* Add missing tips */
787
- oidset_insert_from_set(&missing_objects, &revs.missing_commits);
845
+ while ((oid = oidset_iter_next(&iter)))
846
+ add_missing_object_entry(oid, NULL);
847
+
848
oidset_clear(&revs.missing_commits);
849
}
850
860
printf("~%s\n", oid_to_hex(oid));
861
oidset_clear(&omitted_objects);
862
}
803
- if (arg_missing_action == MA_PRINT) {
804
- struct oidset_iter iter;
805
- struct object_id *oid;
806
- oidset_iter_init(&missing_objects, &iter);
807
- while ((oid = oidset_iter_next(&iter)))
808
- printf("?%s\n", oid_to_hex(oid));
809
- oidset_clear(&missing_objects);
863
+ if (arg_missing_action == MA_PRINT ||
864
+ arg_missing_action == MA_PRINT_INFO) {
865
+ struct missing_objects_map_entry *entry;
866
+ struct oidmap_iter iter;
867
+
868
+ oidmap_iter_init(&missing_objects, &iter);
869
+
870
+ while ((entry = oidmap_iter_next(&iter))) {
871
+ print_missing_object(entry, arg_missing_action ==
872
+ MA_PRINT_INFO);
873
+ free((void *)entry->path);
874
+ }
875
+
876
+ oidmap_free(&missing_objects, true);
877
}
878
879
stop_progress(&progress);