From: Phillip Wood Date: Tue, 04 Oct 2022 16:00:25 GMT Subject: Re: [PATCH 00/10] Add the Git Change command Message-ID: <4b09dadf-7b56-fecd-02c0-08fec8b9bd12@dunelm.org.uk> In-Reply-To: On 04/10/2022 16:55, Chris P wrote: > I got the tests to work, except the last one, that one fails. > > How can I see the output of actual and expect? If you run the test with -i then it will stop at the first failure and you can inspect the files in the directory 'trash directory.t9999-changes'. Running with -v (verbose) -x (shell tracing) is also useful when debugging. Phillip > On Tue, Oct 4, 2022 at 5:19 PM Chris P wrote: >> >> Thanks a lot. >> >> Is there something special I must do to get these scripts to work? The >> entire script fails for me, despite having build git-change. >> >> On Tue, Oct 4, 2022 at 4:24 PM Phillip Wood wrote: >>> >>> Hi Chris >>> >>> On 23/09/2022 19:55, Christophe Poucet via GitGitGadget wrote: >>>> I'm reviving the original git evolve work that was started by >>>> sxenos@google.com >>>> (https://public-inbox.org/git/20190215043105.163688-1-sxenos@google.com/) >>>> >>>> This work is intended to make it easier to deal with stacked changes. >>>> >>>> The following set of patches introduces the design doc on the evolve command >>>> as well as the basics of the git change command. >>> >>> Our test suite can be a little tricky to get started with and I was impatient to >>> check the basic functionality of these patches so I've written some simple >>> example tests for the change command and a couple of fixups to make them pass. >>> >>> Best Wishes >>> >>> Phillip >>> >>> ---- >8 ---- >>> >>> From a7c38d0f388e4d8a1f3debcc3069a7fb43084eda Mon Sep 17 00:00:00 2001 >>> From: Phillip Wood >>> Date: Tue, 4 Oct 2022 15:12:36 +0100 >>> Subject: [PATCH 1/3] fixup! evolve: add support for writing metacommits >>> >>> --- >>> metacommit.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/metacommit.c b/metacommit.c >>> index d2b859a4d3..8f970fa104 100644 >>> --- a/metacommit.c >>> +++ b/metacommit.c >>> @@ -296,7 +296,7 @@ int record_metacommit_withresult( >>> if (override_change) { >>> string_list_clear(changes, 0); >>> overridden_head = get_change_head(chtable, override_change); >>> - if (!overridden_head) { >>> + if (overridden_head) { >>> /* This is an existing change */ >>> old_head = &overridden_head->head; >>> if (!force) { >>> -- >>> 2.37.3.947.g1b8ba4da7f.dirty >>> >>> >>> From cc7e8ba0b1a90268ced85d3f0c91aed49f2246d6 Mon Sep 17 00:00:00 2001 >>> From: Phillip Wood >>> Date: Tue, 4 Oct 2022 15:15:32 +0100 >>> Subject: [PATCH 2/3] fixup! evolve: implement the git change command >>> >>> --- >>> t/t9999-changes.sh | 126 +++++++++++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 126 insertions(+) >>> create mode 100755 t/t9999-changes.sh >>> >>> diff --git a/t/t9999-changes.sh b/t/t9999-changes.sh >>> new file mode 100755 >>> index 0000000000..9e58925b23 >>> --- /dev/null >>> +++ b/t/t9999-changes.sh >>> @@ -0,0 +1,126 @@ >>> +#!/bin/sh >>> + >>> +test_description='git change - low level meta-commit management' >>> + >>> +. ./test-lib.sh >>> + >>> +. "$TEST_DIRECTORY"/lib-rebase.sh >>> + >>> +test_expect_success 'setup commits and meta-commits' ' >>> + for c in one two three >>> + do >>> + test_commit $c && >>> + git change update --content $c >actual 2>err && >>> + echo "Created change metas/$c" >expect && >>> + test_cmp expect actual && >>> + test_must_be_empty err && >>> + test_cmp_rev refs/metas/$c $c || return 1 >>> + done >>> +' >>> + >>> +# Check a meta-commit has the correct parents Call with the object >>> +# name of the meta-commit followed by pairs of type and parent >>> +check_meta_commit () { >>> + name=$1 >>> + shift >>> + while test $# -gt 0 >>> + do >>> + printf '%s %s\n' $1 $(git rev-parse --verify $2) >>> + shift >>> + shift >>> + done | sort >expect >>> + git cat-file commit $name >metacommit && >>> + # commit body should consist of parent-type >>> + types="$(sed -n '/^$/ { >>> + :loop >>> + n >>> + s/^parent-type // >>> + p >>> + b loop >>> + }' metacommit)" && >>> + while read key value >>> + do >>> + # TODO: don't sort the first parent >>> + if test "$key" = "parent" >>> + then >>> + type="${types%% *}" >>> + test -n "$type" || return 1 >>> + printf '%s %s\n' $type $value >>> + types="${types#?}" >>> + types="${types# }" >>> + elif test "$key" = "tree" >>> + then >>> + test_cmp_rev "$value" $EMPTY_TREE || return 1 >>> + elif test -z "$key" >>> + then >>> + # only parse commit headers >>> + break >>> + fi >>> + done actual-unsorted && >>> + test -z "$types" && >>> + sort >actual >> + test_cmp expect actual >>> +} >>> + >>> +test_expect_success 'update meta-commits after rebase' ' >>> + ( >>> + set_fake_editor && >>> + FAKE_AMEND=edited && >>> + FAKE_LINES="reword 1 pick 2 fixup 3" && >>> + export FAKE_AMEND FAKE_LINES && >>> + git rebase -i --root >>> + ) && >>> + >>> + # update meta-commits >>> + git change update --replace tags/one --content HEAD~1 >out 2>err && >>> + echo "Updated change metas/one" >expect && >>> + test_cmp expect out && >>> + test_must_be_empty err && >>> + git change update --replace tags/two --content HEAD@{2} && >>> + oid=$(git rev-parse --verify metas/two) && >>> + git change update --replace HEAD@{2} --replace tags/three \ >>> + --content HEAD && >>> + >>> + # check meta-commits >>> + check_meta_commit metas/one c HEAD~1 r tags/one && >>> + check_meta_commit $oid c HEAD@{2} r tags/two && >>> + # NB this checks that "git change update" uses the meta-commit ($oid) >>> + # corresponding to the replaces commit (HEAD@2 above) given on the >>> + # commandline. >>> + check_meta_commit metas/two c HEAD r $oid r tags/three && >>> + check_meta_commit metas/three c HEAD r $oid r tags/three >>> +' >>> + >>> +reset_meta_commits () { >>> + for c in one two three >>> + do >>> + echo "update refs/metas/$c refs/tags/$c^0" >>> + done | git update-ref --stdin >>> +} >>> + >>> +test_expect_success 'override change name' ' >>> + # TODO: builtin/change.c expects --change to be the full refname, >>> + # ideally it would prepend refs/metas to the string given by the >>> + # user. >>> + git change update --change refs/metas/another-one --content one && >>> + test_cmp_rev metas/another-one one >>> +' >>> + >>> +test_expect_success 'non-fast forward meta-commit update refused' ' >>> + test_must_fail git change update --change refs/metas/one --content two \ >>> + >out 2>err && >>> + echo "error: non-fast-forward update to ${SQ}refs/metas/one${SQ}" \ >>> + >expect && >>> + test_cmp expect err && >>> + test_must_be_empty out >>> +' >>> + >>> +test_expect_success 'forced non-fast forward update succeeds' ' >>> + git change update --change refs/metas/one --content two --force \ >>> + >out 2>err && >>> + echo "Updated change metas/one" >expect && >>> + test_cmp expect out && >>> + test_must_be_empty err >>> +' >>> + >>> +test_done >>> -- >>> 2.37.3.947.g1b8ba4da7f.dirty >>> >>> >>> From 7784f253fa799dd11fcbc81fe815fb387af52d97 Mon Sep 17 00:00:00 2001 >>> From: Phillip Wood >>> Date: Tue, 4 Oct 2022 15:16:05 +0100 >>> Subject: [PATCH 3/3] fixup! evolve: add the git change list command >>> >>> --- >>> builtin/change.c | 16 +++++----------- >>> t/t9999-changes.sh | 11 +++++++++++ >>> 2 files changed, 16 insertions(+), 11 deletions(-) >>> >>> diff --git a/builtin/change.c b/builtin/change.c >>> index 07d029d82d..888ef648fa 100644 >>> --- a/builtin/change.c >>> +++ b/builtin/change.c >>> @@ -34,9 +34,8 @@ static int change_list(int argc, const char **argv, const char* prefix) >>> OPT_END() >>> }; >>> struct ref_filter filter; >>> - /* TODO: See below >>> struct ref_sorting *sorting; >>> - struct string_list sorting_options = STRING_LIST_INIT_DUP; */ >>> + struct string_list sorting_options = STRING_LIST_INIT_DUP; >>> struct ref_format format = REF_FORMAT_INIT; >>> struct ref_array array; >>> int i; >>> @@ -53,19 +52,15 @@ static int change_list(int argc, const char **argv, const char* prefix) >>> >>> filter_refs(&array, &filter, FILTER_REFS_CHANGES); >>> >>> - /* TODO: This causes a crash. It sets one of the atom_value handlers to >>> - * something invalid, which causes a crash later when we call >>> - * show_ref_array_item. Figure out why this happens and put back the sorting. >>> - * >>> - * sorting = ref_sorting_options(&sorting_options); >>> - * ref_array_sort(sorting, &array); */ >>> - >>> if (!format.format) >>> format.format = "%(refname:lstrip=1)"; >>> >>> if (verify_ref_format(&format)) >>> die(_("unable to parse format string")); >>> >>> + sorting = ref_sorting_options(&sorting_options); >>> + ref_array_sort(sorting, &array); >>> + >>> for (i = 0; i < array.nr; i++) { >>> struct strbuf output = STRBUF_INIT; >>> struct strbuf err = STRBUF_INIT; >>> @@ -79,8 +74,7 @@ static int change_list(int argc, const char **argv, const char* prefix) >>> } >>> >>> ref_array_clear(&array); >>> - /* TODO: see above >>> - ref_sorting_release(sorting); */ >>> + ref_sorting_release(sorting); >>> >>> return 0; >>> } >>> diff --git a/t/t9999-changes.sh b/t/t9999-changes.sh >>> index 9e58925b23..9312eba86d 100755 >>> --- a/t/t9999-changes.sh >>> +++ b/t/t9999-changes.sh >>> @@ -123,4 +123,15 @@ test_expect_success 'forced non-fast forward update succeeds' ' >>> test_must_be_empty err >>> ' >>> >>> +test_expect_success 'list changes' ' >>> + cat >expect <<-\EOF && >>> + metas/another-one >>> + metas/one >>> + metas/three >>> + metas/two >>> + EOF >>> + git change list >actual && >>> + test_cmp expect actual >>> +' >>> + >>> test_done >>> -- >>> 2.37.3.947.g1b8ba4da7f.dirty