Git development
 help / color / mirror / Atom feed
* Help needed on 2.54.0-rc0 t5301.13 looping.
@ 2026-04-07 23:37 rsbecker
  2026-04-08  5:20 ` Jeff King
  0 siblings, 1 reply; 18+ messages in thread
From: rsbecker @ 2026-04-07 23:37 UTC (permalink / raw)
  To: git

Weird fail on t5401.13. Any opinions or advise on this?

expecting success of 5401.13 'pre-receive hook that forgets to read its
input':
        test_hook --clobber -C victim.git pre-receive <<-\EOF &&
        exit 0
        EOF
        rm -f victim.git/hooks/update victim.git/hooks/post-update &&

        test_seq -f "create refs/heads/branch_%d main" 100 999 |
        git update-ref --stdin &&
        git push ./victim.git "+refs/heads/*:refs/heads/*"

Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To ./victim.git
 ! [remote rejected] tofail -> tofail (pre-receive hook declined)
 ! [remote rejected] branch_100 -> branch_100 (pre-receive hook declined)
 ! [remote rejected] branch_101 -> branch_101 (pre-receive hook declined)
 ! [remote rejected] branch_102 -> branch_102 (pre-receive hook declined)
 ! [remote rejected] branch_103 -> branch_103 (pre-receive hook declined)
 ! [remote rejected] branch_104 -> branch_104 (pre-receive hook declined)
 ! [remote rejected] branch_105 -> branch_105 (pre-receive hook declined)
 ! [remote rejected] branch_106 -> branch_106 (pre-receive hook declined)
 ! [remote rejected] branch_107 -> branch_107 (pre-receive hook declined)
 ! [remote rejected] branch_108 -> branch_108 (pre-receive hook declined)
 ! [remote rejected] branch_109 -> branch_109 (pre-receive hook declined)
 ! [remote rejected] branch_110 -> branch_110 (pre-receive hook declined)
 ! [remote rejected] branch_111 -> branch_111 (pre-receive hook declined)
 ! [remote rejected] branch_112 -> branch_112 (pre-receive hook declined)
 ! [remote rejected] branch_113 -> branch_113 (pre-receive hook declined)
 ! [remote rejected] branch_114 -> branch_114 (pre-receive hook declined)
 ! [remote rejected] branch_115 -> branch_115 (pre-receive hook declined)
 ! [remote rejected] branch_116 -> branch_116 (pre-receive hook declined)
 ! [remote rejected] branch_117 -> branch_117 (pre-receive hook declined)
 ! [remote rejected] branch_118 -> branch_118 (pre-receive hook declined)
 ! [remote rejected] branch_119 -> branch_119 (pre-receive hook declined)
 ! [remote rejected] branch_120 -> branch_120 (pre-receive hook declined)
 ! [remote rejected] branch_121 -> branch_121 (pre-receive hook declined)
 ! [remote rejected] branch_122 -> branch_122 (pre-receive hook declined)
 ! [remote rejected] branch_123 -> branch_123 (pre-receive hook declined)
 ! [remote rejected] branch_124 -> branch_124 (pre-receive hook declined)
 ! [remote rejected] branch_125 -> branch_125 (pre-receive hook declined)
 ! [remote rejected] branch_126 -> branch_126 (pre-receive hook declined)
 ! [remote rejected] branch_127 -> branch_127 (pre-receive hook declined)
 ! [remote rejected] branch_128 -> branch_128 (pre-receive hook declined)
 ! [remote rejected] branch_129 -> branch_129 (pre-receive hook declined)
 ! [remote rejected] branch_130 -> branch_130 (pre-receive hook declined)
 ! [remote rejected] branch_131 -> branch_131 (pre-receive hook declined)
 ! [remote rejected] branch_132 -> branch_132 (pre-receive hook declined)
 ! [remote rejected] branch_133 -> branch_133 (pre-receive hook declined)
 ! [remote rejected] branch_134 -> branch_134 (pre-receive hook declined)
 ! [remote rejected] branch_135 -> branch_135 (pre-receive hook declined)
 ! [remote rejected] branch_136 -> branch_136 (pre-receive hook declined)
 ! [remote rejected] branch_137 -> branch_137 (pre-receive hook declined)
 ! [remote rejected] branch_138 -> branch_138 (pre-receive hook declined)
 ! [remote rejected] branch_139 -> branch_139 (pre-receive hook declined)
 ! [remote rejected] branch_140 -> branch_140 (pre-receive hook declined)
 ! [remote rejected] branch_141 -> branch_141 (pre-receive hook declined)
 ! [remote rejected] branch_142 -> branch_142 (pre-receive hook declined)
 ! [remote rejected] branch_143 -> branch_143 (pre-receive hook declined)
 ! [remote rejected] branch_144 -> branch_144 (pre-receive hook declined)
 ! [remote rejected] branch_145 -> branch_145 (pre-receive hook declined)
 ! [remote rejected] branch_146 -> branch_146 (pre-receive hook declined)
 ! [remote rejected] branch_147 -> branch_147 (pre-receive hook declined)
 ! [remote rejected] branch_148 -> branch_148 (pre-receive hook declined)
 ! [remote rejected] branch_149 -> branch_149 (pre-receive hook declined)
 ! [remote rejected] branch_150 -> branch_150 (pre-receive hook declined)
 ! [remote rejected] branch_151 -> branch_151 (pre-receive hook declined)
 ! [remote rejected] branch_152 -> branch_152 (pre-receive hook declined)
 ! [remote rejected] branch_153 -> branch_153 (pre-receive hook declined)
 ! [remote rejected] branch_154 -> branch_154 (pre-receive hook declined)
 ! [remote rejected] branch_155 -> branch_155 (pre-receive hook declined)
 ! [remote rejected] branch_156 -> branch_156 (pre-receive hook declined)
 ! [remote rejected] branch_157 -> branch_157 (pre-receive hook declined)
 ! [remote rejected] branch_158 -> branch_158 (pre-receive hook declined)
 ! [remote rejected] branch_159 -> branch_159 (pre-receive hook declined)
 ! [remote rejected] branch_160 -> branch_160 (pre-receive hook declined)
 ! [remote rejected] branch_161 -> branch_161 (pre-receive hook declined)
 ! [remote rejected] branch_162 -> branch_162 (pre-receive hook declined)
 ! [remote rejected] branch_163 -> branch_163 (pre-receive hook declined)
 ! [remote rejected] branch_164 -> branch_164 (pre-receive hook declined)
 ! [remote rejected] branch_165 -> branch_165 (pre-receive hook declined)
 ! [remote rejected] branch_166 -> branch_166 (pre-receive hook declined)
 ! [remote rejected] branch_167 -> branch_167 (pre-receive hook declined)
 ! [remote rejected] branch_168 -> branch_168 (pre-receive hook declined)
 ! [remote rejected] branch_169 -> branch_169 (pre-receive hook declined)
 ! [remote rejected] branch_170 -> branch_170 (pre-receive hook declined)
 ! [remote rejected] branch_171 -> branch_171 (pre-receive hook declined)
 ! [remote rejected] branch_172 -> branch_172 (pre-receive hook declined)
 ! [remote rejected] branch_173 -> branch_173 (pre-receive hook declined)
 ! [remote rejected] branch_174 -> branch_174 (pre-receive hook declined)
 ! [remote rejected] branch_175 -> branch_175 (pre-receive hook declined)
 ! [remote rejected] branch_176 -> branch_176 (pre-receive hook declined)
 ! [remote rejected] branch_177 -> branch_177 (pre-receive hook declined)
 ! [remote rejected] branch_178 -> branch_178 (pre-receive hook declined)
 ! [remote rejected] branch_179 -> branch_179 (pre-receive hook declined)
 ! [remote rejected] branch_180 -> branch_180 (pre-receive hook declined)
 ! [remote rejected] branch_181 -> branch_181 (pre-receive hook declined)
 ! [remote rejected] branch_182 -> branch_182 (pre-receive hook declined)
 ! [remote rejected] branch_183 -> branch_183 (pre-receive hook declined)
 ! [remote rejected] branch_184 -> branch_184 (pre-receive hook declined)
 ! [remote rejected] branch_185 -> branch_185 (pre-receive hook declined)
 ! [remote rejected] branch_186 -> branch_186 (pre-receive hook declined)
 ! [remote rejected] branch_187 -> branch_187 (pre-receive hook declined)
 ! [remote rejected] branch_188 -> branch_188 (pre-receive hook declined)
 ! [remote rejected] branch_189 -> branch_189 (pre-receive hook declined)
 ! [remote rejected] branch_190 -> branch_190 (pre-receive hook declined)
 ! [remote rejected] branch_191 -> branch_191 (pre-receive hook declined)
 ! [remote rejected] branch_192 -> branch_192 (pre-receive hook declined)
 ! [remote rejected] branch_193 -> branch_193 (pre-receive hook declined)
 ! [remote rejected] branch_194 -> branch_194 (pre-receive hook declined)
 ! [remote rejected] branch_195 -> branch_195 (pre-receive hook declined)
 ! [remote rejected] branch_196 -> branch_196 (pre-receive hook declined)
 ! [remote rejected] branch_197 -> branch_197 (pre-receive hook declined)
 ! [remote rejected] branch_198 -> branch_198 (pre-receive hook declined)
 ! [remote rejected] branch_199 -> branch_199 (pre-receive hook declined)
 ! [remote rejected] branch_200 -> branch_200 (pre-receive hook declined)
 ! [remote rejected] branch_201 -> branch_201 (pre-receive hook declined)
 ! [remote rejected] branch_202 -> branch_202 (pre-receive hook declined)
 ! [remote rejected] branch_203 -> branch_203 (pre-receive hook declined)
 ! [remote rejected] branch_204 -> branch_204 (pre-receive hook declined)
 ! [remote rejected] branch_205 -> branch_205 (pre-receive hook declined)
 ! [remote rejected] branch_206 -> branch_206 (pre-receive hook declined)
 ! [remote rejected] branch_207 -> branch_207 (pre-receive hook declined)
 ! [remote rejected] branch_208 -> branch_208 (pre-receive hook declined)
 ! [remote rejected] branch_209 -> branch_209 (pre-receive hook declined)
 ! [remote rejected] branch_210 -> branch_210 (pre-receive hook declined)
 ! [remote rejected] branch_211 -> branch_211 (pre-receive hook declined)
 ! [remote rejected] branch_212 -> branch_212 (pre-receive hook declined)
 ! [remote rejected] branch_213 -> branch_213 (pre-receive hook declined)
 ! [remote rejected] branch_214 -> branch_214 (pre-receive hook declined)
 ! [remote rejected] branch_215 -> branch_215 (pre-receive hook declined)
 ! [remote rejected] branch_216 -> branch_216 (pre-receive hook declined)
 ! [remote rejected] branch_217 -> branch_217 (pre-receive hook declined)
 ! [remote rejected] branch_218 -> branch_218 (pre-receive hook declined)
 ! [remote rejected] branch_219 -> branch_219 (pre-receive hook declined)
 ! [remote rejected] branch_220 -> branch_220 (pre-receive hook declined)
 ! [remote rejected] branch_221 -> branch_221 (pre-receive hook declined)
 ! [remote rejected] branch_222 -> branch_222 (pre-receive hook declined)
 ! [remote rejected] branch_223 -> branch_223 (pre-receive hook declined)
 ! [remote rejected] branch_224 -> branch_224 (pre-receive hook declined)
 ! [remote rejected] branch_225 -> branch_225 (pre-receive hook declined)
 ! [remote rejected] branch_226 -> branch_226 (pre-receive hook declined)
 ! [remote rejected] branch_227 -> branch_227 (pre-receive hook declined)
 ! [remote rejected] branch_228 -> branch_228 (pre-receive hook declined)
 ! [remote rejected] branch_229 -> branch_229 (pre-receive hook declined)
 ! [remote rejected] branch_230 -> branch_230 (pre-receive hook declined)
 ! [remote rejected] branch_231 -> branch_231 (pre-receive hook declined)
 ! [remote rejected] branch_232 -> branch_232 (pre-receive hook declined)
 ! [remote rejected] branch_233 -> branch_233 (pre-receive hook declined)
 ! [remote rejected] branch_234 -> branch_234 (pre-receive hook declined)
 ! [remote rejected] branch_235 -> branch_235 (pre-receive hook declined)
 ! [remote rejected] branch_236 -> branch_236 (pre-receive hook declined)
 ! [remote rejected] branch_237 -> branch_237 (pre-receive hook declined)
 ! [remote rejected] branch_238 -> branch_238 (pre-receive hook declined)
 ! [remote rejected] branch_239 -> branch_239 (pre-receive hook declined)
 ! [remote rejected] branch_240 -> branch_240 (pre-receive hook declined)
 ! [remote rejected] branch_241 -> branch_241 (pre-receive hook declined)
 ! [remote rejected] branch_242 -> branch_242 (pre-receive hook declined)
 ! [remote rejected] branch_243 -> branch_243 (pre-receive hook declined)
 ! [remote rejected] branch_244 -> branch_244 (pre-receive hook declined)
 ! [remote rejected] branch_245 -> branch_245 (pre-receive hook declined)
 ! [remote rejected] branch_246 -> branch_246 (pre-receive hook declined)
 ! [remote rejected] branch_247 -> branch_247 (pre-receive hook declined)
 ! [remote rejected] branch_248 -> branch_248 (pre-receive hook declined)
 ! [remote rejected] branch_249 -> branch_249 (pre-receive hook declined)
 ! [remote rejected] branch_250 -> branch_250 (pre-receive hook declined)
 ! [remote rejected] branch_251 -> branch_251 (pre-receive hook declined)
 ! [remote rejected] branch_252 -> branch_252 (pre-receive hook declined)
 ! [remote rejected] branch_253 -> branch_253 (pre-receive hook declined)
 ! [remote rejected] branch_254 -> branch_254 (pre-receive hook declined)
 ! [remote rejected] branch_255 -> branch_255 (pre-receive hook declined)
 ! [remote rejected] branch_256 -> branch_256 (pre-receive hook declined)
 ! [remote rejected] branch_257 -> branch_257 (pre-receive hook declined)
 ! [remote rejected] branch_258 -> branch_258 (pre-receive hook declined)
 ! [remote rejected] branch_259 -> branch_259 (pre-receive hook declined)
 ! [remote rejected] branch_260 -> branch_260 (pre-receive hook declined)
 ! [remote rejected] branch_261 -> branch_261 (pre-receive hook declined)
 ! [remote rejected] branch_262 -> branch_262 (pre-receive hook declined)
 ! [remote rejected] branch_263 -> branch_263 (pre-receive hook declined)
 ! [remote rejected] branch_264 -> branch_264 (pre-receive hook declined)
 ! [remote rejected] branch_265 -> branch_265 (pre-receive hook declined)
 ! [remote rejected] branch_266 -> branch_266 (pre-receive hook declined)
 ! [remote rejected] branch_267 -> branch_267 (pre-receive hook declined)
 ! [remote rejected] branch_268 -> branch_268 (pre-receive hook declined)
 ! [remote rejected] branch_269 -> branch_269 (pre-receive hook declined)
 ! [remote rejected] branch_270 -> branch_270 (pre-receive hook declined)
 ! [remote rejected] branch_271 -> branch_271 (pre-receive hook declined)
 ! [remote rejected] branch_272 -> branch_272 (pre-receive hook declined)
 ! [remote rejected] branch_273 -> branch_273 (pre-receive hook declined)
 ! [remote rejected] branch_274 -> branch_274 (pre-receive hook declined)
 ! [remote rejected] branch_275 -> branch_275 (pre-receive hook declined)
 ! [remote rejected] branch_276 -> branch_276 (pre-receive hook declined)
 ! [remote rejected] branch_277 -> branch_277 (pre-receive hook declined)
 ! [remote rejected] branch_278 -> branch_278 (pre-receive hook declined)
 ! [remote rejected] branch_279 -> branch_279 (pre-receive hook declined)
 ! [remote rejected] branch_280 -> branch_280 (pre-receive hook declined)
 ! [remote rejected] branch_281 -> branch_281 (pre-receive hook declined)
 ! [remote rejected] branch_282 -> branch_282 (pre-receive hook declined)
 ! [remote rejected] branch_283 -> branch_283 (pre-receive hook declined)
 ! [remote rejected] branch_284 -> branch_284 (pre-receive hook declined)
 ! [remote rejected] branch_285 -> branch_285 (pre-receive hook declined)
 ! [remote rejected] branch_286 -> branch_286 (pre-receive hook declined)
 ! [remote rejected] branch_287 -> branch_287 (pre-receive hook declined)
 ! [remote rejected] branch_288 -> branch_288 (pre-receive hook declined)
 ! [remote rejected] branch_289 -> branch_289 (pre-receive hook declined)
 ! [remote rejected] branch_290 -> branch_290 (pre-receive hook declined)
 ! [remote rejected] branch_291 -> branch_291 (pre-receive hook declined)
 ! [remote rejected] branch_292 -> branch_292 (pre-receive hook declined)
 ! [remote rejected] branch_293 -> branch_293 (pre-receive hook declined)
 ! [remote rejected] branch_294 -> branch_294 (pre-receive hook declined)
 ! [remote rejected] branch_295 -> branch_295 (pre-receive hook declined)
 ! [remote rejected] branch_296 -> branch_296 (pre-receive hook declined)
 ! [remote rejected] branch_297 -> branch_297 (pre-receive hook declined)
 ! [remote rejected] branch_298 -> branch_298 (pre-receive hook declined)
 ! [remote rejected] branch_299 -> branch_299 (pre-receive hook declined)
 ! [remote rejected] branch_300 -> branch_300 (pre-receive hook declined)
 ! [remote rejected] branch_301 -> branch_301 (pre-receive hook declined)
 ! [remote rejected] branch_302 -> branch_302 (pre-receive hook declined)
 ! [remote rejected] branch_303 -> branch_303 (pre-receive hook declined)
 ! [remote rejected] branch_304 -> branch_304 (pre-receive hook declined)
 ! [remote rejected] branch_305 -> branch_305 (pre-receive hook declined)
 ! [remote rejected] branch_306 -> branch_306 (pre-receive hook declined)
 ! [remote rejected] branch_307 -> branch_307 (pre-receive hook declined)
 ! [remote rejected] branch_308 -> branch_308 (pre-receive hook declined)
 ! [remote rejected] branch_309 -> branch_309 (pre-receive hook declined)
 ! [remote rejected] branch_310 -> branch_310 (pre-receive hook declined)
 ! [remote rejected] branch_311 -> branch_311 (pre-receive hook declined)
 ! [remote rejected] branch_312 -> branch_312 (pre-receive hook declined)
 ! [remote rejected] branch_313 -> branch_313 (pre-receive hook declined)
 ! [remote rejected] branch_314 -> branch_314 (pre-receive hook declined)
 ! [remote rejected] branch_315 -> branch_315 (pre-receive hook declined)
 ! [remote rejected] branch_316 -> branch_316 (pre-receive hook declined)
 ! [remote rejected] branch_317 -> branch_317 (pre-receive hook declined)
 ! [remote rejected] branch_318 -> branch_318 (pre-receive hook declined)
 ! [remote rejected] branch_319 -> branch_319 (pre-receive hook declined)
 ! [remote rejected] branch_320 -> branch_320 (pre-receive hook declined)
 ! [remote rejected] branch_321 -> branch_321 (pre-receive hook declined)
 ! [remote rejected] branch_322 -> branch_322 (pre-receive hook declined)
 ! [remote rejected] branch_323 -> branch_323 (pre-receive hook declined)
 ! [remote rejected] branch_324 -> branch_324 (pre-receive hook declined)
 ! [remote rejected] branch_325 -> branch_325 (pre-receive hook declined)
 ! [remote rejected] branch_326 -> branch_326 (pre-receive hook declined)
 ! [remote rejected] branch_327 -> branch_327 (pre-receive hook declined)
 ! [remote rejected] branch_328 -> branch_328 (pre-receive hook declined)
 ! [remote rejected] branch_329 -> branch_329 (pre-receive hook declined)
 ! [remote rejected] branch_330 -> branch_330 (pre-receive hook declined)
 ! [remote rejected] branch_331 -> branch_331 (pre-receive hook declined)
 ! [remote rejected] branch_332 -> branch_332 (pre-receive hook declined)
 ! [remote rejected] branch_333 -> branch_333 (pre-receive hook declined)
 ! [remote rejected] branch_334 -> branch_334 (pre-receive hook declined)
 ! [remote rejected] branch_335 -> branch_335 (pre-receive hook declined)
 ! [remote rejected] branch_336 -> branch_336 (pre-receive hook declined)
 ! [remote rejected] branch_337 -> branch_337 (pre-receive hook declined)
 ! [remote rejected] branch_338 -> branch_338 (pre-receive hook declined)
 ! [remote rejected] branch_339 -> branch_339 (pre-receive hook declined)
 ! [remote rejected] branch_340 -> branch_340 (pre-receive hook declined)
 ! [remote rejected] branch_341 -> branch_341 (pre-receive hook declined)
 ! [remote rejected] branch_342 -> branch_342 (pre-receive hook declined)
 ! [remote rejected] branch_343 -> branch_343 (pre-receive hook declined)
 ! [remote rejected] branch_344 -> branch_344 (pre-receive hook declined)
 ! [remote rejected] branch_345 -> branch_345 (pre-receive hook declined)
 ! [remote rejected] branch_346 -> branch_346 (pre-receive hook declined)
 ! [remote rejected] branch_347 -> branch_347 (pre-receive hook declined)
 ! [remote rejected] branch_348 -> branch_348 (pre-receive hook declined)
 ! [remote rejected] branch_349 -> branch_349 (pre-receive hook declined)
 ! [remote rejected] branch_350 -> branch_350 (pre-receive hook declined)
 ! [remote rejected] branch_351 -> branch_351 (pre-receive hook declined)
 ! [remote rejected] branch_352 -> branch_352 (pre-receive hook declined)
 ! [remote rejected] branch_353 -> branch_353 (pre-receive hook declined)
 ! [remote rejected] branch_354 -> branch_354 (pre-receive hook declined)
 ! [remote rejected] branch_355 -> branch_355 (pre-receive hook declined)
 ! [remote rejected] branch_356 -> branch_356 (pre-receive hook declined)
 ! [remote rejected] branch_357 -> branch_357 (pre-receive hook declined)
 ! [remote rejected] branch_358 -> branch_358 (pre-receive hook declined)
 ! [remote rejected] branch_359 -> branch_359 (pre-receive hook declined)
 ! [remote rejected] branch_360 -> branch_360 (pre-receive hook declined)
 ! [remote rejected] branch_361 -> branch_361 (pre-receive hook declined)
 ! [remote rejected] branch_362 -> branch_362 (pre-receive hook declined)
 ! [remote rejected] branch_363 -> branch_363 (pre-receive hook declined)
 ! [remote rejected] branch_364 -> branch_364 (pre-receive hook declined)
 ! [remote rejected] branch_365 -> branch_365 (pre-receive hook declined)
 ! [remote rejected] branch_366 -> branch_366 (pre-receive hook declined)
 ! [remote rejected] branch_367 -> branch_367 (pre-receive hook declined)
 ! [remote rejected] branch_368 -> branch_368 (pre-receive hook declined)
 ! [remote rejected] branch_369 -> branch_369 (pre-receive hook declined)
 ! [remote rejected] branch_370 -> branch_370 (pre-receive hook declined)
 ! [remote rejected] branch_371 -> branch_371 (pre-receive hook declined)
 ! [remote rejected] branch_372 -> branch_372 (pre-receive hook declined)
 ! [remote rejected] branch_373 -> branch_373 (pre-receive hook declined)
 ! [remote rejected] branch_374 -> branch_374 (pre-receive hook declined)
 ! [remote rejected] branch_375 -> branch_375 (pre-receive hook declined)
 ! [remote rejected] branch_376 -> branch_376 (pre-receive hook declined)
 ! [remote rejected] branch_377 -> branch_377 (pre-receive hook declined)
 ! [remote rejected] branch_378 -> branch_378 (pre-receive hook declined)
 ! [remote rejected] branch_379 -> branch_379 (pre-receive hook declined)
 ! [remote rejected] branch_380 -> branch_380 (pre-receive hook declined)
 ! [remote rejected] branch_381 -> branch_381 (pre-receive hook declined)
 ! [remote rejected] branch_382 -> branch_382 (pre-receive hook declined)
 ! [remote rejected] branch_383 -> branch_383 (pre-receive hook declined)
 ! [remote rejected] branch_384 -> branch_384 (pre-receive hook declined)
 ! [remote rejected] branch_385 -> branch_385 (pre-receive hook declined)
 ! [remote rejected] branch_386 -> branch_386 (pre-receive hook declined)
 ! [remote rejected] branch_387 -> branch_387 (pre-receive hook declined)
 ! [remote rejected] branch_388 -> branch_388 (pre-receive hook declined)
 ! [remote rejected] branch_389 -> branch_389 (pre-receive hook declined)
 ! [remote rejected] branch_390 -> branch_390 (pre-receive hook declined)
 ! [remote rejected] branch_391 -> branch_391 (pre-receive hook declined)
 ! [remote rejected] branch_392 -> branch_392 (pre-receive hook declined)
 ! [remote rejected] branch_393 -> branch_393 (pre-receive hook declined)
 ! [remote rejected] branch_394 -> branch_394 (pre-receive hook declined)
 ! [remote rejected] branch_395 -> branch_395 (pre-receive hook declined)
 ! [remote rejected] branch_396 -> branch_396 (pre-receive hook declined)
 ! [remote rejected] branch_397 -> branch_397 (pre-receive hook declined)
 ! [remote rejected] branch_398 -> branch_398 (pre-receive hook declined)
 ! [remote rejected] branch_399 -> branch_399 (pre-receive hook declined)
 ! [remote rejected] branch_400 -> branch_400 (pre-receive hook declined)
 ! [remote rejected] branch_401 -> branch_401 (pre-receive hook declined)
 ! [remote rejected] branch_402 -> branch_402 (pre-receive hook declined)
 ! [remote rejected] branch_403 -> branch_403 (pre-receive hook declined)
 ! [remote rejected] branch_404 -> branch_404 (pre-receive hook declined)
 ! [remote rejected] branch_405 -> branch_405 (pre-receive hook declined)
 ! [remote rejected] branch_406 -> branch_406 (pre-receive hook declined)
 ! [remote rejected] branch_407 -> branch_407 (pre-receive hook declined)
 ! [remote rejected] branch_408 -> branch_408 (pre-receive hook declined)
 ! [remote rejected] branch_409 -> branch_409 (pre-receive hook declined)
 ! [remote rejected] branch_410 -> branch_410 (pre-receive hook declined)
 ! [remote rejected] branch_411 -> branch_411 (pre-receive hook declined)
 ! [remote rejected] branch_412 -> branch_412 (pre-receive hook declined)
 ! [remote rejected] branch_413 -> branch_413 (pre-receive hook declined)
 ! [remote rejected] branch_414 -> branch_414 (pre-receive hook declined)
 ! [remote rejected] branch_415 -> branch_415 (pre-receive hook declined)
 ! [remote rejected] branch_416 -> branch_416 (pre-receive hook declined)
 ! [remote rejected] branch_417 -> branch_417 (pre-receive hook declined)
 ! [remote rejected] branch_418 -> branch_418 (pre-receive hook declined)
 ! [remote rejected] branch_419 -> branch_419 (pre-receive hook declined)
 ! [remote rejected] branch_420 -> branch_420 (pre-receive hook declined)
 ! [remote rejected] branch_421 -> branch_421 (pre-receive hook declined)
 ! [remote rejected] branch_422 -> branch_422 (pre-receive hook declined)
 ! [remote rejected] branch_423 -> branch_423 (pre-receive hook declined)
 ! [remote rejected] branch_424 -> branch_424 (pre-receive hook declined)
 ! [remote rejected] branch_425 -> branch_425 (pre-receive hook declined)
 ! [remote rejected] branch_426 -> branch_426 (pre-receive hook declined)
 ! [remote rejected] branch_427 -> branch_427 (pre-receive hook declined)
 ! [remote rejected] branch_428 -> branch_428 (pre-receive hook declined)
 ! [remote rejected] branch_429 -> branch_429 (pre-receive hook declined)
 ! [remote rejected] branch_430 -> branch_430 (pre-receive hook declined)
 ! [remote rejected] branch_431 -> branch_431 (pre-receive hook declined)
 ! [remote rejected] branch_432 -> branch_432 (pre-receive hook declined)
 ! [remote rejected] branch_433 -> branch_433 (pre-receive hook declined)
 ! [remote rejected] branch_434 -> branch_434 (pre-receive hook declined)
 ! [remote rejected] branch_435 -> branch_435 (pre-receive hook declined)
 ! [remote rejected] branch_436 -> branch_436 (pre-receive hook declined)
 ! [remote rejected] branch_437 -> branch_437 (pre-receive hook declined)
 ! [remote rejected] branch_438 -> branch_438 (pre-receive hook declined)
 ! [remote rejected] branch_439 -> branch_439 (pre-receive hook declined)
 ! [remote rejected] branch_440 -> branch_440 (pre-receive hook declined)
 ! [remote rejected] branch_441 -> branch_441 (pre-receive hook declined)
 ! [remote rejected] branch_442 -> branch_442 (pre-receive hook declined)
 ! [remote rejected] branch_443 -> branch_443 (pre-receive hook declined)
 ! [remote rejected] branch_444 -> branch_444 (pre-receive hook declined)
 ! [remote rejected] branch_445 -> branch_445 (pre-receive hook declined)
 ! [remote rejected] branch_446 -> branch_446 (pre-receive hook declined)
 ! [remote rejected] branch_447 -> branch_447 (pre-receive hook declined)
 ! [remote rejected] branch_448 -> branch_448 (pre-receive hook declined)
 ! [remote rejected] branch_449 -> branch_449 (pre-receive hook declined)
 ! [remote rejected] branch_450 -> branch_450 (pre-receive hook declined)
 ! [remote rejected] branch_451 -> branch_451 (pre-receive hook declined)
 ! [remote rejected] branch_452 -> branch_452 (pre-receive hook declined)
 ! [remote rejected] branch_453 -> branch_453 (pre-receive hook declined)
 ! [remote rejected] branch_454 -> branch_454 (pre-receive hook declined)
 ! [remote rejected] branch_455 -> branch_455 (pre-receive hook declined)
 ! [remote rejected] branch_456 -> branch_456 (pre-receive hook declined)
 ! [remote rejected] branch_457 -> branch_457 (pre-receive hook declined)
 ! [remote rejected] branch_458 -> branch_458 (pre-receive hook declined)
 ! [remote rejected] branch_459 -> branch_459 (pre-receive hook declined)
 ! [remote rejected] branch_460 -> branch_460 (pre-receive hook declined)
 ! [remote rejected] branch_461 -> branch_461 (pre-receive hook declined)
 ! [remote rejected] branch_462 -> branch_462 (pre-receive hook declined)
 ! [remote rejected] branch_463 -> branch_463 (pre-receive hook declined)
 ! [remote rejected] branch_464 -> branch_464 (pre-receive hook declined)
 ! [remote rejected] branch_465 -> branch_465 (pre-receive hook declined)
 ! [remote rejected] branch_466 -> branch_466 (pre-receive hook declined)
 ! [remote rejected] branch_467 -> branch_467 (pre-receive hook declined)
 ! [remote rejected] branch_468 -> branch_468 (pre-receive hook declined)
 ! [remote rejected] branch_469 -> branch_469 (pre-receive hook declined)
 ! [remote rejected] branch_470 -> branch_470 (pre-receive hook declined)
 ! [remote rejected] branch_471 -> branch_471 (pre-receive hook declined)
 ! [remote rejected] branch_472 -> branch_472 (pre-receive hook declined)
 ! [remote rejected] branch_473 -> branch_473 (pre-receive hook declined)
 ! [remote rejected] branch_474 -> branch_474 (pre-receive hook declined)
 ! [remote rejected] branch_475 -> branch_475 (pre-receive hook declined)
 ! [remote rejected] branch_476 -> branch_476 (pre-receive hook declined)
 ! [remote rejected] branch_477 -> branch_477 (pre-receive hook declined)
 ! [remote rejected] branch_478 -> branch_478 (pre-receive hook declined)
 ! [remote rejected] branch_479 -> branch_479 (pre-receive hook declined)
 ! [remote rejected] branch_480 -> branch_480 (pre-receive hook declined)
 ! [remote rejected] branch_481 -> branch_481 (pre-receive hook declined)
 ! [remote rejected] branch_482 -> branch_482 (pre-receive hook declined)
 ! [remote rejected] branch_483 -> branch_483 (pre-receive hook declined)
 ! [remote rejected] branch_484 -> branch_484 (pre-receive hook declined)
 ! [remote rejected] branch_485 -> branch_485 (pre-receive hook declined)
 ! [remote rejected] branch_486 -> branch_486 (pre-receive hook declined)
 ! [remote rejected] branch_487 -> branch_487 (pre-receive hook declined)
 ! [remote rejected] branch_488 -> branch_488 (pre-receive hook declined)
 ! [remote rejected] branch_489 -> branch_489 (pre-receive hook declined)
 ! [remote rejected] branch_490 -> branch_490 (pre-receive hook declined)
 ! [remote rejected] branch_491 -> branch_491 (pre-receive hook declined)
 ! [remote rejected] branch_492 -> branch_492 (pre-receive hook declined)
 ! [remote rejected] branch_493 -> branch_493 (pre-receive hook declined)
 ! [remote rejected] branch_494 -> branch_494 (pre-receive hook declined)
 ! [remote rejected] branch_495 -> branch_495 (pre-receive hook declined)
 ! [remote rejected] branch_496 -> branch_496 (pre-receive hook declined)
 ! [remote rejected] branch_497 -> branch_497 (pre-receive hook declined)
 ! [remote rejected] branch_498 -> branch_498 (pre-receive hook declined)
 ! [remote rejected] branch_499 -> branch_499 (pre-receive hook declined)
 ! [remote rejected] branch_500 -> branch_500 (pre-receive hook declined)
 ! [remote rejected] branch_501 -> branch_501 (pre-receive hook declined)
 ! [remote rejected] branch_502 -> branch_502 (pre-receive hook declined)
 ! [remote rejected] branch_503 -> branch_503 (pre-receive hook declined)
 ! [remote rejected] branch_504 -> branch_504 (pre-receive hook declined)
 ! [remote rejected] branch_505 -> branch_505 (pre-receive hook declined)
 ! [remote rejected] branch_506 -> branch_506 (pre-receive hook declined)
 ! [remote rejected] branch_507 -> branch_507 (pre-receive hook declined)
 ! [remote rejected] branch_508 -> branch_508 (pre-receive hook declined)
 ! [remote rejected] branch_509 -> branch_509 (pre-receive hook declined)
 ! [remote rejected] branch_510 -> branch_510 (pre-receive hook declined)
 ! [remote rejected] branch_511 -> branch_511 (pre-receive hook declined)
 ! [remote rejected] branch_512 -> branch_512 (pre-receive hook declined)
 ! [remote rejected] branch_513 -> branch_513 (pre-receive hook declined)
 ! [remote rejected] branch_514 -> branch_514 (pre-receive hook declined)
 ! [remote rejected] branch_515 -> branch_515 (pre-receive hook declined)
 ! [remote rejected] branch_516 -> branch_516 (pre-receive hook declined)
 ! [remote rejected] branch_517 -> branch_517 (pre-receive hook declined)
 ! [remote rejected] branch_518 -> branch_518 (pre-receive hook declined)
 ! [remote rejected] branch_519 -> branch_519 (pre-receive hook declined)
 ! [remote rejected] branch_520 -> branch_520 (pre-receive hook declined)
 ! [remote rejected] branch_521 -> branch_521 (pre-receive hook declined)
 ! [remote rejected] branch_522 -> branch_522 (pre-receive hook declined)
 ! [remote rejected] branch_523 -> branch_523 (pre-receive hook declined)
 ! [remote rejected] branch_524 -> branch_524 (pre-receive hook declined)
 ! [remote rejected] branch_525 -> branch_525 (pre-receive hook declined)
 ! [remote rejected] branch_526 -> branch_526 (pre-receive hook declined)
 ! [remote rejected] branch_527 -> branch_527 (pre-receive hook declined)
 ! [remote rejected] branch_528 -> branch_528 (pre-receive hook declined)
 ! [remote rejected] branch_529 -> branch_529 (pre-receive hook declined)
 ! [remote rejected] branch_530 -> branch_530 (pre-receive hook declined)
 ! [remote rejected] branch_531 -> branch_531 (pre-receive hook declined)
 ! [remote rejected] branch_532 -> branch_532 (pre-receive hook declined)
 ! [remote rejected] branch_533 -> branch_533 (pre-receive hook declined)
 ! [remote rejected] branch_534 -> branch_534 (pre-receive hook declined)
 ! [remote rejected] branch_535 -> branch_535 (pre-receive hook declined)
 ! [remote rejected] branch_536 -> branch_536 (pre-receive hook declined)
 ! [remote rejected] branch_537 -> branch_537 (pre-receive hook declined)
 ! [remote rejected] branch_538 -> branch_538 (pre-receive hook declined)
 ! [remote rejected] branch_539 -> branch_539 (pre-receive hook declined)
 ! [remote rejected] branch_540 -> branch_540 (pre-receive hook declined)
 ! [remote rejected] branch_541 -> branch_541 (pre-receive hook declined)
 ! [remote rejected] branch_542 -> branch_542 (pre-receive hook declined)
 ! [remote rejected] branch_543 -> branch_543 (pre-receive hook declined)
 ! [remote rejected] branch_544 -> branch_544 (pre-receive hook declined)
 ! [remote rejected] branch_545 -> branch_545 (pre-receive hook declined)
 ! [remote rejected] branch_546 -> branch_546 (pre-receive hook declined)
 ! [remote rejected] branch_547 -> branch_547 (pre-receive hook declined)
 ! [remote rejected] branch_548 -> branch_548 (pre-receive hook declined)
 ! [remote rejected] branch_549 -> branch_549 (pre-receive hook declined)
 ! [remote rejected] branch_550 -> branch_550 (pre-receive hook declined)
 ! [remote rejected] branch_551 -> branch_551 (pre-receive hook declined)
 ! [remote rejected] branch_552 -> branch_552 (pre-receive hook declined)
 ! [remote rejected] branch_553 -> branch_553 (pre-receive hook declined)
 ! [remote rejected] branch_554 -> branch_554 (pre-receive hook declined)
 ! [remote rejected] branch_555 -> branch_555 (pre-receive hook declined)
 ! [remote rejected] branch_556 -> branch_556 (pre-receive hook declined)
 ! [remote rejected] branch_557 -> branch_557 (pre-receive hook declined)
 ! [remote rejected] branch_558 -> branch_558 (pre-receive hook declined)
 ! [remote rejected] branch_559 -> branch_559 (pre-receive hook declined)
 ! [remote rejected] branch_560 -> branch_560 (pre-receive hook declined)
 ! [remote rejected] branch_561 -> branch_561 (pre-receive hook declined)
 ! [remote rejected] branch_562 -> branch_562 (pre-receive hook declined)
 ! [remote rejected] branch_563 -> branch_563 (pre-receive hook declined)
 ! [remote rejected] branch_564 -> branch_564 (pre-receive hook declined)
 ! [remote rejected] branch_565 -> branch_565 (pre-receive hook declined)
 ! [remote rejected] branch_566 -> branch_566 (pre-receive hook declined)
 ! [remote rejected] branch_567 -> branch_567 (pre-receive hook declined)
 ! [remote rejected] branch_568 -> branch_568 (pre-receive hook declined)
 ! [remote rejected] branch_569 -> branch_569 (pre-receive hook declined)
 ! [remote rejected] branch_570 -> branch_570 (pre-receive hook declined)
 ! [remote rejected] branch_571 -> branch_571 (pre-receive hook declined)
 ! [remote rejected] branch_572 -> branch_572 (pre-receive hook declined)
 ! [remote rejected] branch_573 -> branch_573 (pre-receive hook declined)
 ! [remote rejected] branch_574 -> branch_574 (pre-receive hook declined)
 ! [remote rejected] branch_575 -> branch_575 (pre-receive hook declined)
 ! [remote rejected] branch_576 -> branch_576 (pre-receive hook declined)
 ! [remote rejected] branch_577 -> branch_577 (pre-receive hook declined)
 ! [remote rejected] branch_578 -> branch_578 (pre-receive hook declined)
 ! [remote rejected] branch_579 -> branch_579 (pre-receive hook declined)
 ! [remote rejected] branch_580 -> branch_580 (pre-receive hook declined)
 ! [remote rejected] branch_581 -> branch_581 (pre-receive hook declined)
 ! [remote rejected] branch_582 -> branch_582 (pre-receive hook declined)
 ! [remote rejected] branch_583 -> branch_583 (pre-receive hook declined)
 ! [remote rejected] branch_584 -> branch_584 (pre-receive hook declined)
 ! [remote rejected] branch_585 -> branch_585 (pre-receive hook declined)
 ! [remote rejected] branch_586 -> branch_586 (pre-receive hook declined)
 ! [remote rejected] branch_587 -> branch_587 (pre-receive hook declined)
 ! [remote rejected] branch_588 -> branch_588 (pre-receive hook declined)
 ! [remote rejected] branch_589 -> branch_589 (pre-receive hook declined)
 ! [remote rejected] branch_590 -> branch_590 (pre-receive hook declined)
 ! [remote rejected] branch_591 -> branch_591 (pre-receive hook declined)
 ! [remote rejected] branch_592 -> branch_592 (pre-receive hook declined)
 ! [remote rejected] branch_593 -> branch_593 (pre-receive hook declined)
 ! [remote rejected] branch_594 -> branch_594 (pre-receive hook declined)
 ! [remote rejected] branch_595 -> branch_595 (pre-receive hook declined)
 ! [remote rejected] branch_596 -> branch_596 (pre-receive hook declined)
 ! [remote rejected] branch_597 -> branch_597 (pre-receive hook declined)
 ! [remote rejected] branch_598 -> branch_598 (pre-receive hook declined)
 ! [remote rejected] branch_599 -> branch_599 (pre-receive hook declined)
 ! [remote rejected] branch_600 -> branch_600 (pre-receive hook declined)
 ! [remote rejected] branch_601 -> branch_601 (pre-receive hook declined)
 ! [remote rejected] branch_602 -> branch_602 (pre-receive hook declined)
 ! [remote rejected] branch_603 -> branch_603 (pre-receive hook declined)
 ! [remote rejected] branch_604 -> branch_604 (pre-receive hook declined)
 ! [remote rejected] branch_605 -> branch_605 (pre-receive hook declined)
 ! [remote rejected] branch_606 -> branch_606 (pre-receive hook declined)
 ! [remote rejected] branch_607 -> branch_607 (pre-receive hook declined)
 ! [remote rejected] branch_608 -> branch_608 (pre-receive hook declined)
 ! [remote rejected] branch_609 -> branch_609 (pre-receive hook declined)
 ! [remote rejected] branch_610 -> branch_610 (pre-receive hook declined)
 ! [remote rejected] branch_611 -> branch_611 (pre-receive hook declined)
 ! [remote rejected] branch_612 -> branch_612 (pre-receive hook declined)
 ! [remote rejected] branch_613 -> branch_613 (pre-receive hook declined)
 ! [remote rejected] branch_614 -> branch_614 (pre-receive hook declined)
 ! [remote rejected] branch_615 -> branch_615 (pre-receive hook declined)
 ! [remote rejected] branch_616 -> branch_616 (pre-receive hook declined)
 ! [remote rejected] branch_617 -> branch_617 (pre-receive hook declined)
 ! [remote rejected] branch_618 -> branch_618 (pre-receive hook declined)
 ! [remote rejected] branch_619 -> branch_619 (pre-receive hook declined)
 ! [remote rejected] branch_620 -> branch_620 (pre-receive hook declined)
 ! [remote rejected] branch_621 -> branch_621 (pre-receive hook declined)
 ! [remote rejected] branch_622 -> branch_622 (pre-receive hook declined)
 ! [remote rejected] branch_623 -> branch_623 (pre-receive hook declined)
 ! [remote rejected] branch_624 -> branch_624 (pre-receive hook declined)
 ! [remote rejected] branch_625 -> branch_625 (pre-receive hook declined)
 ! [remote rejected] branch_626 -> branch_626 (pre-receive hook declined)
 ! [remote rejected] branch_627 -> branch_627 (pre-receive hook declined)
 ! [remote rejected] branch_628 -> branch_628 (pre-receive hook declined)
 ! [remote rejected] branch_629 -> branch_629 (pre-receive hook declined)
 ! [remote rejected] branch_630 -> branch_630 (pre-receive hook declined)
 ! [remote rejected] branch_631 -> branch_631 (pre-receive hook declined)
 ! [remote rejected] branch_632 -> branch_632 (pre-receive hook declined)
 ! [remote rejected] branch_633 -> branch_633 (pre-receive hook declined)
 ! [remote rejected] branch_634 -> branch_634 (pre-receive hook declined)
 ! [remote rejected] branch_635 -> branch_635 (pre-receive hook declined)
 ! [remote rejected] branch_636 -> branch_636 (pre-receive hook declined)
 ! [remote rejected] branch_637 -> branch_637 (pre-receive hook declined)
 ! [remote rejected] branch_638 -> branch_638 (pre-receive hook declined)
 ! [remote rejected] branch_639 -> branch_639 (pre-receive hook declined)
 ! [remote rejected] branch_640 -> branch_640 (pre-receive hook declined)
 ! [remote rejected] branch_641 -> branch_641 (pre-receive hook declined)
 ! [remote rejected] branch_642 -> branch_642 (pre-receive hook declined)
 ! [remote rejected] branch_643 -> branch_643 (pre-receive hook declined)
 ! [remote rejected] branch_644 -> branch_644 (pre-receive hook declined)
 ! [remote rejected] branch_645 -> branch_645 (pre-receive hook declined)
 ! [remote rejected] branch_646 -> branch_646 (pre-receive hook declined)
 ! [remote rejected] branch_647 -> branch_647 (pre-receive hook declined)
 ! [remote rejected] branch_648 -> branch_648 (pre-receive hook declined)
 ! [remote rejected] branch_649 -> branch_649 (pre-receive hook declined)
 ! [remote rejected] branch_650 -> branch_650 (pre-receive hook declined)
 ! [remote rejected] branch_651 -> branch_651 (pre-receive hook declined)
 ! [remote rejected] branch_652 -> branch_652 (pre-receive hook declined)
 ! [remote rejected] branch_653 -> branch_653 (pre-receive hook declined)
 ! [remote rejected] branch_654 -> branch_654 (pre-receive hook declined)
 ! [remote rejected] branch_655 -> branch_655 (pre-receive hook declined)
 ! [remote rejected] branch_656 -> branch_656 (pre-receive hook declined)
 ! [remote rejected] branch_657 -> branch_657 (pre-receive hook declined)
 ! [remote rejected] branch_658 -> branch_658 (pre-receive hook declined)
 ! [remote rejected] branch_659 -> branch_659 (pre-receive hook declined)
 ! [remote rejected] branch_660 -> branch_660 (pre-receive hook declined)
 ! [remote rejected] branch_661 -> branch_661 (pre-receive hook declined)
 ! [remote rejected] branch_662 -> branch_662 (pre-receive hook declined)
 ! [remote rejected] branch_663 -> branch_663 (pre-receive hook declined)
 ! [remote rejected] branch_664 -> branch_664 (pre-receive hook declined)
 ! [remote rejected] branch_665 -> branch_665 (pre-receive hook declined)
 ! [remote rejected] branch_666 -> branch_666 (pre-receive hook declined)
 ! [remote rejected] branch_667 -> branch_667 (pre-receive hook declined)
 ! [remote rejected] branch_668 -> branch_668 (pre-receive hook declined)
 ! [remote rejected] branch_669 -> branch_669 (pre-receive hook declined)
 ! [remote rejected] branch_670 -> branch_670 (pre-receive hook declined)
 ! [remote rejected] branch_671 -> branch_671 (pre-receive hook declined)
 ! [remote rejected] branch_672 -> branch_672 (pre-receive hook declined)
 ! [remote rejected] branch_673 -> branch_673 (pre-receive hook declined)
 ! [remote rejected] branch_674 -> branch_674 (pre-receive hook declined)
 ! [remote rejected] branch_675 -> branch_675 (pre-receive hook declined)
 ! [remote rejected] branch_676 -> branch_676 (pre-receive hook declined)
 ! [remote rejected] branch_677 -> branch_677 (pre-receive hook declined)
 ! [remote rejected] branch_678 -> branch_678 (pre-receive hook declined)
 ! [remote rejected] branch_679 -> branch_679 (pre-receive hook declined)
 ! [remote rejected] branch_680 -> branch_680 (pre-receive hook declined)
 ! [remote rejected] branch_681 -> branch_681 (pre-receive hook declined)
 ! [remote rejected] branch_682 -> branch_682 (pre-receive hook declined)
 ! [remote rejected] branch_683 -> branch_683 (pre-receive hook declined)
 ! [remote rejected] branch_684 -> branch_684 (pre-receive hook declined)
 ! [remote rejected] branch_685 -> branch_685 (pre-receive hook declined)
 ! [remote rejected] branch_686 -> branch_686 (pre-receive hook declined)
 ! [remote rejected] branch_687 -> branch_687 (pre-receive hook declined)
 ! [remote rejected] branch_688 -> branch_688 (pre-receive hook declined)
 ! [remote rejected] branch_689 -> branch_689 (pre-receive hook declined)
 ! [remote rejected] branch_690 -> branch_690 (pre-receive hook declined)
 ! [remote rejected] branch_691 -> branch_691 (pre-receive hook declined)
 ! [remote rejected] branch_692 -> branch_692 (pre-receive hook declined)
 ! [remote rejected] branch_693 -> branch_693 (pre-receive hook declined)
 ! [remote rejected] branch_694 -> branch_694 (pre-receive hook declined)
 ! [remote rejected] branch_695 -> branch_695 (pre-receive hook declined)
 ! [remote rejected] branch_696 -> branch_696 (pre-receive hook declined)
 ! [remote rejected] branch_697 -> branch_697 (pre-receive hook declined)
 ! [remote rejected] branch_698 -> branch_698 (pre-receive hook declined)
 ! [remote rejected] branch_699 -> branch_699 (pre-receive hook declined)
 ! [remote rejected] branch_700 -> branch_700 (pre-receive hook declined)
 ! [remote rejected] branch_701 -> branch_701 (pre-receive hook declined)
 ! [remote rejected] branch_702 -> branch_702 (pre-receive hook declined)
 ! [remote rejected] branch_703 -> branch_703 (pre-receive hook declined)
 ! [remote rejected] branch_704 -> branch_704 (pre-receive hook declined)
 ! [remote rejected] branch_705 -> branch_705 (pre-receive hook declined)
 ! [remote rejected] branch_706 -> branch_706 (pre-receive hook declined)
 ! [remote rejected] branch_707 -> branch_707 (pre-receive hook declined)
 ! [remote rejected] branch_708 -> branch_708 (pre-receive hook declined)
 ! [remote rejected] branch_709 -> branch_709 (pre-receive hook declined)
 ! [remote rejected] branch_710 -> branch_710 (pre-receive hook declined)
 ! [remote rejected] branch_711 -> branch_711 (pre-receive hook declined)
 ! [remote rejected] branch_712 -> branch_712 (pre-receive hook declined)
 ! [remote rejected] branch_713 -> branch_713 (pre-receive hook declined)
 ! [remote rejected] branch_714 -> branch_714 (pre-receive hook declined)
 ! [remote rejected] branch_715 -> branch_715 (pre-receive hook declined)
 ! [remote rejected] branch_716 -> branch_716 (pre-receive hook declined)
 ! [remote rejected] branch_717 -> branch_717 (pre-receive hook declined)
 ! [remote rejected] branch_718 -> branch_718 (pre-receive hook declined)
 ! [remote rejected] branch_719 -> branch_719 (pre-receive hook declined)
 ! [remote rejected] branch_720 -> branch_720 (pre-receive hook declined)
 ! [remote rejected] branch_721 -> branch_721 (pre-receive hook declined)
 ! [remote rejected] branch_722 -> branch_722 (pre-receive hook declined)
 ! [remote rejected] branch_723 -> branch_723 (pre-receive hook declined)
 ! [remote rejected] branch_724 -> branch_724 (pre-receive hook declined)
 ! [remote rejected] branch_725 -> branch_725 (pre-receive hook declined)
 ! [remote rejected] branch_726 -> branch_726 (pre-receive hook declined)
 ! [remote rejected] branch_727 -> branch_727 (pre-receive hook declined)
 ! [remote rejected] branch_728 -> branch_728 (pre-receive hook declined)
 ! [remote rejected] branch_729 -> branch_729 (pre-receive hook declined)
 ! [remote rejected] branch_730 -> branch_730 (pre-receive hook declined)
 ! [remote rejected] branch_731 -> branch_731 (pre-receive hook declined)
 ! [remote rejected] branch_732 -> branch_732 (pre-receive hook declined)
 ! [remote rejected] branch_733 -> branch_733 (pre-receive hook declined)
 ! [remote rejected] branch_734 -> branch_734 (pre-receive hook declined)
 ! [remote rejected] branch_735 -> branch_735 (pre-receive hook declined)
 ! [remote rejected] branch_736 -> branch_736 (pre-receive hook declined)
 ! [remote rejected] branch_737 -> branch_737 (pre-receive hook declined)
 ! [remote rejected] branch_738 -> branch_738 (pre-receive hook declined)
 ! [remote rejected] branch_739 -> branch_739 (pre-receive hook declined)
 ! [remote rejected] branch_740 -> branch_740 (pre-receive hook declined)
 ! [remote rejected] branch_741 -> branch_741 (pre-receive hook declined)
 ! [remote rejected] branch_742 -> branch_742 (pre-receive hook declined)
 ! [remote rejected] branch_743 -> branch_743 (pre-receive hook declined)
 ! [remote rejected] branch_744 -> branch_744 (pre-receive hook declined)
 ! [remote rejected] branch_745 -> branch_745 (pre-receive hook declined)
 ! [remote rejected] branch_746 -> branch_746 (pre-receive hook declined)
 ! [remote rejected] branch_747 -> branch_747 (pre-receive hook declined)
 ! [remote rejected] branch_748 -> branch_748 (pre-receive hook declined)
 ! [remote rejected] branch_749 -> branch_749 (pre-receive hook declined)
 ! [remote rejected] branch_750 -> branch_750 (pre-receive hook declined)
 ! [remote rejected] branch_751 -> branch_751 (pre-receive hook declined)
 ! [remote rejected] branch_752 -> branch_752 (pre-receive hook declined)
 ! [remote rejected] branch_753 -> branch_753 (pre-receive hook declined)
 ! [remote rejected] branch_754 -> branch_754 (pre-receive hook declined)
 ! [remote rejected] branch_755 -> branch_755 (pre-receive hook declined)
 ! [remote rejected] branch_756 -> branch_756 (pre-receive hook declined)
 ! [remote rejected] branch_757 -> branch_757 (pre-receive hook declined)
 ! [remote rejected] branch_758 -> branch_758 (pre-receive hook declined)
 ! [remote rejected] branch_759 -> branch_759 (pre-receive hook declined)
 ! [remote rejected] branch_760 -> branch_760 (pre-receive hook declined)
 ! [remote rejected] branch_761 -> branch_761 (pre-receive hook declined)
 ! [remote rejected] branch_762 -> branch_762 (pre-receive hook declined)
 ! [remote rejected] branch_763 -> branch_763 (pre-receive hook declined)
 ! [remote rejected] branch_764 -> branch_764 (pre-receive hook declined)
 ! [remote rejected] branch_765 -> branch_765 (pre-receive hook declined)
 ! [remote rejected] branch_766 -> branch_766 (pre-receive hook declined)
 ! [remote rejected] branch_767 -> branch_767 (pre-receive hook declined)
 ! [remote rejected] branch_768 -> branch_768 (pre-receive hook declined)
 ! [remote rejected] branch_769 -> branch_769 (pre-receive hook declined)
 ! [remote rejected] branch_770 -> branch_770 (pre-receive hook declined)
 ! [remote rejected] branch_771 -> branch_771 (pre-receive hook declined)
 ! [remote rejected] branch_772 -> branch_772 (pre-receive hook declined)
 ! [remote rejected] branch_773 -> branch_773 (pre-receive hook declined)
 ! [remote rejected] branch_774 -> branch_774 (pre-receive hook declined)
 ! [remote rejected] branch_775 -> branch_775 (pre-receive hook declined)
 ! [remote rejected] branch_776 -> branch_776 (pre-receive hook declined)
 ! [remote rejected] branch_777 -> branch_777 (pre-receive hook declined)
 ! [remote rejected] branch_778 -> branch_778 (pre-receive hook declined)
 ! [remote rejected] branch_779 -> branch_779 (pre-receive hook declined)
 ! [remote rejected] branch_780 -> branch_780 (pre-receive hook declined)
 ! [remote rejected] branch_781 -> branch_781 (pre-receive hook declined)
 ! [remote rejected] branch_782 -> branch_782 (pre-receive hook declined)
 ! [remote rejected] branch_783 -> branch_783 (pre-receive hook declined)
 ! [remote rejected] branch_784 -> branch_784 (pre-receive hook declined)
 ! [remote rejected] branch_785 -> branch_785 (pre-receive hook declined)
 ! [remote rejected] branch_786 -> branch_786 (pre-receive hook declined)
 ! [remote rejected] branch_787 -> branch_787 (pre-receive hook declined)
 ! [remote rejected] branch_788 -> branch_788 (pre-receive hook declined)
 ! [remote rejected] branch_789 -> branch_789 (pre-receive hook declined)
 ! [remote rejected] branch_790 -> branch_790 (pre-receive hook declined)
 ! [remote rejected] branch_791 -> branch_791 (pre-receive hook declined)
 ! [remote rejected] branch_792 -> branch_792 (pre-receive hook declined)
 ! [remote rejected] branch_793 -> branch_793 (pre-receive hook declined)
 ! [remote rejected] branch_794 -> branch_794 (pre-receive hook declined)
 ! [remote rejected] branch_795 -> branch_795 (pre-receive hook declined)
 ! [remote rejected] branch_796 -> branch_796 (pre-receive hook declined)
 ! [remote rejected] branch_797 -> branch_797 (pre-receive hook declined)
 ! [remote rejected] branch_798 -> branch_798 (pre-receive hook declined)
 ! [remote rejected] branch_799 -> branch_799 (pre-receive hook declined)
 ! [remote rejected] branch_800 -> branch_800 (pre-receive hook declined)
 ! [remote rejected] branch_801 -> branch_801 (pre-receive hook declined)
 ! [remote rejected] branch_802 -> branch_802 (pre-receive hook declined)
 ! [remote rejected] branch_803 -> branch_803 (pre-receive hook declined)
 ! [remote rejected] branch_804 -> branch_804 (pre-receive hook declined)
 ! [remote rejected] branch_805 -> branch_805 (pre-receive hook declined)
 ! [remote rejected] branch_806 -> branch_806 (pre-receive hook declined)
 ! [remote rejected] branch_807 -> branch_807 (pre-receive hook declined)
 ! [remote rejected] branch_808 -> branch_808 (pre-receive hook declined)
 ! [remote rejected] branch_809 -> branch_809 (pre-receive hook declined)
 ! [remote rejected] branch_810 -> branch_810 (pre-receive hook declined)
 ! [remote rejected] branch_811 -> branch_811 (pre-receive hook declined)
 ! [remote rejected] branch_812 -> branch_812 (pre-receive hook declined)
 ! [remote rejected] branch_813 -> branch_813 (pre-receive hook declined)
 ! [remote rejected] branch_814 -> branch_814 (pre-receive hook declined)
 ! [remote rejected] branch_815 -> branch_815 (pre-receive hook declined)
 ! [remote rejected] branch_816 -> branch_816 (pre-receive hook declined)
 ! [remote rejected] branch_817 -> branch_817 (pre-receive hook declined)
 ! [remote rejected] branch_818 -> branch_818 (pre-receive hook declined)
 ! [remote rejected] branch_819 -> branch_819 (pre-receive hook declined)
 ! [remote rejected] branch_820 -> branch_820 (pre-receive hook declined)
 ! [remote rejected] branch_821 -> branch_821 (pre-receive hook declined)
 ! [remote rejected] branch_822 -> branch_822 (pre-receive hook declined)
 ! [remote rejected] branch_823 -> branch_823 (pre-receive hook declined)
 ! [remote rejected] branch_824 -> branch_824 (pre-receive hook declined)
 ! [remote rejected] branch_825 -> branch_825 (pre-receive hook declined)
 ! [remote rejected] branch_826 -> branch_826 (pre-receive hook declined)
 ! [remote rejected] branch_827 -> branch_827 (pre-receive hook declined)
 ! [remote rejected] branch_828 -> branch_828 (pre-receive hook declined)
 ! [remote rejected] branch_829 -> branch_829 (pre-receive hook declined)
 ! [remote rejected] branch_830 -> branch_830 (pre-receive hook declined)
 ! [remote rejected] branch_831 -> branch_831 (pre-receive hook declined)
 ! [remote rejected] branch_832 -> branch_832 (pre-receive hook declined)
 ! [remote rejected] branch_833 -> branch_833 (pre-receive hook declined)
 ! [remote rejected] branch_834 -> branch_834 (pre-receive hook declined)
 ! [remote rejected] branch_835 -> branch_835 (pre-receive hook declined)
 ! [remote rejected] branch_836 -> branch_836 (pre-receive hook declined)
 ! [remote rejected] branch_837 -> branch_837 (pre-receive hook declined)
 ! [remote rejected] branch_838 -> branch_838 (pre-receive hook declined)
 ! [remote rejected] branch_839 -> branch_839 (pre-receive hook declined)
 ! [remote rejected] branch_840 -> branch_840 (pre-receive hook declined)
 ! [remote rejected] branch_841 -> branch_841 (pre-receive hook declined)
 ! [remote rejected] branch_842 -> branch_842 (pre-receive hook declined)
 ! [remote rejected] branch_843 -> branch_843 (pre-receive hook declined)
 ! [remote rejected] branch_844 -> branch_844 (pre-receive hook declined)
 ! [remote rejected] branch_845 -> branch_845 (pre-receive hook declined)
 ! [remote rejected] branch_846 -> branch_846 (pre-receive hook declined)
 ! [remote rejected] branch_847 -> branch_847 (pre-receive hook declined)
 ! [remote rejected] branch_848 -> branch_848 (pre-receive hook declined)
 ! [remote rejected] branch_849 -> branch_849 (pre-receive hook declined)
 ! [remote rejected] branch_850 -> branch_850 (pre-receive hook declined)
 ! [remote rejected] branch_851 -> branch_851 (pre-receive hook declined)
 ! [remote rejected] branch_852 -> branch_852 (pre-receive hook declined)
 ! [remote rejected] branch_853 -> branch_853 (pre-receive hook declined)
 ! [remote rejected] branch_854 -> branch_854 (pre-receive hook declined)
 ! [remote rejected] branch_855 -> branch_855 (pre-receive hook declined)
 ! [remote rejected] branch_856 -> branch_856 (pre-receive hook declined)
 ! [remote rejected] branch_857 -> branch_857 (pre-receive hook declined)
 ! [remote rejected] branch_858 -> branch_858 (pre-receive hook declined)
 ! [remote rejected] branch_859 -> branch_859 (pre-receive hook declined)
 ! [remote rejected] branch_860 -> branch_860 (pre-receive hook declined)
 ! [remote rejected] branch_861 -> branch_861 (pre-receive hook declined)
 ! [remote rejected] branch_862 -> branch_862 (pre-receive hook declined)
 ! [remote rejected] branch_863 -> branch_863 (pre-receive hook declined)
 ! [remote rejected] branch_864 -> branch_864 (pre-receive hook declined)
 ! [remote rejected] branch_865 -> branch_865 (pre-receive hook declined)
 ! [remote rejected] branch_866 -> branch_866 (pre-receive hook declined)
 ! [remote rejected] branch_867 -> branch_867 (pre-receive hook declined)
 ! [remote rejected] branch_868 -> branch_868 (pre-receive hook declined)
 ! [remote rejected] branch_869 -> branch_869 (pre-receive hook declined)
 ! [remote rejected] branch_870 -> branch_870 (pre-receive hook declined)
 ! [remote rejected] branch_871 -> branch_871 (pre-receive hook declined)
 ! [remote rejected] branch_872 -> branch_872 (pre-receive hook declined)
 ! [remote rejected] branch_873 -> branch_873 (pre-receive hook declined)
 ! [remote rejected] branch_874 -> branch_874 (pre-receive hook declined)
 ! [remote rejected] branch_875 -> branch_875 (pre-receive hook declined)
 ! [remote rejected] branch_876 -> branch_876 (pre-receive hook declined)
 ! [remote rejected] branch_877 -> branch_877 (pre-receive hook declined)
 ! [remote rejected] branch_878 -> branch_878 (pre-receive hook declined)
 ! [remote rejected] branch_879 -> branch_879 (pre-receive hook declined)
 ! [remote rejected] branch_880 -> branch_880 (pre-receive hook declined)
 ! [remote rejected] branch_881 -> branch_881 (pre-receive hook declined)
 ! [remote rejected] branch_882 -> branch_882 (pre-receive hook declined)
 ! [remote rejected] branch_883 -> branch_883 (pre-receive hook declined)
 ! [remote rejected] branch_884 -> branch_884 (pre-receive hook declined)
 ! [remote rejected] branch_885 -> branch_885 (pre-receive hook declined)
 ! [remote rejected] branch_886 -> branch_886 (pre-receive hook declined)
 ! [remote rejected] branch_887 -> branch_887 (pre-receive hook declined)
 ! [remote rejected] branch_888 -> branch_888 (pre-receive hook declined)
 ! [remote rejected] branch_889 -> branch_889 (pre-receive hook declined)
 ! [remote rejected] branch_890 -> branch_890 (pre-receive hook declined)
 ! [remote rejected] branch_891 -> branch_891 (pre-receive hook declined)
 ! [remote rejected] branch_892 -> branch_892 (pre-receive hook declined)
 ! [remote rejected] branch_893 -> branch_893 (pre-receive hook declined)
 ! [remote rejected] branch_894 -> branch_894 (pre-receive hook declined)
 ! [remote rejected] branch_895 -> branch_895 (pre-receive hook declined)
 ! [remote rejected] branch_896 -> branch_896 (pre-receive hook declined)
 ! [remote rejected] branch_897 -> branch_897 (pre-receive hook declined)
 ! [remote rejected] branch_898 -> branch_898 (pre-receive hook declined)
 ! [remote rejected] branch_899 -> branch_899 (pre-receive hook declined)
 ! [remote rejected] branch_900 -> branch_900 (pre-receive hook declined)
 ! [remote rejected] branch_901 -> branch_901 (pre-receive hook declined)
 ! [remote rejected] branch_902 -> branch_902 (pre-receive hook declined)
 ! [remote rejected] branch_903 -> branch_903 (pre-receive hook declined)
 ! [remote rejected] branch_904 -> branch_904 (pre-receive hook declined)
 ! [remote rejected] branch_905 -> branch_905 (pre-receive hook declined)
 ! [remote rejected] branch_906 -> branch_906 (pre-receive hook declined)
 ! [remote rejected] branch_907 -> branch_907 (pre-receive hook declined)
 ! [remote rejected] branch_908 -> branch_908 (pre-receive hook declined)
 ! [remote rejected] branch_909 -> branch_909 (pre-receive hook declined)
 ! [remote rejected] branch_910 -> branch_910 (pre-receive hook declined)
 ! [remote rejected] branch_911 -> branch_911 (pre-receive hook declined)
 ! [remote rejected] branch_912 -> branch_912 (pre-receive hook declined)
 ! [remote rejected] branch_913 -> branch_913 (pre-receive hook declined)
 ! [remote rejected] branch_914 -> branch_914 (pre-receive hook declined)
 ! [remote rejected] branch_915 -> branch_915 (pre-receive hook declined)
 ! [remote rejected] branch_916 -> branch_916 (pre-receive hook declined)
 ! [remote rejected] branch_917 -> branch_917 (pre-receive hook declined)
 ! [remote rejected] branch_918 -> branch_918 (pre-receive hook declined)
 ! [remote rejected] branch_919 -> branch_919 (pre-receive hook declined)
 ! [remote rejected] branch_920 -> branch_920 (pre-receive hook declined)
 ! [remote rejected] branch_921 -> branch_921 (pre-receive hook declined)
 ! [remote rejected] branch_922 -> branch_922 (pre-receive hook declined)
 ! [remote rejected] branch_923 -> branch_923 (pre-receive hook declined)
 ! [remote rejected] branch_924 -> branch_924 (pre-receive hook declined)
 ! [remote rejected] branch_925 -> branch_925 (pre-receive hook declined)
 ! [remote rejected] branch_926 -> branch_926 (pre-receive hook declined)
 ! [remote rejected] branch_927 -> branch_927 (pre-receive hook declined)
 ! [remote rejected] branch_928 -> branch_928 (pre-receive hook declined)
 ! [remote rejected] branch_929 -> branch_929 (pre-receive hook declined)
 ! [remote rejected] branch_930 -> branch_930 (pre-receive hook declined)
 ! [remote rejected] branch_931 -> branch_931 (pre-receive hook declined)
 ! [remote rejected] branch_932 -> branch_932 (pre-receive hook declined)
 ! [remote rejected] branch_933 -> branch_933 (pre-receive hook declined)
 ! [remote rejected] branch_934 -> branch_934 (pre-receive hook declined)
 ! [remote rejected] branch_935 -> branch_935 (pre-receive hook declined)
 ! [remote rejected] branch_936 -> branch_936 (pre-receive hook declined)
 ! [remote rejected] branch_937 -> branch_937 (pre-receive hook declined)
 ! [remote rejected] branch_938 -> branch_938 (pre-receive hook declined)
 ! [remote rejected] branch_939 -> branch_939 (pre-receive hook declined)
 ! [remote rejected] branch_940 -> branch_940 (pre-receive hook declined)
 ! [remote rejected] branch_941 -> branch_941 (pre-receive hook declined)
 ! [remote rejected] branch_942 -> branch_942 (pre-receive hook declined)
 ! [remote rejected] branch_943 -> branch_943 (pre-receive hook declined)
 ! [remote rejected] branch_944 -> branch_944 (pre-receive hook declined)
 ! [remote rejected] branch_945 -> branch_945 (pre-receive hook declined)
 ! [remote rejected] branch_946 -> branch_946 (pre-receive hook declined)
 ! [remote rejected] branch_947 -> branch_947 (pre-receive hook declined)
 ! [remote rejected] branch_948 -> branch_948 (pre-receive hook declined)
 ! [remote rejected] branch_949 -> branch_949 (pre-receive hook declined)
 ! [remote rejected] branch_950 -> branch_950 (pre-receive hook declined)
 ! [remote rejected] branch_951 -> branch_951 (pre-receive hook declined)
 ! [remote rejected] branch_952 -> branch_952 (pre-receive hook declined)
 ! [remote rejected] branch_953 -> branch_953 (pre-receive hook declined)
 ! [remote rejected] branch_954 -> branch_954 (pre-receive hook declined)
 ! [remote rejected] branch_955 -> branch_955 (pre-receive hook declined)
 ! [remote rejected] branch_956 -> branch_956 (pre-receive hook declined)
 ! [remote rejected] branch_957 -> branch_957 (pre-receive hook declined)
 ! [remote rejected] branch_958 -> branch_958 (pre-receive hook declined)
 ! [remote rejected] branch_959 -> branch_959 (pre-receive hook declined)
 ! [remote rejected] branch_960 -> branch_960 (pre-receive hook declined)
 ! [remote rejected] branch_961 -> branch_961 (pre-receive hook declined)
 ! [remote rejected] branch_962 -> branch_962 (pre-receive hook declined)
 ! [remote rejected] branch_963 -> branch_963 (pre-receive hook declined)
 ! [remote rejected] branch_964 -> branch_964 (pre-receive hook declined)
 ! [remote rejected] branch_965 -> branch_965 (pre-receive hook declined)
 ! [remote rejected] branch_966 -> branch_966 (pre-receive hook declined)
 ! [remote rejected] branch_967 -> branch_967 (pre-receive hook declined)
 ! [remote rejected] branch_968 -> branch_968 (pre-receive hook declined)
 ! [remote rejected] branch_969 -> branch_969 (pre-receive hook declined)
 ! [remote rejected] branch_970 -> branch_970 (pre-receive hook declined)
 ! [remote rejected] branch_971 -> branch_971 (pre-receive hook declined)
 ! [remote rejected] branch_972 -> branch_972 (pre-receive hook declined)
 ! [remote rejected] branch_973 -> branch_973 (pre-receive hook declined)
 ! [remote rejected] branch_974 -> branch_974 (pre-receive hook declined)
 ! [remote rejected] branch_975 -> branch_975 (pre-receive hook declined)
 ! [remote rejected] branch_976 -> branch_976 (pre-receive hook declined)
 ! [remote rejected] branch_977 -> branch_977 (pre-receive hook declined)
 ! [remote rejected] branch_978 -> branch_978 (pre-receive hook declined)
 ! [remote rejected] branch_979 -> branch_979 (pre-receive hook declined)
 ! [remote rejected] branch_980 -> branch_980 (pre-receive hook declined)
 ! [remote rejected] branch_981 -> branch_981 (pre-receive hook declined)
 ! [remote rejected] branch_982 -> branch_982 (pre-receive hook declined)
 ! [remote rejected] branch_983 -> branch_983 (pre-receive hook declined)
 ! [remote rejected] branch_984 -> branch_984 (pre-receive hook declined)
 ! [remote rejected] branch_985 -> branch_985 (pre-receive hook declined)
 ! [remote rejected] branch_986 -> branch_986 (pre-receive hook declined)
 ! [remote rejected] branch_987 -> branch_987 (pre-receive hook declined)
 ! [remote rejected] branch_988 -> branch_988 (pre-receive hook declined)
 ! [remote rejected] branch_989 -> branch_989 (pre-receive hook declined)
 ! [remote rejected] branch_990 -> branch_990 (pre-receive hook declined)
 ! [remote rejected] branch_991 -> branch_991 (pre-receive hook declined)
 ! [remote rejected] branch_992 -> branch_992 (pre-receive hook declined)
 ! [remote rejected] branch_993 -> branch_993 (pre-receive hook declined)
 ! [remote rejected] branch_994 -> branch_994 (pre-receive hook declined)
 ! [remote rejected] branch_995 -> branch_995 (pre-receive hook declined)
 ! [remote rejected] branch_996 -> branch_996 (pre-receive hook declined)
 ! [remote rejected] branch_997 -> branch_997 (pre-receive hook declined)
 ! [remote rejected] branch_998 -> branch_998 (pre-receive hook declined)
 ! [remote rejected] branch_999 -> branch_999 (pre-receive hook declined)
error: failed to push some refs to './victim.git'
not ok 13 - pre-receive hook that forgets to

--
Brief whoami: NonStop&UNIX developer since approximately
UNIX(421664400)
NonStop(211288444200000000)
-- In real life, I talk too much.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-07 23:37 Help needed on 2.54.0-rc0 t5301.13 looping rsbecker
@ 2026-04-08  5:20 ` Jeff King
  2026-04-08  5:43   ` Jeff King
  2026-04-08 15:50   ` Help needed on 2.54.0-rc0 t5301.13 looping Junio C Hamano
  0 siblings, 2 replies; 18+ messages in thread
