Skip to content

Commit 031062d

Browse files
committed
Merge branch 'er/fast-import-dump-refs-on-checkpoint' into maint
The checkpoint command "git fast-import" did not flush updates to refs and marks unless at least one object was created since the last checkpoint, which has been corrected, as these things can happen without any new object getting created. * er/fast-import-dump-refs-on-checkpoint: fast-import: checkpoint: dump branches/tags/marks even if object_count==0
2 parents 120ce97 + 30e215a commit 031062d

File tree

2 files changed

+145
-3
lines changed

2 files changed

+145
-3
lines changed

fast-import.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,10 +3188,10 @@ static void checkpoint(void)
31883188
checkpoint_requested = 0;
31893189
if (object_count) {
31903190
cycle_packfile();
3191-
dump_branches();
3192-
dump_tags();
3193-
dump_marks();
31943191
}
3192+
dump_branches();
3193+
dump_tags();
3194+
dump_marks();
31953195
}
31963196

31973197
static void parse_checkpoint(void)

t/t9300-fast-import.sh

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
31233265
test_done

0 commit comments

Comments
 (0)