Re: [PATCH] branch: let --delete-merged find squash merged branches
- From
- Phillip Wood <phillip.wood123@gmail.com>
- Date
- Oct 4, 2026, 09:54 UTC
- Message-ID
- <39a28064-1698-4971-a80f-4a4c4dcdd8d9@gmail.com>
- In-Reply-To
- <CALnO6CBwWy3aafyDJPKFk5vuWy2EF1n1Oc=W7+RVAE3rxpXwiw@mail.gmail.com>
On 29/09/2026 12:26, D. Ben Knoble wrote:
Show 6 quoted lines
> On Tue, Sep 29, 2026 at 3:33 AM Harald Nordgren via GitGitGadget > <gitgitgadget@gmail.com> wrote: > > …in the rebase case, I would expect something like git-log's > --cherry-mark option (or really the algorithm behind it, git-cherry, > and git-range-diff)
That's what I was expecting as well. It would be worth carefully studying the implementation of git-cherry. "git cherry A...B" precalculates the patch-ids from the side of the merge base that has the fewest commits and then walks the other side to compare them. While it is walking the other side I think it also looks at which paths were changed to avoid calculating the patch-id for commits that cannot match. It also batches fetches the blobs it needs in partial clones.
As far as I can see the implementation here makes a separate upstream revision walk for each branch, and recalculates the upstream diffs each time which seems less efficient than it could be.
Show 5 quoted lines
> to be useful for identifying rebased branches. But > of course even rebase-merged branches can end up with minor > differences (say, a commit was made upstream before that branch was > rebased with an identical change; no conflict occurs, but the new > commit differs from the old by not having that change).
Yes if a branch has been rebased before it is merged it may be altered such that we cannot detect it.
> In the squash case, I suppose the best we can do is check that all our > changes were applied at some point between the merge-base and the tip. > There probably won't be any tree-same commits, though maybe a > (premature?) optimization can return early if the trees match exactly.
If we have
(topic) D - C - B - A
\
(main) M - Q - P - O -
\ /
- - S - -where M is a squashed merge of topic I think we have
M^2^{tree} == topic^{tree}
Merge-base(M^1, M^2) == Merge-base(topic, topic@{upstream})
$(git rev-list --count --right-only M^1...M^2) == 1If you know your repository only has squash merges that were not rebased it would be a lot more efficient to just look at the trees and merge-bases, especially in a blobless clone. Having an option to turn off the patch-id based detection would probably be useful in that case.
I think detecting branches that have been squashed and/or rebased is a useful improvement, but it needs careful implementation to be efficient enough that it is practical in large repositories and I'm unlikely to have time to closely review it.
Thanks
Phillip
Show 20 quoted lines
> It looked like you don't distinguish the 2 cases in the code, and I > think that's reasonable: we wouldn't know a priori whether to check > for a rebased series or a squashed commit, so we'd have to run both > checks, and the latter presumably subsumes the former. > > Anyway, I can see how this would all be fairly expensive---on one repo > I work in, git-range-diff can be somewhat slow depending on how many > commits are in the range, I think. I don't know if it's worth trying > to state that for folks, though? If we ever make improvements to > performance, we'd have to remember to remove the "this may be slow" > text. > >> After the release of 2.56, I saw people liking the --delete-merged >> feature, but asking for this. A lot of people, me included prefer >> squash-merge and it currently doesn't work with --delete-merged. > > Btw, I wonder if you can share where you saw this? 2.56 was released > so recently I'm (pleasantly) surprised there's already feedback on > this! >