From: Jeff King @ 2026-04-08  5:20 UTC (permalink / raw)
  To: rsbecker; +Cc: Junio C Hamano, Adrian Ratiu, git

On Tue, Apr 07, 2026 at 07:37:49PM -0400, rsbecker@nexbridge.com wrote:

> Weird fail on t5401.13. Any opinions or advise on this?
> 
> expecting success of 5401.13 'pre-receive hook that forgets to read its
> input':
>         test_hook --clobber -C victim.git pre-receive <<-\EOF &&
>         exit 0
>         EOF
>         rm -f victim.git/hooks/update victim.git/hooks/post-update &&
> 
>         test_seq -f "create refs/heads/branch_%d main" 100 999 |
>         git update-ref --stdin &&
>         git push ./victim.git "+refs/heads/*:refs/heads/*"

OK, so this test is trying to feed a bunch of data to a pre-receive hook
that doesn't read anything, and we want to make sure we aren't killed by
SIGPIPE.

When the test was added originally in ec7dbd145b (receive-pack: allow
hooks to ignore its standard input stream, 2014-09-12), we just stuck a:

  sigchain_push(SIGPIPE, SIG_IGN);

at the top of the hook function. But now that function has been
rewritten to use the hook API, and that sigchain_push() is gone.

What does the new hook API do? It works with run-command's
run_processes_parallel() function. Which similarly ignores SIGPIPE,
courtesy of ec0becacc9 (run-command: add stdin callback for
parallelization, 2026-01-28):

          /*
           * Child tasks might receive input via stdin, terminating early (or not), so
           * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which
           * actually writes the data to children stdin fds.
           */
          sigchain_push(SIGPIPE, SIG_IGN);

