git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] replay: drop commits that become empty

From
PWPhillip Wood <phillip.wood123@gmail.com>
Date
Dec 4, 2025, 14:06 UTC
Message-ID
<10f9afd8-6ac2-4e17-979f-2222bd0a2fda@gmail.com>
In-Reply-To
<CABPp-BEZFPmLnEtnD0WaNbkZ5uE7q5T6uKJQRUvtq+L=C1o9wg@mail.gmail.com>
On 28/11/2025 08:06, Elijah Newren wrote:
Show 14 quoted lines
> On Thu, Nov 27, 2025 at 8:16 AM Phillip Wood <phillip.wood123@gmail.com> wrote:
>>
>> From: Phillip Wood <phillip.wood@dunelm.org.uk>
>>
>> If the changes in a commit being replayed are already in the branch
>> that the commits are being replayed onto then "git replay" creates an
>> empty commit. This is confusing because the commit message no longer
>> matches the contents of the commit. Drop the commit instead. Commits
>> that start off empty are not dropped.
> 
> Yeah, I've got a commit in my local branch that does the same thing.
> 
> It feels like there should be a paragraph break in here somewhere, but
> maybe that's just me?  Pretty minor either way.
Yes it could do with a paragraph break, I'll add one
Show 26 quoted lines
>> This matches the behavior of
>> "git rebase --reapply-cherry-pick --empty=drop" and "git cherry-pick
>> --empty-drop". If a branch points to a commit that is dropped it will
>> be updated to point to the last commit that was not dropped. This can
>> been seen in the new test where "topic1" is updated to point to the
>> rebased "C" as "F" is dropped because it is already upstream. While
>> this is a breaking change "git replay" is marked as experimental to
>> allow improvements like this that change the behavior.
> 
> Yep.
> 
>>
>> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
>> ---
>> Elijah - I'm not really clear why we were setting result->tree before
>> calling merge_incore_nonrecursive(), was it just for convenience to
>> avoid declaring a local variable or have I missed something?
> 
> I don't know the reason.  That traces back to a commit with
> Christian's Co-authored-by, so it may have been either him or me that
> introduced it.  My original work on replay was on a branch that I long
> ago rebased on top of the version Christian submitted, and the old
> history is no longer reachable from my local reflog, so I don't have a
> way to narrow down who of us did it.  If it was him, he may be able to
> answer.  If it was me, I've long since forgotten.  I think using a
> temporary, as you've done, is better.

Thanks, I was worried I might have missed some subtlety and inadvertently broken a corner case.

Show 24 quoted lines
>> +       # Write the new value of refs/heads/empty to "new-empty" and
>> +       # generate a sed script that annotates the output of
>> +       # `git log --format="%H %s"` with the updated branches
>> +       SCRIPT="$(sed -e "
>> +               /empty/{
>> +                       h
>> +                       s|^.*empty \([^ ]*\) .*|\1|wnew-empty
>> +                       g
>> +               }
>> +               s|^.*/\([^/ ]*\) \([^ ]*\).*|/^\2/s/\\\$/ (\1)/|
>> +               \$s|\$|;s/^[^ ]* //|" result)" &&
>> +       git log --format="%H %s" --stdin <new-empty >actual.raw &&
>> +       sed -e "$SCRIPT" actual.raw >actual &&
>> +       test_write_lines >expect \
>> +               "empty (empty)" "H (topic3)" G "C (topic1)" F M L B A &&
>> +       test_cmp expect actual
> 
> After digging around for a while (my sed-fu is far weaker than yours),
> this feels like you are going out of your way to avoid changing any
> branches, but then trying to figure out what the branch changes would
> have been.  Would it be simpler to remove the --ref-action=print
> flags, check directly what changes were made, and use a
> test_when_finished to reset the branches back to their starting point
> at the end?  That'd change this test to something like:

I used --ref-action=print to match the existing tests, but it would be much simpler to drop it. Your suggestion below looks good.

Thanks
Phillip
Show 22 quoted lines
> test_expect_success 'commits that become empty are dropped' '
>      # Save original branches
>      git for-each-ref --format="update %(refname) %(objectname)"
> refs/heads/ >original-branches &&
>      test_when_finished "git update-ref --stdin <original-branches &&
> rm original-branches" &&
> 
>      # Cherry-pick tip of topic1 ("F"), from the middle of A..empty, to main
>      git replay --advance main topic1^! &&
> 
>      # Replay all of A..empty onto main (which includes topic1 & thus F
> in the middle)
>      git replay --onto main --contained A..empty &&
> 
>      # Check that "F" was applied first, then "C", and that "F" wasn't
> applied twice.  Also, that topic1 now points to "C".
>      git log --format="%s%d" L..empty >actual &&
>      test_write_lines >expect \
>          "empty (empty)" "H (topic3)" G "C (topic1)" F "M (main)" &&
>      test_cmp expect actual
> '
> 
Previous: Elijah NewrenNext: Phillip Wood
Message 5 of 16 in “replay: drop commits that become empty”
  1. replay: drop commits that become emptyPhillip Wood, Nov 27, 2025
  2. Junio C HamanoNov 28, 2025
  3. Phillip WoodDec 4, 2025
  4. Elijah NewrenNov 28, 2025
  5. Phillip WoodDec 4, 2025
  6. replay: drop commits that become emptyPhillip Wood, Dec 15, 2025
  7. Junio C HamanoDec 15, 2025
  8. Phillip WoodDec 16, 2025
  9. Phillip WoodDec 17, 2025
  10. Junio C HamanoDec 17, 2025
  11. Elijah NewrenDec 16, 2025
  12. replay: drop commits that become emptyPhillip Wood, Dec 16, 2025
  13. Elijah NewrenDec 16, 2025
  14. Phillip WoodDec 17, 2025
  15. replay: drop commits that become emptyPhillip Wood, Dec 18, 2025
  16. Junio C HamanoDec 19, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.