@@ -1316,65 +1316,72 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing)
13161316 die (_ ("Aborting." ));
13171317}
13181318
1319- static int run_pre_push_hook (struct transport * transport ,
1320- struct ref * remote_refs )
1321- {
1322- int ret = 0 , x ;
1323- struct ref * r ;
1324- struct child_process proc = CHILD_PROCESS_INIT ;
1319+ struct feed_pre_push_hook_data {
13251320 struct strbuf buf ;
1326- const char * hook_path = find_hook (the_repository , "pre-push" );
1321+ const struct ref * refs ;
1322+ };
13271323
1328- if (!hook_path )
1329- return 0 ;
1324+ static int pre_push_hook_feed_stdin (int hook_stdin_fd , void * pp_cb UNUSED , void * pp_task_cb )
1325+ {
1326+ struct feed_pre_push_hook_data * data = pp_task_cb ;
1327+ const struct ref * r = data -> refs ;
1328+ int ret = 0 ;
13301329
1331- strvec_push (& proc .args , hook_path );
1332- strvec_push (& proc .args , transport -> remote -> name );
1333- strvec_push (& proc .args , transport -> url );
1330+ if (!r )
1331+ return 1 ; /* no more refs */
13341332
1335- proc .in = -1 ;
1336- proc .trace2_hook_name = "pre-push" ;
1333+ data -> refs = r -> next ;
13371334
1338- if (start_command (& proc )) {
1339- finish_command (& proc );
1340- return -1 ;
1335+ switch (r -> status ) {
1336+ case REF_STATUS_REJECT_NONFASTFORWARD :
1337+ case REF_STATUS_REJECT_REMOTE_UPDATED :
1338+ case REF_STATUS_REJECT_STALE :
1339+ case REF_STATUS_UPTODATE :
1340+ return 0 ; /* skip refs which won't be pushed */
1341+ default :
1342+ break ;
13411343 }
13421344
1343- sigchain_push (SIGPIPE , SIG_IGN );
1345+ if (!r -> peer_ref )
1346+ return 0 ;
13441347
1345- strbuf_init (& buf , 256 );
1348+ strbuf_reset (& data -> buf );
1349+ strbuf_addf (& data -> buf , "%s %s %s %s\n" ,
1350+ r -> peer_ref -> name , oid_to_hex (& r -> new_oid ),
1351+ r -> name , oid_to_hex (& r -> old_oid ));
13461352
1347- for (r = remote_refs ; r ; r = r -> next ) {
1348- if (!r -> peer_ref ) continue ;
1349- if (r -> status == REF_STATUS_REJECT_NONFASTFORWARD ) continue ;
1350- if (r -> status == REF_STATUS_REJECT_STALE ) continue ;
1351- if (r -> status == REF_STATUS_REJECT_REMOTE_UPDATED ) continue ;
1352- if (r -> status == REF_STATUS_UPTODATE ) continue ;
1353+ ret = write_in_full (hook_stdin_fd , data -> buf .buf , data -> buf .len );
1354+ if (ret < 0 && errno != EPIPE )
1355+ return ret ; /* We do not mind if a hook does not read all refs. */
13531356
1354- strbuf_reset (& buf );
1355- strbuf_addf ( & buf , "%s %s %s %s\n" ,
1356- r -> peer_ref -> name , oid_to_hex (& r -> new_oid ),
1357- r -> name , oid_to_hex (& r -> old_oid ));
1357+ return 0 ;
1358+ }
13581359
1359- if (write_in_full (proc .in , buf .buf , buf .len ) < 0 ) {
1360- /* We do not mind if a hook does not read all refs. */
1361- if (errno != EPIPE )
1362- ret = -1 ;
1363- break ;
1364- }
1365- }
1360+ static int run_pre_push_hook (struct transport * transport ,
1361+ struct ref * remote_refs )
1362+ {
1363+ struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT ;
1364+ struct feed_pre_push_hook_data data ;
1365+ int ret = 0 ;
1366+
1367+ strvec_push (& opt .args , transport -> remote -> name );
1368+ strvec_push (& opt .args , transport -> url );
13661369
1367- strbuf_release (& buf );
1370+ strbuf_init (& data .buf , 0 );
1371+ data .refs = remote_refs ;
13681372
1369- x = close (proc .in );
1370- if (!ret )
1371- ret = x ;
1373+ opt .feed_pipe = pre_push_hook_feed_stdin ;
1374+ opt .feed_pipe_cb_data = & data ;
1375+
1376+ /*
1377+ * pre-push hooks expect stdout & stderr to be separate, so don't merge
1378+ * them to keep backwards compatibility with existing hooks.
1379+ */
1380+ opt .stdout_to_stderr = 0 ;
13721381
1373- sigchain_pop ( SIGPIPE );
1382+ ret = run_hooks_opt ( the_repository , "pre-push" , & opt );
13741383
1375- x = finish_command (& proc );
1376- if (!ret )
1377- ret = x ;
1384+ strbuf_release (& data .buf );
13781385
13791386 return ret ;
13801387}
0 commit comments