I would like to organize my PR after my feature is done by removing all of my 'work in progress'-commits and creating new commits that group files to improve the readability of my PR.
I have tried using git reset, but that only unstages changes that have been added using git add . & all files that are already committed seem to be out of reach.
Undo a commit & redo
$ git commit -m "Something terribly misguided" # (0: Your Accident)
$ git reset HEAD~ # (1)
# === If you just want to undo the commit, stop here! ===
[ edit files as necessary ] # (2)
$ git add . # (3)
$ git commit -c ORIG_HEAD # (4)
git resetis the command responsible for the undo. It will undo your last commit while leaving your working tree (the state of your files on disk) untouched. You'll need to add them again before you can commit them again.- Make corrections to working tree files.
git addanything that you want to include in your new commit.- Commit the changes, reusing the old commit message.
resetcopied the old head to.git/ORIG_HEAD;commitwith-c ORIG_HEADwill open an editor, which initially contains the log message from the old commit and allows you to edit it. If you do not need to edit the message, you could use the-Coption.
Alternatively, to edit the previous commit (or just its commit message), commit --amend will add changes within the current index to the previous commit.
To remove (not revert) a commit that has been pushed to the server, rewriting history with git push origin main --force[-with-lease] is necessary. It's almost always a bad idea to use --force; prefer --force-with-lease instead, and as noted in the git manual:
You should understand the implications of rewriting history if you amend a commit that has already been published.
Further Reading
You can use git reflog to determine the SHA-1 for the commit to which you wish to revert. Once you have this value, use the sequence of commands as explained above.
HEAD~ is the same as HEAD~1. The article What is the HEAD in git? is helpful if you want to uncommit multiple commits.
Undoing a commit is a little scary if you don't know how it works. But it's actually amazingly easy if you do understand. I'll show you the 4 different ways you can undo a commit.
Say you have this, where C is your HEAD and (F) is the state of your files.
(F)
A-B-C
↑
master
Option 1: git reset --hard
You want to destroy commit C and also throw away any uncommitted changes. You do this:
git reset --hard HEAD~1
The result is:
(F)
A-B
↑
master
Now B is the HEAD. Because you used --hard, your files are reset to their state at commit B.
Option 2: git reset
Maybe commit C wasn't a disaster, but just a bit off. You want to undo the commit but keep your changes for a bit of editing before you do a better commit. Starting again from here, with C as your HEAD:
(F)
A-B-C
↑
master
Do this, leaving off the --hard:
git reset HEAD~1
In this case the result is:
(F)
A-B-C
↑
master
In both cases, HEAD is just a pointer to the latest commit. When you do a git reset HEAD~1, you tell Git to move the HEAD pointer back one commit. But (unless you use --hard) you leave your files as they were. So now git status shows the changes you had checked into C. You haven't lost a thing!
Option 3: git reset --soft
For the lightest touch, you can even undo your commit but leave your files and your index:
git reset --soft HEAD~1
This not only leaves your files alone, it even leaves your index alone. When you do git status, you'll see that the same files are in the index as before. In fact, right after this command, you could do git commit and you'd be redoing the same commit you just had.
Option 4: you did git reset --hard and need to get that code back
One more thing: Suppose you destroy a commit as in the first example, but then discover you needed it after all? Tough luck, right?
Nope, there's still a way to get it back. Type this
git reflog
and you'll see a list of (partial) commit SHAs (that is, hashes) that you've moved around in. Find the commit you destroyed, and do this:
git checkout -b someNewBranchName shaYouDestroyed
You've now resurrected that commit. Commits don't actually get destroyed in Git for some 90 days, so you can usually go back and rescue one you didn't mean to get rid of.
Im working in enterprise and Ive never had to do this before . I accidentally pushed the target folder. How would I revert the commits without losing my changes safely in IntelliJ. I have googled but I am afraid in case it messes up my work
I need to delete the remote branch then back the changes. .
You can reset the head on your checked out branch to any hash you'd like in your history. It won't make changes to the files in your workspace without the -hard flag, so just do a reset to whatever commit you'd like, without passing it -hard.
This, of course, ignores whatever "Intellij" is, but you asked a question in "r/git", and that's how what you asked is addressed with Git.
Besides the suggested commands, you might also be interested in bfg_cleaner
Hello everyone! I'm working on a project in a team. I'm using GUI git client Fork, while also learning command line git.
I finished a task and made a commit (not pushed), but soon realized that I didn't get it done properly, and that I needed to put more work into it. So I left my initial commit as it was, and just kept on working on the task. Right now I'm finally finishing it, but I'm asked to make only one commit with the whole task in it.
When I try to Revert the initial commit, it gives me an error:
Your local changes to the following files would be overwritten by merge Revert failed
What should I do to keep the changes in the initial commit and reapply the new ones? I may have rewritten some code from the initial commit, but not fully, so some parts must stay, and the new changes to be added.
Thank you for your attention!
Maintainers will be more than happy if you keep the git history clean :D
I'm quite sure all of these happened to you at least once:
-
You committed a change with the wrong message (typo, wrong tense, etc.)
-
You committed a change with the wrong files (something missing, too many files, etc.)
-
You committed a change too early (feature isn't complete yet)
-
You committed a change you didn't want to (wrong code, just needs to be deleted)
Sure, you can just add a new commit, but in the long run, this will mess up your git history (unless you're closing PRs with squash).
If you want to keep your history clean and make your mistake disappear, let me show you 4 different ways to undo a commit. They're similar but not exactly the same, so you can apply the best one for your situation.
Bonus content: I'll also show you how to restore hard-deleted changes. What does that mean? I'll get into that later.
As usual, there's a live demo waiting for you on my YouTube channel where I show you all the content of this article plus some extra words and scenarios. If you're just here for the commands, you can skip the video and go straight to the article.
--> Click here for the video <--
Table of Contents
-
-
Amend no-edit
-
-
2. Amend & Change Message
-
3. Reset (soft)
-
4. Reset (hard)
-
Bonus: Restore Hard Deleted Changes
1. Amend no-edit
Let's start with the easiest situation, you already did a commit but you forgot to add some files.
Instead of creating an extra commit on top, you can run git commit --amend --no-edit. As a result, the last commit will be updated with the new files.
git add . git commit --amend --no-edit
No extra actions required, you're done!
2. Amend & Change Message
Similar situation to the previous one, but you also want to change the commit message.
git add . git commit --amend
This will open your default editor and you can change the commit message. Once you're done, save and close the editor. The commit will be updated with the new message.
Actually, git add . is not required if all you wanted to do is to change the commit message. You can just run git commit --amend.
3. Reset (soft)
This is the case where you want to undo a commit, but you want to keep the changes so that you can make a new commit at a later time.
git reset is kind of a time travel, really powerful but also dangerous. The most common use case is probably to undo a commit but keep in mind that you can do much more.
The full command we need is git reset --soft HEAD~1.
-
--softmeans that the changes will be kept. -
HEADmeans the current commit you're on. -
HEAD~1means the last commit, but you can also useHEAD~2to undo the last 2 commits. -
A shortcut for
HEADis@, so@~1would be the same asHEAD~1.
After running this command, you'll see that the last commit is gone but the files still have your changes applied.
You can now keep working and whenever you're ready you can do a new commit.
4. Reset (hard)
This is the case where you want to undo a commit and you don't want to keep the changes.
If you want to delete the changes, you need to add the --hard flag while running git reset.
Warning: this will also delete any uncommitted changes you have.
The full command we need this time is git reset --hard HEAD~1 and it will delete the last commit and the changes. Forever. Or is it?
Bonus: Restore Hard Deleted Changes
If you run git reset --hard HEAD~1 and you're not happy with the result, you can still restore the changes.
As we've just seen, git reset is our time travel machine, but we need to tell it where to go. In this case we entirely removed a commit and there's no trace in the git history, so we cannot say HEAD~number anymore.
Luckily, git keeps a log of all the commits that have been removed. You can see this log by running git reflog.
You want to look at a log like this one:
1b2c3d4 HEAD@{0}: reset: moving to HEAD~1This means that you were at commit 1b2c3d4 and you did a reset to the previous commit. You can now use this commit ID to restore the changes.
git reset --hard 1b2c3d4
What are we doing here? We're telling git to go back to the commit 1b2c3d4 and to get rid of all the changes we did (in this case, the change was deleting the commit). Undoing a delete operation actually means restoring the deleted commit.
Conclusion
I hope you found this article useful and learned something new. If you have any questions or suggestions, feel free to leave a comment below.
I know there are at least a dozen different ways of moving around in git. I selected these 4 for simplicity but if you want to expand and add more in the comment section, let's do it!
Let me recommend once more to also watch the live demo on YouTube and leave a like to support my work.
Thanks!
Say you have this
commit A
commit B
commit C
commit D
where commit A is the earliest, and D is the latest commit.
You now realize that you made mistake in commit B. You want to revert the changes made in B but you do not want to revert the changes in commit C and D.
Sorry for the noob question but all the google answers are spread out over 10 years and totally different answers. I can't find a common consensus on this and don't want to screw anything up.
I just need to go back to my last commit. I committed and everything was fine but recent code changes broke the site and I need to go back to when things were working.
It says in the terminal:
(use "git restore <file>..." to discard changes in working directory)
This is what I'm looking for right? If I do "git restore <file>" it will discard all my changes and go back to what the file was like before I made the breaking changes?
Also, if so, I have a lot of files to change, if I just do "git restore" without a specified file will it restore ALL the files that have been modified so I don't have to go one by one?
Hi, I'm kind of stuck. I'm working on a local repository which I haven't pushed to a remote repository yet. The latest commit has a file that I'd like to remove from the commit because it is too big.
I didn't mean to add it to the staging area and I wasn't careful and committed it but only realized when I attempted to push it and got an error that there's a large file.
I've come across many answers like this one on StackOverflow and this on Medium but I'm not sure which one I should use. If anyone could point me in a direction, I would really appreciate it.
I apologize if this doesn't belong here and I will remove it.
Hi there –
I've made a complete mess of my repo. Three branches are now in an unreliable state.
Unfortunately, much of the mess is already on GitHub.
I'd like to completely delete all commits that were made after a certain point, so that I can start over with a clean slate.
How can I do this, in a way that will also delete the problematic commits from GitHub?
Unfortunately, I'm not a very proficient Git user – so anything about rebasing, reflogs, etc. is going to lose me very quickly. Please, speak slowly and use small words :)
Thanks for any suggestions.
ETA: I found this StackOverflow answer, which recommends doing git reset --hard <last_working_commit_id> to delete the bad commits, and then using git push --force to delete them from GitHub. This sounds easy, but is there anything I should consider before using this technique?
Just curious, is there a way to do that?
Like if you have a list of commits:
C:\Users\username\yourproject>git log --oneline 3 (HEAD -> master) profit 2 ??? 1 steal underwear 0 initial commit
And instead of reverting "???" to get to steal underwear, you just do some other thing to get to steal underwear that you're also able to commit forward, how would you do that?
Are there any options?