I accidentally amended my previous commit. The commit should have been separate to keep history of the changes I made to a particular file.
Is there a way to undo that last commit? If I do something like git reset --hard HEAD^
, the first commit also is undone.
(I have not yet pushed to any remote directories)
git log --reflog -p -- {{name-of-the-dir-or-file-in-question}}
. It shows both the actual changes and the commit messages for each action. - anyone What you need to do is to create a new commit with the same details as the current HEAD
commit, but with the parent as the previous version of HEAD
. git reset --soft
will move the branch pointer so that the next commit happens on top of a different commit from where the current branch head is now.
# Move the current head so that it's pointing at the old commit
# Leave the index intact for redoing the commit.
# HEAD@{1} gives you "the commit that HEAD pointed at before
# it was moved to where it currently points at". Note that this is
# different from HEAD~1, which gives you "the commit that is the
# parent node of the commit that HEAD is currently pointing to."
git reset --soft HEAD@{1}
# commit the current tree using the commit details of the previous
# HEAD commit. (Note that HEAD@{1} is pointing somewhere different from the
# previous command. It's now pointing at the erroneously amended commit.)
# The -C option takes the given commit and reuses the log message and
# authorship information.
git commit -C HEAD@{1}
Answered 2023-09-21 08:09:27
git reflog
to find the correct number e.g. {2}
. - anyone git commit --amend
. The 2nd is a "redo" into a new commit. These work for any git commit
, not just --amend
. - anyone git commit
. - anyone git reset --soft HEAD@{1}
: fatal: ambiguous argument 'HEAD@1': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
. When I replaced HEAD@{1}
with the equivalent commit hash shown in git reflog
(thanks JJD!), this answer worked wonderfully! - anyone HEAD@{1}
. If I run echo HEAD@{1}
in tcsh for example, the output is HEAD@1
because the braces were interpreted by tcsh. If I use single quotes, the braces are preserved. - anyone use the ref-log:
git branch fixing-things HEAD@{1}
git reset fixing-things
you should then have all your previously amended changes only in your working copy and can commit again
to see a full list of previous indices type git reflog
Answered 2023-09-21 08:09:27
HEAD~1
is exactly the same as HEAD^
and identifiers the parent of the current commit. HEAD@{1}
on the other hand refers to the commit which HEAD pointed to before this one, i.e. they mean different commits when you checkout a different branch or amend a commit. - anyone git reset HEAD@{1}
is enough. - anyone reflog
means ref-log
and not re-flog
? This makes so much more sense - anyone None of these answers with the use of HEAD@{1}
worked out for me, so here's my solution:
git reflog
d0c9f22 HEAD@{0}: commit (amend): [Feature] - ABC Commit Description
c296452 HEAD@{1}: commit: [Feature] - ABC Commit Description
git reset --soft c296452
Your staging environment will now contain all of the changes that you accidentally merged with the c296452 commit.
Answered 2023-09-21 08:09:27
git commit --amend
on an already pushed commit and therefore the other suggestions did not work. But this did. Thanks. - anyone git reset --soft HEAD@{1}
to cancel the latest amend. - anyone git reset --soft "HEAD@{1}"
needs to have quotes. {1}
is special syntax it seems like - anyone Find your amended commits by:
git log --reflog
Note: You may add --patch
to see the body of the commits for clarity. Same as git reflog
.
then reset your HEAD to any previous commit at the point it was fine by:
git reset SHA1 --hard
Note: Replace SHA1 with your real commit hash. Also note that this command will lose any uncommitted changes, so you may stash them before. Alternatively, use --soft
instead to retain the latest changes and then commit them.
Then cherry-pick the other commit that you need on top of it:
git cherry-pick SHA1
Answered 2023-09-21 08:09:27
git reset SHA1 --soft
, you can retain the latest changes and then commit them. - anyone git log --reflog -p -- {{name-of-the-dir-or-file-in-question}}
. It shows both the actual changes and the commit messages. - anyone git reset SHA1
, which defaults to mode --mixed
which doesn't reset the working tree, allowing you to commit right away. git reset SHA1 && git commit -m "abc"
- anyone reset --soft
has the benefit (as I see it in this scenario) of putting the changes back in the index (not in the working tree). This way you're sure, if you commit again, you'll be committing the same changes as the commit you just reset it. This is handy to me when I amend a commit by mistake. - anyone git reset --soft 'HEAD@{1}'
- anyone If you have pushed the commit to remote and then erroneously amended changes to that commit this will fix your problem. Issue a git log
to find the SHA before the commit. (this assumes remote is named origin). Now issue these command using that SHA.
git reset --soft <SHA BEFORE THE AMMEND>
#you now see all the changes in the commit and the amend undone
#save ALL the changes to the stash
git stash
git pull origin <your-branch> --ff-only
#if you issue git log you can see that you have the commit you didn't want to amend
git stash pop
#git status reveals only the changes you incorrectly amended
#now you can create your new unamended commit
Answered 2023-09-21 08:09:27
Possibly worth noting that if you're still in your editor with the commit message, you can delete the commit message and it will abort the git commit --amend
command.
Answered 2023-09-21 08:09:27
You can always split a commit, From the manual
Answered 2023-09-21 08:09:27
git reflog
is all you need - anyone git reset
instead of git reset --soft
, then do git add --patch
. - anyone Maybe can use git reflog
to get two commit before amend and after amend.
Then use git diff before_commit_id after_commit_id > d.diff
to get diff between before amend and after amend.
Next use git checkout before_commit_id
to back to before commit
And last use git apply d.diff
to apply the real change you did.
That solves my problem.
Answered 2023-09-21 08:09:27
You can do below to undo your git commit —amend
git reset --soft HEAD^
git checkout files_from_old_commit_on_branch
git pull origin your_branch_name
====================================
Now your changes are as per previous. So you are done with the undo for git commit —amend
Now you can do git push origin <your_branch_name>
, to push to the branch.
Answered 2023-09-21 08:09:27
git restore --staged <YOUR_FILES>
to unstage changes. - anyone Almost 9 years late to this but didn't see this variation mentioned accomplishing the same thing (it's kind of a combination of a few of these, similar to to top answer (https://stackoverflow.com/a/1459264/4642530).
Search all detached heads on branch
git reflog show origin/BRANCH_NAME --date=relative
Then find the SHA1 hash
Reset to old SHA1
git reset --hard SHA1
Then push it back up.
git push origin BRANCH_NAME
Done.
This will revert you back to the old commit entirely.
(Including the date of the prior overwritten detached commit head)
Answered 2023-09-21 08:09:27
--soft
to keep my changes. I just want it committed separately - anyone Checkout to temporary branch with last commit
git branch temp HEAD@{1}
Reset last commit
git reset temp
Now, you'll have all files your commit as well as previous commit. Check status of all the files.
git status
Reset your commit files from git stage.
git reset myfile1.js
(so on)
Reattach this commit
git commit -C HEAD@{1}
Add and commit your files to new commit.
Answered 2023-09-21 08:09:27
Simple Solution Solution Works Given: If your HEAD commit is in sync with remote commit.
The cherry-picked commit will only contain your latest changes, not the old changes. You can now just rename this commit.
Answered 2023-09-21 08:09:27
master
/ main
if no one else has merged to it yet. Saved me today! - anyone This is how you can do it easily:
git reset --soft HEAD^
git commit -m "new commit msg"
Now push the changes and rebase this commit on top of last commit on which you had amended your changes.
This will make sure that the new commit has only amended changes.
Answered 2023-09-21 08:09:27