OK, so far so good. But that's not quite the end of the story. In
pp_init(), we then sigchain_push() another handler, but this time it's a
real function:

  static void handle_children_on_signal(int signo)
  {
          kill_children_signal(pp_for_signal, signo);
          sigchain_pop(signo);
          raise(signo);
  }

So now when we get a SIGPIPE, we end up there. It tries to propagate the
signal to any child processes we spawned. Which is a bit funny, since it
was the child process closing that caused us to get the signal in the
first place, but of course our handler doesn't know that.

And then afterwards, it pops itself off the handler stack and re-raises.
But that will hit the SIG_IGN we pushed earlier and do nothing. So that
part isn't interesting.

What is interesting is that we end up calling "kill(<pid>, SIGPIPE)" on
the child via kill_children_signal(). At least on my Linux system that
works fine, since we haven't reaped the process via wait() yet. But of
course nothing interesting happens to the child, which has already
exited. Killing it with SIGPIPE does not seem to affect its exit code.

However, I could believe that on some other system it might behave
differently. Possibly even racily. For example, if the child process had
closed its pipe (giving us SIGPIPE in the parent) but not yet fully
exited, could our kill() cause it to change its exit code? And then it
would look like the hook reported failure (because it died by signal).
And I'd expect the output you saw.

I think the root of the issue is that we should not be trying to
propagate SIGPIPE to the child in this case at all. Our handler is
pushed there only because it's part of sigchain_push_common(), which is
sensible: in general if we are dying to SIGPIPE we want to do our
cleanup. It's just funny in this case with the ordering of our SIG_IGN,
because now that SIG_IGN isn't on top of the stack anymore.

