sequencer: notify user of --update-refs activity

When the user runs 'git rebase -i --update-refs', the end message still says only Successfully rebased and updated <HEAD-ref>. Update the sequencer to collect the successful (and unsuccessful) ref updates due to the --update-refs option, so the end message now says Successfully rebased and updated <HEAD-ref>. Updated the following refs with --update-refs: refs/heads/first refs/heads/third Failed to update the following refs with --update-refs: refs/heads/second To test this output, we need to be very careful to format the expected error to drop the leading tab characters. Also, we need to be aware that the verbose output from 'git rebase' is writing progress lines which don't use traditional newlines but clear the line after every progress item is complete. When opening the error file in an editor, these lines are visible, but when looking at the diff in a terminal those lines disappear because of the characters that delete the previous characters. Use 'sed' to clear those progress lines and clear the tabs so we can get an exact match on our expected output. Reported-by: Elijah Newren <newren@gmail.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Jul 19, 2022 at 18:33 UTC 4611884ea883908a9638cafbd824c401c41cf7f6
2 files changed +67 -10
sequencer.c
+34 -6
@@ -4286,26 +4286,54 @@ static int do_update_ref(struct repository *r, const char *refname)
4286 return 0;
4287 }
4288
4289 -static int do_update_refs(struct repository *r)
4289 +static int do_update_refs(struct repository *r, int quiet)
4290 {
4291 int res = 0;
4292 struct string_list_item *item;
4293 struct string_list refs_to_oids = STRING_LIST_INIT_DUP;
4294 struct ref_store *refs = get_main_ref_store(r);
4295 + struct strbuf update_msg = STRBUF_INIT;
4296 + struct strbuf error_msg = STRBUF_INIT;
4297
4298 if ((res = sequencer_get_update_refs_state(r->gitdir, &refs_to_oids)))
4299 return res;
4300
4301 for_each_string_list_item(item, &refs_to_oids) {
4302 struct update_ref_record *rec = item->util;
4303 + int loop_res;
4304
4302 - res |= refs_update_ref(refs, "rewritten during rebase",
4303 - item->string,
4304 - &rec->after, &rec->before,
4305 - 0, UPDATE_REFS_MSG_ON_ERR);
4305 + loop_res = refs_update_ref(refs, "rewritten during rebase",
4306 + item->string,
4307 + &rec->after, &rec->before,
4308 + 0, UPDATE_REFS_MSG_ON_ERR);
4309 + res |= loop_res;
4310 +
4311 + if (quiet)
4312 + continue;
4313 +
4314 + if (loop_res)
4315 + strbuf_addf(&error_msg, "\t%s\n", item->string);
4316 + else
4317 + strbuf_addf(&update_msg, "\t%s\n", item->string);
4318 + }
4319 +
4320 + if (!quiet &&
4321 + (update_msg.len || error_msg.len)) {
4322 + fprintf(stderr,
4323 + _("Updated the following refs with %s:\n%s"),
4324 + "--update-refs",
4325 + update_msg.buf);
4326 +
4327 + if (res)
4328 + fprintf(stderr,
4329 + _("Failed to update the following refs with %s:\n%s"),
4330 + "--update-refs",
4331 + error_msg.buf);
4332 }
4333
4334 string_list_clear(&refs_to_oids, 1);
4335 + strbuf_release(&update_msg);
4336 + strbuf_release(&error_msg);
4337 return res;
4338 }
4339
@@ -4826,7 +4854,7 @@ cleanup_head_ref:
4854 strbuf_release(&buf);
4855 strbuf_release(&head_ref);
4856
4829 - if (do_update_refs(r))
4857 + if (do_update_refs(r, opts->quiet))
4858 return -1;
4859 }
4860
t/t3404-rebase-interactive.sh
+33 -4
@@ -1840,12 +1840,26 @@ test_expect_success '--update-refs updates refs correctly' '
1840 test_commit extra2 fileX &&
1841 git commit --amend --fixup=L &&
1842
1843 - git rebase -i --autosquash --update-refs primary &&
1843 + git rebase -i --autosquash --update-refs primary 2>err &&
1844
1845 test_cmp_rev HEAD~3 refs/heads/first &&
1846 test_cmp_rev HEAD~3 refs/heads/second &&
1847 test_cmp_rev HEAD~1 refs/heads/third &&
1848 - test_cmp_rev HEAD refs/heads/no-conflict-branch
1848 + test_cmp_rev HEAD refs/heads/no-conflict-branch &&
1849 +
1850 + cat >expect <<-\EOF &&
1851 + Successfully rebased and updated refs/heads/update-refs.
1852 + Updated the following refs with --update-refs:
1853 + refs/heads/first
1854 + refs/heads/no-conflict-branch
1855 + refs/heads/second
1856 + refs/heads/third
1857 + EOF
1858 +
1859 + # Clear "Rebasing (X/Y)" progress lines and drop leading tabs.
1860 + sed -e "s/Rebasing.*Successfully/Successfully/g" -e "s/^\t//g" \
1861 + <err >err.trimmed &&
1862 + test_cmp expect err.trimmed
1863 '
1864
1865 test_expect_success 'respect user edits to update-ref steps' '
@@ -1983,8 +1997,23 @@ test_expect_success '--update-refs: check failed ref update' '
1997 # the lock in the update-refs file.
1998 git rev-parse third >.git/refs/heads/second &&
1999
1986 - git rebase --continue 2>err &&
1987 - grep "update_ref failed for ref '\''refs/heads/second'\''" err
2000 + test_must_fail git rebase --continue 2>err &&
2001 + grep "update_ref failed for ref '\''refs/heads/second'\''" err &&
2002 +
2003 + cat >expect <<-\EOF &&
2004 + Updated the following refs with --update-refs:
2005 + refs/heads/first
2006 + refs/heads/no-conflict-branch
2007 + refs/heads/third
2008 + Failed to update the following refs with --update-refs:
2009 + refs/heads/second
2010 + EOF
2011 +
2012 + # Clear "Rebasing (X/Y)" progress lines and drop leading tabs.
2013 + tail -n 6 err >err.last &&
2014 + sed -e "s/Rebasing.*Successfully/Successfully/g" -e "s/^\t//g" \
2015 + <err.last >err.trimmed &&
2016 + test_cmp expect err.trimmed
2017 '
2018
2019 # This must be the last test in this file