@@ -155,10 +155,14 @@ void check_shallow_file_for_update(void)
155155 die ("shallow file was changed during fetch" );
156156}
157157
158+ #define SEEN_ONLY 1
159+ #define VERBOSE 2
160+
158161struct write_shallow_data {
159162 struct strbuf * out ;
160163 int use_pack_protocol ;
161164 int count ;
165+ unsigned flags ;
162166};
163167
164168static int write_one_shallow (const struct commit_graft * graft , void * cb_data )
@@ -167,6 +171,15 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
167171 const char * hex = sha1_to_hex (graft -> sha1 );
168172 if (graft -> nr_parent != -1 )
169173 return 0 ;
174+ if (data -> flags & SEEN_ONLY ) {
175+ struct commit * c = lookup_commit (graft -> sha1 );
176+ if (!c || !(c -> object .flags & SEEN )) {
177+ if (data -> flags & VERBOSE )
178+ printf ("Removing %s from .git/shallow\n" ,
179+ sha1_to_hex (c -> object .sha1 ));
180+ return 0 ;
181+ }
182+ }
170183 data -> count ++ ;
171184 if (data -> use_pack_protocol )
172185 packet_buf_write (data -> out , "shallow %s" , hex );
@@ -177,14 +190,16 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
177190 return 0 ;
178191}
179192
180- int write_shallow_commits (struct strbuf * out , int use_pack_protocol ,
181- const struct sha1_array * extra )
193+ static int write_shallow_commits_1 (struct strbuf * out , int use_pack_protocol ,
194+ const struct sha1_array * extra ,
195+ unsigned flags )
182196{
183197 struct write_shallow_data data ;
184198 int i ;
185199 data .out = out ;
186200 data .use_pack_protocol = use_pack_protocol ;
187201 data .count = 0 ;
202+ data .flags = flags ;
188203 for_each_commit_graft (write_one_shallow , & data );
189204 if (!extra )
190205 return data .count ;
@@ -196,6 +211,12 @@ int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
196211 return data .count ;
197212}
198213
214+ int write_shallow_commits (struct strbuf * out , int use_pack_protocol ,
215+ const struct sha1_array * extra )
216+ {
217+ return write_shallow_commits_1 (out , use_pack_protocol , extra , 0 );
218+ }
219+
199220char * setup_temporary_shallow (const struct sha1_array * extra )
200221{
201222 struct strbuf sb = STRBUF_INIT ;
@@ -258,6 +279,36 @@ void advertise_shallow_grafts(int fd)
258279 for_each_commit_graft (advertise_shallow_grafts_cb , & fd );
259280}
260281
282+ /*
283+ * mark_reachable_objects() should have been run prior to this and all
284+ * reachable commits marked as "SEEN".
285+ */
286+ void prune_shallow (int show_only )
287+ {
288+ static struct lock_file shallow_lock ;
289+ struct strbuf sb = STRBUF_INIT ;
290+ int fd ;
291+
292+ if (show_only ) {
293+ write_shallow_commits_1 (& sb , 0 , NULL , SEEN_ONLY | VERBOSE );
294+ strbuf_release (& sb );
295+ return ;
296+ }
297+ check_shallow_file_for_update ();
298+ fd = hold_lock_file_for_update (& shallow_lock , git_path ("shallow" ),
299+ LOCK_DIE_ON_ERROR );
300+ if (write_shallow_commits_1 (& sb , 0 , NULL , SEEN_ONLY )) {
301+ if (write_in_full (fd , sb .buf , sb .len ) != sb .len )
302+ die_errno ("failed to write to %s" ,
303+ shallow_lock .filename );
304+ commit_lock_file (& shallow_lock );
305+ } else {
306+ unlink (git_path ("shallow" ));
307+ rollback_lock_file (& shallow_lock );
308+ }
309+ strbuf_release (& sb );
310+ }
311+
261312#define TRACE_KEY "GIT_TRACE_SHALLOW"
262313
263314/*
0 commit comments