threads / discuss / 60207

Please explain avoiding history simplifications when diffing merges

Subject: Please explain avoiding history simplifications when diffing merges

## tl;dr

4 messages between Sep 8, 2023 and Sep 25, 2023.

replies: 3people: 2as markdown or json

Magnus Holmgren· Sep 8, 2023, 09:09 UTC · lore
Hi (and thanks for a great free tool).

QGit was bitten by https://github.com/git/git/commit/0dec322d31db3920872f43bdd2a7ddd282a5be67

It looks like passing --simplify-merges to override the default solves the problem, but I still want to ask here because I'm not sure I fully understand the reasoning:

> the default history simplification would remove merge commits from 
> consideration if the file "path" matched the second parent.

I guess that means that even if there was a difference relative to the first parent, which you wanted to see, the merge commit would be omitted if there's no diff relative to the second parent? That's fine, and history simplification isn't trivial, but now every merge commit ever is included in the commit log of an individual file, even if that file was only added somewhere in the middle and never changed since. Is that really desirable? Shouldn't it be possible to include only merge commits that are not TREESAME to *all* parents?

Thanks,
-- 
Magnus Holmgren
./¯\_/¯\. Milient
(also holmgren@debian.org)
Magnus Holmgren· Sep 15, 2023, 15:10 UTC · re: Magnus Holmgren · lore

Re: Please explain avoiding history simplifications when diffing merges

Friday, 8 September 2023 11:09:20 CEST, I wrote
> QGit was bitten by
> https://github.com/git/git/commit/0dec322d31db3920872f43bdd2a7ddd282a5be67

Maybe I should link to the QGit issue: https://github.com/tibirna/qgit/issues/129

Show 6 quoted lines
> It looks like passing --simplify-merges to override the default solves the
> problem, but I still want to ask here because I'm not sure I fully
> understand
> the reasoning:
> > the default history simplification would remove merge commits from
> > consideration if the file "path" matched the second parent.

As I wrote at the above URL, I realized that the old git log output without -- simplify-merges and the output with --simplify-merges aren't quite the same. The old output indeed omits some interesting merge commits, which may explain why the change was made, but git log --simplify-merges does include them, so it seems a reasonable default to me.

However, QGit has a problem: git log --diff-merges=separate includes a separate diff for each parent, but only for each parent with differences compared to the merge commit, *and* there's no custom format placeholder for the current parent, only for the list of parents (%P/%p). How should one go about adding that? I figure the format_commit_context struct in pretty.c needs another field.

-- 
Magnus Holmgren
./¯\_/¯\. Milient
Bagas Sanjaya· Sep 17, 2023, 09:58 UTC · re: Magnus Holmgren · lore

Re: Please explain avoiding history simplifications when diffing merges

On Fri, Sep 15, 2023 at 05:10:28PM +0200, Magnus Holmgren wrote:
Show 19 quoted lines
> Friday, 8 September 2023 11:09:20 CEST, I wrote
> > QGit was bitten by
> > https://github.com/git/git/commit/0dec322d31db3920872f43bdd2a7ddd282a5be67
> 
> Maybe I should link to the QGit issue:
> https://github.com/tibirna/qgit/issues/129
> 
> > It looks like passing --simplify-merges to override the default solves the
> > problem, but I still want to ask here because I'm not sure I fully
> > understand
> > the reasoning:
> > > the default history simplification would remove merge commits from
> > > consideration if the file "path" matched the second parent.
> 
> As I wrote at the above URL, I realized that the old git log output without --
> simplify-merges and the output with --simplify-merges aren't quite the same. 
> The old output indeed omits some interesting merge commits, which may explain 
> why the change was made, but git log --simplify-merges does include them, so 
> it seems a reasonable default to me.
Can you provide examples?
Show 7 quoted lines
> 
> However, QGit has a problem: git log --diff-merges=separate includes a 
> separate diff for each parent, but only for each parent with differences 
> compared to the merge commit, *and* there's no custom format placeholder for 
> the current parent, only for the list of parents (%P/%p). How should one go 
> about adding that? I figure the format_commit_context struct in pretty.c needs 
> another field.
What are you trying to accomplish with your proposed formatting verbs?
Confused...
-- 
An old man doll... just what I always wanted! - Clara
Magnus Holmgren· Sep 25, 2023, 16:11 UTC · re: Bagas Sanjaya · lore

Re: Please explain avoiding history simplifications when diffing merges

söndag 17 september 2023 11:58:14 CEST skrev  Bagas Sanjaya:
Show 27 quoted lines
> On Fri, Sep 15, 2023 at 05:10:28PM +0200, Magnus Holmgren wrote:
> > Friday, 8 September 2023 11:09:20 CEST, I wrote
> > 
> > > QGit was bitten by
> > > https://github.com/git/git/commit/0dec322d31db3920872f43bdd2a7ddd282a5be
> > > 67
> > 
> > Maybe I should link to the QGit issue:
> > https://github.com/tibirna/qgit/issues/129
> > 
> > > It looks like passing --simplify-merges to override the default solves
> > > the
> > > problem, but I still want to ask here because I'm not sure I fully
> > > understand
> > > 
> > > the reasoning:
> > > > the default history simplification would remove merge commits from
> > > > consideration if the file "path" matched the second parent.
> > 
> > As I wrote at the above URL, I realized that the old git log output
> > without -- simplify-merges and the output with --simplify-merges aren't
> > quite the same. The old output indeed omits some interesting merge
> > commits, which may explain why the change was made, but git log
> > --simplify-merges does include them, so it seems a reasonable default to
> > me.
> 
> Can you provide examples?

git init git-test; cd git-test echo foo > test; git add test; git commit -m Initial git branch testbranch git branch irrelevantbranch echo foobar > test; git commit -am Change git switch testbranch echo barfoo > test; git commit -am Diverge git switch irrelevantbranch echo whatever > otherfile; git add otherfile git commit -m "Add other file" git switch master git merge -m "Merge branch 'testbranch'" -s ours testbranch git merge -m "Merge branch 'irrelevantbranch' irrelevantbranch git log test # old git doesn't show either merge commit, new git shows both git log --simplify-merges test # both versions show the first merge commit git log --diff-merges=separate -p --simplify-merges test # only in new git # note that only one diff is generated because the other would be empty, # although the man page says "Separate log entry and diff is generated for # each parent."

Show 8 quoted lines
> > However, QGit has a problem: git log --diff-merges=separate includes a
> > separate diff for each parent, but only for each parent with differences
> > compared to the merge commit, *and* there's no custom format placeholder
> > for the current parent, only for the list of parents (%P/%p). How should
> > one go about adding that? I figure the format_commit_context struct in
> > pretty.c needs another field.
> 
> What are you trying to accomplish with your proposed formatting verbs?

QGit builds annotated file histories by parsing git log output. To accomplish that, it needs to use a custom, more machine-readable format, and to handle merge commits correctly, it either needs one diff per parent in the order the parents are listed, or it needs to know which parent each diff is relative to.

Because old git log (without --simplify-merges) only included merge commits where the file in question is different to all parents, it didn't get confused by missing diffs - it was all or nothing - but some merge commits were missing in the file history view.

QGit should be rewritten to use libgit2, but regardless, I think all the information you can get with a standard format should be available to custom formats as well.

-- 
Magnus Holmgren
./¯\_/¯\. Milient

← back to recent threads