Detect and Warn When a Commit Reapplied After Revert Is Dropped by Merge Train
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Background
Currently, GitLab Merge Trains (and likely Rebase Merges generally) will silently drop commits that have already been applied and then reverted, if they are reintroduced in exactly the same form. This is due to Git’s patch ID–based deduplication logic during rebase/cherry-pick operations.
This behavior can result in loss of intended code changes, even though the Merge Request appears “merged” successfully, leading to critical business issues like missing release deadlines.
Situation
When a commit A is:
- Merged into the main branch,
- Then reverted via git revert A, and
- Later reintroduced as a new MR (with the same patch content as A),
GitLab’s Merge Train can drop that reintroduced commit silently, due to git cherry-pick deduplication based on patch ID. Git sees this as a “no-op” and skips it—even though the original effect of the commit was undone by a revert.
This behaviour is technically consistent with Git’s semantics, but from a product perspective, it is dangerously misleading. GitLab:
- Shows the MR as “merged”
- But drops the changes entirely
- Without any error or warning to the developer or reviewer
The result: an MR appears successful, but its code never lands.
Proposed Solution
GitLab should detect this situation and surface a warning or hard failure in the MR pipeline or UI.
Implementation Suggestion:
When preparing to apply commits to a Merge Train:
- Compute the patch ID for each commit being rebased (already done implicitly).
- Check Git history (on the target branch) for:
- The same patch ID having appeared before, and
- A subsequent git revert of that commit.
- If such a revert is found, do not treat the patch as a duplicate, or at the very least:
- Raise a warning in the MR UI: “This commit appears to have been previously applied and reverted. It may be dropped during the merge.”
- Optionally, block the merge train unless the patch is changed or manually confirmed.
This logic mimics what a careful human reviewer would do: “Wait, isn’t this just something we reverted last week? Are we sure we want it back?”
Constraints
This does not require GitLab to override Git’s rebase logic—but it does require analysis of patch IDs + revert commit metadata prior to merge execution.
This could be implemented as a check in the Merge Train logic, or as part of the Merge Request, similar to how GitLab handles approval rules, pipeline status, or blocking discussions.
Why This Matters
- Reduces risk of silent data/code loss
- Makes GitLab safer for teams using Merge Trains and trunk-based development
- Helps non-Git-expert developers avoid confusing, hard-to-diagnose issues
- Aligns GitLab behaviour with user expectations: “If an MR says merged, it should have merged something.”