@@ -3120,4 +3120,146 @@ test_expect_success 'U: validate root delete result' '
31203120 compare_diff_raw expect actual
31213121'
31223122
3123+ # ##
3124+ # ## series V (checkpoint)
3125+ # ##
3126+
3127+ # The commands in input_file should not produce any output on the file
3128+ # descriptor set with --cat-blob-fd (or stdout if unspecified).
3129+ #
3130+ # To make sure you're observing the side effects of checkpoint *before*
3131+ # fast-import terminates (and thus writes out its state), check that the
3132+ # fast-import process is still running using background_import_still_running
3133+ # *after* evaluating the test conditions.
3134+ background_import_then_checkpoint () {
3135+ options=$1
3136+ input_file=$2
3137+
3138+ mkfifo V.input
3139+ exec 8<> V.input
3140+ rm V.input
3141+
3142+ mkfifo V.output
3143+ exec 9<> V.output
3144+ rm V.output
3145+
3146+ git fast-import $options < & 8 >&9 &
3147+ echo $! > V.pid
3148+ # We don't mind if fast-import has already died by the time the test
3149+ # ends.
3150+ test_when_finished " exec 8>&-; exec 9>&-; kill $( cat V.pid) || true"
3151+
3152+ # Start in the background to ensure we adhere strictly to (blocking)
3153+ # pipes writing sequence. We want to assume that the write below could
3154+ # block, e.g. if fast-import blocks writing its own output to &9
3155+ # because there is no reader on &9 yet.
3156+ (
3157+ cat " $input_file "
3158+ echo " checkpoint"
3159+ echo " progress checkpoint"
3160+ ) >&8 &
3161+
3162+ error=1 ; # assume the worst
3163+ while read output < & 9
3164+ do
3165+ if test " $output " = " progress checkpoint"
3166+ then
3167+ error=0
3168+ break
3169+ fi
3170+ # otherwise ignore cruft
3171+ echo >&2 " cruft: $output "
3172+ done
3173+
3174+ if test $error -eq 1
3175+ then
3176+ false
3177+ fi
3178+ }
3179+
3180+ background_import_still_running () {
3181+ if ! kill -0 " $( cat V.pid) "
3182+ then
3183+ echo >&2 " background fast-import terminated too early"
3184+ false
3185+ fi
3186+ }
3187+
3188+ test_expect_success PIPE ' V: checkpoint helper does not get stuck with extra output' '
3189+ cat >input <<-INPUT_END &&
3190+ progress foo
3191+ progress bar
3192+
3193+ INPUT_END
3194+
3195+ background_import_then_checkpoint "" input &&
3196+ background_import_still_running
3197+ '
3198+
3199+ test_expect_success PIPE ' V: checkpoint updates refs after reset' '
3200+ cat >input <<-\INPUT_END &&
3201+ reset refs/heads/V
3202+ from refs/heads/U
3203+
3204+ INPUT_END
3205+
3206+ background_import_then_checkpoint "" input &&
3207+ test "$(git rev-parse --verify V)" = "$(git rev-parse --verify U)" &&
3208+ background_import_still_running
3209+ '
3210+
3211+ test_expect_success PIPE ' V: checkpoint updates refs and marks after commit' '
3212+ cat >input <<-INPUT_END &&
3213+ commit refs/heads/V
3214+ mark :1
3215+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3216+ data 0
3217+ from refs/heads/U
3218+
3219+ INPUT_END
3220+
3221+ background_import_then_checkpoint "--export-marks=marks.actual" input &&
3222+
3223+ echo ":1 $(git rev-parse --verify V)" >marks.expected &&
3224+
3225+ test "$(git rev-parse --verify V^)" = "$(git rev-parse --verify U)" &&
3226+ test_cmp marks.expected marks.actual &&
3227+ background_import_still_running
3228+ '
3229+
3230+ # Re-create the exact same commit, but on a different branch: no new object is
3231+ # created in the database, but the refs and marks still need to be updated.
3232+ test_expect_success PIPE ' V: checkpoint updates refs and marks after commit (no new objects)' '
3233+ cat >input <<-INPUT_END &&
3234+ commit refs/heads/V2
3235+ mark :2
3236+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3237+ data 0
3238+ from refs/heads/U
3239+
3240+ INPUT_END
3241+
3242+ background_import_then_checkpoint "--export-marks=marks.actual" input &&
3243+
3244+ echo ":2 $(git rev-parse --verify V2)" >marks.expected &&
3245+
3246+ test "$(git rev-parse --verify V2)" = "$(git rev-parse --verify V)" &&
3247+ test_cmp marks.expected marks.actual &&
3248+ background_import_still_running
3249+ '
3250+
3251+ test_expect_success PIPE ' V: checkpoint updates tags after tag' '
3252+ cat >input <<-INPUT_END &&
3253+ tag Vtag
3254+ from refs/heads/V
3255+ tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3256+ data 0
3257+
3258+ INPUT_END
3259+
3260+ background_import_then_checkpoint "" input &&
3261+ git show-ref -d Vtag &&
3262+ background_import_still_running
3263+ '
3264+
31233265test_done
0 commit comments