{"thread":{"id":"65455","subject":"Help needed on 2.54.0-rc0 t5301.13 looping.","startedAt":"2026-04-07T23:37:57Z","lastAt":"2026-04-09T13:40:26Z","messageCount":18,"participants":["rsbecker@nexbridge.com","Jeff King","Adrian Ratiu","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"541111","messageId":"00f501dcc6e7$8ef295c0$acd7c140$@nexbridge.com","threadId":"65455","inReplyTo":null,"subject":"Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"","fromEmail":"rsbecker@nexbridge.com","sentAt":"2026-04-07T23:37:49Z","receivedAt":"2026-04-07T23:37:57Z","isPatch":false,"body":"Weird fail on t5401.13. Any opinions or advise on this?\n\nexpecting success of 5401.13 'pre-receive hook that forgets to read its\ninput':\n        test_hook --clobber -C victim.git pre-receive <<-\\EOF &&\n        exit 0\n        EOF\n        rm -f victim.git/hooks/update victim.git/hooks/post-update &&\n\n        test_seq -f \"create refs/heads/branch_%d main\" 100 999 |\n        git update-ref --stdin &&\n        git push ./victim.git \"+refs/heads/*:refs/heads/*\"\n\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\nTo ./victim.git\n ! [remote rejected] tofail -> tofail (pre-receive hook declined)\n ! [remote rejected] branch_100 -> branch_100 (pre-receive hook declined)\n ! [remote rejected] branch_101 -> branch_101 (pre-receive hook declined)\n ! [remote rejected] branch_102 -> branch_102 (pre-receive hook declined)\n ! [remote rejected] branch_103 -> branch_103 (pre-receive hook declined)\n ! [remote rejected] branch_104 -> branch_104 (pre-receive hook declined)\n ! [remote rejected] branch_105 -> branch_105 (pre-receive hook declined)\n ! [remote rejected] branch_106 -> branch_106 (pre-receive hook declined)\n ! [remote rejected] branch_107 -> branch_107 (pre-receive hook declined)\n ! [remote rejected] branch_108 -> branch_108 (pre-receive hook declined)\n ! [remote rejected] branch_109 -> branch_109 (pre-receive hook declined)\n ! [remote rejected] branch_110 -> branch_110 (pre-receive hook declined)\n ! [remote rejected] branch_111 -> branch_111 (pre-receive hook declined)\n ! [remote rejected] branch_112 -> branch_112 (pre-receive hook declined)\n ! [remote rejected] branch_113 -> branch_113 (pre-receive hook declined)\n ! [remote rejected] branch_114 -> branch_114 (pre-receive hook declined)\n ! [remote rejected] branch_115 -> branch_115 (pre-receive hook declined)\n ! [remote rejected] branch_116 -> branch_116 (pre-receive hook declined)\n ! [remote rejected] branch_117 -> branch_117 (pre-receive hook declined)\n ! [remote rejected] branch_118 -> branch_118 (pre-receive hook declined)\n ! [remote rejected] branch_119 -> branch_119 (pre-receive hook declined)\n ! [remote rejected] branch_120 -> branch_120 (pre-receive hook declined)\n ! [remote rejected] branch_121 -> branch_121 (pre-receive hook declined)\n ! [remote rejected] branch_122 -> branch_122 (pre-receive hook declined)\n ! [remote rejected] branch_123 -> branch_123 (pre-receive hook declined)\n ! [remote rejected] branch_124 -> branch_124 (pre-receive hook declined)\n ! [remote rejected] branch_125 -> branch_125 (pre-receive hook declined)\n ! [remote rejected] branch_126 -> branch_126 (pre-receive hook declined)\n ! [remote rejected] branch_127 -> branch_127 (pre-receive hook declined)\n ! [remote rejected] branch_128 -> branch_128 (pre-receive hook declined)\n ! [remote rejected] branch_129 -> branch_129 (pre-receive hook declined)\n ! [remote rejected] branch_130 -> branch_130 (pre-receive hook declined)\n ! [remote rejected] branch_131 -> branch_131 (pre-receive hook declined)\n ! [remote rejected] branch_132 -> branch_132 (pre-receive hook declined)\n ! [remote rejected] branch_133 -> branch_133 (pre-receive hook declined)\n ! [remote rejected] branch_134 -> branch_134 (pre-receive hook declined)\n ! [remote rejected] branch_135 -> branch_135 (pre-receive hook declined)\n ! [remote rejected] branch_136 -> branch_136 (pre-receive hook declined)\n ! [remote rejected] branch_137 -> branch_137 (pre-receive hook declined)\n ! [remote rejected] branch_138 -> branch_138 (pre-receive hook declined)\n ! [remote rejected] branch_139 -> branch_139 (pre-receive hook declined)\n ! [remote rejected] branch_140 -> branch_140 (pre-receive hook declined)\n ! [remote rejected] branch_141 -> branch_141 (pre-receive hook declined)\n ! [remote rejected] branch_142 -> branch_142 (pre-receive hook declined)\n ! [remote rejected] branch_143 -> branch_143 (pre-receive hook declined)\n ! [remote rejected] branch_144 -> branch_144 (pre-receive hook declined)\n ! [remote rejected] branch_145 -> branch_145 (pre-receive hook declined)\n ! [remote rejected] branch_146 -> branch_146 (pre-receive hook declined)\n ! [remote rejected] branch_147 -> branch_147 (pre-receive hook declined)\n ! [remote rejected] branch_148 -> branch_148 (pre-receive hook declined)\n ! [remote rejected] branch_149 -> branch_149 (pre-receive hook declined)\n ! [remote rejected] branch_150 -> branch_150 (pre-receive hook declined)\n ! [remote rejected] branch_151 -> branch_151 (pre-receive hook declined)\n ! [remote rejected] branch_152 -> branch_152 (pre-receive hook declined)\n ! [remote rejected] branch_153 -> branch_153 (pre-receive hook declined)\n ! [remote rejected] branch_154 -> branch_154 (pre-receive hook declined)\n ! [remote rejected] branch_155 -> branch_155 (pre-receive hook declined)\n ! [remote rejected] branch_156 -> branch_156 (pre-receive hook declined)\n ! [remote rejected] branch_157 -> branch_157 (pre-receive hook declined)\n ! [remote rejected] branch_158 -> branch_158 (pre-receive hook declined)\n ! [remote rejected] branch_159 -> branch_159 (pre-receive hook declined)\n ! [remote rejected] branch_160 -> branch_160 (pre-receive hook declined)\n ! [remote rejected] branch_161 -> branch_161 (pre-receive hook declined)\n ! [remote rejected] branch_162 -> branch_162 (pre-receive hook declined)\n ! [remote rejected] branch_163 -> branch_163 (pre-receive hook declined)\n ! [remote rejected] branch_164 -> branch_164 (pre-receive hook declined)\n ! [remote rejected] branch_165 -> branch_165 (pre-receive hook declined)\n ! [remote rejected] branch_166 -> branch_166 (pre-receive hook declined)\n ! [remote rejected] branch_167 -> branch_167 (pre-receive hook declined)\n ! [remote rejected] branch_168 -> branch_168 (pre-receive hook declined)\n ! [remote rejected] branch_169 -> branch_169 (pre-receive hook declined)\n ! [remote rejected] branch_170 -> branch_170 (pre-receive hook declined)\n ! [remote rejected] branch_171 -> branch_171 (pre-receive hook declined)\n ! [remote rejected] branch_172 -> branch_172 (pre-receive hook declined)\n ! [remote rejected] branch_173 -> branch_173 (pre-receive hook declined)\n ! [remote rejected] branch_174 -> branch_174 (pre-receive hook declined)\n ! [remote rejected] branch_175 -> branch_175 (pre-receive hook declined)\n ! [remote rejected] branch_176 -> branch_176 (pre-receive hook declined)\n ! [remote rejected] branch_177 -> branch_177 (pre-receive hook declined)\n ! [remote rejected] branch_178 -> branch_178 (pre-receive hook declined)\n ! [remote rejected] branch_179 -> branch_179 (pre-receive hook declined)\n ! [remote rejected] branch_180 -> branch_180 (pre-receive hook declined)\n ! [remote rejected] branch_181 -> branch_181 (pre-receive hook declined)\n ! [remote rejected] branch_182 -> branch_182 (pre-receive hook declined)\n ! [remote rejected] branch_183 -> branch_183 (pre-receive hook declined)\n ! [remote rejected] branch_184 -> branch_184 (pre-receive hook declined)\n ! [remote rejected] branch_185 -> branch_185 (pre-receive hook declined)\n ! [remote rejected] branch_186 -> branch_186 (pre-receive hook declined)\n ! [remote rejected] branch_187 -> branch_187 (pre-receive hook declined)\n ! [remote rejected] branch_188 -> branch_188 (pre-receive hook declined)\n ! [remote rejected] branch_189 -> branch_189 (pre-receive hook declined)\n ! [remote rejected] branch_190 -> branch_190 (pre-receive hook declined)\n ! [remote rejected] branch_191 -> branch_191 (pre-receive hook declined)\n ! [remote rejected] branch_192 -> branch_192 (pre-receive hook declined)\n ! [remote rejected] branch_193 -> branch_193 (pre-receive hook declined)\n ! [remote rejected] branch_194 -> branch_194 (pre-receive hook declined)\n ! [remote rejected] branch_195 -> branch_195 (pre-receive hook declined)\n ! [remote rejected] branch_196 -> branch_196 (pre-receive hook declined)\n ! [remote rejected] branch_197 -> branch_197 (pre-receive hook declined)\n ! [remote rejected] branch_198 -> branch_198 (pre-receive hook declined)\n ! [remote rejected] branch_199 -> branch_199 (pre-receive hook declined)\n ! [remote rejected] branch_200 -> branch_200 (pre-receive hook declined)\n ! [remote rejected] branch_201 -> branch_201 (pre-receive hook declined)\n ! [remote rejected] branch_202 -> branch_202 (pre-receive hook declined)\n ! [remote rejected] branch_203 -> branch_203 (pre-receive hook declined)\n ! [remote rejected] branch_204 -> branch_204 (pre-receive hook declined)\n ! [remote rejected] branch_205 -> branch_205 (pre-receive hook declined)\n ! [remote rejected] branch_206 -> branch_206 (pre-receive hook declined)\n ! [remote rejected] branch_207 -> branch_207 (pre-receive hook declined)\n ! [remote rejected] branch_208 -> branch_208 (pre-receive hook declined)\n ! [remote rejected] branch_209 -> branch_209 (pre-receive hook declined)\n ! [remote rejected] branch_210 -> branch_210 (pre-receive hook declined)\n ! [remote rejected] branch_211 -> branch_211 (pre-receive hook declined)\n ! [remote rejected] branch_212 -> branch_212 (pre-receive hook declined)\n ! [remote rejected] branch_213 -> branch_213 (pre-receive hook declined)\n ! [remote rejected] branch_214 -> branch_214 (pre-receive hook declined)\n ! [remote rejected] branch_215 -> branch_215 (pre-receive hook declined)\n ! [remote rejected] branch_216 -> branch_216 (pre-receive hook declined)\n ! [remote rejected] branch_217 -> branch_217 (pre-receive hook declined)\n ! [remote rejected] branch_218 -> branch_218 (pre-receive hook declined)\n ! [remote rejected] branch_219 -> branch_219 (pre-receive hook declined)\n ! [remote rejected] branch_220 -> branch_220 (pre-receive hook declined)\n ! [remote rejected] branch_221 -> branch_221 (pre-receive hook declined)\n ! [remote rejected] branch_222 -> branch_222 (pre-receive hook declined)\n ! [remote rejected] branch_223 -> branch_223 (pre-receive hook declined)\n ! [remote rejected] branch_224 -> branch_224 (pre-receive hook declined)\n ! [remote rejected] branch_225 -> branch_225 (pre-receive hook declined)\n ! [remote rejected] branch_226 -> branch_226 (pre-receive hook declined)\n ! [remote rejected] branch_227 -> branch_227 (pre-receive hook declined)\n ! [remote rejected] branch_228 -> branch_228 (pre-receive hook declined)\n ! [remote rejected] branch_229 -> branch_229 (pre-receive hook declined)\n ! [remote rejected] branch_230 -> branch_230 (pre-receive hook declined)\n ! [remote rejected] branch_231 -> branch_231 (pre-receive hook declined)\n ! [remote rejected] branch_232 -> branch_232 (pre-receive hook declined)\n ! [remote rejected] branch_233 -> branch_233 (pre-receive hook declined)\n ! [remote rejected] branch_234 -> branch_234 (pre-receive hook declined)\n ! [remote rejected] branch_235 -> branch_235 (pre-receive hook declined)\n ! [remote rejected] branch_236 -> branch_236 (pre-receive hook declined)\n ! [remote rejected] branch_237 -> branch_237 (pre-receive hook declined)\n ! [remote rejected] branch_238 -> branch_238 (pre-receive hook declined)\n ! [remote rejected] branch_239 -> branch_239 (pre-receive hook declined)\n ! [remote rejected] branch_240 -> branch_240 (pre-receive hook declined)\n ! [remote rejected] branch_241 -> branch_241 (pre-receive hook declined)\n ! [remote rejected] branch_242 -> branch_242 (pre-receive hook declined)\n ! [remote rejected] branch_243 -> branch_243 (pre-receive hook declined)\n ! [remote rejected] branch_244 -> branch_244 (pre-receive hook declined)\n ! [remote rejected] branch_245 -> branch_245 (pre-receive hook declined)\n ! [remote rejected] branch_246 -> branch_246 (pre-receive hook declined)\n ! [remote rejected] branch_247 -> branch_247 (pre-receive hook declined)\n ! [remote rejected] branch_248 -> branch_248 (pre-receive hook declined)\n ! [remote rejected] branch_249 -> branch_249 (pre-receive hook declined)\n ! [remote rejected] branch_250 -> branch_250 (pre-receive hook declined)\n ! [remote rejected] branch_251 -> branch_251 (pre-receive hook declined)\n ! [remote rejected] branch_252 -> branch_252 (pre-receive hook declined)\n ! [remote rejected] branch_253 -> branch_253 (pre-receive hook declined)\n ! [remote rejected] branch_254 -> branch_254 (pre-receive hook declined)\n ! [remote rejected] branch_255 -> branch_255 (pre-receive hook declined)\n ! [remote rejected] branch_256 -> branch_256 (pre-receive hook declined)\n ! [remote rejected] branch_257 -> branch_257 (pre-receive hook declined)\n ! [remote rejected] branch_258 -> branch_258 (pre-receive hook declined)\n ! [remote rejected] branch_259 -> branch_259 (pre-receive hook declined)\n ! [remote rejected] branch_260 -> branch_260 (pre-receive hook declined)\n ! [remote rejected] branch_261 -> branch_261 (pre-receive hook declined)\n ! [remote rejected] branch_262 -> branch_262 (pre-receive hook declined)\n ! [remote rejected] branch_263 -> branch_263 (pre-receive hook declined)\n ! [remote rejected] branch_264 -> branch_264 (pre-receive hook declined)\n ! [remote rejected] branch_265 -> branch_265 (pre-receive hook declined)\n ! [remote rejected] branch_266 -> branch_266 (pre-receive hook declined)\n ! [remote rejected] branch_267 -> branch_267 (pre-receive hook declined)\n ! [remote rejected] branch_268 -> branch_268 (pre-receive hook declined)\n ! [remote rejected] branch_269 -> branch_269 (pre-receive hook declined)\n ! [remote rejected] branch_270 -> branch_270 (pre-receive hook declined)\n ! [remote rejected] branch_271 -> branch_271 (pre-receive hook declined)\n ! [remote rejected] branch_272 -> branch_272 (pre-receive hook declined)\n ! [remote rejected] branch_273 -> branch_273 (pre-receive hook declined)\n ! [remote rejected] branch_274 -> branch_274 (pre-receive hook declined)\n ! [remote rejected] branch_275 -> branch_275 (pre-receive hook declined)\n ! [remote rejected] branch_276 -> branch_276 (pre-receive hook declined)\n ! [remote rejected] branch_277 -> branch_277 (pre-receive hook declined)\n ! [remote rejected] branch_278 -> branch_278 (pre-receive hook declined)\n ! [remote rejected] branch_279 -> branch_279 (pre-receive hook declined)\n ! [remote rejected] branch_280 -> branch_280 (pre-receive hook declined)\n ! [remote rejected] branch_281 -> branch_281 (pre-receive hook declined)\n ! [remote rejected] branch_282 -> branch_282 (pre-receive hook declined)\n ! [remote rejected] branch_283 -> branch_283 (pre-receive hook declined)\n ! [remote rejected] branch_284 -> branch_284 (pre-receive hook declined)\n ! [remote rejected] branch_285 -> branch_285 (pre-receive hook declined)\n ! [remote rejected] branch_286 -> branch_286 (pre-receive hook declined)\n ! [remote rejected] branch_287 -> branch_287 (pre-receive hook declined)\n ! [remote rejected] branch_288 -> branch_288 (pre-receive hook declined)\n ! [remote rejected] branch_289 -> branch_289 (pre-receive hook declined)\n ! [remote rejected] branch_290 -> branch_290 (pre-receive hook declined)\n ! [remote rejected] branch_291 -> branch_291 (pre-receive hook declined)\n ! [remote rejected] branch_292 -> branch_292 (pre-receive hook declined)\n ! [remote rejected] branch_293 -> branch_293 (pre-receive hook declined)\n ! [remote rejected] branch_294 -> branch_294 (pre-receive hook declined)\n ! [remote rejected] branch_295 -> branch_295 (pre-receive hook declined)\n ! [remote rejected] branch_296 -> branch_296 (pre-receive hook declined)\n ! [remote rejected] branch_297 -> branch_297 (pre-receive hook declined)\n ! [remote rejected] branch_298 -> branch_298 (pre-receive hook declined)\n ! [remote rejected] branch_299 -> branch_299 (pre-receive hook declined)\n ! [remote rejected] branch_300 -> branch_300 (pre-receive hook declined)\n ! [remote rejected] branch_301 -> branch_301 (pre-receive hook declined)\n ! [remote rejected] branch_302 -> branch_302 (pre-receive hook declined)\n ! [remote rejected] branch_303 -> branch_303 (pre-receive hook declined)\n ! [remote rejected] branch_304 -> branch_304 (pre-receive hook declined)\n ! [remote rejected] branch_305 -> branch_305 (pre-receive hook declined)\n ! [remote rejected] branch_306 -> branch_306 (pre-receive hook declined)\n ! [remote rejected] branch_307 -> branch_307 (pre-receive hook declined)\n ! [remote rejected] branch_308 -> branch_308 (pre-receive hook declined)\n ! [remote rejected] branch_309 -> branch_309 (pre-receive hook declined)\n ! [remote rejected] branch_310 -> branch_310 (pre-receive hook declined)\n ! [remote rejected] branch_311 -> branch_311 (pre-receive hook declined)\n ! [remote rejected] branch_312 -> branch_312 (pre-receive hook declined)\n ! [remote rejected] branch_313 -> branch_313 (pre-receive hook declined)\n ! [remote rejected] branch_314 -> branch_314 (pre-receive hook declined)\n ! [remote rejected] branch_315 -> branch_315 (pre-receive hook declined)\n ! [remote rejected] branch_316 -> branch_316 (pre-receive hook declined)\n ! [remote rejected] branch_317 -> branch_317 (pre-receive hook declined)\n ! [remote rejected] branch_318 -> branch_318 (pre-receive hook declined)\n ! [remote rejected] branch_319 -> branch_319 (pre-receive hook declined)\n ! [remote rejected] branch_320 -> branch_320 (pre-receive hook declined)\n ! [remote rejected] branch_321 -> branch_321 (pre-receive hook declined)\n ! [remote rejected] branch_322 -> branch_322 (pre-receive hook declined)\n ! [remote rejected] branch_323 -> branch_323 (pre-receive hook declined)\n ! [remote rejected] branch_324 -> branch_324 (pre-receive hook declined)\n ! [remote rejected] branch_325 -> branch_325 (pre-receive hook declined)\n ! [remote rejected] branch_326 -> branch_326 (pre-receive hook declined)\n ! [remote rejected] branch_327 -> branch_327 (pre-receive hook declined)\n ! [remote rejected] branch_328 -> branch_328 (pre-receive hook declined)\n ! [remote rejected] branch_329 -> branch_329 (pre-receive hook declined)\n ! [remote rejected] branch_330 -> branch_330 (pre-receive hook declined)\n ! [remote rejected] branch_331 -> branch_331 (pre-receive hook declined)\n ! [remote rejected] branch_332 -> branch_332 (pre-receive hook declined)\n ! [remote rejected] branch_333 -> branch_333 (pre-receive hook declined)\n ! [remote rejected] branch_334 -> branch_334 (pre-receive hook declined)\n ! [remote rejected] branch_335 -> branch_335 (pre-receive hook declined)\n ! [remote rejected] branch_336 -> branch_336 (pre-receive hook declined)\n ! [remote rejected] branch_337 -> branch_337 (pre-receive hook declined)\n ! [remote rejected] branch_338 -> branch_338 (pre-receive hook declined)\n ! [remote rejected] branch_339 -> branch_339 (pre-receive hook declined)\n ! [remote rejected] branch_340 -> branch_340 (pre-receive hook declined)\n ! [remote rejected] branch_341 -> branch_341 (pre-receive hook declined)\n ! [remote rejected] branch_342 -> branch_342 (pre-receive hook declined)\n ! [remote rejected] branch_343 -> branch_343 (pre-receive hook declined)\n ! [remote rejected] branch_344 -> branch_344 (pre-receive hook declined)\n ! [remote rejected] branch_345 -> branch_345 (pre-receive hook declined)\n ! [remote rejected] branch_346 -> branch_346 (pre-receive hook declined)\n ! [remote rejected] branch_347 -> branch_347 (pre-receive hook declined)\n ! [remote rejected] branch_348 -> branch_348 (pre-receive hook declined)\n ! [remote rejected] branch_349 -> branch_349 (pre-receive hook declined)\n ! [remote rejected] branch_350 -> branch_350 (pre-receive hook declined)\n ! [remote rejected] branch_351 -> branch_351 (pre-receive hook declined)\n ! [remote rejected] branch_352 -> branch_352 (pre-receive hook declined)\n ! [remote rejected] branch_353 -> branch_353 (pre-receive hook declined)\n ! [remote rejected] branch_354 -> branch_354 (pre-receive hook declined)\n ! [remote rejected] branch_355 -> branch_355 (pre-receive hook declined)\n ! [remote rejected] branch_356 -> branch_356 (pre-receive hook declined)\n ! [remote rejected] branch_357 -> branch_357 (pre-receive hook declined)\n ! [remote rejected] branch_358 -> branch_358 (pre-receive hook declined)\n ! [remote rejected] branch_359 -> branch_359 (pre-receive hook declined)\n ! [remote rejected] branch_360 -> branch_360 (pre-receive hook declined)\n ! [remote rejected] branch_361 -> branch_361 (pre-receive hook declined)\n ! [remote rejected] branch_362 -> branch_362 (pre-receive hook declined)\n ! [remote rejected] branch_363 -> branch_363 (pre-receive hook declined)\n ! [remote rejected] branch_364 -> branch_364 (pre-receive hook declined)\n ! [remote rejected] branch_365 -> branch_365 (pre-receive hook declined)\n ! [remote rejected] branch_366 -> branch_366 (pre-receive hook declined)\n ! [remote rejected] branch_367 -> branch_367 (pre-receive hook declined)\n ! [remote rejected] branch_368 -> branch_368 (pre-receive hook declined)\n ! [remote rejected] branch_369 -> branch_369 (pre-receive hook declined)\n ! [remote rejected] branch_370 -> branch_370 (pre-receive hook declined)\n ! [remote rejected] branch_371 -> branch_371 (pre-receive hook declined)\n ! [remote rejected] branch_372 -> branch_372 (pre-receive hook declined)\n ! [remote rejected] branch_373 -> branch_373 (pre-receive hook declined)\n ! [remote rejected] branch_374 -> branch_374 (pre-receive hook declined)\n ! [remote rejected] branch_375 -> branch_375 (pre-receive hook declined)\n ! [remote rejected] branch_376 -> branch_376 (pre-receive hook declined)\n ! [remote rejected] branch_377 -> branch_377 (pre-receive hook declined)\n ! [remote rejected] branch_378 -> branch_378 (pre-receive hook declined)\n ! [remote rejected] branch_379 -> branch_379 (pre-receive hook declined)\n ! [remote rejected] branch_380 -> branch_380 (pre-receive hook declined)\n ! [remote rejected] branch_381 -> branch_381 (pre-receive hook declined)\n ! [remote rejected] branch_382 -> branch_382 (pre-receive hook declined)\n ! [remote rejected] branch_383 -> branch_383 (pre-receive hook declined)\n ! [remote rejected] branch_384 -> branch_384 (pre-receive hook declined)\n ! [remote rejected] branch_385 -> branch_385 (pre-receive hook declined)\n ! [remote rejected] branch_386 -> branch_386 (pre-receive hook declined)\n ! [remote rejected] branch_387 -> branch_387 (pre-receive hook declined)\n ! [remote rejected] branch_388 -> branch_388 (pre-receive hook declined)\n ! [remote rejected] branch_389 -> branch_389 (pre-receive hook declined)\n ! [remote rejected] branch_390 -> branch_390 (pre-receive hook declined)\n ! [remote rejected] branch_391 -> branch_391 (pre-receive hook declined)\n ! [remote rejected] branch_392 -> branch_392 (pre-receive hook declined)\n ! [remote rejected] branch_393 -> branch_393 (pre-receive hook declined)\n ! [remote rejected] branch_394 -> branch_394 (pre-receive hook declined)\n ! [remote rejected] branch_395 -> branch_395 (pre-receive hook declined)\n ! [remote rejected] branch_396 -> branch_396 (pre-receive hook declined)\n ! [remote rejected] branch_397 -> branch_397 (pre-receive hook declined)\n ! [remote rejected] branch_398 -> branch_398 (pre-receive hook declined)\n ! [remote rejected] branch_399 -> branch_399 (pre-receive hook declined)\n ! [remote rejected] branch_400 -> branch_400 (pre-receive hook declined)\n ! [remote rejected] branch_401 -> branch_401 (pre-receive hook declined)\n ! [remote rejected] branch_402 -> branch_402 (pre-receive hook declined)\n ! [remote rejected] branch_403 -> branch_403 (pre-receive hook declined)\n ! [remote rejected] branch_404 -> branch_404 (pre-receive hook declined)\n ! [remote rejected] branch_405 -> branch_405 (pre-receive hook declined)\n ! [remote rejected] branch_406 -> branch_406 (pre-receive hook declined)\n ! [remote rejected] branch_407 -> branch_407 (pre-receive hook declined)\n ! [remote rejected] branch_408 -> branch_408 (pre-receive hook declined)\n ! [remote rejected] branch_409 -> branch_409 (pre-receive hook declined)\n ! [remote rejected] branch_410 -> branch_410 (pre-receive hook declined)\n ! [remote rejected] branch_411 -> branch_411 (pre-receive hook declined)\n ! [remote rejected] branch_412 -> branch_412 (pre-receive hook declined)\n ! [remote rejected] branch_413 -> branch_413 (pre-receive hook declined)\n ! [remote rejected] branch_414 -> branch_414 (pre-receive hook declined)\n ! [remote rejected] branch_415 -> branch_415 (pre-receive hook declined)\n ! [remote rejected] branch_416 -> branch_416 (pre-receive hook declined)\n ! [remote rejected] branch_417 -> branch_417 (pre-receive hook declined)\n ! [remote rejected] branch_418 -> branch_418 (pre-receive hook declined)\n ! [remote rejected] branch_419 -> branch_419 (pre-receive hook declined)\n ! [remote rejected] branch_420 -> branch_420 (pre-receive hook declined)\n ! [remote rejected] branch_421 -> branch_421 (pre-receive hook declined)\n ! [remote rejected] branch_422 -> branch_422 (pre-receive hook declined)\n ! [remote rejected] branch_423 -> branch_423 (pre-receive hook declined)\n ! [remote rejected] branch_424 -> branch_424 (pre-receive hook declined)\n ! [remote rejected] branch_425 -> branch_425 (pre-receive hook declined)\n ! [remote rejected] branch_426 -> branch_426 (pre-receive hook declined)\n ! [remote rejected] branch_427 -> branch_427 (pre-receive hook declined)\n ! [remote rejected] branch_428 -> branch_428 (pre-receive hook declined)\n ! [remote rejected] branch_429 -> branch_429 (pre-receive hook declined)\n ! [remote rejected] branch_430 -> branch_430 (pre-receive hook declined)\n ! [remote rejected] branch_431 -> branch_431 (pre-receive hook declined)\n ! [remote rejected] branch_432 -> branch_432 (pre-receive hook declined)\n ! [remote rejected] branch_433 -> branch_433 (pre-receive hook declined)\n ! [remote rejected] branch_434 -> branch_434 (pre-receive hook declined)\n ! [remote rejected] branch_435 -> branch_435 (pre-receive hook declined)\n ! [remote rejected] branch_436 -> branch_436 (pre-receive hook declined)\n ! [remote rejected] branch_437 -> branch_437 (pre-receive hook declined)\n ! [remote rejected] branch_438 -> branch_438 (pre-receive hook declined)\n ! [remote rejected] branch_439 -> branch_439 (pre-receive hook declined)\n ! [remote rejected] branch_440 -> branch_440 (pre-receive hook declined)\n ! [remote rejected] branch_441 -> branch_441 (pre-receive hook declined)\n ! [remote rejected] branch_442 -> branch_442 (pre-receive hook declined)\n ! [remote rejected] branch_443 -> branch_443 (pre-receive hook declined)\n ! [remote rejected] branch_444 -> branch_444 (pre-receive hook declined)\n ! [remote rejected] branch_445 -> branch_445 (pre-receive hook declined)\n ! [remote rejected] branch_446 -> branch_446 (pre-receive hook declined)\n ! [remote rejected] branch_447 -> branch_447 (pre-receive hook declined)\n ! [remote rejected] branch_448 -> branch_448 (pre-receive hook declined)\n ! [remote rejected] branch_449 -> branch_449 (pre-receive hook declined)\n ! [remote rejected] branch_450 -> branch_450 (pre-receive hook declined)\n ! [remote rejected] branch_451 -> branch_451 (pre-receive hook declined)\n ! [remote rejected] branch_452 -> branch_452 (pre-receive hook declined)\n ! [remote rejected] branch_453 -> branch_453 (pre-receive hook declined)\n ! [remote rejected] branch_454 -> branch_454 (pre-receive hook declined)\n ! [remote rejected] branch_455 -> branch_455 (pre-receive hook declined)\n ! [remote rejected] branch_456 -> branch_456 (pre-receive hook declined)\n ! [remote rejected] branch_457 -> branch_457 (pre-receive hook declined)\n ! [remote rejected] branch_458 -> branch_458 (pre-receive hook declined)\n ! [remote rejected] branch_459 -> branch_459 (pre-receive hook declined)\n ! [remote rejected] branch_460 -> branch_460 (pre-receive hook declined)\n ! [remote rejected] branch_461 -> branch_461 (pre-receive hook declined)\n ! [remote rejected] branch_462 -> branch_462 (pre-receive hook declined)\n ! [remote rejected] branch_463 -> branch_463 (pre-receive hook declined)\n ! [remote rejected] branch_464 -> branch_464 (pre-receive hook declined)\n ! [remote rejected] branch_465 -> branch_465 (pre-receive hook declined)\n ! [remote rejected] branch_466 -> branch_466 (pre-receive hook declined)\n ! [remote rejected] branch_467 -> branch_467 (pre-receive hook declined)\n ! [remote rejected] branch_468 -> branch_468 (pre-receive hook declined)\n ! [remote rejected] branch_469 -> branch_469 (pre-receive hook declined)\n ! [remote rejected] branch_470 -> branch_470 (pre-receive hook declined)\n ! [remote rejected] branch_471 -> branch_471 (pre-receive hook declined)\n ! [remote rejected] branch_472 -> branch_472 (pre-receive hook declined)\n ! [remote rejected] branch_473 -> branch_473 (pre-receive hook declined)\n ! [remote rejected] branch_474 -> branch_474 (pre-receive hook declined)\n ! [remote rejected] branch_475 -> branch_475 (pre-receive hook declined)\n ! [remote rejected] branch_476 -> branch_476 (pre-receive hook declined)\n ! [remote rejected] branch_477 -> branch_477 (pre-receive hook declined)\n ! [remote rejected] branch_478 -> branch_478 (pre-receive hook declined)\n ! [remote rejected] branch_479 -> branch_479 (pre-receive hook declined)\n ! [remote rejected] branch_480 -> branch_480 (pre-receive hook declined)\n ! [remote rejected] branch_481 -> branch_481 (pre-receive hook declined)\n ! [remote rejected] branch_482 -> branch_482 (pre-receive hook declined)\n ! [remote rejected] branch_483 -> branch_483 (pre-receive hook declined)\n ! [remote rejected] branch_484 -> branch_484 (pre-receive hook declined)\n ! [remote rejected] branch_485 -> branch_485 (pre-receive hook declined)\n ! [remote rejected] branch_486 -> branch_486 (pre-receive hook declined)\n ! [remote rejected] branch_487 -> branch_487 (pre-receive hook declined)\n ! [remote rejected] branch_488 -> branch_488 (pre-receive hook declined)\n ! [remote rejected] branch_489 -> branch_489 (pre-receive hook declined)\n ! [remote rejected] branch_490 -> branch_490 (pre-receive hook declined)\n ! [remote rejected] branch_491 -> branch_491 (pre-receive hook declined)\n ! [remote rejected] branch_492 -> branch_492 (pre-receive hook declined)\n ! [remote rejected] branch_493 -> branch_493 (pre-receive hook declined)\n ! [remote rejected] branch_494 -> branch_494 (pre-receive hook declined)\n ! [remote rejected] branch_495 -> branch_495 (pre-receive hook declined)\n ! [remote rejected] branch_496 -> branch_496 (pre-receive hook declined)\n ! [remote rejected] branch_497 -> branch_497 (pre-receive hook declined)\n ! [remote rejected] branch_498 -> branch_498 (pre-receive hook declined)\n ! [remote rejected] branch_499 -> branch_499 (pre-receive hook declined)\n ! [remote rejected] branch_500 -> branch_500 (pre-receive hook declined)\n ! [remote rejected] branch_501 -> branch_501 (pre-receive hook declined)\n ! [remote rejected] branch_502 -> branch_502 (pre-receive hook declined)\n ! [remote rejected] branch_503 -> branch_503 (pre-receive hook declined)\n ! [remote rejected] branch_504 -> branch_504 (pre-receive hook declined)\n ! [remote rejected] branch_505 -> branch_505 (pre-receive hook declined)\n ! [remote rejected] branch_506 -> branch_506 (pre-receive hook declined)\n ! [remote rejected] branch_507 -> branch_507 (pre-receive hook declined)\n ! [remote rejected] branch_508 -> branch_508 (pre-receive hook declined)\n ! [remote rejected] branch_509 -> branch_509 (pre-receive hook declined)\n ! [remote rejected] branch_510 -> branch_510 (pre-receive hook declined)\n ! [remote rejected] branch_511 -> branch_511 (pre-receive hook declined)\n ! [remote rejected] branch_512 -> branch_512 (pre-receive hook declined)\n ! [remote rejected] branch_513 -> branch_513 (pre-receive hook declined)\n ! [remote rejected] branch_514 -> branch_514 (pre-receive hook declined)\n ! [remote rejected] branch_515 -> branch_515 (pre-receive hook declined)\n ! [remote rejected] branch_516 -> branch_516 (pre-receive hook declined)\n ! [remote rejected] branch_517 -> branch_517 (pre-receive hook declined)\n ! [remote rejected] branch_518 -> branch_518 (pre-receive hook declined)\n ! [remote rejected] branch_519 -> branch_519 (pre-receive hook declined)\n ! [remote rejected] branch_520 -> branch_520 (pre-receive hook declined)\n ! [remote rejected] branch_521 -> branch_521 (pre-receive hook declined)\n ! [remote rejected] branch_522 -> branch_522 (pre-receive hook declined)\n ! [remote rejected] branch_523 -> branch_523 (pre-receive hook declined)\n ! [remote rejected] branch_524 -> branch_524 (pre-receive hook declined)\n ! [remote rejected] branch_525 -> branch_525 (pre-receive hook declined)\n ! [remote rejected] branch_526 -> branch_526 (pre-receive hook declined)\n ! [remote rejected] branch_527 -> branch_527 (pre-receive hook declined)\n ! [remote rejected] branch_528 -> branch_528 (pre-receive hook declined)\n ! [remote rejected] branch_529 -> branch_529 (pre-receive hook declined)\n ! [remote rejected] branch_530 -> branch_530 (pre-receive hook declined)\n ! [remote rejected] branch_531 -> branch_531 (pre-receive hook declined)\n ! [remote rejected] branch_532 -> branch_532 (pre-receive hook declined)\n ! [remote rejected] branch_533 -> branch_533 (pre-receive hook declined)\n ! [remote rejected] branch_534 -> branch_534 (pre-receive hook declined)\n ! [remote rejected] branch_535 -> branch_535 (pre-receive hook declined)\n ! [remote rejected] branch_536 -> branch_536 (pre-receive hook declined)\n ! [remote rejected] branch_537 -> branch_537 (pre-receive hook declined)\n ! [remote rejected] branch_538 -> branch_538 (pre-receive hook declined)\n ! [remote rejected] branch_539 -> branch_539 (pre-receive hook declined)\n ! [remote rejected] branch_540 -> branch_540 (pre-receive hook declined)\n ! [remote rejected] branch_541 -> branch_541 (pre-receive hook declined)\n ! [remote rejected] branch_542 -> branch_542 (pre-receive hook declined)\n ! [remote rejected] branch_543 -> branch_543 (pre-receive hook declined)\n ! [remote rejected] branch_544 -> branch_544 (pre-receive hook declined)\n ! [remote rejected] branch_545 -> branch_545 (pre-receive hook declined)\n ! [remote rejected] branch_546 -> branch_546 (pre-receive hook declined)\n ! [remote rejected] branch_547 -> branch_547 (pre-receive hook declined)\n ! [remote rejected] branch_548 -> branch_548 (pre-receive hook declined)\n ! [remote rejected] branch_549 -> branch_549 (pre-receive hook declined)\n ! [remote rejected] branch_550 -> branch_550 (pre-receive hook declined)\n ! [remote rejected] branch_551 -> branch_551 (pre-receive hook declined)\n ! [remote rejected] branch_552 -> branch_552 (pre-receive hook declined)\n ! [remote rejected] branch_553 -> branch_553 (pre-receive hook declined)\n ! [remote rejected] branch_554 -> branch_554 (pre-receive hook declined)\n ! [remote rejected] branch_555 -> branch_555 (pre-receive hook declined)\n ! [remote rejected] branch_556 -> branch_556 (pre-receive hook declined)\n ! [remote rejected] branch_557 -> branch_557 (pre-receive hook declined)\n ! [remote rejected] branch_558 -> branch_558 (pre-receive hook declined)\n ! [remote rejected] branch_559 -> branch_559 (pre-receive hook declined)\n ! [remote rejected] branch_560 -> branch_560 (pre-receive hook declined)\n ! [remote rejected] branch_561 -> branch_561 (pre-receive hook declined)\n ! [remote rejected] branch_562 -> branch_562 (pre-receive hook declined)\n ! [remote rejected] branch_563 -> branch_563 (pre-receive hook declined)\n ! [remote rejected] branch_564 -> branch_564 (pre-receive hook declined)\n ! [remote rejected] branch_565 -> branch_565 (pre-receive hook declined)\n ! [remote rejected] branch_566 -> branch_566 (pre-receive hook declined)\n ! [remote rejected] branch_567 -> branch_567 (pre-receive hook declined)\n ! [remote rejected] branch_568 -> branch_568 (pre-receive hook declined)\n ! [remote rejected] branch_569 -> branch_569 (pre-receive hook declined)\n ! [remote rejected] branch_570 -> branch_570 (pre-receive hook declined)\n ! [remote rejected] branch_571 -> branch_571 (pre-receive hook declined)\n ! [remote rejected] branch_572 -> branch_572 (pre-receive hook declined)\n ! [remote rejected] branch_573 -> branch_573 (pre-receive hook declined)\n ! [remote rejected] branch_574 -> branch_574 (pre-receive hook declined)\n ! [remote rejected] branch_575 -> branch_575 (pre-receive hook declined)\n ! [remote rejected] branch_576 -> branch_576 (pre-receive hook declined)\n ! [remote rejected] branch_577 -> branch_577 (pre-receive hook declined)\n ! [remote rejected] branch_578 -> branch_578 (pre-receive hook declined)\n ! [remote rejected] branch_579 -> branch_579 (pre-receive hook declined)\n ! [remote rejected] branch_580 -> branch_580 (pre-receive hook declined)\n ! [remote rejected] branch_581 -> branch_581 (pre-receive hook declined)\n ! [remote rejected] branch_582 -> branch_582 (pre-receive hook declined)\n ! [remote rejected] branch_583 -> branch_583 (pre-receive hook declined)\n ! [remote rejected] branch_584 -> branch_584 (pre-receive hook declined)\n ! [remote rejected] branch_585 -> branch_585 (pre-receive hook declined)\n ! [remote rejected] branch_586 -> branch_586 (pre-receive hook declined)\n ! [remote rejected] branch_587 -> branch_587 (pre-receive hook declined)\n ! [remote rejected] branch_588 -> branch_588 (pre-receive hook declined)\n ! [remote rejected] branch_589 -> branch_589 (pre-receive hook declined)\n ! [remote rejected] branch_590 -> branch_590 (pre-receive hook declined)\n ! [remote rejected] branch_591 -> branch_591 (pre-receive hook declined)\n ! [remote rejected] branch_592 -> branch_592 (pre-receive hook declined)\n ! [remote rejected] branch_593 -> branch_593 (pre-receive hook declined)\n ! [remote rejected] branch_594 -> branch_594 (pre-receive hook declined)\n ! [remote rejected] branch_595 -> branch_595 (pre-receive hook declined)\n ! [remote rejected] branch_596 -> branch_596 (pre-receive hook declined)\n ! [remote rejected] branch_597 -> branch_597 (pre-receive hook declined)\n ! [remote rejected] branch_598 -> branch_598 (pre-receive hook declined)\n ! [remote rejected] branch_599 -> branch_599 (pre-receive hook declined)\n ! [remote rejected] branch_600 -> branch_600 (pre-receive hook declined)\n ! [remote rejected] branch_601 -> branch_601 (pre-receive hook declined)\n ! [remote rejected] branch_602 -> branch_602 (pre-receive hook declined)\n ! [remote rejected] branch_603 -> branch_603 (pre-receive hook declined)\n ! [remote rejected] branch_604 -> branch_604 (pre-receive hook declined)\n ! [remote rejected] branch_605 -> branch_605 (pre-receive hook declined)\n ! [remote rejected] branch_606 -> branch_606 (pre-receive hook declined)\n ! [remote rejected] branch_607 -> branch_607 (pre-receive hook declined)\n ! [remote rejected] branch_608 -> branch_608 (pre-receive hook declined)\n ! [remote rejected] branch_609 -> branch_609 (pre-receive hook declined)\n ! [remote rejected] branch_610 -> branch_610 (pre-receive hook declined)\n ! [remote rejected] branch_611 -> branch_611 (pre-receive hook declined)\n ! [remote rejected] branch_612 -> branch_612 (pre-receive hook declined)\n ! [remote rejected] branch_613 -> branch_613 (pre-receive hook declined)\n ! [remote rejected] branch_614 -> branch_614 (pre-receive hook declined)\n ! [remote rejected] branch_615 -> branch_615 (pre-receive hook declined)\n ! [remote rejected] branch_616 -> branch_616 (pre-receive hook declined)\n ! [remote rejected] branch_617 -> branch_617 (pre-receive hook declined)\n ! [remote rejected] branch_618 -> branch_618 (pre-receive hook declined)\n ! [remote rejected] branch_619 -> branch_619 (pre-receive hook declined)\n ! [remote rejected] branch_620 -> branch_620 (pre-receive hook declined)\n ! [remote rejected] branch_621 -> branch_621 (pre-receive hook declined)\n ! [remote rejected] branch_622 -> branch_622 (pre-receive hook declined)\n ! [remote rejected] branch_623 -> branch_623 (pre-receive hook declined)\n ! [remote rejected] branch_624 -> branch_624 (pre-receive hook declined)\n ! [remote rejected] branch_625 -> branch_625 (pre-receive hook declined)\n ! [remote rejected] branch_626 -> branch_626 (pre-receive hook declined)\n ! [remote rejected] branch_627 -> branch_627 (pre-receive hook declined)\n ! [remote rejected] branch_628 -> branch_628 (pre-receive hook declined)\n ! [remote rejected] branch_629 -> branch_629 (pre-receive hook declined)\n ! [remote rejected] branch_630 -> branch_630 (pre-receive hook declined)\n ! [remote rejected] branch_631 -> branch_631 (pre-receive hook declined)\n ! [remote rejected] branch_632 -> branch_632 (pre-receive hook declined)\n ! [remote rejected] branch_633 -> branch_633 (pre-receive hook declined)\n ! [remote rejected] branch_634 -> branch_634 (pre-receive hook declined)\n ! [remote rejected] branch_635 -> branch_635 (pre-receive hook declined)\n ! [remote rejected] branch_636 -> branch_636 (pre-receive hook declined)\n ! [remote rejected] branch_637 -> branch_637 (pre-receive hook declined)\n ! [remote rejected] branch_638 -> branch_638 (pre-receive hook declined)\n ! [remote rejected] branch_639 -> branch_639 (pre-receive hook declined)\n ! [remote rejected] branch_640 -> branch_640 (pre-receive hook declined)\n ! [remote rejected] branch_641 -> branch_641 (pre-receive hook declined)\n ! [remote rejected] branch_642 -> branch_642 (pre-receive hook declined)\n ! [remote rejected] branch_643 -> branch_643 (pre-receive hook declined)\n ! [remote rejected] branch_644 -> branch_644 (pre-receive hook declined)\n ! [remote rejected] branch_645 -> branch_645 (pre-receive hook declined)\n ! [remote rejected] branch_646 -> branch_646 (pre-receive hook declined)\n ! [remote rejected] branch_647 -> branch_647 (pre-receive hook declined)\n ! [remote rejected] branch_648 -> branch_648 (pre-receive hook declined)\n ! [remote rejected] branch_649 -> branch_649 (pre-receive hook declined)\n ! [remote rejected] branch_650 -> branch_650 (pre-receive hook declined)\n ! [remote rejected] branch_651 -> branch_651 (pre-receive hook declined)\n ! [remote rejected] branch_652 -> branch_652 (pre-receive hook declined)\n ! [remote rejected] branch_653 -> branch_653 (pre-receive hook declined)\n ! [remote rejected] branch_654 -> branch_654 (pre-receive hook declined)\n ! [remote rejected] branch_655 -> branch_655 (pre-receive hook declined)\n ! [remote rejected] branch_656 -> branch_656 (pre-receive hook declined)\n ! [remote rejected] branch_657 -> branch_657 (pre-receive hook declined)\n ! [remote rejected] branch_658 -> branch_658 (pre-receive hook declined)\n ! [remote rejected] branch_659 -> branch_659 (pre-receive hook declined)\n ! [remote rejected] branch_660 -> branch_660 (pre-receive hook declined)\n ! [remote rejected] branch_661 -> branch_661 (pre-receive hook declined)\n ! [remote rejected] branch_662 -> branch_662 (pre-receive hook declined)\n ! [remote rejected] branch_663 -> branch_663 (pre-receive hook declined)\n ! [remote rejected] branch_664 -> branch_664 (pre-receive hook declined)\n ! [remote rejected] branch_665 -> branch_665 (pre-receive hook declined)\n ! [remote rejected] branch_666 -> branch_666 (pre-receive hook declined)\n ! [remote rejected] branch_667 -> branch_667 (pre-receive hook declined)\n ! [remote rejected] branch_668 -> branch_668 (pre-receive hook declined)\n ! [remote rejected] branch_669 -> branch_669 (pre-receive hook declined)\n ! [remote rejected] branch_670 -> branch_670 (pre-receive hook declined)\n ! [remote rejected] branch_671 -> branch_671 (pre-receive hook declined)\n ! [remote rejected] branch_672 -> branch_672 (pre-receive hook declined)\n ! [remote rejected] branch_673 -> branch_673 (pre-receive hook declined)\n ! [remote rejected] branch_674 -> branch_674 (pre-receive hook declined)\n ! [remote rejected] branch_675 -> branch_675 (pre-receive hook declined)\n ! [remote rejected] branch_676 -> branch_676 (pre-receive hook declined)\n ! [remote rejected] branch_677 -> branch_677 (pre-receive hook declined)\n ! [remote rejected] branch_678 -> branch_678 (pre-receive hook declined)\n ! [remote rejected] branch_679 -> branch_679 (pre-receive hook declined)\n ! [remote rejected] branch_680 -> branch_680 (pre-receive hook declined)\n ! [remote rejected] branch_681 -> branch_681 (pre-receive hook declined)\n ! [remote rejected] branch_682 -> branch_682 (pre-receive hook declined)\n ! [remote rejected] branch_683 -> branch_683 (pre-receive hook declined)\n ! [remote rejected] branch_684 -> branch_684 (pre-receive hook declined)\n ! [remote rejected] branch_685 -> branch_685 (pre-receive hook declined)\n ! [remote rejected] branch_686 -> branch_686 (pre-receive hook declined)\n ! [remote rejected] branch_687 -> branch_687 (pre-receive hook declined)\n ! [remote rejected] branch_688 -> branch_688 (pre-receive hook declined)\n ! [remote rejected] branch_689 -> branch_689 (pre-receive hook declined)\n ! [remote rejected] branch_690 -> branch_690 (pre-receive hook declined)\n ! [remote rejected] branch_691 -> branch_691 (pre-receive hook declined)\n ! [remote rejected] branch_692 -> branch_692 (pre-receive hook declined)\n ! [remote rejected] branch_693 -> branch_693 (pre-receive hook declined)\n ! [remote rejected] branch_694 -> branch_694 (pre-receive hook declined)\n ! [remote rejected] branch_695 -> branch_695 (pre-receive hook declined)\n ! [remote rejected] branch_696 -> branch_696 (pre-receive hook declined)\n ! [remote rejected] branch_697 -> branch_697 (pre-receive hook declined)\n ! [remote rejected] branch_698 -> branch_698 (pre-receive hook declined)\n ! [remote rejected] branch_699 -> branch_699 (pre-receive hook declined)\n ! [remote rejected] branch_700 -> branch_700 (pre-receive hook declined)\n ! [remote rejected] branch_701 -> branch_701 (pre-receive hook declined)\n ! [remote rejected] branch_702 -> branch_702 (pre-receive hook declined)\n ! [remote rejected] branch_703 -> branch_703 (pre-receive hook declined)\n ! [remote rejected] branch_704 -> branch_704 (pre-receive hook declined)\n ! [remote rejected] branch_705 -> branch_705 (pre-receive hook declined)\n ! [remote rejected] branch_706 -> branch_706 (pre-receive hook declined)\n ! [remote rejected] branch_707 -> branch_707 (pre-receive hook declined)\n ! [remote rejected] branch_708 -> branch_708 (pre-receive hook declined)\n ! [remote rejected] branch_709 -> branch_709 (pre-receive hook declined)\n ! [remote rejected] branch_710 -> branch_710 (pre-receive hook declined)\n ! [remote rejected] branch_711 -> branch_711 (pre-receive hook declined)\n ! [remote rejected] branch_712 -> branch_712 (pre-receive hook declined)\n ! [remote rejected] branch_713 -> branch_713 (pre-receive hook declined)\n ! [remote rejected] branch_714 -> branch_714 (pre-receive hook declined)\n ! [remote rejected] branch_715 -> branch_715 (pre-receive hook declined)\n ! [remote rejected] branch_716 -> branch_716 (pre-receive hook declined)\n ! [remote rejected] branch_717 -> branch_717 (pre-receive hook declined)\n ! [remote rejected] branch_718 -> branch_718 (pre-receive hook declined)\n ! [remote rejected] branch_719 -> branch_719 (pre-receive hook declined)\n ! [remote rejected] branch_720 -> branch_720 (pre-receive hook declined)\n ! [remote rejected] branch_721 -> branch_721 (pre-receive hook declined)\n ! [remote rejected] branch_722 -> branch_722 (pre-receive hook declined)\n ! [remote rejected] branch_723 -> branch_723 (pre-receive hook declined)\n ! [remote rejected] branch_724 -> branch_724 (pre-receive hook declined)\n ! [remote rejected] branch_725 -> branch_725 (pre-receive hook declined)\n ! [remote rejected] branch_726 -> branch_726 (pre-receive hook declined)\n ! [remote rejected] branch_727 -> branch_727 (pre-receive hook declined)\n ! [remote rejected] branch_728 -> branch_728 (pre-receive hook declined)\n ! [remote rejected] branch_729 -> branch_729 (pre-receive hook declined)\n ! [remote rejected] branch_730 -> branch_730 (pre-receive hook declined)\n ! [remote rejected] branch_731 -> branch_731 (pre-receive hook declined)\n ! [remote rejected] branch_732 -> branch_732 (pre-receive hook declined)\n ! [remote rejected] branch_733 -> branch_733 (pre-receive hook declined)\n ! [remote rejected] branch_734 -> branch_734 (pre-receive hook declined)\n ! [remote rejected] branch_735 -> branch_735 (pre-receive hook declined)\n ! [remote rejected] branch_736 -> branch_736 (pre-receive hook declined)\n ! [remote rejected] branch_737 -> branch_737 (pre-receive hook declined)\n ! [remote rejected] branch_738 -> branch_738 (pre-receive hook declined)\n ! [remote rejected] branch_739 -> branch_739 (pre-receive hook declined)\n ! [remote rejected] branch_740 -> branch_740 (pre-receive hook declined)\n ! [remote rejected] branch_741 -> branch_741 (pre-receive hook declined)\n ! [remote rejected] branch_742 -> branch_742 (pre-receive hook declined)\n ! [remote rejected] branch_743 -> branch_743 (pre-receive hook declined)\n ! [remote rejected] branch_744 -> branch_744 (pre-receive hook declined)\n ! [remote rejected] branch_745 -> branch_745 (pre-receive hook declined)\n ! [remote rejected] branch_746 -> branch_746 (pre-receive hook declined)\n ! [remote rejected] branch_747 -> branch_747 (pre-receive hook declined)\n ! [remote rejected] branch_748 -> branch_748 (pre-receive hook declined)\n ! [remote rejected] branch_749 -> branch_749 (pre-receive hook declined)\n ! [remote rejected] branch_750 -> branch_750 (pre-receive hook declined)\n ! [remote rejected] branch_751 -> branch_751 (pre-receive hook declined)\n ! [remote rejected] branch_752 -> branch_752 (pre-receive hook declined)\n ! [remote rejected] branch_753 -> branch_753 (pre-receive hook declined)\n ! [remote rejected] branch_754 -> branch_754 (pre-receive hook declined)\n ! [remote rejected] branch_755 -> branch_755 (pre-receive hook declined)\n ! [remote rejected] branch_756 -> branch_756 (pre-receive hook declined)\n ! [remote rejected] branch_757 -> branch_757 (pre-receive hook declined)\n ! [remote rejected] branch_758 -> branch_758 (pre-receive hook declined)\n ! [remote rejected] branch_759 -> branch_759 (pre-receive hook declined)\n ! [remote rejected] branch_760 -> branch_760 (pre-receive hook declined)\n ! [remote rejected] branch_761 -> branch_761 (pre-receive hook declined)\n ! [remote rejected] branch_762 -> branch_762 (pre-receive hook declined)\n ! [remote rejected] branch_763 -> branch_763 (pre-receive hook declined)\n ! [remote rejected] branch_764 -> branch_764 (pre-receive hook declined)\n ! [remote rejected] branch_765 -> branch_765 (pre-receive hook declined)\n ! [remote rejected] branch_766 -> branch_766 (pre-receive hook declined)\n ! [remote rejected] branch_767 -> branch_767 (pre-receive hook declined)\n ! [remote rejected] branch_768 -> branch_768 (pre-receive hook declined)\n ! [remote rejected] branch_769 -> branch_769 (pre-receive hook declined)\n ! [remote rejected] branch_770 -> branch_770 (pre-receive hook declined)\n ! [remote rejected] branch_771 -> branch_771 (pre-receive hook declined)\n ! [remote rejected] branch_772 -> branch_772 (pre-receive hook declined)\n ! [remote rejected] branch_773 -> branch_773 (pre-receive hook declined)\n ! [remote rejected] branch_774 -> branch_774 (pre-receive hook declined)\n ! [remote rejected] branch_775 -> branch_775 (pre-receive hook declined)\n ! [remote rejected] branch_776 -> branch_776 (pre-receive hook declined)\n ! [remote rejected] branch_777 -> branch_777 (pre-receive hook declined)\n ! [remote rejected] branch_778 -> branch_778 (pre-receive hook declined)\n ! [remote rejected] branch_779 -> branch_779 (pre-receive hook declined)\n ! [remote rejected] branch_780 -> branch_780 (pre-receive hook declined)\n ! [remote rejected] branch_781 -> branch_781 (pre-receive hook declined)\n ! [remote rejected] branch_782 -> branch_782 (pre-receive hook declined)\n ! [remote rejected] branch_783 -> branch_783 (pre-receive hook declined)\n ! [remote rejected] branch_784 -> branch_784 (pre-receive hook declined)\n ! [remote rejected] branch_785 -> branch_785 (pre-receive hook declined)\n ! [remote rejected] branch_786 -> branch_786 (pre-receive hook declined)\n ! [remote rejected] branch_787 -> branch_787 (pre-receive hook declined)\n ! [remote rejected] branch_788 -> branch_788 (pre-receive hook declined)\n ! [remote rejected] branch_789 -> branch_789 (pre-receive hook declined)\n ! [remote rejected] branch_790 -> branch_790 (pre-receive hook declined)\n ! [remote rejected] branch_791 -> branch_791 (pre-receive hook declined)\n ! [remote rejected] branch_792 -> branch_792 (pre-receive hook declined)\n ! [remote rejected] branch_793 -> branch_793 (pre-receive hook declined)\n ! [remote rejected] branch_794 -> branch_794 (pre-receive hook declined)\n ! [remote rejected] branch_795 -> branch_795 (pre-receive hook declined)\n ! [remote rejected] branch_796 -> branch_796 (pre-receive hook declined)\n ! [remote rejected] branch_797 -> branch_797 (pre-receive hook declined)\n ! [remote rejected] branch_798 -> branch_798 (pre-receive hook declined)\n ! [remote rejected] branch_799 -> branch_799 (pre-receive hook declined)\n ! [remote rejected] branch_800 -> branch_800 (pre-receive hook declined)\n ! [remote rejected] branch_801 -> branch_801 (pre-receive hook declined)\n ! [remote rejected] branch_802 -> branch_802 (pre-receive hook declined)\n ! [remote rejected] branch_803 -> branch_803 (pre-receive hook declined)\n ! [remote rejected] branch_804 -> branch_804 (pre-receive hook declined)\n ! [remote rejected] branch_805 -> branch_805 (pre-receive hook declined)\n ! [remote rejected] branch_806 -> branch_806 (pre-receive hook declined)\n ! [remote rejected] branch_807 -> branch_807 (pre-receive hook declined)\n ! [remote rejected] branch_808 -> branch_808 (pre-receive hook declined)\n ! [remote rejected] branch_809 -> branch_809 (pre-receive hook declined)\n ! [remote rejected] branch_810 -> branch_810 (pre-receive hook declined)\n ! [remote rejected] branch_811 -> branch_811 (pre-receive hook declined)\n ! [remote rejected] branch_812 -> branch_812 (pre-receive hook declined)\n ! [remote rejected] branch_813 -> branch_813 (pre-receive hook declined)\n ! [remote rejected] branch_814 -> branch_814 (pre-receive hook declined)\n ! [remote rejected] branch_815 -> branch_815 (pre-receive hook declined)\n ! [remote rejected] branch_816 -> branch_816 (pre-receive hook declined)\n ! [remote rejected] branch_817 -> branch_817 (pre-receive hook declined)\n ! [remote rejected] branch_818 -> branch_818 (pre-receive hook declined)\n ! [remote rejected] branch_819 -> branch_819 (pre-receive hook declined)\n ! [remote rejected] branch_820 -> branch_820 (pre-receive hook declined)\n ! [remote rejected] branch_821 -> branch_821 (pre-receive hook declined)\n ! [remote rejected] branch_822 -> branch_822 (pre-receive hook declined)\n ! [remote rejected] branch_823 -> branch_823 (pre-receive hook declined)\n ! [remote rejected] branch_824 -> branch_824 (pre-receive hook declined)\n ! [remote rejected] branch_825 -> branch_825 (pre-receive hook declined)\n ! [remote rejected] branch_826 -> branch_826 (pre-receive hook declined)\n ! [remote rejected] branch_827 -> branch_827 (pre-receive hook declined)\n ! [remote rejected] branch_828 -> branch_828 (pre-receive hook declined)\n ! [remote rejected] branch_829 -> branch_829 (pre-receive hook declined)\n ! [remote rejected] branch_830 -> branch_830 (pre-receive hook declined)\n ! [remote rejected] branch_831 -> branch_831 (pre-receive hook declined)\n ! [remote rejected] branch_832 -> branch_832 (pre-receive hook declined)\n ! [remote rejected] branch_833 -> branch_833 (pre-receive hook declined)\n ! [remote rejected] branch_834 -> branch_834 (pre-receive hook declined)\n ! [remote rejected] branch_835 -> branch_835 (pre-receive hook declined)\n ! [remote rejected] branch_836 -> branch_836 (pre-receive hook declined)\n ! [remote rejected] branch_837 -> branch_837 (pre-receive hook declined)\n ! [remote rejected] branch_838 -> branch_838 (pre-receive hook declined)\n ! [remote rejected] branch_839 -> branch_839 (pre-receive hook declined)\n ! [remote rejected] branch_840 -> branch_840 (pre-receive hook declined)\n ! [remote rejected] branch_841 -> branch_841 (pre-receive hook declined)\n ! [remote rejected] branch_842 -> branch_842 (pre-receive hook declined)\n ! [remote rejected] branch_843 -> branch_843 (pre-receive hook declined)\n ! [remote rejected] branch_844 -> branch_844 (pre-receive hook declined)\n ! [remote rejected] branch_845 -> branch_845 (pre-receive hook declined)\n ! [remote rejected] branch_846 -> branch_846 (pre-receive hook declined)\n ! [remote rejected] branch_847 -> branch_847 (pre-receive hook declined)\n ! [remote rejected] branch_848 -> branch_848 (pre-receive hook declined)\n ! [remote rejected] branch_849 -> branch_849 (pre-receive hook declined)\n ! [remote rejected] branch_850 -> branch_850 (pre-receive hook declined)\n ! [remote rejected] branch_851 -> branch_851 (pre-receive hook declined)\n ! [remote rejected] branch_852 -> branch_852 (pre-receive hook declined)\n ! [remote rejected] branch_853 -> branch_853 (pre-receive hook declined)\n ! [remote rejected] branch_854 -> branch_854 (pre-receive hook declined)\n ! [remote rejected] branch_855 -> branch_855 (pre-receive hook declined)\n ! [remote rejected] branch_856 -> branch_856 (pre-receive hook declined)\n ! [remote rejected] branch_857 -> branch_857 (pre-receive hook declined)\n ! [remote rejected] branch_858 -> branch_858 (pre-receive hook declined)\n ! [remote rejected] branch_859 -> branch_859 (pre-receive hook declined)\n ! [remote rejected] branch_860 -> branch_860 (pre-receive hook declined)\n ! [remote rejected] branch_861 -> branch_861 (pre-receive hook declined)\n ! [remote rejected] branch_862 -> branch_862 (pre-receive hook declined)\n ! [remote rejected] branch_863 -> branch_863 (pre-receive hook declined)\n ! [remote rejected] branch_864 -> branch_864 (pre-receive hook declined)\n ! [remote rejected] branch_865 -> branch_865 (pre-receive hook declined)\n ! [remote rejected] branch_866 -> branch_866 (pre-receive hook declined)\n ! [remote rejected] branch_867 -> branch_867 (pre-receive hook declined)\n ! [remote rejected] branch_868 -> branch_868 (pre-receive hook declined)\n ! [remote rejected] branch_869 -> branch_869 (pre-receive hook declined)\n ! [remote rejected] branch_870 -> branch_870 (pre-receive hook declined)\n ! [remote rejected] branch_871 -> branch_871 (pre-receive hook declined)\n ! [remote rejected] branch_872 -> branch_872 (pre-receive hook declined)\n ! [remote rejected] branch_873 -> branch_873 (pre-receive hook declined)\n ! [remote rejected] branch_874 -> branch_874 (pre-receive hook declined)\n ! [remote rejected] branch_875 -> branch_875 (pre-receive hook declined)\n ! [remote rejected] branch_876 -> branch_876 (pre-receive hook declined)\n ! [remote rejected] branch_877 -> branch_877 (pre-receive hook declined)\n ! [remote rejected] branch_878 -> branch_878 (pre-receive hook declined)\n ! [remote rejected] branch_879 -> branch_879 (pre-receive hook declined)\n ! [remote rejected] branch_880 -> branch_880 (pre-receive hook declined)\n ! [remote rejected] branch_881 -> branch_881 (pre-receive hook declined)\n ! [remote rejected] branch_882 -> branch_882 (pre-receive hook declined)\n ! [remote rejected] branch_883 -> branch_883 (pre-receive hook declined)\n ! [remote rejected] branch_884 -> branch_884 (pre-receive hook declined)\n ! [remote rejected] branch_885 -> branch_885 (pre-receive hook declined)\n ! [remote rejected] branch_886 -> branch_886 (pre-receive hook declined)\n ! [remote rejected] branch_887 -> branch_887 (pre-receive hook declined)\n ! [remote rejected] branch_888 -> branch_888 (pre-receive hook declined)\n ! [remote rejected] branch_889 -> branch_889 (pre-receive hook declined)\n ! [remote rejected] branch_890 -> branch_890 (pre-receive hook declined)\n ! [remote rejected] branch_891 -> branch_891 (pre-receive hook declined)\n ! [remote rejected] branch_892 -> branch_892 (pre-receive hook declined)\n ! [remote rejected] branch_893 -> branch_893 (pre-receive hook declined)\n ! [remote rejected] branch_894 -> branch_894 (pre-receive hook declined)\n ! [remote rejected] branch_895 -> branch_895 (pre-receive hook declined)\n ! [remote rejected] branch_896 -> branch_896 (pre-receive hook declined)\n ! [remote rejected] branch_897 -> branch_897 (pre-receive hook declined)\n ! [remote rejected] branch_898 -> branch_898 (pre-receive hook declined)\n ! [remote rejected] branch_899 -> branch_899 (pre-receive hook declined)\n ! [remote rejected] branch_900 -> branch_900 (pre-receive hook declined)\n ! [remote rejected] branch_901 -> branch_901 (pre-receive hook declined)\n ! [remote rejected] branch_902 -> branch_902 (pre-receive hook declined)\n ! [remote rejected] branch_903 -> branch_903 (pre-receive hook declined)\n ! [remote rejected] branch_904 -> branch_904 (pre-receive hook declined)\n ! [remote rejected] branch_905 -> branch_905 (pre-receive hook declined)\n ! [remote rejected] branch_906 -> branch_906 (pre-receive hook declined)\n ! [remote rejected] branch_907 -> branch_907 (pre-receive hook declined)\n ! [remote rejected] branch_908 -> branch_908 (pre-receive hook declined)\n ! [remote rejected] branch_909 -> branch_909 (pre-receive hook declined)\n ! [remote rejected] branch_910 -> branch_910 (pre-receive hook declined)\n ! [remote rejected] branch_911 -> branch_911 (pre-receive hook declined)\n ! [remote rejected] branch_912 -> branch_912 (pre-receive hook declined)\n ! [remote rejected] branch_913 -> branch_913 (pre-receive hook declined)\n ! [remote rejected] branch_914 -> branch_914 (pre-receive hook declined)\n ! [remote rejected] branch_915 -> branch_915 (pre-receive hook declined)\n ! [remote rejected] branch_916 -> branch_916 (pre-receive hook declined)\n ! [remote rejected] branch_917 -> branch_917 (pre-receive hook declined)\n ! [remote rejected] branch_918 -> branch_918 (pre-receive hook declined)\n ! [remote rejected] branch_919 -> branch_919 (pre-receive hook declined)\n ! [remote rejected] branch_920 -> branch_920 (pre-receive hook declined)\n ! [remote rejected] branch_921 -> branch_921 (pre-receive hook declined)\n ! [remote rejected] branch_922 -> branch_922 (pre-receive hook declined)\n ! [remote rejected] branch_923 -> branch_923 (pre-receive hook declined)\n ! [remote rejected] branch_924 -> branch_924 (pre-receive hook declined)\n ! [remote rejected] branch_925 -> branch_925 (pre-receive hook declined)\n ! [remote rejected] branch_926 -> branch_926 (pre-receive hook declined)\n ! [remote rejected] branch_927 -> branch_927 (pre-receive hook declined)\n ! [remote rejected] branch_928 -> branch_928 (pre-receive hook declined)\n ! [remote rejected] branch_929 -> branch_929 (pre-receive hook declined)\n ! [remote rejected] branch_930 -> branch_930 (pre-receive hook declined)\n ! [remote rejected] branch_931 -> branch_931 (pre-receive hook declined)\n ! [remote rejected] branch_932 -> branch_932 (pre-receive hook declined)\n ! [remote rejected] branch_933 -> branch_933 (pre-receive hook declined)\n ! [remote rejected] branch_934 -> branch_934 (pre-receive hook declined)\n ! [remote rejected] branch_935 -> branch_935 (pre-receive hook declined)\n ! [remote rejected] branch_936 -> branch_936 (pre-receive hook declined)\n ! [remote rejected] branch_937 -> branch_937 (pre-receive hook declined)\n ! [remote rejected] branch_938 -> branch_938 (pre-receive hook declined)\n ! [remote rejected] branch_939 -> branch_939 (pre-receive hook declined)\n ! [remote rejected] branch_940 -> branch_940 (pre-receive hook declined)\n ! [remote rejected] branch_941 -> branch_941 (pre-receive hook declined)\n ! [remote rejected] branch_942 -> branch_942 (pre-receive hook declined)\n ! [remote rejected] branch_943 -> branch_943 (pre-receive hook declined)\n ! [remote rejected] branch_944 -> branch_944 (pre-receive hook declined)\n ! [remote rejected] branch_945 -> branch_945 (pre-receive hook declined)\n ! [remote rejected] branch_946 -> branch_946 (pre-receive hook declined)\n ! [remote rejected] branch_947 -> branch_947 (pre-receive hook declined)\n ! [remote rejected] branch_948 -> branch_948 (pre-receive hook declined)\n ! [remote rejected] branch_949 -> branch_949 (pre-receive hook declined)\n ! [remote rejected] branch_950 -> branch_950 (pre-receive hook declined)\n ! [remote rejected] branch_951 -> branch_951 (pre-receive hook declined)\n ! [remote rejected] branch_952 -> branch_952 (pre-receive hook declined)\n ! [remote rejected] branch_953 -> branch_953 (pre-receive hook declined)\n ! [remote rejected] branch_954 -> branch_954 (pre-receive hook declined)\n ! [remote rejected] branch_955 -> branch_955 (pre-receive hook declined)\n ! [remote rejected] branch_956 -> branch_956 (pre-receive hook declined)\n ! [remote rejected] branch_957 -> branch_957 (pre-receive hook declined)\n ! [remote rejected] branch_958 -> branch_958 (pre-receive hook declined)\n ! [remote rejected] branch_959 -> branch_959 (pre-receive hook declined)\n ! [remote rejected] branch_960 -> branch_960 (pre-receive hook declined)\n ! [remote rejected] branch_961 -> branch_961 (pre-receive hook declined)\n ! [remote rejected] branch_962 -> branch_962 (pre-receive hook declined)\n ! [remote rejected] branch_963 -> branch_963 (pre-receive hook declined)\n ! [remote rejected] branch_964 -> branch_964 (pre-receive hook declined)\n ! [remote rejected] branch_965 -> branch_965 (pre-receive hook declined)\n ! [remote rejected] branch_966 -> branch_966 (pre-receive hook declined)\n ! [remote rejected] branch_967 -> branch_967 (pre-receive hook declined)\n ! [remote rejected] branch_968 -> branch_968 (pre-receive hook declined)\n ! [remote rejected] branch_969 -> branch_969 (pre-receive hook declined)\n ! [remote rejected] branch_970 -> branch_970 (pre-receive hook declined)\n ! [remote rejected] branch_971 -> branch_971 (pre-receive hook declined)\n ! [remote rejected] branch_972 -> branch_972 (pre-receive hook declined)\n ! [remote rejected] branch_973 -> branch_973 (pre-receive hook declined)\n ! [remote rejected] branch_974 -> branch_974 (pre-receive hook declined)\n ! [remote rejected] branch_975 -> branch_975 (pre-receive hook declined)\n ! [remote rejected] branch_976 -> branch_976 (pre-receive hook declined)\n ! [remote rejected] branch_977 -> branch_977 (pre-receive hook declined)\n ! [remote rejected] branch_978 -> branch_978 (pre-receive hook declined)\n ! [remote rejected] branch_979 -> branch_979 (pre-receive hook declined)\n ! [remote rejected] branch_980 -> branch_980 (pre-receive hook declined)\n ! [remote rejected] branch_981 -> branch_981 (pre-receive hook declined)\n ! [remote rejected] branch_982 -> branch_982 (pre-receive hook declined)\n ! [remote rejected] branch_983 -> branch_983 (pre-receive hook declined)\n ! [remote rejected] branch_984 -> branch_984 (pre-receive hook declined)\n ! [remote rejected] branch_985 -> branch_985 (pre-receive hook declined)\n ! [remote rejected] branch_986 -> branch_986 (pre-receive hook declined)\n ! [remote rejected] branch_987 -> branch_987 (pre-receive hook declined)\n ! [remote rejected] branch_988 -> branch_988 (pre-receive hook declined)\n ! [remote rejected] branch_989 -> branch_989 (pre-receive hook declined)\n ! [remote rejected] branch_990 -> branch_990 (pre-receive hook declined)\n ! [remote rejected] branch_991 -> branch_991 (pre-receive hook declined)\n ! [remote rejected] branch_992 -> branch_992 (pre-receive hook declined)\n ! [remote rejected] branch_993 -> branch_993 (pre-receive hook declined)\n ! [remote rejected] branch_994 -> branch_994 (pre-receive hook declined)\n ! [remote rejected] branch_995 -> branch_995 (pre-receive hook declined)\n ! [remote rejected] branch_996 -> branch_996 (pre-receive hook declined)\n ! [remote rejected] branch_997 -> branch_997 (pre-receive hook declined)\n ! [remote rejected] branch_998 -> branch_998 (pre-receive hook declined)\n ! [remote rejected] branch_999 -> branch_999 (pre-receive hook declined)\nerror: failed to push some refs to './victim.git'\nnot ok 13 - pre-receive hook that forgets to\n\n--\nBrief whoami: NonStop&UNIX developer since approximately\nUNIX(421664400)\nNonStop(211288444200000000)\n-- In real life, I talk too much.\n\n\n"},{"id":"541116","messageId":"20260408052031.GB1324339@coredump.intra.peff.net","threadId":"65455","inReplyTo":"00f501dcc6e7$8ef295c0$acd7c140$@nexbridge.com","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-04-08T05:20:31Z","receivedAt":"2026-04-08T05:20:33Z","isPatch":false,"body":"On Tue, Apr 07, 2026 at 07:37:49PM -0400, rsbecker@nexbridge.com wrote:\n\n> Weird fail on t5401.13. Any opinions or advise on this?\n> \n> expecting success of 5401.13 'pre-receive hook that forgets to read its\n> input':\n>         test_hook --clobber -C victim.git pre-receive <<-\\EOF &&\n>         exit 0\n>         EOF\n>         rm -f victim.git/hooks/update victim.git/hooks/post-update &&\n> \n>         test_seq -f \"create refs/heads/branch_%d main\" 100 999 |\n>         git update-ref --stdin &&\n>         git push ./victim.git \"+refs/heads/*:refs/heads/*\"\n\nOK, so this test is trying to feed a bunch of data to a pre-receive hook\nthat doesn't read anything, and we want to make sure we aren't killed by\nSIGPIPE.\n\nWhen the test was added originally in ec7dbd145b (receive-pack: allow\nhooks to ignore its standard input stream, 2014-09-12), we just stuck a:\n\n  sigchain_push(SIGPIPE, SIG_IGN);\n\nat the top of the hook function. But now that function has been\nrewritten to use the hook API, and that sigchain_push() is gone.\n\nWhat does the new hook API do? It works with run-command's\nrun_processes_parallel() function. Which similarly ignores SIGPIPE,\ncourtesy of ec0becacc9 (run-command: add stdin callback for\nparallelization, 2026-01-28):\n\n          /*\n           * Child tasks might receive input via stdin, terminating early (or not), so\n           * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which\n           * actually writes the data to children stdin fds.\n           */\n          sigchain_push(SIGPIPE, SIG_IGN);\n\nOK, so far so good. But that's not quite the end of the story. In\npp_init(), we then sigchain_push() another handler, but this time it's a\nreal function:\n\n  static void handle_children_on_signal(int signo)\n  {\n          kill_children_signal(pp_for_signal, signo);\n          sigchain_pop(signo);\n          raise(signo);\n  }\n\nSo now when we get a SIGPIPE, we end up there. It tries to propagate the\nsignal to any child processes we spawned. Which is a bit funny, since it\nwas the child process closing that caused us to get the signal in the\nfirst place, but of course our handler doesn't know that.\n\nAnd then afterwards, it pops itself off the handler stack and re-raises.\nBut that will hit the SIG_IGN we pushed earlier and do nothing. So that\npart isn't interesting.\n\nWhat is interesting is that we end up calling \"kill(<pid>, SIGPIPE)\" on\nthe child via kill_children_signal(). At least on my Linux system that\nworks fine, since we haven't reaped the process via wait() yet. But of\ncourse nothing interesting happens to the child, which has already\nexited. Killing it with SIGPIPE does not seem to affect its exit code.\n\nHowever, I could believe that on some other system it might behave\ndifferently. Possibly even racily. For example, if the child process had\nclosed its pipe (giving us SIGPIPE in the parent) but not yet fully\nexited, could our kill() cause it to change its exit code? And then it\nwould look like the hook reported failure (because it died by signal).\nAnd I'd expect the output you saw.\n\nI think the root of the issue is that we should not be trying to\npropagate SIGPIPE to the child in this case at all. Our handler is\npushed there only because it's part of sigchain_push_common(), which is\nsensible: in general if we are dying to SIGPIPE we want to do our\ncleanup. It's just funny in this case with the ordering of our SIG_IGN,\nbecause now that SIG_IGN isn't on top of the stack anymore.\n\nI.e., I think we want to reorder like this:\n\ndiff --git a/run-command.c b/run-command.c\nindex 32c290ee6a..8a95f7ff1e 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n \t\t\t\t\t   \"max:%\"PRIuMAX,\n \t\t\t\t\t   (uintmax_t)opts->processes);\n \n+\tpp_init(&pp, opts, &pp_sig);\n+\n \t/*\n \t * Child tasks might receive input via stdin, terminating early (or not), so\n \t * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which\n \t * actually writes the data to children stdin fds.\n+\t *\n+\t * This _must_ come after pp_init(), because it installs its own\n+\t * SIGPIPE handler (to cleanup children), and we want to supersede\n+\t * that.\n \t */\n \tsigchain_push(SIGPIPE, SIG_IGN);\n \n-\tpp_init(&pp, opts, &pp_sig);\n \twhile (1) {\n \t\tfor (i = 0;\n \t\t    i < spawn_cap && !pp.shutdown &&\n\nDoes that make your problem go away?\n\nI suspect we could construct a related case that does fail on Linux\nwithout the patch above. Imagine we actually have two hooks running in\nparallel. The first one is fast and does not read its input, and the\nsecond one is slow. We'll get SIGPIPE writing to the first one, and then\nkill _both_ children. But that's wrong! There is no reason to kill the\nsecond hook, as our intent was to ignore SIGPIPE.\n\n-Peff\n"},{"id":"541117","messageId":"20260408054347.GA2284358@coredump.intra.peff.net","threadId":"65455","inReplyTo":"20260408052031.GB1324339@coredump.intra.peff.net","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-04-08T05:43:47Z","receivedAt":"2026-04-08T05:43:48Z","isPatch":false,"body":"On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:\n\n> I suspect we could construct a related case that does fail on Linux\n> without the patch above. Imagine we actually have two hooks running in\n> parallel. The first one is fast and does not read its input, and the\n> second one is slow. We'll get SIGPIPE writing to the first one, and then\n> kill _both_ children. But that's wrong! There is no reason to kill the\n> second hook, as our intent was to ignore SIGPIPE.\n\nThis would require running hooks in parallel, which isn't implemented\nyet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,\nthen this test:\n\ndiff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\nindex 44ec875aef..97257763d3 100755\n--- a/t/t5401-update-hooks.sh\n+++ b/t/t5401-update-hooks.sh\n@@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets to read its input' '\n \tgit push ./victim.git \"+refs/heads/*:refs/heads/*\"\n '\n \n+test_expect_success 'hooks in parallel that do not read input' '\n+\t# Add this to our $PATH to avoid having to write the whole trash\n+\t# directory into our config options, which would require quoting.\n+\tmkdir bin &&\n+\tPATH=$PWD/bin:$PATH &&\n+\n+\twrite_script bin/hook-fast <<-\\EOF &&\n+\t# This hook does not read its input, so the parent process\n+\t# may see SIGPIPE if it is not ignored. It should happen\n+\t# relatively quickly.\n+\texit 0\n+\tEOF\n+\n+\twrite_script bin/hook-slow <<-\\EOF &&\n+\t# This hook is slow, so we expect it to still be running\n+\t# when the other hook has exited (and the parent has a pipe error\n+\t# writing to it).\n+\t#\n+\t# So we want to be slow enough that we expect this to happen, but not\n+\t# so slow that the test takes forever. 1 second is probably enough\n+\t# in practice (and if it is occasionally not on a loaded system, we\n+\t# will err on the side of having the test pass).\n+\tsleep 1\n+\texit 0\n+\tEOF\n+\n+\n+\tgit init --bare parallel.git &&\n+\tgit -C parallel.git config hook.fast.command \"hook-fast\" &&\n+\tgit -C parallel.git config hook.fast.event pre-receive &&\n+\tgit -C parallel.git config hook.fast.parallel true &&\n+\tgit -C parallel.git config hook.slow.command \"hook-slow\" &&\n+\tgit -C parallel.git config hook.slow.event pre-receive &&\n+\tgit -C parallel.git config hook.slow.parallel true &&\n+\tgit -C parallel.git config hook.jobs 2 &&\n+\n+\tgit push ./parallel.git \"+refs/heads/*:refs/heads/*\"\n+'\n+\n test_done\n\nfails reliably. And applying the patch I suggested earlier fixes it.\n\nSo I think it's probably a good idea regardless, though I'm still\ncurious to see if it solves Randall's non-parallel case on NonStop.\n\n-Peff\n"},{"id":"541131","messageId":"871pgp3byq.fsf@collabora.com","threadId":"65455","inReplyTo":"20260408054347.GA2284358@coredump.intra.peff.net","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Adrian Ratiu","fromEmail":"adrian.ratiu@collabora.com","sentAt":"2026-04-08T11:53:17Z","receivedAt":"2026-04-08T11:53:30Z","isPatch":false,"body":"On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:\n> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:\n>\n>> I suspect we could construct a related case that does fail on Linux\n>> without the patch above. Imagine we actually have two hooks running in\n>> parallel. The first one is fast and does not read its input, and the\n>> second one is slow. We'll get SIGPIPE writing to the first one, and then\n>> kill _both_ children. But that's wrong! There is no reason to kill the\n>> second hook, as our intent was to ignore SIGPIPE.\n>\n> This would require running hooks in parallel, which isn't implemented\n> yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,\n> then this test:\n>\n> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\n> index 44ec875aef..97257763d3 100755\n> --- a/t/t5401-update-hooks.sh\n> +++ b/t/t5401-update-hooks.sh\n> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets to read its input' '\n>  \tgit push ./victim.git \"+refs/heads/*:refs/heads/*\"\n>  '\n>  \n> +test_expect_success 'hooks in parallel that do not read input' '\n> +\t# Add this to our $PATH to avoid having to write the whole trash\n> +\t# directory into our config options, which would require quoting.\n> +\tmkdir bin &&\n> +\tPATH=$PWD/bin:$PATH &&\n> +\n> +\twrite_script bin/hook-fast <<-\\EOF &&\n> +\t# This hook does not read its input, so the parent process\n> +\t# may see SIGPIPE if it is not ignored. It should happen\n> +\t# relatively quickly.\n> +\texit 0\n> +\tEOF\n> +\n> +\twrite_script bin/hook-slow <<-\\EOF &&\n> +\t# This hook is slow, so we expect it to still be running\n> +\t# when the other hook has exited (and the parent has a pipe error\n> +\t# writing to it).\n> +\t#\n> +\t# So we want to be slow enough that we expect this to happen, but not\n> +\t# so slow that the test takes forever. 1 second is probably enough\n> +\t# in practice (and if it is occasionally not on a loaded system, we\n> +\t# will err on the side of having the test pass).\n> +\tsleep 1\n> +\texit 0\n> +\tEOF\n> +\n> +\n> +\tgit init --bare parallel.git &&\n> +\tgit -C parallel.git config hook.fast.command \"hook-fast\" &&\n> +\tgit -C parallel.git config hook.fast.event pre-receive &&\n> +\tgit -C parallel.git config hook.fast.parallel true &&\n> +\tgit -C parallel.git config hook.slow.command \"hook-slow\" &&\n> +\tgit -C parallel.git config hook.slow.event pre-receive &&\n> +\tgit -C parallel.git config hook.slow.parallel true &&\n> +\tgit -C parallel.git config hook.jobs 2 &&\n> +\n> +\tgit push ./parallel.git \"+refs/heads/*:refs/heads/*\"\n> +'\n> +\n>  test_done\n>\n> fails reliably. And applying the patch I suggested earlier fixes it.\n>\n> So I think it's probably a good idea regardless, though I'm still\n> curious to see if it solves Randall's non-parallel case on NonStop.\n\nThanks Peff for the in-depth analysis, fix and test.\nIt is very much appreciated. I missed this case.\n\nI agree with your assesement: this must be fixed regardless if it also\nfixes Randall's case or not (might be a separate root cause).\n\nI would proceed like this (obviously crediting you for the fix & test):\n\nIf it fixes Randall's case:\n   send a standalone bug-fix patch, then integrate the test into the\n   parallel series.\nelse\n   integrate both the fix and the test into the parallel series.\n\n@Randall please let us know if the fix proposed by Peff in the other\nresponse works for you.\n"},{"id":"541139","messageId":"012001dcc76e$aa0449d0$fe0cdd70$@nexbridge.com","threadId":"65455","inReplyTo":"871pgp3byq.fsf@collabora.com","subject":"RE: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"","fromEmail":"rsbecker@nexbridge.com","sentAt":"2026-04-08T15:44:56Z","receivedAt":"2026-04-08T15:45:09Z","isPatch":false,"body":"On April 8, 2026 7:53 AM, Adrian Ratiu wrote:\n>On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:\n>> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:\n>>\n>>> I suspect we could construct a related case that does fail on Linux\n>>> without the patch above. Imagine we actually have two hooks running in\n>>> parallel. The first one is fast and does not read its input, and the\n>>> second one is slow. We'll get SIGPIPE writing to the first one, and then\n>>> kill _both_ children. But that's wrong! There is no reason to kill the\n>>> second hook, as our intent was to ignore SIGPIPE.\n>>\n>> This would require running hooks in parallel, which isn't implemented\n>> yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,\n>> then this test:\n>>\n>> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\n>> index 44ec875aef..97257763d3 100755\n>> --- a/t/t5401-update-hooks.sh\n>> +++ b/t/t5401-update-hooks.sh\n>> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets\nto\n>read its input' '\n>>  \tgit push ./victim.git \"+refs/heads/*:refs/heads/*\"\n>>  '\n>>\n>> +test_expect_success 'hooks in parallel that do not read input' '\n>> +\t# Add this to our $PATH to avoid having to write the whole trash\n>> +\t# directory into our config options, which would require quoting.\n>> +\tmkdir bin &&\n>> +\tPATH=$PWD/bin:$PATH &&\n>> +\n>> +\twrite_script bin/hook-fast <<-\\EOF &&\n>> +\t# This hook does not read its input, so the parent process\n>> +\t# may see SIGPIPE if it is not ignored. It should happen\n>> +\t# relatively quickly.\n>> +\texit 0\n>> +\tEOF\n>> +\n>> +\twrite_script bin/hook-slow <<-\\EOF &&\n>> +\t# This hook is slow, so we expect it to still be running\n>> +\t# when the other hook has exited (and the parent has a pipe error\n>> +\t# writing to it).\n>> +\t#\n>> +\t# So we want to be slow enough that we expect this to happen, but\nnot\n>> +\t# so slow that the test takes forever. 1 second is probably enough\n>> +\t# in practice (and if it is occasionally not on a loaded system, we\n>> +\t# will err on the side of having the test pass).\n>> +\tsleep 1\n>> +\texit 0\n>> +\tEOF\n>> +\n>> +\n>> +\tgit init --bare parallel.git &&\n>> +\tgit -C parallel.git config hook.fast.command \"hook-fast\" &&\n>> +\tgit -C parallel.git config hook.fast.event pre-receive &&\n>> +\tgit -C parallel.git config hook.fast.parallel true &&\n>> +\tgit -C parallel.git config hook.slow.command \"hook-slow\" &&\n>> +\tgit -C parallel.git config hook.slow.event pre-receive &&\n>> +\tgit -C parallel.git config hook.slow.parallel true &&\n>> +\tgit -C parallel.git config hook.jobs 2 &&\n>> +\n>> +\tgit push ./parallel.git \"+refs/heads/*:refs/heads/*\"\n>> +'\n>> +\n>>  test_done\n>>\n>> fails reliably. And applying the patch I suggested earlier fixes it.\n>>\n>> So I think it's probably a good idea regardless, though I'm still\n>> curious to see if it solves Randall's non-parallel case on NonStop.\n>\n>Thanks Peff for the in-depth analysis, fix and test.\n>It is very much appreciated. I missed this case.\n>\n>I agree with your assesement: this must be fixed regardless if it also\n>fixes Randall's case or not (might be a separate root cause).\n>\n>I would proceed like this (obviously crediting you for the fix & test):\n>\n>If it fixes Randall's case:\n>   send a standalone bug-fix patch, then integrate the test into the\n>   parallel series.\n>else\n>   integrate both the fix and the test into the parallel series.\n>\n>@Randall please let us know if the fix proposed by Peff in the other\n>response works for you.\n\nYes, this fix worked on NonStop. Thanks Peff. The new test also passed.\n\n"},{"id":"541140","messageId":"xmqqpl491mfd.fsf@gitster.g","threadId":"65455","inReplyTo":"20260408052031.GB1324339@coredump.intra.peff.net","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-08T15:50:14Z","receivedAt":"2026-04-08T15:50:17Z","isPatch":false,"body":"Jeff King <peff@peff.net> writes:\n\n> I think the root of the issue is that we should not be trying to\n> propagate SIGPIPE to the child in this case at all. Our handler is\n> pushed there only because it's part of sigchain_push_common(), which is\n> sensible: in general if we are dying to SIGPIPE we want to do our\n> cleanup. It's just funny in this case with the ordering of our SIG_IGN,\n> because now that SIG_IGN isn't on top of the stack anymore.\n>\n> I.e., I think we want to reorder like this:\n>\n> diff --git a/run-command.c b/run-command.c\n> index 32c290ee6a..8a95f7ff1e 100644\n> --- a/run-command.c\n> +++ b/run-command.c\n> @@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n>  \t\t\t\t\t   \"max:%\"PRIuMAX,\n>  \t\t\t\t\t   (uintmax_t)opts->processes);\n>  \n> +\tpp_init(&pp, opts, &pp_sig);\n> +\n>  \t/*\n>  \t * Child tasks might receive input via stdin, terminating early (or not), so\n>  \t * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which\n>  \t * actually writes the data to children stdin fds.\n> +\t *\n> +\t * This _must_ come after pp_init(), because it installs its own\n> +\t * SIGPIPE handler (to cleanup children), and we want to supersede\n> +\t * that.\n>  \t */\n>  \tsigchain_push(SIGPIPE, SIG_IGN);\n>  \n> -\tpp_init(&pp, opts, &pp_sig);\n>  \twhile (1) {\n>  \t\tfor (i = 0;\n>  \t\t    i < spawn_cap && !pp.shutdown &&\n>\n> Does that make your problem go away?\n>\n> I suspect we could construct a related case that does fail on Linux\n> without the patch above. Imagine we actually have two hooks running in\n> parallel. The first one is fast and does not read its input, and the\n> second one is slow. We'll get SIGPIPE writing to the first one, and then\n> kill _both_ children. But that's wrong! There is no reason to kill the\n> second hook, as our intent was to ignore SIGPIPE.\n\nOh, I am very much impressed by this analysis.\n\nAs -rc1 has already been tagged (but not pushed out yet), we would\nprobably want to apply a fix before -rc2, I suppose.\n\nThanks.\n"},{"id":"541141","messageId":"012101dcc76f$bae10a80$30a31f80$@nexbridge.com","threadId":"65455","inReplyTo":"871pgp3byq.fsf@collabora.com","subject":"RE: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"","fromEmail":"rsbecker@nexbridge.com","sentAt":"2026-04-08T15:52:34Z","receivedAt":"2026-04-08T15:52:44Z","isPatch":false,"body":"On April 8, 2026 7:53 AM, Adrian Ratiu wrote:\n>To: Jeff King <peff@peff.net>; rsbecker@nexbridge.com\n>Cc: Junio C Hamano <gitster@pobox.com>; git@vger.kernel.org\n>Subject: Re: Help needed on 2.54.0-rc0 t5301.13 looping.\n>\n>On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:\n>> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:\n>>\n>>> I suspect we could construct a related case that does fail on Linux\n>>> without the patch above. Imagine we actually have two hooks running in\n>>> parallel. The first one is fast and does not read its input, and the\n>>> second one is slow. We'll get SIGPIPE writing to the first one, and then\n>>> kill _both_ children. But that's wrong! There is no reason to kill the\n>>> second hook, as our intent was to ignore SIGPIPE.\n>>\n>> This would require running hooks in parallel, which isn't implemented\n>> yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,\n>> then this test:\n>>\n>> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\n>> index 44ec875aef..97257763d3 100755\n>> --- a/t/t5401-update-hooks.sh\n>> +++ b/t/t5401-update-hooks.sh\n>> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets\nto\n>read its input' '\n>>  \tgit push ./victim.git \"+refs/heads/*:refs/heads/*\"\n>>  '\n>>\n>> +test_expect_success 'hooks in parallel that do not read input' '\n>> +\t# Add this to our $PATH to avoid having to write the whole trash\n>> +\t# directory into our config options, which would require quoting.\n>> +\tmkdir bin &&\n>> +\tPATH=$PWD/bin:$PATH &&\n>> +\n>> +\twrite_script bin/hook-fast <<-\\EOF &&\n>> +\t# This hook does not read its input, so the parent process\n>> +\t# may see SIGPIPE if it is not ignored. It should happen\n>> +\t# relatively quickly.\n>> +\texit 0\n>> +\tEOF\n>> +\n>> +\twrite_script bin/hook-slow <<-\\EOF &&\n>> +\t# This hook is slow, so we expect it to still be running\n>> +\t# when the other hook has exited (and the parent has a pipe error\n>> +\t# writing to it).\n>> +\t#\n>> +\t# So we want to be slow enough that we expect this to happen, but\nnot\n>> +\t# so slow that the test takes forever. 1 second is probably enough\n>> +\t# in practice (and if it is occasionally not on a loaded system, we\n>> +\t# will err on the side of having the test pass).\n>> +\tsleep 1\n>> +\texit 0\n>> +\tEOF\n>> +\n>> +\n>> +\tgit init --bare parallel.git &&\n>> +\tgit -C parallel.git config hook.fast.command \"hook-fast\" &&\n>> +\tgit -C parallel.git config hook.fast.event pre-receive &&\n>> +\tgit -C parallel.git config hook.fast.parallel true &&\n>> +\tgit -C parallel.git config hook.slow.command \"hook-slow\" &&\n>> +\tgit -C parallel.git config hook.slow.event pre-receive &&\n>> +\tgit -C parallel.git config hook.slow.parallel true &&\n>> +\tgit -C parallel.git config hook.jobs 2 &&\n>> +\n>> +\tgit push ./parallel.git \"+refs/heads/*:refs/heads/*\"\n>> +'\n>> +\n>>  test_done\n>>\n>> fails reliably. And applying the patch I suggested earlier fixes it.\n>>\n>> So I think it's probably a good idea regardless, though I'm still\n>> curious to see if it solves Randall's non-parallel case on NonStop.\n>\n>Thanks Peff for the in-depth analysis, fix and test.\n>It is very much appreciated. I missed this case.\n>\n>I agree with your assesement: this must be fixed regardless if it also\n>fixes Randall's case or not (might be a separate root cause).\n>\n>I would proceed like this (obviously crediting you for the fix & test):\n>\n>If it fixes Randall's case:\n>   send a standalone bug-fix patch, then integrate the test into the\n>   parallel series.\n>else\n>   integrate both the fix and the test into the parallel series.\n>\n>@Randall please let us know if the fix proposed by Peff in the other\n>response works for you.\n\nThis fix, however, causes an unreported infinite loop in t5571:\n\nexpecting success of 5571.11 'sigpipe does not cause pre-push hook failure':\n        test_hook --clobber pre-push <<-\\EOF &&\n        exit 0\n        EOF\n        git push parent1 \"refs/heads/b/*:refs/heads/b/*\"\n\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\n<and hung>\n\n"},{"id":"541142","messageId":"012b01dcc770$126425d0$372c7170$@nexbridge.com","threadId":"65455","inReplyTo":"871pgp3byq.fsf@collabora.com","subject":"RE: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"","fromEmail":"rsbecker@nexbridge.com","sentAt":"2026-04-08T15:55:01Z","receivedAt":"2026-04-08T15:55:11Z","isPatch":false,"body":"On April 8, 2026 11:53 AM, I wrote (accidentally):\n>To: 'Adrian Ratiu' <adrian.ratiu@collabora.com>; 'Jeff King'\n<peff@peff.net>\n>Cc: 'Junio C Hamano' <gitster@pobox.com>; 'git@vger.kernel.org'\n><git@vger.kernel.org>\n>Subject: RE: Help needed on 2.54.0-rc0 t5301.13 looping.\n>\n>On April 8, 2026 7:53 AM, Adrian Ratiu wrote:\n>>To: Jeff King <peff@peff.net>; rsbecker@nexbridge.com\n>>Cc: Junio C Hamano <gitster@pobox.com>; git@vger.kernel.org\n>>Subject: Re: Help needed on 2.54.0-rc0 t5301.13 looping.\n>>\n>>On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:\n>>> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:\n>>>\n>>>> I suspect we could construct a related case that does fail on Linux\n>>>> without the patch above. Imagine we actually have two hooks running\n>>>> in parallel. The first one is fast and does not read its input, and\n>>>> the second one is slow. We'll get SIGPIPE writing to the first one,\n>>>> and then kill _both_ children. But that's wrong! There is no reason\n>>>> to kill the second hook, as our intent was to ignore SIGPIPE.\n>>>\n>>> This would require running hooks in parallel, which isn't implemented\n>>> yet for v2.54.0. But if I build on top of the ar/parallel-hooks\n>>> topic, then this test:\n>>>\n>>> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index\n>>> 44ec875aef..97257763d3 100755\n>>> --- a/t/t5401-update-hooks.sh\n>>> +++ b/t/t5401-update-hooks.sh\n>>> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that\n>>> forgets to\n>>read its input' '\n>>>  \tgit push ./victim.git \"+refs/heads/*:refs/heads/*\"\n>>>  '\n>>>\n>>> +test_expect_success 'hooks in parallel that do not read input' '\n>>> +\t# Add this to our $PATH to avoid having to write the whole trash\n>>> +\t# directory into our config options, which would require quoting.\n>>> +\tmkdir bin &&\n>>> +\tPATH=$PWD/bin:$PATH &&\n>>> +\n>>> +\twrite_script bin/hook-fast <<-\\EOF &&\n>>> +\t# This hook does not read its input, so the parent process\n>>> +\t# may see SIGPIPE if it is not ignored. It should happen\n>>> +\t# relatively quickly.\n>>> +\texit 0\n>>> +\tEOF\n>>> +\n>>> +\twrite_script bin/hook-slow <<-\\EOF &&\n>>> +\t# This hook is slow, so we expect it to still be running\n>>> +\t# when the other hook has exited (and the parent has a pipe error\n>>> +\t# writing to it).\n>>> +\t#\n>>> +\t# So we want to be slow enough that we expect this to happen, but\nnot\n>>> +\t# so slow that the test takes forever. 1 second is probably enough\n>>> +\t# in practice (and if it is occasionally not on a loaded system, we\n>>> +\t# will err on the side of having the test pass).\n>>> +\tsleep 1\n>>> +\texit 0\n>>> +\tEOF\n>>> +\n>>> +\n>>> +\tgit init --bare parallel.git &&\n>>> +\tgit -C parallel.git config hook.fast.command \"hook-fast\" &&\n>>> +\tgit -C parallel.git config hook.fast.event pre-receive &&\n>>> +\tgit -C parallel.git config hook.fast.parallel true &&\n>>> +\tgit -C parallel.git config hook.slow.command \"hook-slow\" &&\n>>> +\tgit -C parallel.git config hook.slow.event pre-receive &&\n>>> +\tgit -C parallel.git config hook.slow.parallel true &&\n>>> +\tgit -C parallel.git config hook.jobs 2 &&\n>>> +\n>>> +\tgit push ./parallel.git \"+refs/heads/*:refs/heads/*\"\n>>> +'\n>>> +\n>>>  test_done\n>>>\n>>> fails reliably. And applying the patch I suggested earlier fixes it.\n>>>\n>>> So I think it's probably a good idea regardless, though I'm still\n>>> curious to see if it solves Randall's non-parallel case on NonStop.\n>>\n>>Thanks Peff for the in-depth analysis, fix and test.\n>>It is very much appreciated. I missed this case.\n>>\n>>I agree with your assesement: this must be fixed regardless if it also\n>>fixes Randall's case or not (might be a separate root cause).\n>>\n>>I would proceed like this (obviously crediting you for the fix & test):\n>>\n>>If it fixes Randall's case:\n>>   send a standalone bug-fix patch, then integrate the test into the\n>>   parallel series.\n>>else\n>>   integrate both the fix and the test into the parallel series.\n>>\n>>@Randall please let us know if the fix proposed by Peff in the other\n>>response works for you.\n>\n>This fix, however, causes an unreported infinite loop in t5571:\n>\n>expecting success of 5571.11 'sigpipe does not cause pre-push hook\nfailure':\n>        test_hook --clobber pre-push <<-\\EOF &&\n>        exit 0\n>        EOF\n>        git push parent1 \"refs/heads/b/*:refs/heads/b/*\"\n>\n>Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) <and hung>\n\nI was not patient enough. This continued eventually and passed.\n\n"},{"id":"541146","messageId":"87y0ix1kq4.fsf@collabora.com","threadId":"65455","inReplyTo":"xmqqpl491mfd.fsf@gitster.g","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Adrian Ratiu","fromEmail":"adrian.ratiu@collabora.com","sentAt":"2026-04-08T16:26:59Z","receivedAt":"2026-04-08T16:27:11Z","isPatch":false,"body":"On Wed, 08 Apr 2026, Junio C Hamano <gitster@pobox.com> wrote:\n> Jeff King <peff@peff.net> writes:\n>\n>> I think the root of the issue is that we should not be trying to\n>> propagate SIGPIPE to the child in this case at all. Our handler is\n>> pushed there only because it's part of sigchain_push_common(), which is\n>> sensible: in general if we are dying to SIGPIPE we want to do our\n>> cleanup. It's just funny in this case with the ordering of our SIG_IGN,\n>> because now that SIG_IGN isn't on top of the stack anymore.\n>>\n>> I.e., I think we want to reorder like this:\n>>\n>> diff --git a/run-command.c b/run-command.c\n>> index 32c290ee6a..8a95f7ff1e 100644\n>> --- a/run-command.c\n>> +++ b/run-command.c\n>> @@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n>>  \t\t\t\t\t   \"max:%\"PRIuMAX,\n>>  \t\t\t\t\t   (uintmax_t)opts->processes);\n>>  \n>> +\tpp_init(&pp, opts, &pp_sig);\n>> +\n>>  \t/*\n>>  \t * Child tasks might receive input via stdin, terminating early (or not), so\n>>  \t * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which\n>>  \t * actually writes the data to children stdin fds.\n>> +\t *\n>> +\t * This _must_ come after pp_init(), because it installs its own\n>> +\t * SIGPIPE handler (to cleanup children), and we want to supersede\n>> +\t * that.\n>>  \t */\n>>  \tsigchain_push(SIGPIPE, SIG_IGN);\n>>  \n>> -\tpp_init(&pp, opts, &pp_sig);\n>>  \twhile (1) {\n>>  \t\tfor (i = 0;\n>>  \t\t    i < spawn_cap && !pp.shutdown &&\n>>\n>> Does that make your problem go away?\n>>\n>> I suspect we could construct a related case that does fail on Linux\n>> without the patch above. Imagine we actually have two hooks running in\n>> parallel. The first one is fast and does not read its input, and the\n>> second one is slow. We'll get SIGPIPE writing to the first one, and then\n>> kill _both_ children. But that's wrong! There is no reason to kill the\n>> second hook, as our intent was to ignore SIGPIPE.\n>\n> Oh, I am very much impressed by this analysis.\n>\n> As -rc1 has already been tagged (but not pushed out yet), we would\n> probably want to apply a fix before -rc2, I suppose.\n\nYes, that is fine.\n\nAll my local tests also look good with Peff's patch\n(including the parallel series).\n\n@Peff\n\nPlease let me know if you wish me to send a patch or if you wish to send\nit yourself, since this investigation is your work & effort. :)\n"},{"id":"541147","messageId":"xmqqcy091jht.fsf@gitster.g","threadId":"65455","inReplyTo":"871pgp3byq.fsf@collabora.com","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-08T16:53:34Z","receivedAt":"2026-04-08T16:53:37Z","isPatch":false,"body":"Adrian Ratiu <adrian.ratiu@collabora.com> writes:\n\n> Thanks Peff for the in-depth analysis, fix and test.\n> It is very much appreciated. I missed this case.\n>\n> I agree with your assesement: this must be fixed regardless if it also\n> fixes Randall's case or not (might be a separate root cause).\n>\n> I would proceed like this (obviously crediting you for the fix & test):\n>\n> If it fixes Randall's case:\n>    send a standalone bug-fix patch, then integrate the test into the\n>    parallel series.\n> else\n>    integrate both the fix and the test into the parallel series.\n>\n> @Randall please let us know if the fix proposed by Peff in the other\n> response works for you.\n\nIt sounds sensible, but a standalone fix early before 2.54 final, as\nthe problem and the fix shown by Peff here looked correct, without\nwaiting for NonStop may be simpler to work with.  Then, rebuild\nparallel series on top of the 'master' that has the fix applied,\nperhaps?\n\nThanks.\n"},{"id":"541149","messageId":"013c01dcc778$ff106620$fd313260$@nexbridge.com","threadId":"65455","inReplyTo":"xmqqcy091jht.fsf@gitster.g","subject":"RE: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"","fromEmail":"rsbecker@nexbridge.com","sentAt":"2026-04-08T16:58:54Z","receivedAt":"2026-04-08T16:59:06Z","isPatch":false,"body":"On April 8, 2026 12:54 PM, Junio C Hamano wrote:\n>Adrian Ratiu <adrian.ratiu@collabora.com> writes:\n>\n>> Thanks Peff for the in-depth analysis, fix and test.\n>> It is very much appreciated. I missed this case.\n>>\n>> I agree with your assesement: this must be fixed regardless if it also\n>> fixes Randall's case or not (might be a separate root cause).\n>>\n>> I would proceed like this (obviously crediting you for the fix & test):\n>>\n>> If it fixes Randall's case:\n>>    send a standalone bug-fix patch, then integrate the test into the\n>>    parallel series.\n>> else\n>>    integrate both the fix and the test into the parallel series.\n>>\n>> @Randall please let us know if the fix proposed by Peff in the other\n>> response works for you.\n>\n>It sounds sensible, but a standalone fix early before 2.54 final, as the\nproblem and\n>the fix shown by Peff here looked correct, without waiting for NonStop may\nbe\n>simpler to work with.  Then, rebuild parallel series on top of the 'master'\nthat has\n>the fix applied, perhaps?\n\nThe fix works on NonStop as previously supplied. So I'm good.\n\n"},{"id":"541150","messageId":"87v7e11j4q.fsf@collabora.com","threadId":"65455","inReplyTo":"xmqqcy091jht.fsf@gitster.g","subject":"Re: Help needed on 2.54.0-rc0 t5301.13 looping.","fromName":"Adrian Ratiu","fromEmail":"adrian.ratiu@collabora.com","sentAt":"2026-04-08T17:01:25Z","receivedAt":"2026-04-08T17:01:39Z","isPatch":false,"body":"On Wed, 08 Apr 2026, Junio C Hamano <gitster@pobox.com> wrote:\n> Adrian Ratiu <adrian.ratiu@collabora.com> writes:\n>\n>> Thanks Peff for the in-depth analysis, fix and test.\n>> It is very much appreciated. I missed this case.\n>>\n>> I agree with your assesement: this must be fixed regardless if it also\n>> fixes Randall's case or not (might be a separate root cause).\n>>\n>> I would proceed like this (obviously crediting you for the fix & test):\n>>\n>> If it fixes Randall's case:\n>>    send a standalone bug-fix patch, then integrate the test into the\n>>    parallel series.\n>> else\n>>    integrate both the fix and the test into the parallel series.\n>>\n>> @Randall please let us know if the fix proposed by Peff in the other\n>> response works for you.\n>\n> It sounds sensible, but a standalone fix early before 2.54 final, as\n> the problem and the fix shown by Peff here looked correct, without\n> waiting for NonStop may be simpler to work with.  Then, rebuild\n> parallel series on top of the 'master' that has the fix applied,\n> perhaps?\n\nYes, that is the path forward now that Randall also confirmed the fix\nworks on NonStop (btw thank you Randall). :)\n\nJust waiting for Peff to tell me if he wants to send it himself.\n"},{"id":"541155","messageId":"20260408172055.GA2293804@coredump.intra.peff.net","threadId":"65455","inReplyTo":"87y0ix1kq4.fsf@collabora.com","subject":"[PATCH] run_processes_parallel(): fix order of sigpipe handling","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-04-08T17:20:55Z","receivedAt":"2026-04-08T17:20:57Z","isPatch":true,"body":"On Wed, Apr 08, 2026 at 07:26:59PM +0300, Adrian Ratiu wrote:\n\n> @Peff\n> \n> Please let me know if you wish me to send a patch or if you wish to send\n> it yourself, since this investigation is your work & effort. :)\n\nHere it is with a small cleanup and a real commit message.\n\n-- >8 --\nSubject: run_processes_parallel(): fix order of sigpipe handling\n\nIn commit ec0becacc9 (run-command: add stdin callback for\nparallelization, 2026-01-28), we taught run_processes_parallel() to\nignore SIGPIPE, since we wouldn't want a write() to a broken pipe of one\nof the children to take down the whole process.\n\nBut there's a subtle ordering issue. After we ignore SIGPIPE, we call\npp_init(), which installs its own cleanup handler for multiple signals\nusing sigchain_push_common(), which includes SIGPIPE. So if we receive\nSIGPIPE while writing to a child, we'll trigger that handler first, pop\nit off the stack, and then re-raise (which is then ignored because of\nthe SIG_IGN we pushed first).\n\nBut what does that handler do? It tries to clean up all of the child\nprocesses, under the assumption that when we re-raise the signal we'll\nbe exiting the process!\n\nSo a hook that exits without reading all of its input will cause us to\nget SIGPIPE, which will put us in a signal handler that then tries to\nkill() that same child.\n\nThis seems to be mostly harmless on Linux. The process has already\nexited by this point, and though kill() does not complain (since the\nprocess has not been reaped with a wait() call), it does not affect the\nexit status of the process.\n\nHowever, this seems not to be true on all platforms. This case is\ntriggered by t5401.13, \"pre-receive hook that forgets to read its\ninput\". This test fails on NonStop since that hook was converted to the\nrun_processes_parallel() API.\n\nWe can fix it by reordering the code a bit. We should run pp_init()\nfirst, and then push our SIG_IGN onto the stack afterwards, so that it\nis truly ignored while feeding the sub-processes.\n\nNote that we also reorder the popping at the end of the function, too.\nThis is not technically necessary, as we are doing two pops either way,\nbut now the pops will correctly match their pushes.\n\nThis also fixes a related case that we can't test yet. If we did have\nmore than one process to run, then one child causing SIGPIPE would cause\nus to kill() all of the children (which might still actually be\nrunning). But the hook API is the only user of the new feed_pipe\nfeature, and it does not yet support parallel hook execution. So for now\nwe'll always execute the processes sequentially. Once parallel hook\nexecution exists, we'll be able to add a test which covers this.\n\nReported-by: Randall S. Becker <rsbecker@nexbridge.com>\nSigned-off-by: Jeff King <peff@peff.net>\n---\n run-command.c | 11 ++++++++---\n 1 file changed, 8 insertions(+), 3 deletions(-)\n\ndiff --git a/run-command.c b/run-command.c\nindex 32c290ee6a..574d5c40f0 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n \t\t\t\t\t   \"max:%\"PRIuMAX,\n \t\t\t\t\t   (uintmax_t)opts->processes);\n \n+\tpp_init(&pp, opts, &pp_sig);\n+\n \t/*\n \t * Child tasks might receive input via stdin, terminating early (or not), so\n \t * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which\n \t * actually writes the data to children stdin fds.\n+\t *\n+\t * This _must_ come after pp_init(), because it installs its own\n+\t * SIGPIPE handler (to cleanup children), and we want to supersede\n+\t * that.\n \t */\n \tsigchain_push(SIGPIPE, SIG_IGN);\n \n-\tpp_init(&pp, opts, &pp_sig);\n \twhile (1) {\n \t\tfor (i = 0;\n \t\t    i < spawn_cap && !pp.shutdown &&\n@@ -1928,10 +1933,10 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n \t\t}\n \t}\n \n-\tpp_cleanup(&pp, opts);\n-\n \tsigchain_pop(SIGPIPE);\n \n+\tpp_cleanup(&pp, opts);\n+\n \tif (do_trace2)\n \t\ttrace2_region_leave(tr2_category, tr2_label, NULL);\n }\n-- \n2.54.0.rc1.274.g1f8c576c50\n\n"},{"id":"541157","messageId":"20260408173032.GB2293804@coredump.intra.peff.net","threadId":"65455","inReplyTo":"87v7e11j4q.fsf@collabora.com","subject":"[PATCH] t5401: test SIGPIPE with parallel hooks","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-04-08T17:30:32Z","receivedAt":"2026-04-08T17:30:34Z","isPatch":true,"body":"On Wed, Apr 08, 2026 at 08:01:25PM +0300, Adrian Ratiu wrote:\n\n> > It sounds sensible, but a standalone fix early before 2.54 final, as\n> > the problem and the fix shown by Peff here looked correct, without\n> > waiting for NonStop may be simpler to work with.  Then, rebuild\n> > parallel series on top of the 'master' that has the fix applied,\n> > perhaps?\n> \n> Yes, that is the path forward now that Randall also confirmed the fix\n> works on NonStop (btw thank you Randall). :)\n> \n> Just waiting for Peff to tell me if he wants to send it himself.\n\nI just sent out the fix patch, which should be good for 2.54. Here's the\ntest patch, which I hope you'll include when re-rolling the parallel\nseries (either as-is, or if you prefer it can be moved to another script\nwhere we're doing other parallel hook tests).\n\nIt would be nice to refer to the fix commit using its id, but we won't\nknow what it is until Junio applies it. :) So once that happens it might\nbe worth tweaking the commit message.\n\n-- >8 --\nSubject: t5401: test SIGPIPE with parallel hooks\n\nWe recently fixed a bug where a hook that caused us to get SIGPIPE would\naccidentally trigger the run_processes_parallel() cleanup handler,\nkilling the child processes.\n\nFor a single hook, this meant killing the already-exited hook. This case\nwas triggered by our tests, but was only a problem on some platforms.\n\nBut if you have multiple hooks running in parallel, this causes a\nproblem everywhere, since one hook failing to read its input would take\ndown all hooks. Now that we have parallel hook support, we can add a\ntest for this case. It should pass already, due to the existing fix.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n t/t5401-update-hooks.sh | 38 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 38 insertions(+)\n\ndiff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\nindex 44ec875aef..f727b5d545 100755\n--- a/t/t5401-update-hooks.sh\n+++ b/t/t5401-update-hooks.sh\n@@ -139,4 +139,42 @@ test_expect_success 'pre-receive hook that forgets to read its input' '\n \tgit push ./victim.git \"+refs/heads/*:refs/heads/*\"\n '\n \n+test_expect_success 'hooks in parallel that do not read input' '\n+\t# Add this to our $PATH to avoid having to write the whole trash\n+\t# directory into our config options, which would require quoting.\n+\tmkdir bin &&\n+\tPATH=$PWD/bin:$PATH &&\n+\n+\twrite_script bin/hook-fast <<-\\EOF &&\n+\t# This hook does not read its input, so the parent process\n+\t# may see SIGPIPE if it is not ignored. It should happen\n+\t# relatively quickly.\n+\texit 0\n+\tEOF\n+\n+\twrite_script bin/hook-slow <<-\\EOF &&\n+\t# This hook is slow, so we expect it to still be running\n+\t# when the other hook has exited (and the parent has a pipe error\n+\t# writing to it).\n+\t#\n+\t# So we want to be slow enough that we expect this to happen, but not\n+\t# so slow that the test takes forever. 1 second is probably enough\n+\t# in practice (and if it is occasionally not on a loaded system, we\n+\t# will err on the side of having the test pass).\n+\tsleep 1\n+\texit 0\n+\tEOF\n+\n+\tgit init --bare parallel.git &&\n+\tgit -C parallel.git config hook.fast.command \"hook-fast\" &&\n+\tgit -C parallel.git config hook.fast.event pre-receive &&\n+\tgit -C parallel.git config hook.fast.parallel true &&\n+\tgit -C parallel.git config hook.slow.command \"hook-slow\" &&\n+\tgit -C parallel.git config hook.slow.event pre-receive &&\n+\tgit -C parallel.git config hook.slow.parallel true &&\n+\tgit -C parallel.git config hook.jobs 2 &&\n+\n+\tgit push ./parallel.git \"+refs/heads/*:refs/heads/*\"\n+'\n+\n test_done\n-- \n2.54.0.rc1.274.g1f8c576c50\n\n"},{"id":"541164","messageId":"xmqqcy09z62e.fsf@gitster.g","threadId":"65455","inReplyTo":"20260408172055.GA2293804@coredump.intra.peff.net","subject":"Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-08T17:59:37Z","receivedAt":"2026-04-08T17:59:40Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n> We can fix it by reordering the code a bit. We should run pp_init()\n> first, and then push our SIG_IGN onto the stack afterwards, so that it\n> is truly ignored while feeding the sub-processes.\n>\n> Note that we also reorder the popping at the end of the function, too.\n> This is not technically necessary, as we are doing two pops either way,\n> but now the pops will correctly match their pushes.\n\nSounds quite sensible.\n\n> This also fixes a related case that we can't test yet. If we did have\n> more than one process to run, then one child causing SIGPIPE would cause\n> us to kill() all of the children (which might still actually be\n> running). But the hook API is the only user of the new feed_pipe\n> feature, and it does not yet support parallel hook execution. So for now\n> we'll always execute the processes sequentially. Once parallel hook\n> execution exists, we'll be able to add a test which covers this.\n\nGreat.\n\n> Reported-by: Randall S. Becker <rsbecker@nexbridge.com>\n> Signed-off-by: Jeff King <peff@peff.net>\n\nThanks, all of you, for addressing the issue so quickly.\n\nApplied.\n\n> ---\n>  run-command.c | 11 ++++++++---\n>  1 file changed, 8 insertions(+), 3 deletions(-)\n>\n> diff --git a/run-command.c b/run-command.c\n> index 32c290ee6a..574d5c40f0 100644\n> --- a/run-command.c\n> +++ b/run-command.c\n> @@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n>  \t\t\t\t\t   \"max:%\"PRIuMAX,\n>  \t\t\t\t\t   (uintmax_t)opts->processes);\n>  \n> +\tpp_init(&pp, opts, &pp_sig);\n> +\n>  \t/*\n>  \t * Child tasks might receive input via stdin, terminating early (or not), so\n>  \t * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which\n>  \t * actually writes the data to children stdin fds.\n> +\t *\n> +\t * This _must_ come after pp_init(), because it installs its own\n> +\t * SIGPIPE handler (to cleanup children), and we want to supersede\n> +\t * that.\n>  \t */\n>  \tsigchain_push(SIGPIPE, SIG_IGN);\n>  \n> -\tpp_init(&pp, opts, &pp_sig);\n>  \twhile (1) {\n>  \t\tfor (i = 0;\n>  \t\t    i < spawn_cap && !pp.shutdown &&\n> @@ -1928,10 +1933,10 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)\n>  \t\t}\n>  \t}\n>  \n> -\tpp_cleanup(&pp, opts);\n> -\n>  \tsigchain_pop(SIGPIPE);\n>  \n> +\tpp_cleanup(&pp, opts);\n> +\n>  \tif (do_trace2)\n>  \t\ttrace2_region_leave(tr2_category, tr2_label, NULL);\n>  }\n"},{"id":"541179","messageId":"xmqqmrzdxjel.fsf@gitster.g","threadId":"65455","inReplyTo":"xmqqcy09z62e.fsf@gitster.g","subject":"Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-08T20:54:26Z","receivedAt":"2026-04-08T20:54:29Z","isPatch":true,"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> Reported-by: Randall S. Becker <rsbecker@nexbridge.com>\n>> Signed-off-by: Jeff King <peff@peff.net>\n>\n> Thanks, all of you, for addressing the issue so quickly.\n>\n> Applied.\n\nWe have a few places where we sigchain_push(SIGPIPE, SIG_IGN) then\nrun start_command().  One is in upload-pack.c where we spawn\n\"rev-list\" for reachability check, and the other is in fetch-pack.c\nwhere we spawn unpack-objects/index-pack.\n\nCurrently neither subprocess is marked with the clean-on-exit bit.\nbut if somebody is careless and flips the bit for these\nsubprocesses, start_command() will call mark_child_for_cleanup() and\ncauses sigchain_push_common() to set up cleanup_children_on_signal()\nto be called, which would lead to a very similar bug.\n\nI wonder if swapping the order of start_command() and sigchain_push()\nin these two code paths have downsides, or is it making the code worse\njust to futureproof it against a future that is unlikely to come?\n\n"},{"id":"541194","messageId":"20260408234236.GA2980392@coredump.intra.peff.net","threadId":"65455","inReplyTo":"xmqqmrzdxjel.fsf@gitster.g","subject":"Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-04-08T23:42:36Z","receivedAt":"2026-04-08T23:42:38Z","isPatch":true,"body":"On Wed, Apr 08, 2026 at 01:54:26PM -0700, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n> >> Reported-by: Randall S. Becker <rsbecker@nexbridge.com>\n> >> Signed-off-by: Jeff King <peff@peff.net>\n> >\n> > Thanks, all of you, for addressing the issue so quickly.\n> >\n> > Applied.\n> \n> We have a few places where we sigchain_push(SIGPIPE, SIG_IGN) then\n> run start_command().  One is in upload-pack.c where we spawn\n> \"rev-list\" for reachability check, and the other is in fetch-pack.c\n> where we spawn unpack-objects/index-pack.\n> \n> Currently neither subprocess is marked with the clean-on-exit bit.\n> but if somebody is careless and flips the bit for these\n> subprocesses, start_command() will call mark_child_for_cleanup() and\n> causes sigchain_push_common() to set up cleanup_children_on_signal()\n> to be called, which would lead to a very similar bug.\n\nHmm, good catch. This is a bit worrisome, as we've added some\nclean_on_exit calls recently, and might do so again.\n\n> I wonder if swapping the order of start_command() and sigchain_push()\n> in these two code paths have downsides, or is it making the code worse\n> just to futureproof it against a future that is unlikely to come?\n\nI don't think it's really making the code worse. It's putting the\nSIGPIPE handling closer to where we're actually doing the writes. But I\ndon't like that it is a subtle thing that people writing new code have\nto worry about. And I wouldn't be surprised if there are other cases\nwhere we disable SIGPIPE, and then call start_command() in a much lower\nlevel of the call chain, which would make reordering harder.\n\nI wonder if we can do better.\n\nThe root of the issue is that sigchain_push_common() is not really\nexpressing what we want. We are trying to install a handler to do\ncleanup _if_ we are about to exit. And that is always going to be true\nfor SIGTERM, etc, where we might install handlers but never expect them\nto rescue us from exiting. But for SIGPIPE, our desired action is really\ndependent on whether the signal is being ignored in general.\n\nSo we could perhaps do something like this:\n\ndiff --git a/sigchain.c b/sigchain.c\nindex 66123bdbab..343b5571e0 100644\n--- a/sigchain.c\n+++ b/sigchain.c\n@@ -16,7 +16,7 @@ static void check_signum(int sig)\n \t\tBUG(\"signal out of range: %d\", sig);\n }\n \n-int sigchain_push(int sig, sigchain_fun f)\n+static int sigchain_push_1(int sig, sigchain_fun f, int keep_ignored)\n {\n \tstruct sigchain_signal *s = signals + sig;\n \tcheck_signum(sig);\n@@ -25,10 +25,24 @@ int sigchain_push(int sig, sigchain_fun f)\n \ts->old[s->n] = signal(sig, f);\n \tif (s->old[s->n] == SIG_ERR)\n \t\treturn -1;\n+\tif (keep_ignored && s->old[s->n] == SIG_IGN) {\n+\t\t/*\n+\t\t * The signal was already ignored; keep it that way\n+\t\t * rather than installing a handler which would be used\n+\t\t * for cleanup.\n+\t\t */\n+\t\tif (signal(sig, SIG_IGN) < 0)\n+\t\t\treturn -1;\n+\t}\n \ts->n++;\n \treturn 0;\n }\n \n+int sigchain_push(int sig, sigchain_fun f)\n+{\n+\treturn sigchain_push_1(sig, f, 0);\n+}\n+\n int sigchain_pop(int sig)\n {\n \tstruct sigchain_signal *s = signals + sig;\n@@ -48,7 +62,7 @@ void sigchain_push_common(sigchain_fun f)\n \tsigchain_push(SIGHUP, f);\n \tsigchain_push(SIGTERM, f);\n \tsigchain_push(SIGQUIT, f);\n-\tsigchain_push(SIGPIPE, f);\n+\tsigchain_push_1(SIGPIPE, f, 1);\n }\n \n void sigchain_pop_common(void)\n\n\nAnd that turns the handler setup in pp_init() into a noop (for SIGPIPE),\nsince it sees that we're ignoring the signal already. But I think this\nisn't quite enough for the cases in start_command(), which have\nsomething even deeper going on.\n\nThe handler we set up in mark_child_for_cleanup() is _never_ popped. The\nidea is that we install it once for the first child which needs it, and\nthen the rest of the invocations just add to the cleanup list. But that\nbreaks the push/pop paradigm if it's interleaved with other calls. I.e.,\nif we do:\n\n  sigchain_push(SIGPIPE, SIG_IGN);\n  child.clean_on_exit = 1;\n  start_command(&child);\n  sigchain_pop(SIGPIPE);\n\nthen that pop is not popping SIG_IGN. It's popping the cleanup handler\ninstalled by start_command! So now we're ignoring SIGPIPE forever for\nthe rest of the process.\n\nTo fix that I think we have to reconsider the push/pop idea for signals.\nI suspect the semantics we want are more like:\n\n  - Individual subsystems may register a cleanup handler, but may never\n    remove it. Handlers should recognize when they have no work to do\n    and return (because they have their own lists of children to clean\n    up, temporary files to remove, and so forth).\n\n  - When a cleanup handler is registered, we add it to a linked list and\n    register _one_ signal handler that iterates over the list, calling\n    each cleanup handler that has been registered.\n\n  - You can't install \"ignore\" or SIG_IGN as a cleanup handler. But...\n\n  - Code can push/pop an \"ignore\" flag for a given signal. If a signal\n    is marked as ignored, then that supersedes all cleanup handlers. It\n    can be implemented either with SIG_IGN, or the signal handler can\n    just return from the handler without exiting.\n\nThat's a total rewrite of our signal handling, though. There might be\ndetails I haven't considered.\n\nAs a stop-gap, I think one smaller thing we could do is just register\nall of those one-off handlers (like the one for start_command()) at the\nbeginning of the program, via init_git() or similar. And then they're at\nthe bottom of the sigchain stack, so they're never interleaved with\nother push/pop calls.  That's kind of horrible, but I don't think there\nare so many that it's the end of the world.\n\nAll of that is out-of-scope for -rc2, though. ;)\n\n-Peff\n"},{"id":"541269","messageId":"xmqqo6jsw8u1.fsf@gitster.g","threadId":"65455","inReplyTo":"20260408234236.GA2980392@coredump.intra.peff.net","subject":"Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-09T13:40:22Z","receivedAt":"2026-04-09T13:40:26Z","isPatch":true,"body":"Jeff King <peff@peff.net> writes:\n\n>> Currently neither subprocess is marked with the clean-on-exit bit.\n>> but if somebody is careless and flips the bit for these\n>> subprocesses, start_command() will call mark_child_for_cleanup() and\n>> causes sigchain_push_common() to set up cleanup_children_on_signal()\n>> to be called, which would lead to a very similar bug.\n>\n> Hmm, good catch. This is a bit worrisome, as we've added some\n> clean_on_exit calls recently, and might do so again.\n>\n>> I wonder if swapping the order of start_command() and sigchain_push()\n>> in these two code paths have downsides, or is it making the code worse\n>> just to futureproof it against a future that is unlikely to come?\n>\n> I don't think it's really making the code worse. It's putting the\n> SIGPIPE handling closer to where we're actually doing the writes. But I\n> don't like that it is a subtle thing that people writing new code have\n> to worry about. And I wouldn't be surprised if there are other cases\n> where we disable SIGPIPE, and then call start_command() in a much lower\n> level of the call chain, which would make reordering harder.\n\nOK.  Such a change is easy, compared to anything we try to do better\n;-).\n\n> I wonder if we can do better.\n>\n> The root of the issue is that sigchain_push_common() is not really\n> expressing what we want. We are trying to install a handler to do\n> cleanup _if_ we are about to exit. And that is always going to be true\n> for SIGTERM, etc, where we might install handlers but never expect them\n> to rescue us from exiting. But for SIGPIPE, our desired action is really\n> dependent on whether the signal is being ignored in general.\n\nHmph, I actually was hoping that we do not have to go in the route\nthat each specific signal differently, but I guess it is unavoidable\nas they come with their own semantics (somewhat similar to the way\nhow their default disposition has to be different).\n\n> That's a total rewrite of our signal handling, though. There might be\n> details I haven't considered.\n>\n> All of that is out-of-scope for -rc2, though. ;)\n\nOf course.\n"}]}