I.e., I think we want to reorder like this:

diff --git a/run-command.c b/run-command.c
index 32c290ee6a..8a95f7ff1e 100644
--- a/run-command.c
+++ b/run-command.c
@@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
 					   "max:%"PRIuMAX,
 					   (uintmax_t)opts->processes);
 
+	pp_init(&pp, opts, &pp_sig);
+
 	/*
 	 * Child tasks might receive input via stdin, terminating early (or not), so
 	 * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which
 	 * actually writes the data to children stdin fds.
+	 *
+	 * This _must_ come after pp_init(), because it installs its own
+	 * SIGPIPE handler (to cleanup children), and we want to supersede
+	 * that.
 	 */
 	sigchain_push(SIGPIPE, SIG_IGN);
 
-	pp_init(&pp, opts, &pp_sig);
 	while (1) {
 		for (i = 0;
 		    i < spawn_cap && !pp.shutdown &&

Does that make your problem go away?

I suspect we could construct a related case that does fail on Linux
without the patch above. Imagine we actually have two hooks running in
parallel. The first one is fast and does not read its input, and the
second one is slow. We'll get SIGPIPE writing to the first one, and then
kill _both_ children. But that's wrong! There is no reason to kill the
second hook, as our intent was to ignore SIGPIPE.

-Peff

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08  5:20 ` Jeff King
@ 2026-04-08  5:43   ` Jeff King
  2026-04-08 11:53     ` Adrian Ratiu
  2026-04-08 15:50   ` Help needed on 2.54.0-rc0 t5301.13 looping Junio C Hamano
  1 sibling, 1 reply; 18+ messages in thread
From: Jeff King @ 2026-04-08  5:43 UTC (permalink / raw)
  To: rsbecker; +Cc: Junio C Hamano, Adrian Ratiu, git

On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:

> I suspect we could construct a related case that does fail on Linux
> without the patch above. Imagine we actually have two hooks running in
> parallel. The first one is fast and does not read its input, and the
> second one is slow. We'll get SIGPIPE writing to the first one, and then
> kill _both_ children. But that's wrong! There is no reason to kill the
> second hook, as our intent was to ignore SIGPIPE.

This would require running hooks in parallel, which isn't implemented
yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,
then this test:

diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 44ec875aef..97257763d3 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets to read its input' '
 	git push ./victim.git "+refs/heads/*:refs/heads/*"
 '
 
+test_expect_success 'hooks in parallel that do not read input' '
+	# Add this to our $PATH to avoid having to write the whole trash
+	# directory into our config options, which would require quoting.
+	mkdir bin &&
+	PATH=$PWD/bin:$PATH &&
+
+	write_script bin/hook-fast <<-\EOF &&
+	# This hook does not read its input, so the parent process
+	# may see SIGPIPE if it is not ignored. It should happen
+	# relatively quickly.
+	exit 0
+	EOF
+
+	write_script bin/hook-slow <<-\EOF &&
+	# This hook is slow, so we expect it to still be running
+	# when the other hook has exited (and the parent has a pipe error
+	# writing to it).
+	#
+	# So we want to be slow enough that we expect this to happen, but not
+	# so slow that the test takes forever. 1 second is probably enough
+	# in practice (and if it is occasionally not on a loaded system, we
+	# will err on the side of having the test pass).
+	sleep 1
+	exit 0
+	EOF
+
+
+	git init --bare parallel.git &&
+	git -C parallel.git config hook.fast.command "hook-fast" &&
+	git -C parallel.git config hook.fast.event pre-receive &&
+	git -C parallel.git config hook.fast.parallel true &&
+	git -C parallel.git config hook.slow.command "hook-slow" &&
+	git -C parallel.git config hook.slow.event pre-receive &&
+	git -C parallel.git config hook.slow.parallel true &&
+	git -C parallel.git config hook.jobs 2 &&
+
+	git push ./parallel.git "+refs/heads/*:refs/heads/*"
+'
+
 test_done

fails reliably. And applying the patch I suggested earlier fixes it.

So I think it's probably a good idea regardless, though I'm still
curious to see if it solves Randall's non-parallel case on NonStop.

-Peff

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08  5:43   ` Jeff King
@ 2026-04-08 11:53     ` Adrian Ratiu
  2026-04-08 15:44       ` rsbecker
                         ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Adrian Ratiu @ 2026-04-08 11:53 UTC (permalink / raw)
  To: Jeff King, rsbecker; +Cc: Junio C Hamano, git

On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:
> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:
>
>> I suspect we could construct a related case that does fail on Linux
>> without the patch above. Imagine we actually have two hooks running in
>> parallel. The first one is fast and does not read its input, and the
>> second one is slow. We'll get SIGPIPE writing to the first one, and then
>> kill _both_ children. But that's wrong! There is no reason to kill the
>> second hook, as our intent was to ignore SIGPIPE.
>
> This would require running hooks in parallel, which isn't implemented
> yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,
> then this test:
>
> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
> index 44ec875aef..97257763d3 100755
> --- a/t/t5401-update-hooks.sh
> +++ b/t/t5401-update-hooks.sh
> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets to read its input' '
>  	git push ./victim.git "+refs/heads/*:refs/heads/*"
>  '
>  
> +test_expect_success 'hooks in parallel that do not read input' '
> +	# Add this to our $PATH to avoid having to write the whole trash
> +	# directory into our config options, which would require quoting.
> +	mkdir bin &&
> +	PATH=$PWD/bin:$PATH &&
> +
> +	write_script bin/hook-fast <<-\EOF &&
> +	# This hook does not read its input, so the parent process
> +	# may see SIGPIPE if it is not ignored. It should happen
> +	# relatively quickly.
> +	exit 0
> +	EOF
> +
> +	write_script bin/hook-slow <<-\EOF &&
> +	# This hook is slow, so we expect it to still be running
> +	# when the other hook has exited (and the parent has a pipe error
> +	# writing to it).
> +	#
> +	# So we want to be slow enough that we expect this to happen, but not
> +	# so slow that the test takes forever. 1 second is probably enough
> +	# in practice (and if it is occasionally not on a loaded system, we
> +	# will err on the side of having the test pass).
> +	sleep 1
> +	exit 0
> +	EOF
> +
> +
> +	git init --bare parallel.git &&
> +	git -C parallel.git config hook.fast.command "hook-fast" &&
> +	git -C parallel.git config hook.fast.event pre-receive &&
> +	git -C parallel.git config hook.fast.parallel true &&
> +	git -C parallel.git config hook.slow.command "hook-slow" &&
> +	git -C parallel.git config hook.slow.event pre-receive &&
> +	git -C parallel.git config hook.slow.parallel true &&
> +	git -C parallel.git config hook.jobs 2 &&
> +
> +	git push ./parallel.git "+refs/heads/*:refs/heads/*"
> +'
> +
>  test_done
>
> fails reliably. And applying the patch I suggested earlier fixes it.
>
> So I think it's probably a good idea regardless, though I'm still
> curious to see if it solves Randall's non-parallel case on NonStop.

Thanks Peff for the in-depth analysis, fix and test.
It is very much appreciated. I missed this case.

I agree with your assesement: this must be fixed regardless if it also
fixes Randall's case or not (might be a separate root cause).

I would proceed like this (obviously crediting you for the fix & test):

If it fixes Randall's case:
   send a standalone bug-fix patch, then integrate the test into the
   parallel series.
else
   integrate both the fix and the test into the parallel series.

@Randall please let us know if the fix proposed by Peff in the other
response works for you.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 11:53     ` Adrian Ratiu
@ 2026-04-08 15:44       ` rsbecker
  2026-04-08 15:52       ` rsbecker
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 18+ messages in thread
From: rsbecker @ 2026-04-08 15:44 UTC (permalink / raw)
  To: 'Adrian Ratiu', 'Jeff King'; +Cc: 'Junio C Hamano', git

On April 8, 2026 7:53 AM, Adrian Ratiu wrote:
>On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:
>> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:
>>
>>> I suspect we could construct a related case that does fail on Linux
>>> without the patch above. Imagine we actually have two hooks running in
>>> parallel. The first one is fast and does not read its input, and the
>>> second one is slow. We'll get SIGPIPE writing to the first one, and then
>>> kill _both_ children. But that's wrong! There is no reason to kill the
>>> second hook, as our intent was to ignore SIGPIPE.
>>
>> This would require running hooks in parallel, which isn't implemented
>> yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,
>> then this test:
>>
>> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
>> index 44ec875aef..97257763d3 100755
>> --- a/t/t5401-update-hooks.sh
>> +++ b/t/t5401-update-hooks.sh
>> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets
to
>read its input' '
>>  	git push ./victim.git "+refs/heads/*:refs/heads/*"
>>  '
>>
>> +test_expect_success 'hooks in parallel that do not read input' '
>> +	# Add this to our $PATH to avoid having to write the whole trash
>> +	# directory into our config options, which would require quoting.
>> +	mkdir bin &&
>> +	PATH=$PWD/bin:$PATH &&
>> +
>> +	write_script bin/hook-fast <<-\EOF &&
>> +	# This hook does not read its input, so the parent process
>> +	# may see SIGPIPE if it is not ignored. It should happen
>> +	# relatively quickly.
>> +	exit 0
>> +	EOF
>> +
>> +	write_script bin/hook-slow <<-\EOF &&
>> +	# This hook is slow, so we expect it to still be running
>> +	# when the other hook has exited (and the parent has a pipe error
>> +	# writing to it).
>> +	#
>> +	# So we want to be slow enough that we expect this to happen, but
not
>> +	# so slow that the test takes forever. 1 second is probably enough
>> +	# in practice (and if it is occasionally not on a loaded system, we
>> +	# will err on the side of having the test pass).
>> +	sleep 1
>> +	exit 0
>> +	EOF
>> +
>> +
>> +	git init --bare parallel.git &&
>> +	git -C parallel.git config hook.fast.command "hook-fast" &&
>> +	git -C parallel.git config hook.fast.event pre-receive &&
>> +	git -C parallel.git config hook.fast.parallel true &&
>> +	git -C parallel.git config hook.slow.command "hook-slow" &&
>> +	git -C parallel.git config hook.slow.event pre-receive &&
>> +	git -C parallel.git config hook.slow.parallel true &&
>> +	git -C parallel.git config hook.jobs 2 &&
>> +
>> +	git push ./parallel.git "+refs/heads/*:refs/heads/*"
>> +'
>> +
>>  test_done
>>
>> fails reliably. And applying the patch I suggested earlier fixes it.
>>
>> So I think it's probably a good idea regardless, though I'm still
>> curious to see if it solves Randall's non-parallel case on NonStop.
>
>Thanks Peff for the in-depth analysis, fix and test.
>It is very much appreciated. I missed this case.
>
>I agree with your assesement: this must be fixed regardless if it also
>fixes Randall's case or not (might be a separate root cause).
>
>I would proceed like this (obviously crediting you for the fix & test):
>
>If it fixes Randall's case:
>   send a standalone bug-fix patch, then integrate the test into the
>   parallel series.
>else
>   integrate both the fix and the test into the parallel series.
>
>@Randall please let us know if the fix proposed by Peff in the other
>response works for you.

Yes, this fix worked on NonStop. Thanks Peff. The new test also passed.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08  5:20 ` Jeff King
  2026-04-08  5:43   ` Jeff King
@ 2026-04-08 15:50   ` Junio C Hamano
  2026-04-08 16:26     ` Adrian Ratiu
  1 sibling, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2026-04-08 15:50 UTC (permalink / raw)
  To: Jeff King; +Cc: rsbecker, Adrian Ratiu, git

Jeff King <peff@peff.net> writes:

> I think the root of the issue is that we should not be trying to
> propagate SIGPIPE to the child in this case at all. Our handler is
> pushed there only because it's part of sigchain_push_common(), which is
> sensible: in general if we are dying to SIGPIPE we want to do our
> cleanup. It's just funny in this case with the ordering of our SIG_IGN,
> because now that SIG_IGN isn't on top of the stack anymore.
>
> I.e., I think we want to reorder like this:
>
> diff --git a/run-command.c b/run-command.c
> index 32c290ee6a..8a95f7ff1e 100644
> --- a/run-command.c
> +++ b/run-command.c
> @@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
>  					   "max:%"PRIuMAX,
>  					   (uintmax_t)opts->processes);
>  
> +	pp_init(&pp, opts, &pp_sig);
> +
>  	/*
>  	 * Child tasks might receive input via stdin, terminating early (or not), so
>  	 * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which
>  	 * actually writes the data to children stdin fds.
> +	 *
> +	 * This _must_ come after pp_init(), because it installs its own
> +	 * SIGPIPE handler (to cleanup children), and we want to supersede
> +	 * that.
>  	 */
>  	sigchain_push(SIGPIPE, SIG_IGN);
>  
> -	pp_init(&pp, opts, &pp_sig);
>  	while (1) {
>  		for (i = 0;
>  		    i < spawn_cap && !pp.shutdown &&
>
> Does that make your problem go away?
>
> I suspect we could construct a related case that does fail on Linux
> without the patch above. Imagine we actually have two hooks running in
> parallel. The first one is fast and does not read its input, and the
> second one is slow. We'll get SIGPIPE writing to the first one, and then
> kill _both_ children. But that's wrong! There is no reason to kill the
> second hook, as our intent was to ignore SIGPIPE.

Oh, I am very much impressed by this analysis.

As -rc1 has already been tagged (but not pushed out yet), we would
probably want to apply a fix before -rc2, I suppose.

Thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 11:53     ` Adrian Ratiu
  2026-04-08 15:44       ` rsbecker
@ 2026-04-08 15:52       ` rsbecker
  2026-04-08 15:55       ` rsbecker
  2026-04-08 16:53       ` Junio C Hamano
  3 siblings, 0 replies; 18+ messages in thread
From: rsbecker @ 2026-04-08 15:52 UTC (permalink / raw)
  To: 'Adrian Ratiu', 'Jeff King'; +Cc: 'Junio C Hamano', git

On April 8, 2026 7:53 AM, Adrian Ratiu wrote:
>To: Jeff King <peff@peff.net>; rsbecker@nexbridge.com
>Cc: Junio C Hamano <gitster@pobox.com>; git@vger.kernel.org
>Subject: Re: Help needed on 2.54.0-rc0 t5301.13 looping.
>
>On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:
>> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:
>>
>>> I suspect we could construct a related case that does fail on Linux
>>> without the patch above. Imagine we actually have two hooks running in
>>> parallel. The first one is fast and does not read its input, and the
>>> second one is slow. We'll get SIGPIPE writing to the first one, and then
>>> kill _both_ children. But that's wrong! There is no reason to kill the
>>> second hook, as our intent was to ignore SIGPIPE.
>>
>> This would require running hooks in parallel, which isn't implemented
>> yet for v2.54.0. But if I build on top of the ar/parallel-hooks topic,
>> then this test:
>>
>> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
>> index 44ec875aef..97257763d3 100755
>> --- a/t/t5401-update-hooks.sh
>> +++ b/t/t5401-update-hooks.sh
>> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that forgets
to
>read its input' '
>>  	git push ./victim.git "+refs/heads/*:refs/heads/*"
>>  '
>>
>> +test_expect_success 'hooks in parallel that do not read input' '
>> +	# Add this to our $PATH to avoid having to write the whole trash
>> +	# directory into our config options, which would require quoting.
>> +	mkdir bin &&
>> +	PATH=$PWD/bin:$PATH &&
>> +
>> +	write_script bin/hook-fast <<-\EOF &&
>> +	# This hook does not read its input, so the parent process
>> +	# may see SIGPIPE if it is not ignored. It should happen
>> +	# relatively quickly.
>> +	exit 0
>> +	EOF
>> +
>> +	write_script bin/hook-slow <<-\EOF &&
>> +	# This hook is slow, so we expect it to still be running
>> +	# when the other hook has exited (and the parent has a pipe error
>> +	# writing to it).
>> +	#
>> +	# So we want to be slow enough that we expect this to happen, but
not
>> +	# so slow that the test takes forever. 1 second is probably enough
>> +	# in practice (and if it is occasionally not on a loaded system, we
>> +	# will err on the side of having the test pass).
>> +	sleep 1
>> +	exit 0
>> +	EOF
>> +
>> +
>> +	git init --bare parallel.git &&
>> +	git -C parallel.git config hook.fast.command "hook-fast" &&
>> +	git -C parallel.git config hook.fast.event pre-receive &&
>> +	git -C parallel.git config hook.fast.parallel true &&
>> +	git -C parallel.git config hook.slow.command "hook-slow" &&
>> +	git -C parallel.git config hook.slow.event pre-receive &&
>> +	git -C parallel.git config hook.slow.parallel true &&
>> +	git -C parallel.git config hook.jobs 2 &&
>> +
>> +	git push ./parallel.git "+refs/heads/*:refs/heads/*"
>> +'
>> +
>>  test_done
>>
>> fails reliably. And applying the patch I suggested earlier fixes it.
>>
>> So I think it's probably a good idea regardless, though I'm still
>> curious to see if it solves Randall's non-parallel case on NonStop.
>
>Thanks Peff for the in-depth analysis, fix and test.
>It is very much appreciated. I missed this case.
>
>I agree with your assesement: this must be fixed regardless if it also
>fixes Randall's case or not (might be a separate root cause).
>
>I would proceed like this (obviously crediting you for the fix & test):
>
>If it fixes Randall's case:
>   send a standalone bug-fix patch, then integrate the test into the
>   parallel series.
>else
>   integrate both the fix and the test into the parallel series.
>
>@Randall please let us know if the fix proposed by Peff in the other
>response works for you.

This fix, however, causes an unreported infinite loop in t5571:

expecting success of 5571.11 'sigpipe does not cause pre-push hook failure':
        test_hook --clobber pre-push <<-\EOF &&
        exit 0
        EOF
        git push parent1 "refs/heads/b/*:refs/heads/b/*"

Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
<and hung>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 11:53     ` Adrian Ratiu
  2026-04-08 15:44       ` rsbecker
  2026-04-08 15:52       ` rsbecker
@ 2026-04-08 15:55       ` rsbecker
  2026-04-08 16:53       ` Junio C Hamano
  3 siblings, 0 replies; 18+ messages in thread
From: rsbecker @ 2026-04-08 15:55 UTC (permalink / raw)
  To: 'Adrian Ratiu', 'Jeff King'; +Cc: 'Junio C Hamano', git

On April 8, 2026 11:53 AM, I wrote (accidentally):
>To: 'Adrian Ratiu' <adrian.ratiu@collabora.com>; 'Jeff King'
<peff@peff.net>
>Cc: 'Junio C Hamano' <gitster@pobox.com>; 'git@vger.kernel.org'
><git@vger.kernel.org>
>Subject: RE: Help needed on 2.54.0-rc0 t5301.13 looping.
>
>On April 8, 2026 7:53 AM, Adrian Ratiu wrote:
>>To: Jeff King <peff@peff.net>; rsbecker@nexbridge.com
>>Cc: Junio C Hamano <gitster@pobox.com>; git@vger.kernel.org
>>Subject: Re: Help needed on 2.54.0-rc0 t5301.13 looping.
>>
>>On Wed, 08 Apr 2026, Jeff King <peff@peff.net> wrote:
>>> On Wed, Apr 08, 2026 at 01:20:31AM -0400, Jeff King wrote:
>>>
>>>> I suspect we could construct a related case that does fail on Linux
>>>> without the patch above. Imagine we actually have two hooks running
>>>> in parallel. The first one is fast and does not read its input, and
>>>> the second one is slow. We'll get SIGPIPE writing to the first one,
>>>> and then kill _both_ children. But that's wrong! There is no reason
>>>> to kill the second hook, as our intent was to ignore SIGPIPE.
>>>
>>> This would require running hooks in parallel, which isn't implemented
>>> yet for v2.54.0. But if I build on top of the ar/parallel-hooks
>>> topic, then this test:
>>>
>>> diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index
>>> 44ec875aef..97257763d3 100755
>>> --- a/t/t5401-update-hooks.sh
>>> +++ b/t/t5401-update-hooks.sh
>>> @@ -139,4 +139,43 @@ test_expect_success 'pre-receive hook that
>>> forgets to
>>read its input' '
>>>  	git push ./victim.git "+refs/heads/*:refs/heads/*"
>>>  '
>>>
>>> +test_expect_success 'hooks in parallel that do not read input' '
>>> +	# Add this to our $PATH to avoid having to write the whole trash
>>> +	# directory into our config options, which would require quoting.
>>> +	mkdir bin &&
>>> +	PATH=$PWD/bin:$PATH &&
>>> +
>>> +	write_script bin/hook-fast <<-\EOF &&
>>> +	# This hook does not read its input, so the parent process
>>> +	# may see SIGPIPE if it is not ignored. It should happen
>>> +	# relatively quickly.
>>> +	exit 0
>>> +	EOF
>>> +
>>> +	write_script bin/hook-slow <<-\EOF &&
>>> +	# This hook is slow, so we expect it to still be running
>>> +	# when the other hook has exited (and the parent has a pipe error
>>> +	# writing to it).
>>> +	#
>>> +	# So we want to be slow enough that we expect this to happen, but
not
>>> +	# so slow that the test takes forever. 1 second is probably enough
>>> +	# in practice (and if it is occasionally not on a loaded system, we
>>> +	# will err on the side of having the test pass).
>>> +	sleep 1
>>> +	exit 0
>>> +	EOF
>>> +
>>> +
>>> +	git init --bare parallel.git &&
>>> +	git -C parallel.git config hook.fast.command "hook-fast" &&
>>> +	git -C parallel.git config hook.fast.event pre-receive &&
>>> +	git -C parallel.git config hook.fast.parallel true &&
>>> +	git -C parallel.git config hook.slow.command "hook-slow" &&
>>> +	git -C parallel.git config hook.slow.event pre-receive &&
>>> +	git -C parallel.git config hook.slow.parallel true &&
>>> +	git -C parallel.git config hook.jobs 2 &&
>>> +
>>> +	git push ./parallel.git "+refs/heads/*:refs/heads/*"
>>> +'
>>> +
>>>  test_done
>>>
>>> fails reliably. And applying the patch I suggested earlier fixes it.
>>>
>>> So I think it's probably a good idea regardless, though I'm still
>>> curious to see if it solves Randall's non-parallel case on NonStop.
>>
>>Thanks Peff for the in-depth analysis, fix and test.
>>It is very much appreciated. I missed this case.
>>
>>I agree with your assesement: this must be fixed regardless if it also
>>fixes Randall's case or not (might be a separate root cause).
>>
>>I would proceed like this (obviously crediting you for the fix & test):
>>
>>If it fixes Randall's case:
>>   send a standalone bug-fix patch, then integrate the test into the
>>   parallel series.
>>else
>>   integrate both the fix and the test into the parallel series.
>>
>>@Randall please let us know if the fix proposed by Peff in the other
>>response works for you.
>
>This fix, however, causes an unreported infinite loop in t5571:
>
>expecting success of 5571.11 'sigpipe does not cause pre-push hook
failure':
>        test_hook --clobber pre-push <<-\EOF &&
>        exit 0
>        EOF
>        git push parent1 "refs/heads/b/*:refs/heads/b/*"
>
>Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) <and hung>

I was not patient enough. This continued eventually and passed.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 15:50   ` Help needed on 2.54.0-rc0 t5301.13 looping Junio C Hamano
@ 2026-04-08 16:26     ` Adrian Ratiu
  2026-04-08 17:20       ` [PATCH] run_processes_parallel(): fix order of sigpipe handling Jeff King
  0 siblings, 1 reply; 18+ messages in thread
From: Adrian Ratiu @ 2026-04-08 16:26 UTC (permalink / raw)
  To: Junio C Hamano, Jeff King; +Cc: rsbecker, git

On Wed, 08 Apr 2026, Junio C Hamano <gitster@pobox.com> wrote:
> Jeff King <peff@peff.net> writes:
>
>> I think the root of the issue is that we should not be trying to
>> propagate SIGPIPE to the child in this case at all. Our handler is
>> pushed there only because it's part of sigchain_push_common(), which is
>> sensible: in general if we are dying to SIGPIPE we want to do our
>> cleanup. It's just funny in this case with the ordering of our SIG_IGN,
>> because now that SIG_IGN isn't on top of the stack anymore.
>>
>> I.e., I think we want to reorder like this:
>>
>> diff --git a/run-command.c b/run-command.c
>> index 32c290ee6a..8a95f7ff1e 100644
>> --- a/run-command.c
>> +++ b/run-command.c
>> @@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
>>  					   "max:%"PRIuMAX,
>>  					   (uintmax_t)opts->processes);
>>  
>> +	pp_init(&pp, opts, &pp_sig);
>> +
>>  	/*
>>  	 * Child tasks might receive input via stdin, terminating early (or not), so
>>  	 * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which
>>  	 * actually writes the data to children stdin fds.
>> +	 *
>> +	 * This _must_ come after pp_init(), because it installs its own
>> +	 * SIGPIPE handler (to cleanup children), and we want to supersede
>> +	 * that.
>>  	 */
>>  	sigchain_push(SIGPIPE, SIG_IGN);
>>  
>> -	pp_init(&pp, opts, &pp_sig);
>>  	while (1) {
>>  		for (i = 0;
>>  		    i < spawn_cap && !pp.shutdown &&
>>
>> Does that make your problem go away?
>>
>> I suspect we could construct a related case that does fail on Linux
>> without the patch above. Imagine we actually have two hooks running in
>> parallel. The first one is fast and does not read its input, and the
>> second one is slow. We'll get SIGPIPE writing to the first one, and then
>> kill _both_ children. But that's wrong! There is no reason to kill the
>> second hook, as our intent was to ignore SIGPIPE.
>
> Oh, I am very much impressed by this analysis.
>
> As -rc1 has already been tagged (but not pushed out yet), we would
> probably want to apply a fix before -rc2, I suppose.

Yes, that is fine.

All my local tests also look good with Peff's patch
(including the parallel series).

@Peff

Please let me know if you wish me to send a patch or if you wish to send
it yourself, since this investigation is your work & effort. :)

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 11:53     ` Adrian Ratiu
                         ` (2 preceding siblings ...)
  2026-04-08 15:55       ` rsbecker
@ 2026-04-08 16:53       ` Junio C Hamano
  2026-04-08 16:58         ` rsbecker
  2026-04-08 17:01         ` Adrian Ratiu
  3 siblings, 2 replies; 18+ messages in thread
From: Junio C Hamano @ 2026-04-08 16:53 UTC (permalink / raw)
  To: Adrian Ratiu; +Cc: Jeff King, rsbecker, git

Adrian Ratiu <adrian.ratiu@collabora.com> writes:

> Thanks Peff for the in-depth analysis, fix and test.
> It is very much appreciated. I missed this case.
>
> I agree with your assesement: this must be fixed regardless if it also
> fixes Randall's case or not (might be a separate root cause).
>
> I would proceed like this (obviously crediting you for the fix & test):
>
> If it fixes Randall's case:
>    send a standalone bug-fix patch, then integrate the test into the
>    parallel series.
> else
>    integrate both the fix and the test into the parallel series.
>
> @Randall please let us know if the fix proposed by Peff in the other
> response works for you.

It sounds sensible, but a standalone fix early before 2.54 final, as
the problem and the fix shown by Peff here looked correct, without
waiting for NonStop may be simpler to work with.  Then, rebuild
parallel series on top of the 'master' that has the fix applied,
perhaps?

Thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 16:53       ` Junio C Hamano
@ 2026-04-08 16:58         ` rsbecker
  2026-04-08 17:01         ` Adrian Ratiu
  1 sibling, 0 replies; 18+ messages in thread
From: rsbecker @ 2026-04-08 16:58 UTC (permalink / raw)
  To: 'Junio C Hamano', 'Adrian Ratiu'; +Cc: 'Jeff King', git

On April 8, 2026 12:54 PM, Junio C Hamano wrote:
>Adrian Ratiu <adrian.ratiu@collabora.com> writes:
>
>> Thanks Peff for the in-depth analysis, fix and test.
>> It is very much appreciated. I missed this case.
>>
>> I agree with your assesement: this must be fixed regardless if it also
>> fixes Randall's case or not (might be a separate root cause).
>>
>> I would proceed like this (obviously crediting you for the fix & test):
>>
>> If it fixes Randall's case:
>>    send a standalone bug-fix patch, then integrate the test into the
>>    parallel series.
>> else
>>    integrate both the fix and the test into the parallel series.
>>
>> @Randall please let us know if the fix proposed by Peff in the other
>> response works for you.
>
>It sounds sensible, but a standalone fix early before 2.54 final, as the
problem and
>the fix shown by Peff here looked correct, without waiting for NonStop may
be
>simpler to work with.  Then, rebuild parallel series on top of the 'master'
that has
>the fix applied, perhaps?

The fix works on NonStop as previously supplied. So I'm good.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help needed on 2.54.0-rc0 t5301.13 looping.
  2026-04-08 16:53       ` Junio C Hamano
  2026-04-08 16:58         ` rsbecker
@ 2026-04-08 17:01         ` Adrian Ratiu
  2026-04-08 17:30           ` [PATCH] t5401: test SIGPIPE with parallel hooks Jeff King
  1 sibling, 1 reply; 18+ messages in thread
From: Adrian Ratiu @ 2026-04-08 17:01 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, rsbecker, git

On Wed, 08 Apr 2026, Junio C Hamano <gitster@pobox.com> wrote:
> Adrian Ratiu <adrian.ratiu@collabora.com> writes:
>
>> Thanks Peff for the in-depth analysis, fix and test.
>> It is very much appreciated. I missed this case.
>>
>> I agree with your assesement: this must be fixed regardless if it also
>> fixes Randall's case or not (might be a separate root cause).
>>
>> I would proceed like this (obviously crediting you for the fix & test):
>>
>> If it fixes Randall's case:
>>    send a standalone bug-fix patch, then integrate the test into the
>>    parallel series.
>> else
>>    integrate both the fix and the test into the parallel series.
>>
>> @Randall please let us know if the fix proposed by Peff in the other
>> response works for you.
>
> It sounds sensible, but a standalone fix early before 2.54 final, as
> the problem and the fix shown by Peff here looked correct, without
> waiting for NonStop may be simpler to work with.  Then, rebuild
> parallel series on top of the 'master' that has the fix applied,
> perhaps?

Yes, that is the path forward now that Randall also confirmed the fix
works on NonStop (btw thank you Randall). :)

Just waiting for Peff to tell me if he wants to send it himself.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] run_processes_parallel(): fix order of sigpipe handling
  2026-04-08 16:26     ` Adrian Ratiu
@ 2026-04-08 17:20       ` Jeff King
  2026-04-08 17:59         ` Junio C Hamano
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff King @ 2026-04-08 17:20 UTC (permalink / raw)
  To: Adrian Ratiu; +Cc: Junio C Hamano, rsbecker, git

On Wed, Apr 08, 2026 at 07:26:59PM +0300, Adrian Ratiu wrote:

> @Peff
> 
> Please let me know if you wish me to send a patch or if you wish to send
> it yourself, since this investigation is your work & effort. :)

Here it is with a small cleanup and a real commit message.

-- >8 --
Subject: run_processes_parallel(): fix order of sigpipe handling

In commit ec0becacc9 (run-command: add stdin callback for
parallelization, 2026-01-28), we taught run_processes_parallel() to
ignore SIGPIPE, since we wouldn't want a write() to a broken pipe of one
of the children to take down the whole process.

But there's a subtle ordering issue. After we ignore SIGPIPE, we call
pp_init(), which installs its own cleanup handler for multiple signals
using sigchain_push_common(), which includes SIGPIPE. So if we receive
SIGPIPE while writing to a child, we'll trigger that handler first, pop
it off the stack, and then re-raise (which is then ignored because of
the SIG_IGN we pushed first).

But what does that handler do? It tries to clean up all of the child
processes, under the assumption that when we re-raise the signal we'll
be exiting the process!

So a hook that exits without reading all of its input will cause us to
get SIGPIPE, which will put us in a signal handler that then tries to
kill() that same child.

This seems to be mostly harmless on Linux. The process has already
exited by this point, and though kill() does not complain (since the
process has not been reaped with a wait() call), it does not affect the
exit status of the process.

However, this seems not to be true on all platforms. This case is
triggered by t5401.13, "pre-receive hook that forgets to read its
input". This test fails on NonStop since that hook was converted to the
run_processes_parallel() API.

We can fix it by reordering the code a bit. We should run pp_init()
first, and then push our SIG_IGN onto the stack afterwards, so that it
is truly ignored while feeding the sub-processes.

Note that we also reorder the popping at the end of the function, too.
This is not technically necessary, as we are doing two pops either way,
but now the pops will correctly match their pushes.

This also fixes a related case that we can't test yet. If we did have
more than one process to run, then one child causing SIGPIPE would cause
us to kill() all of the children (which might still actually be
running). But the hook API is the only user of the new feed_pipe
feature, and it does not yet support parallel hook execution. So for now
we'll always execute the processes sequentially. Once parallel hook
execution exists, we'll be able to add a test which covers this.

Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
Signed-off-by: Jeff King <peff@peff.net>
---
 run-command.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/run-command.c b/run-command.c
index 32c290ee6a..574d5c40f0 100644
--- a/run-command.c
+++ b/run-command.c
@@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
 					   "max:%"PRIuMAX,
 					   (uintmax_t)opts->processes);
 
+	pp_init(&pp, opts, &pp_sig);
+
 	/*
 	 * Child tasks might receive input via stdin, terminating early (or not), so
 	 * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which
 	 * actually writes the data to children stdin fds.
+	 *
+	 * This _must_ come after pp_init(), because it installs its own
+	 * SIGPIPE handler (to cleanup children), and we want to supersede
+	 * that.
 	 */
 	sigchain_push(SIGPIPE, SIG_IGN);
 
-	pp_init(&pp, opts, &pp_sig);
 	while (1) {
 		for (i = 0;
 		    i < spawn_cap && !pp.shutdown &&
@@ -1928,10 +1933,10 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
 		}
 	}
 
-	pp_cleanup(&pp, opts);
-
 	sigchain_pop(SIGPIPE);
 
+	pp_cleanup(&pp, opts);
+
 	if (do_trace2)
 		trace2_region_leave(tr2_category, tr2_label, NULL);
 }
-- 
2.54.0.rc1.274.g1f8c576c50


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH] t5401: test SIGPIPE with parallel hooks
  2026-04-08 17:01         ` Adrian Ratiu
