9
9
#include "object.h"
10
10
#include "remote.h"
11
11
#include "transport.h"
12
+ #include "string-list.h"
12
13
13
14
static const char receive_pack_usage [] = "git receive-pack <git-dir>" ;
14
15
@@ -129,13 +130,12 @@ static void write_head_info(void)
129
130
struct command {
130
131
struct command * next ;
131
132
const char * error_string ;
133
+ unsigned int skip_update ;
132
134
unsigned char old_sha1 [20 ];
133
135
unsigned char new_sha1 [20 ];
134
136
char ref_name [FLEX_ARRAY ]; /* more */
135
137
};
136
138
137
- static struct command * commands ;
138
-
139
139
static const char pre_receive_hook [] = "hooks/pre-receive" ;
140
140
static const char post_receive_hook [] = "hooks/post-receive" ;
141
141
@@ -188,7 +188,7 @@ static int copy_to_sideband(int in, int out, void *arg)
188
188
return 0 ;
189
189
}
190
190
191
- static int run_receive_hook (const char * hook_name )
191
+ static int run_receive_hook (struct command * commands , const char * hook_name )
192
192
{
193
193
static char buf [sizeof (commands -> old_sha1 ) * 2 + PATH_MAX + 4 ];
194
194
struct command * cmd ;
@@ -447,15 +447,15 @@ static const char *update(struct command *cmd)
447
447
448
448
static char update_post_hook [] = "hooks/post-update" ;
449
449
450
- static void run_update_post_hook (struct command * cmd )
450
+ static void run_update_post_hook (struct command * commands )
451
451
{
452
- struct command * cmd_p ;
452
+ struct command * cmd ;
453
453
int argc ;
454
454
const char * * argv ;
455
455
struct child_process proc ;
456
456
457
- for (argc = 0 , cmd_p = cmd ; cmd_p ; cmd_p = cmd_p -> next ) {
458
- if (cmd_p -> error_string )
457
+ for (argc = 0 , cmd = commands ; cmd ; cmd = cmd -> next ) {
458
+ if (cmd -> error_string )
459
459
continue ;
460
460
argc ++ ;
461
461
}
@@ -464,12 +464,12 @@ static void run_update_post_hook(struct command *cmd)
464
464
argv = xmalloc (sizeof (* argv ) * (2 + argc ));
465
465
argv [0 ] = update_post_hook ;
466
466
467
- for (argc = 1 , cmd_p = cmd ; cmd_p ; cmd_p = cmd_p -> next ) {
467
+ for (argc = 1 , cmd = commands ; cmd ; cmd = cmd -> next ) {
468
468
char * p ;
469
- if (cmd_p -> error_string )
469
+ if (cmd -> error_string )
470
470
continue ;
471
- p = xmalloc (strlen (cmd_p -> ref_name ) + 1 );
472
- strcpy (p , cmd_p -> ref_name );
471
+ p = xmalloc (strlen (cmd -> ref_name ) + 1 );
472
+ strcpy (p , cmd -> ref_name );
473
473
argv [argc ] = p ;
474
474
argc ++ ;
475
475
}
@@ -488,37 +488,92 @@ static void run_update_post_hook(struct command *cmd)
488
488
}
489
489
}
490
490
491
- static void execute_commands (const char * unpacker_error )
491
+ static void check_aliased_update (struct command * cmd , struct string_list * list )
492
+ {
493
+ struct string_list_item * item ;
494
+ struct command * dst_cmd ;
495
+ unsigned char sha1 [20 ];
496
+ char cmd_oldh [41 ], cmd_newh [41 ], dst_oldh [41 ], dst_newh [41 ];
497
+ int flag ;
498
+
499
+ const char * dst_name = resolve_ref (cmd -> ref_name , sha1 , 0 , & flag );
500
+
501
+ if (!(flag & REF_ISSYMREF ))
502
+ return ;
503
+
504
+ if ((item = string_list_lookup (dst_name , list )) == NULL )
505
+ return ;
506
+
507
+ cmd -> skip_update = 1 ;
508
+
509
+ dst_cmd = (struct command * ) item -> util ;
510
+
511
+ if (!hashcmp (cmd -> old_sha1 , dst_cmd -> old_sha1 ) &&
512
+ !hashcmp (cmd -> new_sha1 , dst_cmd -> new_sha1 ))
513
+ return ;
514
+
515
+ dst_cmd -> skip_update = 1 ;
516
+
517
+ strcpy (cmd_oldh , find_unique_abbrev (cmd -> old_sha1 , DEFAULT_ABBREV ));
518
+ strcpy (cmd_newh , find_unique_abbrev (cmd -> new_sha1 , DEFAULT_ABBREV ));
519
+ strcpy (dst_oldh , find_unique_abbrev (dst_cmd -> old_sha1 , DEFAULT_ABBREV ));
520
+ strcpy (dst_newh , find_unique_abbrev (dst_cmd -> new_sha1 , DEFAULT_ABBREV ));
521
+ rp_error ("refusing inconsistent update between symref '%s' (%s..%s) and"
522
+ " its target '%s' (%s..%s)" ,
523
+ cmd -> ref_name , cmd_oldh , cmd_newh ,
524
+ dst_cmd -> ref_name , dst_oldh , dst_newh );
525
+
526
+ cmd -> error_string = dst_cmd -> error_string =
527
+ "inconsistent aliased update" ;
528
+ }
529
+
530
+ static void check_aliased_updates (struct command * commands )
531
+ {
532
+ struct command * cmd ;
533
+ struct string_list ref_list = { NULL , 0 , 0 , 0 };
534
+
535
+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
536
+ struct string_list_item * item =
537
+ string_list_append (cmd -> ref_name , & ref_list );
538
+ item -> util = (void * )cmd ;
539
+ }
540
+ sort_string_list (& ref_list );
541
+
542
+ for (cmd = commands ; cmd ; cmd = cmd -> next )
543
+ check_aliased_update (cmd , & ref_list );
544
+
545
+ string_list_clear (& ref_list , 0 );
546
+ }
547
+
548
+ static void execute_commands (struct command * commands , const char * unpacker_error )
492
549
{
493
- struct command * cmd = commands ;
550
+ struct command * cmd ;
494
551
unsigned char sha1 [20 ];
495
552
496
553
if (unpacker_error ) {
497
- while (cmd ) {
554
+ for (cmd = commands ; cmd ; cmd = cmd -> next )
498
555
cmd -> error_string = "n/a (unpacker error)" ;
499
- cmd = cmd -> next ;
500
- }
501
556
return ;
502
557
}
503
558
504
- if (run_receive_hook (pre_receive_hook )) {
505
- while (cmd ) {
559
+ if (run_receive_hook (commands , pre_receive_hook )) {
560
+ for (cmd = commands ; cmd ; cmd = cmd -> next )
506
561
cmd -> error_string = "pre-receive hook declined" ;
507
- cmd = cmd -> next ;
508
- }
509
562
return ;
510
563
}
511
564
565
+ check_aliased_updates (commands );
566
+
512
567
head_name = resolve_ref ("HEAD" , sha1 , 0 , NULL );
513
568
514
- while (cmd ) {
515
- cmd -> error_string = update (cmd );
516
- cmd = cmd -> next ;
517
- }
569
+ for (cmd = commands ; cmd ; cmd = cmd -> next )
570
+ if (!cmd -> skip_update )
571
+ cmd -> error_string = update (cmd );
518
572
}
519
573
520
- static void read_head_info (void )
574
+ static struct command * read_head_info (void )
521
575
{
576
+ struct command * commands = NULL ;
522
577
struct command * * p = & commands ;
523
578
for (;;) {
524
579
static char line [1000 ];
@@ -548,15 +603,14 @@ static void read_head_info(void)
548
603
if (strstr (refname + reflen + 1 , "side-band-64k" ))
549
604
use_sideband = LARGE_PACKET_MAX ;
550
605
}
551
- cmd = xmalloc ( sizeof (struct command ) + len - 80 );
606
+ cmd = xcalloc ( 1 , sizeof (struct command ) + len - 80 );
552
607
hashcpy (cmd -> old_sha1 , old_sha1 );
553
608
hashcpy (cmd -> new_sha1 , new_sha1 );
554
609
memcpy (cmd -> ref_name , line + 82 , len - 81 );
555
- cmd -> error_string = NULL ;
556
- cmd -> next = NULL ;
557
610
* p = cmd ;
558
611
p = & cmd -> next ;
559
612
}
613
+ return commands ;
560
614
}
561
615
562
616
static const char * parse_pack_header (struct pack_header * hdr )
@@ -643,7 +697,7 @@ static const char *unpack(void)
643
697
}
644
698
}
645
699
646
- static void report (const char * unpack_status )
700
+ static void report (struct command * commands , const char * unpack_status )
647
701
{
648
702
struct command * cmd ;
649
703
struct strbuf buf = STRBUF_INIT ;
@@ -667,12 +721,12 @@ static void report(const char *unpack_status)
667
721
strbuf_release (& buf );
668
722
}
669
723
670
- static int delete_only (struct command * cmd )
724
+ static int delete_only (struct command * commands )
671
725
{
672
- while (cmd ) {
726
+ struct command * cmd ;
727
+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
673
728
if (!is_null_sha1 (cmd -> new_sha1 ))
674
729
return 0 ;
675
- cmd = cmd -> next ;
676
730
}
677
731
return 1 ;
678
732
}
@@ -722,6 +776,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
722
776
int stateless_rpc = 0 ;
723
777
int i ;
724
778
char * dir = NULL ;
779
+ struct command * commands ;
725
780
726
781
argv ++ ;
727
782
for (i = 1 ; i < argc ; i ++ ) {
@@ -772,18 +827,17 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
772
827
if (advertise_refs )
773
828
return 0 ;
774
829
775
- read_head_info ();
776
- if (commands ) {
830
+ if ((commands = read_head_info ()) != NULL ) {
777
831
const char * unpack_status = NULL ;
778
832
779
833
if (!delete_only (commands ))
780
834
unpack_status = unpack ();
781
- execute_commands (unpack_status );
835
+ execute_commands (commands , unpack_status );
782
836
if (pack_lockfile )
783
837
unlink_or_warn (pack_lockfile );
784
838
if (report_status )
785
- report (unpack_status );
786
- run_receive_hook (post_receive_hook );
839
+ report (commands , unpack_status );
840
+ run_receive_hook (commands , post_receive_hook );
787
841
run_update_post_hook (commands );
788
842
if (auto_gc ) {
789
843
const char * argv_gc_auto [] = {
0 commit comments