@@ -38,9 +38,11 @@ static int receive_fsck_objects = -1;
3838static int transfer_fsck_objects = -1 ;
3939static int receive_unpack_limit = -1 ;
4040static int transfer_unpack_limit = -1 ;
41+ static int advertise_atomic_push = 1 ;
4142static int unpack_limit = 100 ;
4243static int report_status ;
4344static int use_sideband ;
45+ static int use_atomic ;
4446static int quiet ;
4547static int prefer_ofs_delta = 1 ;
4648static int auto_update_server_info ;
@@ -67,6 +69,7 @@ static const char *NONCE_SLOP = "SLOP";
6769static const char * nonce_status ;
6870static long nonce_stamp_slop ;
6971static unsigned long nonce_stamp_slop_limit ;
72+ static struct ref_transaction * transaction ;
7073
7174static enum deny_action parse_deny_action (const char * var , const char * value )
7275{
@@ -160,6 +163,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
160163 return 0 ;
161164 }
162165
166+ if (strcmp (var , "receive.advertiseatomic" ) == 0 ) {
167+ advertise_atomic_push = git_config_bool (var , value );
168+ return 0 ;
169+ }
170+
163171 return git_default_config (var , value , cb );
164172}
165173
@@ -175,6 +183,8 @@ static void show_ref(const char *path, const unsigned char *sha1)
175183
176184 strbuf_addstr (& cap ,
177185 "report-status delete-refs side-band-64k quiet" );
186+ if (advertise_atomic_push )
187+ strbuf_addstr (& cap , " atomic" );
178188 if (prefer_ofs_delta )
179189 strbuf_addstr (& cap , " ofs-delta" );
180190 if (push_cert_nonce )
@@ -910,6 +920,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
910920 }
911921
912922 if (is_null_sha1 (new_sha1 )) {
923+ struct strbuf err = STRBUF_INIT ;
913924 if (!parse_object (old_sha1 )) {
914925 old_sha1 = NULL ;
915926 if (ref_exists (name )) {
@@ -919,35 +930,36 @@ static const char *update(struct command *cmd, struct shallow_info *si)
919930 cmd -> did_not_exist = 1 ;
920931 }
921932 }
922- if (delete_ref (namespaced_name , old_sha1 , 0 )) {
923- rp_error ("failed to delete %s" , name );
933+ if (ref_transaction_delete (transaction ,
934+ namespaced_name ,
935+ old_sha1 ,
936+ 0 , old_sha1 != NULL ,
937+ "push" , & err )) {
938+ rp_error ("%s" , err .buf );
939+ strbuf_release (& err );
924940 return "failed to delete" ;
925941 }
942+ strbuf_release (& err );
926943 return NULL ; /* good */
927944 }
928945 else {
929946 struct strbuf err = STRBUF_INIT ;
930- struct ref_transaction * transaction ;
931-
932947 if (shallow_update && si -> shallow_ref [cmd -> index ] &&
933948 update_shallow_ref (cmd , si ))
934949 return "shallow error" ;
935950
936- transaction = ref_transaction_begin (& err );
937- if (!transaction ||
938- ref_transaction_update (transaction , namespaced_name ,
939- new_sha1 , old_sha1 , 0 , 1 , "push" ,
940- & err ) ||
941- ref_transaction_commit (transaction , & err )) {
942- ref_transaction_free (transaction );
943-
951+ if (ref_transaction_update (transaction ,
952+ namespaced_name ,
953+ new_sha1 , old_sha1 ,
954+ 0 , 1 , "push" ,
955+ & err )) {
944956 rp_error ("%s" , err .buf );
945957 strbuf_release (& err );
958+
946959 return "failed to update ref" ;
947960 }
948-
949- ref_transaction_free (transaction );
950961 strbuf_release (& err );
962+
951963 return NULL ; /* good */
952964 }
953965}
@@ -1131,11 +1143,105 @@ static void reject_updates_to_hidden(struct command *commands)
11311143 }
11321144}
11331145
1146+ static int should_process_cmd (struct command * cmd )
1147+ {
1148+ return !cmd -> error_string && !cmd -> skip_update ;
1149+ }
1150+
1151+ static void warn_if_skipped_connectivity_check (struct command * commands ,
1152+ struct shallow_info * si )
1153+ {
1154+ struct command * cmd ;
1155+ int checked_connectivity = 1 ;
1156+
1157+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
1158+ if (should_process_cmd (cmd ) && si -> shallow_ref [cmd -> index ]) {
1159+ error ("BUG: connectivity check has not been run on ref %s" ,
1160+ cmd -> ref_name );
1161+ checked_connectivity = 0 ;
1162+ }
1163+ }
1164+ if (!checked_connectivity )
1165+ die ("BUG: connectivity check skipped???" );
1166+ }
1167+
1168+ static void execute_commands_non_atomic (struct command * commands ,
1169+ struct shallow_info * si )
1170+ {
1171+ struct command * cmd ;
1172+ struct strbuf err = STRBUF_INIT ;
1173+
1174+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
1175+ if (!should_process_cmd (cmd ))
1176+ continue ;
1177+
1178+ transaction = ref_transaction_begin (& err );
1179+ if (!transaction ) {
1180+ rp_error ("%s" , err .buf );
1181+ strbuf_reset (& err );
1182+ cmd -> error_string = "transaction failed to start" ;
1183+ continue ;
1184+ }
1185+
1186+ cmd -> error_string = update (cmd , si );
1187+
1188+ if (!cmd -> error_string
1189+ && ref_transaction_commit (transaction , & err )) {
1190+ rp_error ("%s" , err .buf );
1191+ strbuf_reset (& err );
1192+ cmd -> error_string = "failed to update ref" ;
1193+ }
1194+ ref_transaction_free (transaction );
1195+ }
1196+ strbuf_release (& err );
1197+ }
1198+
1199+ static void execute_commands_atomic (struct command * commands ,
1200+ struct shallow_info * si )
1201+ {
1202+ struct command * cmd ;
1203+ struct strbuf err = STRBUF_INIT ;
1204+ const char * reported_error = "atomic push failure" ;
1205+
1206+ transaction = ref_transaction_begin (& err );
1207+ if (!transaction ) {
1208+ rp_error ("%s" , err .buf );
1209+ strbuf_reset (& err );
1210+ reported_error = "transaction failed to start" ;
1211+ goto failure ;
1212+ }
1213+
1214+ for (cmd = commands ; cmd ; cmd = cmd -> next ) {
1215+ if (!should_process_cmd (cmd ))
1216+ continue ;
1217+
1218+ cmd -> error_string = update (cmd , si );
1219+
1220+ if (cmd -> error_string )
1221+ goto failure ;
1222+ }
1223+
1224+ if (ref_transaction_commit (transaction , & err )) {
1225+ rp_error ("%s" , err .buf );
1226+ reported_error = "atomic transaction failed" ;
1227+ goto failure ;
1228+ }
1229+ goto cleanup ;
1230+
1231+ failure :
1232+ for (cmd = commands ; cmd ; cmd = cmd -> next )
1233+ if (!cmd -> error_string )
1234+ cmd -> error_string = reported_error ;
1235+
1236+ cleanup :
1237+ ref_transaction_free (transaction );
1238+ strbuf_release (& err );
1239+ }
1240+
11341241static void execute_commands (struct command * commands ,
11351242 const char * unpacker_error ,
11361243 struct shallow_info * si )
11371244{
1138- int checked_connectivity ;
11391245 struct command * cmd ;
11401246 unsigned char sha1 [20 ];
11411247 struct iterate_data data ;
@@ -1166,27 +1272,13 @@ static void execute_commands(struct command *commands,
11661272 free (head_name_to_free );
11671273 head_name = head_name_to_free = resolve_refdup ("HEAD" , 0 , sha1 , NULL );
11681274
1169- checked_connectivity = 1 ;
1170- for (cmd = commands ; cmd ; cmd = cmd -> next ) {
1171- if (cmd -> error_string )
1172- continue ;
1173-
1174- if (cmd -> skip_update )
1175- continue ;
1176-
1177- cmd -> error_string = update (cmd , si );
1178- if (shallow_update && !cmd -> error_string &&
1179- si -> shallow_ref [cmd -> index ]) {
1180- error ("BUG: connectivity check has not been run on ref %s" ,
1181- cmd -> ref_name );
1182- checked_connectivity = 0 ;
1183- }
1184- }
1275+ if (use_atomic )
1276+ execute_commands_atomic (commands , si );
1277+ else
1278+ execute_commands_non_atomic (commands , si );
11851279
1186- if (shallow_update && !checked_connectivity )
1187- error ("BUG: run 'git fsck' for safety.\n"
1188- "If there are errors, try to remove "
1189- "the reported refs above" );
1280+ if (shallow_update )
1281+ warn_if_skipped_connectivity_check (commands , si );
11901282}
11911283
11921284static struct command * * queue_command (struct command * * tail ,
@@ -1268,6 +1360,9 @@ static struct command *read_head_info(struct sha1_array *shallow)
12681360 use_sideband = LARGE_PACKET_MAX ;
12691361 if (parse_feature_request (feature_list , "quiet" ))
12701362 quiet = 1 ;
1363+ if (advertise_atomic_push
1364+ && parse_feature_request (feature_list , "atomic" ))
1365+ use_atomic = 1 ;
12711366 }
12721367
12731368 if (!strcmp (line , "push-cert" )) {
0 commit comments