@ 2026-04-08 17:30           ` Jeff King
  0 siblings, 0 replies; 18+ messages in thread
From: Jeff King @ 2026-04-08 17:30 UTC (permalink / raw)
  To: Adrian Ratiu; +Cc: Junio C Hamano, rsbecker, git

On Wed, Apr 08, 2026 at 08:01:25PM +0300, Adrian Ratiu wrote:

> > It sounds sensible, but a standalone fix early before 2.54 final, as
> > the problem and the fix shown by Peff here looked correct, without
> > waiting for NonStop may be simpler to work with.  Then, rebuild
> > parallel series on top of the 'master' that has the fix applied,
> > perhaps?
> 
> Yes, that is the path forward now that Randall also confirmed the fix
> works on NonStop (btw thank you Randall). :)
> 
> Just waiting for Peff to tell me if he wants to send it himself.

I just sent out the fix patch, which should be good for 2.54. Here's the
test patch, which I hope you'll include when re-rolling the parallel
series (either as-is, or if you prefer it can be moved to another script
where we're doing other parallel hook tests).

It would be nice to refer to the fix commit using its id, but we won't
know what it is until Junio applies it. :) So once that happens it might
be worth tweaking the commit message.

-- >8 --
Subject: t5401: test SIGPIPE with parallel hooks

We recently fixed a bug where a hook that caused us to get SIGPIPE would
accidentally trigger the run_processes_parallel() cleanup handler,
killing the child processes.

For a single hook, this meant killing the already-exited hook. This case
was triggered by our tests, but was only a problem on some platforms.

But if you have multiple hooks running in parallel, this causes a
problem everywhere, since one hook failing to read its input would take
down all hooks. Now that we have parallel hook support, we can add a
test for this case. It should pass already, due to the existing fix.

Signed-off-by: Jeff King <peff@peff.net>
---
 t/t5401-update-hooks.sh | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh
index 44ec875aef..f727b5d545 100755
--- a/t/t5401-update-hooks.sh
+++ b/t/t5401-update-hooks.sh
@@ -139,4 +139,42 @@ test_expect_success 'pre-receive hook that forgets to read its input' '
 	git push ./victim.git "+refs/heads/*:refs/heads/*"
 '
 
+test_expect_success 'hooks in parallel that do not read input' '
+	# Add this to our $PATH to avoid having to write the whole trash
+	# directory into our config options, which would require quoting.
+	mkdir bin &&
+	PATH=$PWD/bin:$PATH &&
+
+	write_script bin/hook-fast <<-\EOF &&
+	# This hook does not read its input, so the parent process
+	# may see SIGPIPE if it is not ignored. It should happen
+	# relatively quickly.
+	exit 0
+	EOF
+
+	write_script bin/hook-slow <<-\EOF &&
+	# This hook is slow, so we expect it to still be running
+	# when the other hook has exited (and the parent has a pipe error
+	# writing to it).
+	#
+	# So we want to be slow enough that we expect this to happen, but not
+	# so slow that the test takes forever. 1 second is probably enough
+	# in practice (and if it is occasionally not on a loaded system, we
+	# will err on the side of having the test pass).
+	sleep 1
+	exit 0
+	EOF
+
+	git init --bare parallel.git &&
+	git -C parallel.git config hook.fast.command "hook-fast" &&
+	git -C parallel.git config hook.fast.event pre-receive &&
+	git -C parallel.git config hook.fast.parallel true &&
+	git -C parallel.git config hook.slow.command "hook-slow" &&
+	git -C parallel.git config hook.slow.event pre-receive &&
+	git -C parallel.git config hook.slow.parallel true &&
+	git -C parallel.git config hook.jobs 2 &&
+
+	git push ./parallel.git "+refs/heads/*:refs/heads/*"
+'
+
 test_done
-- 
2.54.0.rc1.274.g1f8c576c50


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling
  2026-04-08 17:20       ` [PATCH] run_processes_parallel(): fix order of sigpipe handling Jeff King
