Push a previous commit without merging

Hi, I have worked on some code and pushed the changes to the main branch, however I suspect there is a bug in the code. I don’t necessarily want to delete this latest commit since it contains a lot of work, but I want to work with a previous commit before the bug. Changing to the previous branch works, but I can’t push my changes. This is a school assignment, and every push I make gets autograded, so it’s vital that I can push my changes. When I try to push I get the error message:
error: failed to push some refs to ‘https://github.com/path/to/repository.git
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: ‘git pull …’) before pushing again.
hint: See the ‘Note about fast-forwards’ in ‘git push --help’ for details.

How can I work with a previous commit and push my changes without merging?

So, you can arbitrarily create branches from the web editor, or from a command line.

I often do it from the web editor

Consider this series of commits:

Let’s say I want to create a new branch at Allow races! · jsoref/checkout-merge@9d14eb7 · GitHub, I click on that commit (either the description or the blue sha).

That takes me to this:

I change my url from:

https://github.com/jsoref/checkout-merge/commit/9d14eb7ffc86073a872518d6b5cb97c4750ca6f4

to

https://github.com/jsoref/checkout-merge/commits/9d14eb7ffc86073a872518d6b5cb97c4750ca6f4

That takes me to: Commits · jsoref/checkout-merge · GitHub


I click the branch chooser at the top left:

I fill in the text field w/ new-work-point (you can pick any legal branch name that isn’t taken and doesn’t otherwise cause git headaches):


When I click Create branch: new-work-point, I will now have a branch that I can fetch, check out, and push forward in github.

The equivalent from the command line…

Get repository to do work

git clone git@github.com:jsoref/checkout-merge.git
cd checkout-merge

Approach 1 (create branch arbitrarily, checkout, push)

git branch new-work-point 9d14eb7
git push origin new-work-point
git checkout new-work-point

This is probably the closest analog to the flow in the web ui.
The checkout step is entirely optional. I’ve included it in the example because it seems likely that one would want to do work from that point…

Approach 2 (mark branch as a relative of current point)

git checkout -b new-work-point
git reset --hard HEAD~
git push origin new-work-point

Here I’m using ~ to say "go to a parent of HEAD" (this is a loose definition, you’ll want to read some explainers for a better explanation).

Note that the --hard is a dangerous flag, so don’t use it w/o reading about it (or do things as I’m doing them here: create an extra clone and play w/ it, instead of using the one you’re used to using).

Hi Jonathan,

You need to use the revert command to undo the previous commit, this is the documentation: Git - git-revert Documentation

Theory

This command create a new commit that revert the commit selected. Take this history of commit

A—B—C—D

A is the first commit and D the last one. I want to undo the changes made in D commit without erase it. I use the command git revert D this will create a new commit E that restore the changes made in C:

A—B—C—D—E

The project on commit C is the same on E :grinning:

Real Project

Leaving theory aside, let us turn to practice.

I have this got log:

The commit e300574 is the wrong one, but I can’t remove it so I will revert it.

I execute the command git revert e300574, this put me in the editor in order to create the new commit message. By default the message is revert with the commit message of the reverted commit, you can leave as is or change. Warning: the default editor for the commit is usually vim, to save and close click ESC then :wq and al last Enter.

Once you save the commit the revert is done and the history will looks like this:

Now I have the same contents of the commit cb2fa622 and I will push this history without any problems:

Conclusion

Don’t need to do more than this one command :grin: