user1449855
user1449855

Reputation: 1375

How can set an older commit to be HEAD?

I realized that I made some mistakes on HEAD, checked out an older commit and started coding from there. When I attempt a push I'm told that my current commit is behind and I need to merge with HEAD. Git recommends "git pull". However, HEAD has the code I want to ignore. How do I solve this problem?

Flowchart:

-------- HEAD (bad) ---------------------- + (behind conflict, requires
     \                                    /   merge with HEAD, which is
      \------- Current commit (good) ----/    bad and needs to be ignored)

Upvotes: 117

Views: 168314

Answers (11)

David Fischer
David Fischer

Reputation: 182

Rather use git revert <commit-hash> then force push. This keeps the history for others clean.

If you have a history: A ---> B ---> C and use reset you end up with A ---> B . If you use revert you end up with A ---> B ---> C ---> D where D is the undo commit.

If you undo a merge commit you have to also specify the parent branch of the merge commit. git revert -m 1 tells it to use the branch that was merged into. m 2 the branch that was merged. Usually you use 1.

Upvotes: -1

Lexodexo
Lexodexo

Reputation: 11

This works best for me:

git checkout <commit-id> .
git add .
git commit -m "your changes"
git push

Note that the . is important.

Upvotes: 1

frandroid
frandroid

Reputation: 1412

You can update the remote branch more safely with:

git push --force-with-lease

If your remote branch has been committed to since your last pull, it will not reset the branch, but if this bad commit is the last commit, it will update the branch with your current version of the branch. (I've personally aliased this in my .gitconfig file:

[alias]
    please = push --force-with-lease

So I can just do

git please

at the command line. :)

Upvotes: 3

Johan Swanepoel
Johan Swanepoel

Reputation: 482

I'm a bit late to the party - I had to do:

git push -f origin HEAD:<name-of-branch>

Please read the documentation first before executing this command.

Upvotes: 2

Anil M
Anil M

Reputation: 149

The steps that worked for me perfectly are following --

1) git log --oneline

2) Grab the commit that you want to rollback (most likely the commit before your last commit at HEAD and push)

3) git checkout (this is the commit id to where you want your work to rollback to)

4) git push -f origin HEAD:master (-f will force the push overriding any rejection that would happen if pushed branch is behind the remote) HEAD:master(This is to ensure you are pushing the rollback to the master branch and at HEAD of the remote repo)

5) That's it :)

Upvotes: 2

LemonadeGrenade
LemonadeGrenade

Reputation: 51

For those of us working on protected branches, push -f isn't an option.

Instead:

Checkout HEAD
diff {hash of desired commit to use as new HEAD} > myChange.patch
git apply 
commit 
push

If you have changes you'd like to merge into the new version of HEAD like OP, I would back them up first, correct the remote repo, then apply the changes.

This also preserves your repo history.

Upvotes: 5

igronus
igronus

Reputation: 486

The only thing that worked for me:

git checkout <OLD_COMMIT>
git branch temp
git checkout temp
git branch -f master temp
git checkout master
git branch -d temp

Upvotes: 12

radtek
radtek

Reputation: 36370

Here is what you can do:

git checkout <branch-to-modify-head>
git reset --hard <commit-hash-id-to-put-as-head>
git push -f

If you don't force the push, git will throw this error: Updates were rejected because the tip of your current branch is behind.

Note that this will tamper your git history, so another way of doing this is revert each commit you don't want. That way you retain your history:

git revert commit-id

Cheers

Upvotes: 175

Elena
Elena

Reputation: 1829

The way I do it is:

git reset --hard <commit-SHA>
git push origin HEAD:<name-of-remote-branch>

It's the way git recommends and doing git push -f might be a little problematic for everyone else in the development team

Upvotes: 32

Mike Monkiewicz
Mike Monkiewicz

Reputation: 4729

ANeves is right, "git push -f" only works because you were the only person using the repository. This is not an acceptable solution for most people.

Here's your current commit history:

---A-B < HEAD (bad)
    \
     C < my_branch (good)

This has the solutions you want: How do I 'overwrite', rather than 'merge', a branch on another branch in Git?

To recap,

git checkout my_branch
git merge -s ours HEAD

This will stomp all the changes on HEAD's branch, and give you the following:

--A-B-D < HEAD, my_branch (both good)
   \ /
    C

D is effectively the same as C in this case, it just has different parents.

Upvotes: 11

user229044
user229044

Reputation: 239541

If your repository isn't being used by other people, you can safely do git push -f to overwrite the remote branch.

Upvotes: 27

Related Questions