@ 2026-04-08 17:59         ` Junio C Hamano
  2026-04-08 20:54           ` Junio C Hamano
  0 siblings, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2026-04-08 17:59 UTC (permalink / raw)
  To: Jeff King; +Cc: Adrian Ratiu, rsbecker, git

Jeff King <peff@peff.net> writes:

> We can fix it by reordering the code a bit. We should run pp_init()
> first, and then push our SIG_IGN onto the stack afterwards, so that it
> is truly ignored while feeding the sub-processes.
>
> Note that we also reorder the popping at the end of the function, too.
> This is not technically necessary, as we are doing two pops either way,
> but now the pops will correctly match their pushes.

Sounds quite sensible.

> This also fixes a related case that we can't test yet. If we did have
> more than one process to run, then one child causing SIGPIPE would cause
> us to kill() all of the children (which might still actually be
> running). But the hook API is the only user of the new feed_pipe
> feature, and it does not yet support parallel hook execution. So for now
> we'll always execute the processes sequentially. Once parallel hook
> execution exists, we'll be able to add a test which covers this.

Great.

> Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
> Signed-off-by: Jeff King <peff@peff.net>

Thanks, all of you, for addressing the issue so quickly.

Applied.

> ---
>  run-command.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/run-command.c b/run-command.c
> index 32c290ee6a..574d5c40f0 100644
> --- a/run-command.c
> +++ b/run-command.c
> @@ -1895,14 +1895,19 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
>  					   "max:%"PRIuMAX,
>  					   (uintmax_t)opts->processes);
>  
> +	pp_init(&pp, opts, &pp_sig);
> +
>  	/*
>  	 * Child tasks might receive input via stdin, terminating early (or not), so
>  	 * ignore the default SIGPIPE which gets handled by each feed_pipe_fn which
>  	 * actually writes the data to children stdin fds.
> +	 *
> +	 * This _must_ come after pp_init(), because it installs its own
> +	 * SIGPIPE handler (to cleanup children), and we want to supersede
> +	 * that.
>  	 */
>  	sigchain_push(SIGPIPE, SIG_IGN);
>  
> -	pp_init(&pp, opts, &pp_sig);
>  	while (1) {
>  		for (i = 0;
>  		    i < spawn_cap && !pp.shutdown &&
> @@ -1928,10 +1933,10 @@ void run_processes_parallel(const struct run_process_parallel_opts *opts)
>  		}
>  	}
>  
> -	pp_cleanup(&pp, opts);
> -
>  	sigchain_pop(SIGPIPE);
>  
> +	pp_cleanup(&pp, opts);
> +
>  	if (do_trace2)
>  		trace2_region_leave(tr2_category, tr2_label, NULL);
>  }

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling
  2026-04-08 17:59         ` Junio C Hamano
@ 2026-04-08 20:54           ` Junio C Hamano
  2026-04-08 23:42             ` Jeff King
  0 siblings, 1 reply; 18+ messages in thread
From: Junio C Hamano @ 2026-04-08 20:54 UTC (permalink / raw)
  To: Jeff King; +Cc: Adrian Ratiu, rsbecker, git

Junio C Hamano <gitster@pobox.com> writes:

>> Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
>> Signed-off-by: Jeff King <peff@peff.net>
>
> Thanks, all of you, for addressing the issue so quickly.
>
> Applied.

We have a few places where we sigchain_push(SIGPIPE, SIG_IGN) then
run start_command().  One is in upload-pack.c where we spawn
"rev-list" for reachability check, and the other is in fetch-pack.c
where we spawn unpack-objects/index-pack.

Currently neither subprocess is marked with the clean-on-exit bit.
but if somebody is careless and flips the bit for these
subprocesses, start_command() will call mark_child_for_cleanup() and
causes sigchain_push_common() to set up cleanup_children_on_signal()
to be called, which would lead to a very similar bug.

I wonder if swapping the order of start_command() and sigchain_push()
in these two code paths have downsides, or is it making the code worse
just to futureproof it against a future that is unlikely to come?


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling
  2026-04-08 20:54           ` Junio C Hamano
