commit f1e81a0517df837593350dd932e813563bdc01b8 from: Stefan Sperling date: Sat Aug 10 14:57:20 2019 UTC fix bug where 'revert -p' would delete all lines following a reverted change commit - ce2b05c76c2655b619f516e32f44a54d0c8741db commit + f1e81a0517df837593350dd932e813563bdc01b8 blob - d648267d6824b041a3d797dc1d2f990cabb398f4 blob + 96f3f30acc3bcc3a5744cb446aac8bca252f8574 --- lib/worktree.c +++ lib/worktree.c @@ -2893,7 +2893,7 @@ copy_change(FILE *f1, FILE *f2, int *line_cur1, int *l (*line_cur2)++; } /* Skip over old file's replaced lines. */ - while (!feof(f1) && *line_cur1 <= end_new) { + while (!feof(f1) && *line_cur1 <= end_old) { if (rejectfile) err = copy_one_line(f1, NULL, rejectfile); else @@ -2902,12 +2902,33 @@ copy_change(FILE *f1, FILE *f2, int *line_cur1, int *l return err; (*line_cur1)++; } - /* Copy old file's lines after patch. */ - while (!feof(f1) && *line_cur1 <= end_old) { - err = copy_one_line(f1, outfile, rejectfile); - if (err) - return err; - (*line_cur1)++; + + return NULL; +} + +static const struct got_error * +copy_remaining_content(FILE *f1, FILE *f2, int *line_cur1, int *line_cur2, + FILE *outfile, FILE *rejectfile) +{ + const struct got_error *err; + + if (outfile) { + /* Copy old file's lines until EOF. */ + while (!feof(f1)) { + err = copy_one_line(f1, outfile, NULL); + if (err) + return err; + (*line_cur1)++; + } + } + if (rejectfile) { + /* Copy new file's lines until EOF. */ + while (!feof(f2)) { + err = copy_one_line(f2, NULL, rejectfile); + if (err) + return err; + (*line_cur2)++; + } } return NULL; @@ -2968,24 +2989,6 @@ apply_or_reject_change(int *choice, struct got_diff_ch end_old, start_new, end_new, rejectfile, outfile); break; case GOT_PATCH_CHOICE_QUIT: - if (outfile) { - /* Copy old file's lines until EOF. */ - while (!feof(f1)) { - err = copy_one_line(f1, outfile, NULL); - if (err) - goto done; - (*line_cur1)++; - } - } - if (rejectfile) { - /* Copy new file's lines until EOF. */ - while (!feof(f2)) { - err = copy_one_line(f2, NULL, rejectfile); - if (err) - goto done; - (*line_cur2)++; - } - } break; default: err = got_error(GOT_ERR_PATCH_CHOICE); @@ -3086,6 +3089,10 @@ create_patched_content(char **path_outfile, int revers else if (choice == GOT_PATCH_CHOICE_QUIT) break; } + if (have_content) + err = copy_remaining_content(f1, f2, &line_cur1, &line_cur2, + reverse_patch ? NULL : outfile, + reverse_patch ? outfile : NULL); done: free(id_str); if (blob) @@ -5882,6 +5889,9 @@ create_unstaged_content(char **path_unstaged_content, if (choice == GOT_PATCH_CHOICE_QUIT) break; } + if (have_content || have_rejected_content) + err = copy_remaining_content(f1, f2, &line_cur1, &line_cur2, + outfile, rejectfile); done: free(label1); if (blob) blob - e2eeccfccbcc07ff559c411508ff3c8e31f59918 blob + d66beb7f0760252ff97e00a9b4415b40cf50049b --- regress/cmdline/revert.sh +++ regress/cmdline/revert.sh @@ -793,7 +793,75 @@ function test_revert_patch_removed { fi test_done "$testroot" "$ret" } + +function test_revert_patch_one_change { + local testroot=`test_init revert_patch_one_change` + + jot 16 > $testroot/repo/numbers + (cd $testroot/repo && git add numbers) + git_commit $testroot/repo -m "added numbers file" + local commit_id=`git_show_head $testroot/repo` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret="$?" + if [ "$ret" != "0" ]; then + test_done "$testroot" "$ret" + return 1 + fi + + sed -i -e 's/^2$/a/' $testroot/wt/numbers + # revert change with -p + printf "y\n" > $testroot/patchscript + (cd $testroot/wt && got revert -F $testroot/patchscript -p \ + numbers > $testroot/stdout) + ret="$?" + if [ "$ret" != "0" ]; then + echo "got revert command failed unexpectedly" >&2 + test_done "$testroot" "1" + return 1 + fi + cat > $testroot/stdout.expected < $testroot/stdout) + echo -n > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/wt && got diff > $testroot/stdout) + echo -n > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" +} + run_test test_revert_basic run_test test_revert_rm run_test test_revert_add @@ -804,3 +872,4 @@ run_test test_revert_directory run_test test_revert_patch run_test test_revert_patch_added run_test test_revert_patch_removed +run_test test_revert_patch_one_change