1212
1313static const char upload_pack_usage [] = "git-upload-pack [--strict] [--timeout=nn] <dir>" ;
1414
15- #define THEY_HAVE (1U << 0)
16- #define OUR_REF (1U << 1)
17- #define WANTED (1U << 2)
15+ /* bits #0..7 in revision.h, #8..10 in commit.c */
16+ #define THEY_HAVE (1u << 11)
17+ #define OUR_REF (1u << 12)
18+ #define WANTED (1u << 13)
19+ #define COMMON_KNOWN (1u << 14)
20+ #define REACHABLE (1u << 15)
21+
22+ static unsigned long oldest_have ;
23+
1824static int multi_ack , nr_our_refs ;
1925static int use_thin_pack , use_ofs_delta ;
2026static struct object_array have_obj ;
@@ -303,11 +309,12 @@ static void create_pack_file(void)
303309static int got_sha1 (char * hex , unsigned char * sha1 )
304310{
305311 struct object * o ;
312+ int we_knew_they_have = 0 ;
306313
307314 if (get_sha1_hex (hex , sha1 ))
308315 die ("git-upload-pack: expected SHA1 object, got '%s'" , hex );
309316 if (!has_sha1_file (sha1 ))
310- return 0 ;
317+ return -1 ;
311318
312319 o = lookup_object (sha1 );
313320 if (!(o && o -> parsed ))
@@ -316,15 +323,84 @@ static int got_sha1(char *hex, unsigned char *sha1)
316323 die ("oops (%s)" , sha1_to_hex (sha1 ));
317324 if (o -> type == OBJ_COMMIT ) {
318325 struct commit_list * parents ;
326+ struct commit * commit = (struct commit * )o ;
319327 if (o -> flags & THEY_HAVE )
320- return 0 ;
321- o -> flags |= THEY_HAVE ;
322- for (parents = ((struct commit * )o )-> parents ;
328+ we_knew_they_have = 1 ;
329+ else
330+ o -> flags |= THEY_HAVE ;
331+ if (!oldest_have || (commit -> date < oldest_have ))
332+ oldest_have = commit -> date ;
333+ for (parents = commit -> parents ;
323334 parents ;
324335 parents = parents -> next )
325336 parents -> item -> object .flags |= THEY_HAVE ;
326337 }
327- add_object_array (o , NULL , & have_obj );
338+ if (!we_knew_they_have ) {
339+ add_object_array (o , NULL , & have_obj );
340+ return 1 ;
341+ }
342+ return 0 ;
343+ }
344+
345+ static int reachable (struct commit * want )
346+ {
347+ struct commit_list * work = NULL ;
348+
349+ insert_by_date (want , & work );
350+ while (work ) {
351+ struct commit_list * list = work -> next ;
352+ struct commit * commit = work -> item ;
353+ free (work );
354+ work = list ;
355+
356+ if (commit -> object .flags & THEY_HAVE ) {
357+ want -> object .flags |= COMMON_KNOWN ;
358+ break ;
359+ }
360+ if (!commit -> object .parsed )
361+ parse_object (commit -> object .sha1 );
362+ if (commit -> object .flags & REACHABLE )
363+ continue ;
364+ commit -> object .flags |= REACHABLE ;
365+ if (commit -> date < oldest_have )
366+ continue ;
367+ for (list = commit -> parents ; list ; list = list -> next ) {
368+ struct commit * parent = list -> item ;
369+ if (!(parent -> object .flags & REACHABLE ))
370+ insert_by_date (parent , & work );
371+ }
372+ }
373+ want -> object .flags |= REACHABLE ;
374+ clear_commit_marks (want , REACHABLE );
375+ free_commit_list (work );
376+ return (want -> object .flags & COMMON_KNOWN );
377+ }
378+
379+ static int ok_to_give_up (void )
380+ {
381+ int i ;
382+
383+ if (!have_obj .nr )
384+ return 0 ;
385+
386+ for (i = 0 ; i < want_obj .nr ; i ++ ) {
387+ struct object * want = want_obj .objects [i ].item ;
388+
389+ if (want -> flags & COMMON_KNOWN )
390+ continue ;
391+ want = deref_tag (want , "a want line" , 0 );
392+ if (!want || want -> type != OBJ_COMMIT ) {
393+ /* no way to tell if this is reachable by
394+ * looking at the ancestry chain alone, so
395+ * leave a note to ourselves not to worry about
396+ * this object anymore.
397+ */
398+ want_obj .objects [i ].item -> flags |= COMMON_KNOWN ;
399+ continue ;
400+ }
401+ if (!reachable ((struct commit * )want ))
402+ return 0 ;
403+ }
328404 return 1 ;
329405}
330406
@@ -349,7 +425,13 @@ static int get_common_commits(void)
349425 }
350426 len = strip (line , len );
351427 if (!strncmp (line , "have " , 5 )) {
352- if (got_sha1 (line + 5 , sha1 )) {
428+ switch (got_sha1 (line + 5 , sha1 )) {
429+ case -1 : /* they have what we do not */
430+ if (multi_ack && ok_to_give_up ())
431+ packet_write (1 , "ACK %s continue\n" ,
432+ sha1_to_hex (sha1 ));
433+ break ;
434+ default :
353435 memcpy (hex , sha1_to_hex (sha1 ), 41 );
354436 if (multi_ack ) {
355437 const char * msg = "ACK %s continue\n" ;
@@ -358,6 +440,7 @@ static int get_common_commits(void)
358440 }
359441 else if (have_obj .nr == 1 )
360442 packet_write (1 , "ACK %s\n" , hex );
443+ break ;
361444 }
362445 continue ;
363446 }
0 commit comments