@ 2026-04-08 23:42             ` Jeff King
  2026-04-09 13:40               ` Junio C Hamano
  0 siblings, 1 reply; 18+ messages in thread
From: Jeff King @ 2026-04-08 23:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Adrian Ratiu, rsbecker, git

On Wed, Apr 08, 2026 at 01:54:26PM -0700, Junio C Hamano wrote:

> Junio C Hamano <gitster@pobox.com> writes:
> 
> >> Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
> >> Signed-off-by: Jeff King <peff@peff.net>
> >
> > Thanks, all of you, for addressing the issue so quickly.
> >
> > Applied.
> 
> We have a few places where we sigchain_push(SIGPIPE, SIG_IGN) then
> run start_command().  One is in upload-pack.c where we spawn
> "rev-list" for reachability check, and the other is in fetch-pack.c
> where we spawn unpack-objects/index-pack.
> 
> Currently neither subprocess is marked with the clean-on-exit bit.
> but if somebody is careless and flips the bit for these
> subprocesses, start_command() will call mark_child_for_cleanup() and
> causes sigchain_push_common() to set up cleanup_children_on_signal()
> to be called, which would lead to a very similar bug.

Hmm, good catch. This is a bit worrisome, as we've added some
clean_on_exit calls recently, and might do so again.

> I wonder if swapping the order of start_command() and sigchain_push()
> in these two code paths have downsides, or is it making the code worse
> just to futureproof it against a future that is unlikely to come?

