GitLab Git Associate study materials
GitLab Git Associate study resources

Force-push during active review on a 40-file merge request

GitLab Git Associate · Put your knowledge to work in context.

All case studies

Force-push during active review on a 40-file merge request

A 40-file MR in group/web has 18 review threads and two required approvals. The author rebases onto main to clear conflicts and force-pushes while three reviewers are mid-review. GitLab marks several comments outdated and the two existing approvals disappear. The project has 'Remove all approvals when new commits are pushed' enabled. The author still has 6 fixup commits to address review comments. The release cutoff is in 24 hours. Reviewers want to keep the discussion history and avoid another full review. The MR targets a protected branch that requires resolved threads and a green pipeline. The MR was opened as a draft, then marked ready; the author is the only person who can push to the source branch. The branch is not shared.

1. Explain why the approvals disappeared and why the comments became outdated. What should the author have done differently before rebasing, and what should they do now to preserve reviewer context?

Read the worked answer

GitLab positions comments against a commit SHA and diff line. A rebase rewrites every commit SHA, so comments on lines that moved or disappeared cannot be anchored and are shown as outdated. The approvals disappeared because the project enables 'Remove all approvals when new commits are pushed'; a force-push is a new commit set, so the approval records are cleared. This is a policy outcome, not a review failure.

Before rebasing, the author should have announced it in the MR, marked the MR as Draft, and avoided rebasing a branch under active review unless conflicts blocked all work. Merging main into the branch would have preserved the reviewed SHAs, at the cost of a merge commit. If a rebase was unavoidable, git push --force-with-lease is still the right push primitive, but it does not preserve review state.

Now: do not rebase again. Push the six fixup commits as normal commits so reviewers can see incremental changes, reply in the existing threads, and re-request review. Use the MR's version comparison to show what changed since the last review. The two approvals must be re-obtained. Ask reviewers to focus on the new commits and the conflict resolution, not the entire 40-file diff.

2. The author wants to push six fixup commits, then squash them before merge. Compare squashing at merge time with interactive rebase before merge, given the approval-reset setting and protected branch.

Read the worked answer

Squashing at merge time is safer here. If the project enables 'Squash commits when merge request is merged', GitLab creates a squash commit on the target branch without rewriting the source branch. The reviewed SHAs stay stable, existing comments keep their anchors, and the approval-reset rule is not triggered by the squash because no new commits are pushed to the source branch. The merge request can still satisfy a linear-history rule because the target receives one commit.

Interactive rebase before merge rewrites the source branch again. That will clear the two approvals under the current setting, mark more comments outdated, and force a third review. It is appropriate only when the branch has not been reviewed, or when the team explicitly accepts a re-approval cycle.

Practical sequence:

git commit --fixup <reviewed-sha>
# repeat for review fixes, push normally

At merge, choose Squash in GitLab and write a clean commit message. If the project requires signed commits or a specific message format, confirm the squash commit uses them. Do not both interactive-rebase and squash; that doubles the history rewrite without adding value.

3. A reviewer asks for a change that conflicts with `main`. The author proposes merging `main` into the branch, which adds a merge commit. The target branch requires linear history. What are the trade-offs and what would you recommend?

Read the worked answer

Merging main into the feature branch preserves the existing feature SHAs, so review comments and approvals remain valid, but it adds a merge commit to the MR. If the target branch requires linear history, that merge commit cannot be fast-forwarded into main. A squash merge can collapse the branch, including the merge commit, into one commit on main, satisfying linear history while keeping the source branch stable during review. That is the best trade-off if the project allows squash merges.

The alternative is to resolve conflicts by rebasing onto main at the end of review. That produces a clean linear branch but rewrites SHAs, clears approvals under the reset setting, and outdates comments. It should be a planned final step with reviewer notification and re-approval, not an emergency action 24 hours before the cutoff.

Recommendation: merge main now to unblock testing, keep the fixup commits, and use squash merge. Confirm that the protected branch allows squash merges and that the squash commit will trigger the required pipeline. If the project uses fast-forward-only merges without squash, then rebase once, accept the re-approval, and freeze the branch afterward.