Fix broken branches and main mistakes

Shows how to clean up branches after mistakes happen.

Once established, git workflows go fairly smoothly.

At some point, you might realize that a branch pull request (PR) includes commits that it shouldn’t.

Alternatively, your local default branch (main or master for older projects) has somehow managed to get ahead of the remote origin.

To fix things, you need to:

  1. Replace the broken branch
  2. Replace the broken pull request

Replace broken branch

For the most part, you can’t selectively remove commits from a pull request.

Instead you need to replace the broken branch with a new one.

To do so:

  • Review the commits in the broken PR
  • Determine (and save) the commit IDs for the changes you want to keep
  • Create a new branch and then add the selected commits in your new branch
  • Discard the original branch

Here’s how it works:

  1. Determine and save the IDs for the commits you want to keep:

    $ git checkout broken-branch
    $ git log    
    

    If you’re lucky, you just need the first commit ID displayed in the log.

  2. Create and check out a new branch

    $ git checkout broken-branch-update
    $ git log    
    

    Tip: Consider linking the branch names. Here, I’ve added update to the previous branch name so that a future reviewer might recognize the connection between the branches. Such consistency can help when looking back weeks or months later.

  3. Reset the new branch to a known baseline, such as your remote default branch (origin/main).

    $ git fetch origin main
    $ git reset --hard origin/main    
    

    If you receive an error saying Fatal: could not read from remote repository, it’s likely one of the following:

    • You’ve mistyped origin: verify the name of your upstream remote and try again.
    • Your current working directory isn’t (yet) part of your remote branch. Change to a shared directory and try again.
    • Your session credentials have expired; renew your session and try again.
  4. Add the desired commits from the original branch:

    $ git cherry-pick saved-commit-id
    

    Run this for each saved commit ID.

  5. Review your local files and commit your changes.

    When satisfied, push your new branch:

    $ git push origin broken-branch-upd:broken-branch-upd 
    
  6. To finish: create a new pull request (which should be blissfully free from other commits), delete the original (broken) PR, and then clean up your local branches.

Before adding additional commits to your new PR, consider pushing a small edit within the scope of the PR. If this triggers an upstream warning that “changes aren’t tracked remotely,” use the text in the error to set up remote tracking.

$ git push --set-upstream origin broken-branch-upd

Consider doing this now to avoid future surprises.

Reset local default

Once you’ve replaced broken branches and pull requests, you will likely need to reset your local default branch (main) to your remote default (origin/main).

To begin, check out main, investigate the differences between your local copy and your upstream remote, and then resolve any differences. (Most have likely been resolved while replacing broken ranches.)

When things look good, reset your local default (main) to your remote default (origin/main):

$ git checkout main
$ git fetch origin main
$ git reset --hard origin/main
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

Once the working tree is clean, you’re ready to resume your normal activities.

Vital statistics

  • Update
    7 May 2024 - Rewritten to reflect current style and conventions
  • Tested
    8 March 2017 using git 2.10.1, MacOS Sierra 10.12.3
  • Source material
    Based on Stack Overflow Question #25955822.
    (My mileage varied, so I wrote this and added my comments.)