On Gitlab, is there a commonly used procedure, similar to a Merge Request, for changes that rewrite the git history?

Issue

Something we could call a "Reset Request", because instead of requesting to merge the feature branch into master, we’d be requesting to reset master to the feature branch.

The use-cases for this would be for instance to clean up the git history (without any actual code changes), or to get updates from the original repo after a fork, via a rebase, into the master branch of the fork. You would do that on a separate (feature branch), then ask for a "Reset request" to master.

I am aware of the fact that rewriting history on a shared branch is a delicate thing to do. I am thinking of doing this for a repo of a small team, where you can control who has pulled the code locally and communicate whatever steps should be taken to continue development.

I’m looking for standard ways that these things get done. I couldn’t find anything similar to the "Reset Request" I’ve described (neither on Gitlab nor on Github). The only way to do that that I can see right now is to force push to master ; but then how can you organize a review of the changes?

Seems like I’m missing a piece of the puzzle, unless these use-cases aren’t as common as I’d imagined, so don’t hesitate to correct any incorrect assumptions I made.

Solution

I’m pretty sure the answer is No, and I think that’s true for all of the major tools. (GitHub, Azure DevOps, GitLab, Bitbucket, etc.)

Perhaps the two main reasons this functionality doesn’t exist are both things you mentioned:

these use-cases aren’t as common as I’d imagined

Force pushing shared branches should be a rare event.

The use-cases for this would be for instance to clean up the git history (without any actual code changes)…

Most code review tools are file-centric, and as you mentioned, even if there was a mechanism for code reviewing a reset, there actually wouldn’t be any files to review. You’ll still need to inspect the commits, but as mentioned below you can just do it manually on the machine that contains the new code.

As for your sub-question:

I’m looking for standard ways that these things get done.

I don’t know of any (popular) standard for resetting shared branches, perhaps because it’s odd to create a standard around something that is frowned upon and should be rare. That being said:

My preferred method for resetting a shared branch goes something like this:

  1. Decide if you really need to reset, or if a revert will suffice. (Usually the suggestion to reset is due to regretting merging in some code, and in that case a revert can undo it too. In your case, revert doesn’t apply since your desire is to clean-up history. You’ll have to reset, so you can skip this step, or, perhaps you need to decide if you really need to reset it.) If you decide not to reset, you’re done here. (Reverts use the normal code review process.)

  2. Consider locking down the shared branch so no one adds more to it while you’re re-writing it.

  3. Determine the best commit to reset to. For undoing regrettable merges, normally you reset backwards to a commit already in the history, perhaps just before the problem, but if you’re rewriting history it’s likely it won’t be in the history at all. In the case of a rewrite you’ll likely need to review your code outside of the normal review process. Typically, on someone’s machine that contains the rewritten code, you compare the end states and make sure the only differences are whatever you wanted to strip out. Then you spot check specific commits to make sure the large files, passwords, etc, no longer exist anywhere in the history.

  4. If you haven’t already, announce to your entire team that a shared branch is going to be re-written and provide instructions for how to rewrite their WIP branches. Make sure to include the previous tip commit ID of the branch getting rewritten, as well as the proper command(s) to run. Perhaps something like:

    git fetch
    # for each feature branch in progress:
    git rebase <old-tip-commit> my-feature-branch --onto <shared-branch-name>
    
  5. If you use protected branches, temporarily give someone (perhaps the person who has the rewritten history on their machine) permission to force push the shared branch.

  6. Force push the shared branch with the safety net, particularly if you didn’t lock it as suggested above:

    git push --force-with-lease
    
  7. Remove the temporary permission to force push the shared branch.

  8. Announce to your team that it’s done and that they can now rewrite all of their WIP branches.

Answered By – TTT

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published