Open Bug 1557535 Opened 1 year ago Updated 1 month ago

clang-format mercurial extension corrupts rebases


(Firefox Build System :: Lint and Formatting, defect, P2)



(Not tracked)


(Reporter: sfink, Unassigned)


(Blocks 1 open bug)


I filed against mercurial, but on the 3rd time it happened, I experimented and discovered that the culprit is the clang-format mercurial extension.

The situation: I have a stack of patches locally. I have landed some of them via Lando. Other changes have landed on top. I pull down mozilla-central and rebase my stack on top of it. At least one patch requires some conflict resolution (I don't know if this is a required condition or not.) The rebase seems to succeed, but it says that it created some orphans.

When I look at what is in my tree, I have the original upstream revision with all of my old patches on top of it, all of them obsoleted. I also have a messy stack of the same changes rebased on top of the new upstream tip, except for the old top patch (it's messy because sometimes it contains multiple patches with the same description in them, and some of them are empty.) Finally, there's a merge commit with the comment from my original top patch. Its parents are the tips of the two series of changesets described above -- one of them is obsolete, the other is not. Additionally, it contains the changes from the original top patch.

A detailed log of an example of this happening is attached to the above mercurial bug.

If I do the same thing with the clang-format extension disabled, the rebase works fine and I end up with a stack of rebased patches. (Though some of the patches are empty, containing only commit messages that include phabricator revision urls.)

I've turned the extension back off, but I wanted to mention my recovery procedure in case someone else runs into this and doesn't know what to make of the mess. This assumes evolve is installed so you still have all of the commits intact.

Identify the three relevant revisions. Call the merge commit $MERGE, the top obsolete patch $OLDTOP, and the top rebased patch $HEADLESS. I guess this'll only work if it's really just the top patch that got merge-smashed, though that's what happened all 3 times I've seen this. I guess you could get them with

% MERGE=$(hg log -r . -T '{node|short}\n')
% OLDTOP=$(hg log -r 'p1(.)' -T '{node|short}\n')
% HEADLESS=$(hg log -r 'p2(.)' -T '{node|short}\n')

though you'd need to confirm that OLDTOP and HEADLESS aren't the other way around (hg log -r $OLDTOP should give an error because it's a hidden revision.)

Then disable the clang-format extension and do

% hg prune -r $MERGE  # Discard the merge commit
% hg touch -r "ancestors($OLDTOP) and obsolete() and not public()" # Revive your old stack
% NEWTOP=$(hg log -r "allsuccessors($OLDTOP) and not obsolete()" --hidden -T '{node|short}\n') # Find the new stacktop
% hg rebase -d central -r $NEWTOP # Finish off the rebase

I haven't run these exact commands; I did this more manually by looking at various outputs and piecing together what's what. So be careful.

This has been wasting my time since I followed the recent advice on dev.platform to enable the extension for the prettier format… we shouldn't be recommending a tool that corrupts repos on common operations.

Blocks: mach-busted
Type: task → defect

I hadn't heard anyone else complain, so just assumed this was something weird about my setup. Apparently not.

Andi, any idea what is going on here? Thanks

Flags: needinfo?(bpostelnicu)

I want to update the extension, with the latest commits from the original repo, even though I'm not completely sure it will fix our issue.
@Matthew can you please detail a little bit more what do you do in order to encounter this behavior? Can you please provide some logs?

Flags: needinfo?(bpostelnicu) → needinfo?(MattN+bmo)
Priority: -- → P2
You need to log in before you can comment on or make changes to this bug.