22
22
#include "progress.h"
23
23
#include "reflog-walk.h"
24
24
#include "oidset.h"
25
+ #include "oidmap.h"
25
26
#include "packfile.h"
27
+ #include "quote.h"
28
+ #include "strbuf.h"
26
29
27
30
static const char rev_list_usage [] =
28
31
"git rev-list [<options>] <commit>... [--] [<path>...]\n"
@@ -73,11 +76,17 @@ static unsigned progress_counter;
73
76
static struct oidset omitted_objects ;
74
77
static int arg_print_omitted ; /* print objects omitted by filter */
75
78
76
- static struct oidset missing_objects ;
79
+ struct missing_objects_map_entry {
80
+ struct oidmap_entry entry ;
81
+ const char * path ;
82
+ unsigned type ;
83
+ };
84
+ static struct oidmap missing_objects ;
77
85
enum missing_action {
78
86
MA_ERROR = 0 , /* fail if any missing objects are encountered */
79
87
MA_ALLOW_ANY , /* silently allow ALL missing objects */
80
88
MA_PRINT , /* print ALL missing objects in special section */
89
+ MA_PRINT_INFO , /* same as MA_PRINT but also prints missing object info */
81
90
MA_ALLOW_PROMISOR , /* silently allow all missing PROMISOR objects */
82
91
};
83
92
static enum missing_action arg_missing_action ;
@@ -101,7 +110,49 @@ static off_t get_object_disk_usage(struct object *obj)
101
110
return size ;
102
111
}
103
112
104
- static inline void finish_object__ma (struct object * obj )
113
+ static void add_missing_object_entry (struct object_id * oid , const char * path ,
114
+ unsigned type )
115
+ {
116
+ struct missing_objects_map_entry * entry ;
117
+
118
+ if (oidmap_get (& missing_objects , oid ))
119
+ return ;
120
+
121
+ CALLOC_ARRAY (entry , 1 );
122
+ entry -> entry .oid = * oid ;
123
+ entry -> type = type ;
124
+ if (path )
125
+ entry -> path = xstrdup (path );
126
+ oidmap_put (& missing_objects , entry );
127
+ }
128
+
129
+ static void print_missing_object (struct missing_objects_map_entry * entry ,
130
+ int print_missing_info )
131
+ {
132
+ struct strbuf sb = STRBUF_INIT ;
133
+
134
+ if (!print_missing_info ) {
135
+ printf ("?%s\n" , oid_to_hex (& entry -> entry .oid ));
136
+ return ;
137
+ }
138
+
139
+ if (entry -> path && * entry -> path ) {
140
+ struct strbuf path = STRBUF_INIT ;
141
+
142
+ strbuf_addstr (& sb , " path=" );
143
+ quote_path (entry -> path , NULL , & path , QUOTE_PATH_QUOTE_SP );
144
+ strbuf_addbuf (& sb , & path );
145
+
146
+ strbuf_release (& path );
147
+ }
148
+ if (entry -> type )
149
+ strbuf_addf (& sb , " type=%s" , type_name (entry -> type ));
150
+
151
+ printf ("?%s%s\n" , oid_to_hex (& entry -> entry .oid ), sb .buf );
152
+ strbuf_release (& sb );
153
+ }
154
+
155
+ static inline void finish_object__ma (struct object * obj , const char * name )
105
156
{
106
157
/*
107
158
* Whether or not we try to dynamically fetch missing objects
@@ -119,7 +170,8 @@ static inline void finish_object__ma(struct object *obj)
119
170
return ;
120
171
121
172
case MA_PRINT :
122
- oidset_insert (& missing_objects , & obj -> oid );
173
+ case MA_PRINT_INFO :
174
+ add_missing_object_entry (& obj -> oid , name , obj -> type );
123
175
return ;
124
176
125
177
case MA_ALLOW_PROMISOR :
@@ -152,7 +204,7 @@ static void show_commit(struct commit *commit, void *data)
152
204
153
205
if (revs -> do_not_die_on_missing_objects &&
154
206
oidset_contains (& revs -> missing_commits , & commit -> object .oid )) {
155
- finish_object__ma (& commit -> object );
207
+ finish_object__ma (& commit -> object , NULL );
156
208
return ;
157
209
}
158
210
@@ -268,12 +320,11 @@ static void show_commit(struct commit *commit, void *data)
268
320
finish_commit (commit );
269
321
}
270
322
271
- static int finish_object (struct object * obj , const char * name UNUSED ,
272
- void * cb_data )
323
+ static int finish_object (struct object * obj , const char * name , void * cb_data )
273
324
{
274
325
struct rev_list_info * info = cb_data ;
275
326
if (oid_object_info_extended (the_repository , & obj -> oid , NULL , 0 ) < 0 ) {
276
- finish_object__ma (obj );
327
+ finish_object__ma (obj , name );
277
328
return 1 ;
278
329
}
279
330
if (info -> revs -> verify_objects && !obj -> parsed && obj -> type != OBJ_COMMIT )
@@ -414,6 +465,12 @@ static inline int parse_missing_action_value(const char *value)
414
465
return 1 ;
415
466
}
416
467
468
+ if (!strcmp (value , "print-info" )) {
469
+ arg_missing_action = MA_PRINT_INFO ;
470
+ fetch_if_missing = 0 ;
471
+ return 1 ;
472
+ }
473
+
417
474
if (!strcmp (value , "allow-promisor" )) {
418
475
arg_missing_action = MA_ALLOW_PROMISOR ;
419
476
fetch_if_missing = 0 ;
@@ -781,10 +838,18 @@ int cmd_rev_list(int argc,
781
838
782
839
if (arg_print_omitted )
783
840
oidset_init (& omitted_objects , DEFAULT_OIDSET_SIZE );
784
- if (arg_missing_action == MA_PRINT ) {
785
- oidset_init (& missing_objects , DEFAULT_OIDSET_SIZE );
841
+ if (arg_missing_action == MA_PRINT ||
842
+ arg_missing_action == MA_PRINT_INFO ) {
843
+ struct oidset_iter iter ;
844
+ struct object_id * oid ;
845
+
846
+ oidmap_init (& missing_objects , DEFAULT_OIDSET_SIZE );
847
+ oidset_iter_init (& revs .missing_commits , & iter );
848
+
786
849
/* Add missing tips */
787
- oidset_insert_from_set (& missing_objects , & revs .missing_commits );
850
+ while ((oid = oidset_iter_next (& iter )))
851
+ add_missing_object_entry (oid , NULL , 0 );
852
+
788
853
oidset_clear (& revs .missing_commits );
789
854
}
790
855
@@ -800,13 +865,20 @@ int cmd_rev_list(int argc,
800
865
printf ("~%s\n" , oid_to_hex (oid ));
801
866
oidset_clear (& omitted_objects );
802
867
}
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 );
868
+ if (arg_missing_action == MA_PRINT ||
869
+ arg_missing_action == MA_PRINT_INFO ) {
870
+ struct missing_objects_map_entry * entry ;
871
+ struct oidmap_iter iter ;
872
+
873
+ oidmap_iter_init (& missing_objects , & iter );
874
+
875
+ while ((entry = oidmap_iter_next (& iter ))) {
876
+ print_missing_object (entry , arg_missing_action ==
877
+ MA_PRINT_INFO );
878
+ free ((void * )entry -> path );
879
+ }
880
+
881
+ oidmap_free (& missing_objects , true);
810
882
}
811
883
812
884
stop_progress (& progress );
0 commit comments