34

we want to undo the last 2 commits which were both pushed to origin master. in tortoise git, we can view the history, and click on the 3rd from last commit, and chose "reset master to this" which we are guessing means revert to this version.

however, when you select this option you have to choose from one of these three options:

  1. soft - leave working tree and index untouched.
  2. mixed - leave working tree untouched, reset index
  3. hard - reset working tree and index.

Unfortunately, we dont know which of these 3 options we should choose - we just want to undo the last two commits and go back in time.

The next question is does this operation happen on the remote origin, your repo, or your working directory, or a combination of these 3? E.g. does a commit and push have to be done after reverting, or does it do this for you?

We would take a guess that HARD is what we want - it will revert the repository (not sure which) and our local source code back to a previous version. If this is the case, why is this not the default, and what is the use case for the other two options? Either you want to revert or not, and if you only revert the remote repo, and not your local working files then you are going to be in a messy state.

We don't have any locally modified files.

Note, we are quite desperate for a solution which doesnt break git (we have broken git in the past and had to craete a new repo). Perhaps another method possible, such as checkout out a prevous version, then checking it in over the top of the latest version, but we dont know how to do this.

We get that we can do something like:

git checkout [revision]

But how do we then tell git that we want to make this version the new head or replace the head with this? I am guessing we cant just commit, as there is nothing to commit, as we are no longer on the master head. As an aside, if you check out a prev. version, and modify it, and commit, what are you committing and to where?

I have read https://www.atlassian.com/git/tutorials/undoing-changes but it does not address the relationship between local and remote repos. If the commits to be undone are all pushed to the remote origin master, it is unclear what the recipe is to revert the remote origin, the local repo and the working directory - all 3 must be reverted to the commit 3 commits ago. We dont really care if this is done with a reset or revert - we just need a way to do it which works across all 3 locations.

It might be that the corrrect recipie is something like this:

   git status (we are on master with a clean working dir)
   git git revert HEAD~2
   git commit -m "revert"
   git push origin mater

But we have never seen this set of steps in the examples, and would rather do it with tortoise git if possible.

John Little
  • 10,707
  • 19
  • 86
  • 158

4 Answers4

46

There are two ways you can do this.

  1. You can just remove everything and come back to the old state which is proper as per you.
  2. Revert the changes which you have made.

For the 1st Solution, you can use the following commands:

git reset --hard <commit-id>

This will bring the Head for the branch in you are currently to that specific "commit-id" which as per you is correct and proper.

git push -f origin <branch-name>

This command will forcefully push to the branch you are in. The combination of this command and the above command can enable you to remove all the unnecessary commits you have in your branch starting from the very top and till this "commit-id"

Note: This won't remove the "commit-id" everything up till the "commit-id" will be removed from your branch.

For the 2nd Solution, you can use the following commands:

git revert <commit-id>

This command is used to revert the specific "commit-id" you are trying to undo.

If by mistake you have merged another branch into your different branch then you can use this command to revert the merge request:

git revert -m 2 <commit-id>

This command is used to revert or remove all the changes that took place in the merge commit "commit-id". This will allow reverting the merge commit "commit-id", also it will remove all the commit's changes which came with this merge. But it won't remove the commits which came with the merge

Jheel Agrawal
  • 644
  • 6
  • 6
27

this solution saved my time

1) git reset --hard 93827927ed6e245be27f94c93c7e3574e85b91c6 (this is your commit id)
2) git reset HEAD~1
3) git stash
4) git add .
5) git commit -m "your new commit message here"
6) git push --force

arul pushpam
  • 501
  • 6
  • 6
11

There are two options:

  1. go back in history, but preserve history: revert
  2. go back in history and alter history, so the content of the commits is removed forever: reset --hard and push --force.

If you're not sure, then use revert, it's the safest option.

If you really, really, like to remove the commits and don't care about the changed history, use reset --hard and push --force. This has the following consequences:

  • Others could reintroduce the commit
  • Others could depend on the commit that has been removed
  • In public repositories, force pushing to the master is a no-go

Questions

The next question is does this operation happen on the remote origin, your repo, or your working directory, or a combination of these 3? E.g. does a commit and push have to be done after reverting, or does it do this for you?

In general all changes in TortioseGit are in your clone ("working copy"). Also push is always a manual action

We would take a guess that HARD is what we want - it will revert the repository (not sure which) and our local source code back to a previous version. If this is the case, why is this not the default, and what is the use case for the other two options?

Because hard removes commits and so the history, it is a dangerous operation. You could remove also changes of others!

what is the use case for the other two options?

See What's the difference between git reset --mixed, --soft, and --hard?

Steps in TortoiseGit:

Revert

  1. Revert commit (from log)

enter image description here

  1. Commit changes enter image description here

  2. and push

Reset hard and force push

  1. Reset (from log)

enter image description here

  1. Choose hard

enter image description here

  1. Force push (checkbox "known changes")

enter image description here

Julian
  • 33,915
  • 22
  • 119
  • 174
6

I think you're confusing revert and reset, see Undoing Changes:

revert

The git revert command undoes a committed snapshot. But, instead of removing the commit from the project history, it figures out how to undo the changes introduced by the commit and appends a new commit with the resulting content. This prevents Git from losing history, which is important for the integrity of your revision history and for reliable collaboration.

reset

If git revert is a “safe” way to undo changes, you can think of git reset as the dangerous method. When you undo with git reset(and the commits are no longer referenced by any ref or the reflog), there is no way to retrieve the original copy—it is a permanent undo. Care must be taken when using this tool, as it’s one of the only Git commands that has the potential to lose your work.

Probably in your case better to use revert:

enter image description here

in this case you just create new commit, which revert specific commit, no history change. You can do it locally and then push to remote.

If you still want to do reset and don't need to keep local changes, you do hard reset:

enter image description here

and then you should do force push:

git push -f
Alexan
  • 8,165
  • 14
  • 74
  • 101
  • Thanks for the clarification. Unfortuantely, the "Revert.." option in tortoise git then shows a dialog with an emtp list "File list is emtpy", so there is no option to go back. Note, the changes are already pushed to origin. – John Little Oct 23 '17 at 19:46
  • @JohnLittle, I did revert many times and don't remember any dialog with empty list – Alexan Oct 23 '17 at 19:55
  • Ah, I see - you are right clicking on the revision in the log history, I was right clicking on the project root folder. Ok, If I chose "revert changes by this commit" and I have chosen a commit 3 commits ago, will it revert the last 3, or only that specific one? When I chose say the 3rd from last commit, it says "Revisions reverted. All changes integrated into your working tree now", and two buttons "OK" and "commit". Which should I chose - what is the difference? Once I have done this, what next? Do I need to push to the origin master, or is that done? – John Little Oct 23 '17 at 20:16
  • Ok, I tried it, and selected "Commit". Then I pushed. Unfortunately, it only seems to have reverted the one commit, not the last X, so now I am in a worse situation than before. This was what I was worried about, the more I try to fix it without a complete recipe, the worse the mess becomes. – John Little Oct 23 '17 at 20:22
  • if you select one, it revert only one, but you can select several. And yes you need commit and push. – Alexan Oct 23 '17 at 20:23