Search code examples
gitbranchgit-rewrite-historygit-p4

How to replace the history of a branch with another branch?


I have repositories that I migrated from Perforce into Git. Every while, I do a git p4 rebase (where p4 is alias for git-p4) on each repository in order to get new changes from Perfoce into Git. This procedure works fine on all repositories except this one doomed repository, call it GitRepo.

For some reason, every time I "sync" GitRepo with the Perforce one, I end up with an empty merge commit that looks like this:

enter image description here

It happened that for the last two months, there were no changes. So the history now looks like this:

enter image description here

Notice the commits 4/6/2018 and 3/30/2018? Not sure why they are after 6/25/2018 (Which is probably the source of the problem), and they do exist already in the history in there right time-epic.

Long story short, I have checked out the 6/25/2018 commit and pushed the history to a new branch, Branch-A.

Branch-A looks exactly how I want, how can I rewrite the history of master, to be the one in Branch-A?


Solution

  • If you're indeed (as your commentary indicates) working alone on this repo, you can take advantage of the possibility given by the -f option of the branch command and set arbitrarily your master branch on any given commit (or, as is refered to in the doc, committish, which means any ref that can be used to point to a given commit, like branches, tags, and a few more) :

    # First you can, as a backup, set a branch where master is at the start of the process
    git branch backup-master master
    
    # Okay, now we force (-f) the master branch on the same commit where BranchA is
    git branch -f master BranchA
    
    # Local is clear, now is time to update your remote with
    # your rewritten version of repo history
    git push -f origin master
    

    Now master is at the same point than BranchA, down to their history since this is the same commit they both point to. And branch backupMaster is here just in case you change your mind for any reason.