I don't think it's really making the code worse. It's putting the
SIGPIPE handling closer to where we're actually doing the writes. But I
don't like that it is a subtle thing that people writing new code have
to worry about. And I wouldn't be surprised if there are other cases
where we disable SIGPIPE, and then call start_command() in a much lower
level of the call chain, which would make reordering harder.

I wonder if we can do better.

The root of the issue is that sigchain_push_common() is not really
expressing what we want. We are trying to install a handler to do
cleanup _if_ we are about to exit. And that is always going to be true
for SIGTERM, etc, where we might install handlers but never expect them
to rescue us from exiting. But for SIGPIPE, our desired action is really
dependent on whether the signal is being ignored in general.

So we could perhaps do something like this:

diff --git a/sigchain.c b/sigchain.c
index 66123bdbab..343b5571e0 100644
--- a/sigchain.c
+++ b/sigchain.c
@@ -16,7 +16,7 @@ static void check_signum(int sig)
 		BUG("signal out of range: %d", sig);
 }
 
-int sigchain_push(int sig, sigchain_fun f)
+static int sigchain_push_1(int sig, sigchain_fun f, int keep_ignored)
 {
 	struct sigchain_signal *s = signals + sig;
 	check_signum(sig);
@@ -25,10 +25,24 @@ int sigchain_push(int sig, sigchain_fun f)
 	s->old[s->n] = signal(sig, f);
 	if (s->old[s->n] == SIG_ERR)
 		return -1;
+	if (keep_ignored && s->old[s->n] == SIG_IGN) {
+		/*
+		 * The signal was already ignored; keep it that way
+		 * rather than installing a handler which would be used
+		 * for cleanup.
+		 */
+		if (signal(sig, SIG_IGN) < 0)
+			return -1;
+	}
 	s->n++;
 	return 0;
 }
 
+int sigchain_push(int sig, sigchain_fun f)
+{
+	return sigchain_push_1(sig, f, 0);
+}
+
 int sigchain_pop(int sig)
 {
 	struct sigchain_signal *s = signals + sig;
@@ -48,7 +62,7 @@ void sigchain_push_common(sigchain_fun f)
 	sigchain_push(SIGHUP, f);
 	sigchain_push(SIGTERM, f);
 	sigchain_push(SIGQUIT, f);
-	sigchain_push(SIGPIPE, f);
+	sigchain_push_1(SIGPIPE, f, 1);
 }
 
 void sigchain_pop_common(void)


And that turns the handler setup in pp_init() into a noop (for SIGPIPE),
since it sees that we're ignoring the signal already. But I think this
isn't quite enough for the cases in start_command(), which have
something even deeper going on.

The handler we set up in mark_child_for_cleanup() is _never_ popped. The
idea is that we install it once for the first child which needs it, and
then the rest of the invocations just add to the cleanup list. But that
breaks the push/pop paradigm if it's interleaved with other calls. I.e.,
if we do:

  sigchain_push(SIGPIPE, SIG_IGN);
  child.clean_on_exit = 1;
  start_command(&child);
  sigchain_pop(SIGPIPE);

then that pop is not popping SIG_IGN. It's popping the cleanup handler
installed by start_command! So now we're ignoring SIGPIPE forever for
the rest of the process.

To fix that I think we have to reconsider the push/pop idea for signals.
I suspect the semantics we want are more like:

  - Individual subsystems may register a cleanup handler, but may never
    remove it. Handlers should recognize when they have no work to do
    and return (because they have their own lists of children to clean
    up, temporary files to remove, and so forth).

  - When a cleanup handler is registered, we add it to a linked list and
    register _one_ signal handler that iterates over the list, calling
    each cleanup handler that has been registered.

  - You can't install "ignore" or SIG_IGN as a cleanup handler. But...

  - Code can push/pop an "ignore" flag for a given signal. If a signal
    is marked as ignored, then that supersedes all cleanup handlers. It
    can be implemented either with SIG_IGN, or the signal handler can
    just return from the handler without exiting.

That's a total rewrite of our signal handling, though. There might be
details I haven't considered.

As a stop-gap, I think one smaller thing we could do is just register
all of those one-off handlers (like the one for start_command()) at the
beginning of the program, via init_git() or similar. And then they're at
the bottom of the sigchain stack, so they're never interleaved with
other push/pop calls.  That's kind of horrible, but I don't think there
are so many that it's the end of the world.

All of that is out-of-scope for -rc2, though. ;)

-Peff

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH] run_processes_parallel(): fix order of sigpipe handling
  2026-04-08 23:42             ` Jeff King
@ 2026-04-09 13:40               ` Junio C Hamano
  0 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2026-04-09 13:40 UTC (permalink / raw)
  To: Jeff King; +Cc: Adrian Ratiu, rsbecker, git

Jeff King <peff@peff.net> writes:

>> Currently neither subprocess is marked with the clean-on-exit bit.
>> but if somebody is careless and flips the bit for these
>> subprocesses, start_command() will call mark_child_for_cleanup() and
>> causes sigchain_push_common() to set up cleanup_children_on_signal()
>> to be called, which would lead to a very similar bug.
>
> Hmm, good catch. This is a bit worrisome, as we've added some
> clean_on_exit calls recently, and might do so again.
>
>> I wonder if swapping the order of start_command() and sigchain_push()
>> in these two code paths have downsides, or is it making the code worse
>> just to futureproof it against a future that is unlikely to come?
>
> I don't think it's really making the code worse. It's putting the
> SIGPIPE handling closer to where we're actually doing the writes. But I
> don't like that it is a subtle thing that people writing new code have
> to worry about. And I wouldn't be surprised if there are other cases
> where we disable SIGPIPE, and then call start_command() in a much lower
> level of the call chain, which would make reordering harder.

OK.  Such a change is easy, compared to anything we try to do better
;-).

> I wonder if we can do better.
>
> The root of the issue is that sigchain_push_common() is not really
> expressing what we want. We are trying to install a handler to do
> cleanup _if_ we are about to exit. And that is always going to be true
> for SIGTERM, etc, where we might install handlers but never expect them
> to rescue us from exiting. But for SIGPIPE, our desired action is really
> dependent on whether the signal is being ignored in general.

Hmph, I actually was hoping that we do not have to go in the route
that each specific signal differently, but I guess it is unavoidable
as they come with their own semantics (somewhat similar to the way
how their default disposition has to be different).

> That's a total rewrite of our signal handling, though. There might be
> details I haven't considered.
>
> All of that is out-of-scope for -rc2, though. ;)

Of course.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2026-04-09 13:40 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 23:37 Help needed on 2.54.0-rc0 t5301.13 looping rsbecker
2026-04-08  5:20 ` Jeff King
2026-04-08  5:43   ` Jeff King
2026-04-08 11:53     ` Adrian Ratiu
2026-04-08 15:44       ` rsbecker
2026-04-08 15:52       ` rsbecker
2026-04-08 15:55       ` rsbecker
2026-04-08 16:53       ` Junio C Hamano
2026-04-08 16:58         ` rsbecker
2026-04-08 17:01         ` Adrian Ratiu
2026-04-08 17:30           ` [PATCH] t5401: test SIGPIPE with parallel hooks Jeff King
2026-04-08 15:50   ` Help needed on 2.54.0-rc0 t5301.13 looping Junio C Hamano
2026-04-08 16:26     ` Adrian Ratiu
2026-04-08 17:20       ` [PATCH] run_processes_parallel(): fix order of sigpipe handling Jeff King
2026-04-08 17:59         ` Junio C Hamano
2026-04-08 20:54           ` Junio C Hamano
2026-04-08 23:42             ` Jeff King
2026-04-09 13:40               ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox