Search code examples
gitgithubversion-control

I want to rollback changes to a commit ID and then commit these rolled back changes as new commit in GIT


I have to be very careful asking this question as I don't want any misunderstandings.

We merged a bunch of PRs into the main branch but we want to remove these merges from it. Reverting one PR after another will consume a lot of time.

Our main branch is protected and I cannot push a version of main branch that is reset to the commit ID I'm trying to rollback to.

Consider my main branch has commit a, commit b... commit f. Here's what I want to do:

  1. In a new branch, I want to rollback changes to commit c without changing the history of the branch.
  2. I want to commit these changes that have been reset as commit g in the history so it will look like:
  • commit g
  • commit f
  • commit e
  • commit d
  • commit c
  • commit b
  • commit a
  1. Raise PR with rollback changes without conflicts against main.
  2. Should be able to merge the changes from commit d, e, f in future.

I searched for a lot of reset and revert solutions but none has worked for me so far and I wonder, am I even asking the right question? Is this possible in GIT? Am I thinking about this the wrong way? If so, what would be a correct work-around?

A friend of mine suggested this solution (without commands) which confused me more:

just reset to commit, copy a code, rest to head, remove code, copy previous code and push as single commit change and open a PR for this

Any help, appreciated. Thanks in advance.


Solution

  • Another option to revert all changes and restore the state of commit c:

    from your branch on commit f, run:

    # forcefully reset the index (-S) and worktree (-W) to the state in commit [c]:
    git restore -SW -s [c] -- .
    
    # commit
    git commit
    

    A generic word of caution about git restore -W (short for: git restore --worktree) :
    this one of the few destructive git commands -- like git reset --hard -- will happily erase from your disk changes that aren't stored in git, without a way to restore to them.

    It is advised to run this command only on a clean worktree. If you have changes, you can either commit them on a different branch, or use git stash to store them in the stash.