On undoing, fixing, or removing commits in git (2024)

Table of Contents
First step Are you trying to find that which is lost or fix a change that was made? Have you committed? Discard everything or just some things? How to save uncommitted changes How to undo all uncommitted changes How to undo some uncommitted changes Do you have uncommitted stuff in your working directory? Have you pushed? Do you want to discard all unpushed changes on this branch? Discarding all local commits on this branch Replacing all branch history/contents Is the commit you want to fix the most recent? Do you want to remove or change the commit message/contents of the last commit? Removing the last commit Reworking the last commit Moving a commit from one branch to another Updating the last commit's contents or commit message Do you want to remove an entire commit? Removing an entire commit Do you want to remove/change/rename a particular file/directory from all commits during all of git's history Changing all commits during all of git's history Use The BFG to remove unwanted data, like big files or passwords,from Git repository history. Arbitrarily changing all commits during all of git's history Is a merge commit involved? Changing a single commit involving only simple commits Changing a single commit involving a merge Can you make a positive commit to fix the problem and what is the fix class? Making a new commit to fix an old commit Making a new commit to restore a file deleted earlier Reverting an old simple pushed commit Reverting a merge commit Rewriting an old branch with a new branch with a new commit I am a bad person and must rewrite published history I have lost some commits I know I made Undoing the last few git operations affecting HEAD/my branch's tip Recovering from a borked/stupid/moribund merge Recovering from a borked/stupid/moribund rebase Disclaimer Copyright Thanks Comments Line eater fodder

A git choose-your-own-adventure!ⓡ

This document is an attempt to be a fairly comprehensive guide torecovering from what you did not mean to do when using git. It isn'tthat git is so complicated that you need a large document to take careof your particular problem, it is more that the set of things that youmight have done is so large that different techniques are neededdepending on exactly what you have done and what you want to havehappen.

If you have problems after clicking through this document, pleasecopy-paste the "Path" you took (what links you clicked on,automatically presented to you if javascript is available) when askingfor further help, since doing so will explain very precisely what youwere trying to do, and that you at least tried to help yourself.

First step

Strongly consider taking abackupof your current working directory and .git to avoid any possibility oflosing data as a result of the use or misuse of these instructions. Wepromise to laugh at you if you fail to take a backup and regret itlater.

Answer the questions posed by clicking the link for that section.A section with no links is a terminal node and you should have solvedyour problem by completing the suggestions posed by that node (if not,then report the chain of answers you made on #git or some other gitresource and explain further why the proposed answer doesn't help).This is not a document to read linearly.

Proceed to the first question

Are you trying to find that which is lost or fix a change that was made?

Due to previous activities (thrashing about), you may have lostsome work which you would like to find and restore. Alternately, youmay have made some changes which you would like to fix. Fixingincludes updating, rewording, and deleting or discarding.

  • Fix a change
  • Find what is lost

Have you committed?

If you have not yet committed that which you do not want, git doesnot know anything about what you have done yet, so it is pretty easyto undo what you have done.

  • I am in the middle of a bad merge
  • I am in the middle of a bad rebase
  • Yes, commits were made
  • No, I have not yet committed

Discard everything or just some things?

So you have not yet committed, the question is now whether you wantto undo everything which you have done since the last commit or justsome things, or just save what you have done?

  • Discard everything
  • Discard some things
  • I want to save my changes

How to save uncommitted changes

There are five ways you can save your uncommitted change. I alsosuggest you read Pro Git as theseare pretty basic git operations.

DescriptionCommand
Commit them on the local branch.git commit -am "My descriptive message"
Commit them on another branch, no checkout conflicts.git checkout otherbranch && git commit -am "My descriptive message"
Commit them on another branch, conflicts.git stash; git checkout otherbranch; git stash apply; : "resolve conflicts"; git commit -am "My descriptive message"; git stash drop
Commit them on a new branch.git checkout -b newbranch; git commit -am "My descriptive message"
Stash them for a rainy day.git stash save "my descriptive name"

Using git add -p to add/commit only somechanges to make multiple commits is left as an exercise for thereader.

How to undo all uncommitted changes

So you have not yet committed and you want to undo everything.Well, bestpractice is for you to stash the changes in case you were mistakenand later decide that you really wanted them afterall. git stash save "description ofchanges". You can revisit those stasheslater git stash list and decide whetherto git stash drop them after some time haspast. Please note that untracked and ignored files are not stashed bydefault. See "--include-untracked" and "--all" for stash options tohandle those two cases.

However, perhaps you are confident (or arrogant) enough to know forsure that you will never ever want the uncommitted changes. If so,you can run git reset --hard, howeverplease be quite aware that this is almost certainly a completelyunrecoverable operation. Any changes which are removed here cannot berestored later. This will not delete untracked or ignored files.Those can be deleted with git clean-nd git clean -ndX respectively,or git clean -ndx for both at once. Well,actually those command do not delete the files. They show what fileswill be deleted. Replace the "n" in "-nd…" with "f" to actuallydelete thefiles. Bestpractice is to ensure you are not deleting what you should not bylooking at the moribund filenames first.

How to undo some uncommitted changes

So you have not yet committed and you want to undo some things,well git status will tell you exactly whatyou need to do. For example:

# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## new file: .gitignore## Changes not staged for commit:# (use "git add <file>..." to update what will be committed)# (use "git checkout -- <file>..." to discard changes in working directory)## modified: A## Untracked files:# (use "git add <file>..." to include in what will be committed)## C

However, the git checkout in file modeis a command that cannot be recovered from—the changes which arediscarded most probably cannot be recovered. Perhaps you shouldrun git stash save -p "description"instead, and select the changes you no longer want to be stashedinstead of zapping them.

Do you have uncommitted stuff in your working directory?

So you have committed. However, before we go about fixing orremoving whatever is wrong, you should first ensure that anyuncommitted changes are safe, by either committing them(git commit) or by stashing them(git stash save "message") or getting ridof them.

git status will help you understandwhether your working directory is clean or not. It should reportnothing for perfect safety ("Untracked files" only are sometimessafe.)

  • No, I have no changes/working directory is clean
  • Yes, I have bad changes/working directory is dirty: discard it
  • Yes, I have good changes/working directory is dirty: save it

Have you pushed?

So you have committed, the question is now whether you have madeyour changes (or at least the changes you are interesting in "fixing")publicly available or not. Publishing history is a seminal event.

If you are dealing with commits someone else made, thenthis question covers whether they have pushed, and since youhave their commits, the answer is almost certainly "yes".

Please note in any and all events, the recipes provided here willtypically (only one exception which will self-notify) only modify thecurrent branch you are on. Specifically any tags or branchesinvolving the commit you are changing or a child of that commit willnot be modified. You must deal with those separately. Lookat gitk --all --date-order to helpvisualize everything what other git references might need to beupdated.

Also note that these commands will fix up the referenced commits inyour repository. There will be reflog'd and dangling commits holdingthe state you just corrected. This is normally a good thing and itwill eventually go away by itself, but if for some reason you want tocut your seat belts, you can expire the reflog now and garbage collectwith immediate pruning.

  • Yes, pushes were made
  • No pushes

Do you want to discard all unpushed changes on this branch?

There is a shortcut in case you want to discard all changes made onthis branch since you have last pushed or in any event, to make yourlocal branch identical to "upstream". Upstream, for local trackingbranches, is the place you get history from whenyou git pull: typically for master itmight be origin/master. There is a variant of this option which letsyou make your local branch identical to some other branch or ref.

  • Yes, I want to discard all unpushed changes
  • Yes, and I want to make my branch identical to some non-upstream ref
  • No, I want to fix some unpushed changes

Discarding all local commits on this branch

In order to discard all local commits on this branch, to make thelocal branch identical to the "upstream" of this branch, simply rungit reset --hard @{u}

Replacing all branch history/contents

If instead of discarding all local commits, you can make yourbranch identical to some other branch, tag, ref, or SHA that exists onyour system.

The first thing you need to do is identify the SHA or ref of thegood state of your branch. You can do this by looking at the outputof git branch -a; gittag, git log --all or, mypreference, you can look graphically at gitk--all --date-order

Once you have found the correct state of your branch, you can get tothat state by running:

git reset --hard REF

Obviously replace "REF" with the reference or SHA you want to getback to.

Is the commit you want to fix the most recent?

While the techniques mentioned to deal with deeper commits willwork on the most recent, there are some convenient shortcuts you cantake with the most recent commit.

  • Yes, I want to change the most recent commit
  • Yes, I want to discard the most recent commit(s)
  • Yes, I want to undo the last git operation(s) affecting the HEAD/tip of my branch (most useful for rebase, reset, or --amend)
  • No, I want to change an older commit
  • No, I want to restore a older version of/deleted file as a new commit
  • Either way, I want to move a commit from one branch to another

Do you want to remove or change the commit message/contents of the last commit?

  • I want to remove the last commit
  • I want to update the author/message/contents of the last commit
  • I want to reorder, split, merge, or significantly rework the last commit(s)

Removing the last commit

To remove the last commit from git, you can simplyrun git reset --hard HEAD^ If you areremoving multiple commits from the top, you canrun git reset --hard HEAD~2 to remove the lasttwo commits. You can increase the number to remove even morecommits.

If you want to "uncommit" the commits, but keep the changes aroundfor reworking, remove the"--hard": git reset HEAD^ which will evictthe commits from the branch and from the index, but leave the workingtree around.

If you want to save the commits on a new branch name, thenrun git branchnewbranchname before doingthe git reset.

Reworking the last commit

WARNING: These techniques should only be used fornon-merge commits. If you have a merge commit, you are better offdeleting the merge and recreating it.

If you want to perform significant work on the last commit, you cansimply git reset HEAD^. This will undothe commit (peel it off) and restore the index to the state it was inbefore that commit, leaving the working directory with the changesuncommitted, and you can fix whatever you need to fix and tryagain.

You can do this with multiple (non-merge) commits in a row (using"HEAD^^" or similar techniques), but then of course you lose theseparation between the commits and are left with an undifferentiatedworking directory. If you are trying to squash all of the commitstogether, or rework which bits are in which commits, this may be whatyou want.

If you want to reorder commits, split them, merge them together, orotherwise perfect the commits, you shouldexplore PostProduction Editing Using Git.

Moving a commit from one branch to another

So, you have a commit which is in the wrong place and you want tomove it from one branch to another. In order to do this, you willneed to know the SHA of the first and last commit (in a continuousseries of commits) you want to move (those values are the same if youare moving only one commit), the name of the branch you are moving thecommit from, and the name of the branch you are moving the commit to.In the example below, I will name these four values $first, $last,$source, and $destination (respectively). Additionally, you will needto use a noncebranch as a placeholder. I will call the nonce branch "nonce" in thefollowing example. However, you may use any branch name that is notcurrently in use. You can delete it immediately after you aredone.

git branch nonce $lastgit rebase -r --onto $destination $first^ nonce

Remember that when you substitute $first in the command above, leavethe "^" alone, it is literal.

Use gitk --all --date-order to check tomake sure the move looks correct (pretending that nonce is thedestination branch). Please check very carefully if you were tryingto move a merge, it may have been recreated improperly. Ifyou don't like the result, you may delete the nonce branch(git branch -D nonce) and try again.

However, if everything looks good, we can move the actualdestination branch pointer to where nonce is:

git checkout $destinationgit reset --hard noncegit branch -d nonce

If you double-checked with gitk --all--date-order, you would see that the destination branch lookscorrect. However, the commits are still on the source branch as well.We can get rid of those now:

git rebase -r --onto $first^ $last $source

Using gitk --all --date-order one lasttime, you should now see that the commits on the source branch havegone away. You have successfully moved the commits. Please check verycarefully if merges occurred after the commits which were deleted.They may have been recreated incorrectly. If so you caneither undo thedelete or try to delete the bad merge and try to recreate itmanually, or create a fake (--ours) merge from the same SHA so thatgit is aware that the merge occurred.

Updating the last commit's contents or commit message

To update the last commit's contents, author, or commit message fora commit which you have not pushed or otherwise published, first youneed to get the index into the correct state you wish the commit toreflect. If you are changing the commit message only, you need donothing. If you are changing the file contents, typically you wouldmodify the working directory and use gitadd as normal.

Note if you wish to restore a file to a known good state, you canuse: git checkout GOODSHA --path/to/filename.

Once the index is in the correct state, then you canrun git commit --amend to update the lastcommit. Yes, you can use "-a" if you want to avoidthe git add suggested in the previousparagraph. You can also use --author to change the authorinformation.

If you want to do something more sophisticated that what "--amend"allows, please investigate reworking thelast commit.

Do you want to remove an entire commit?

  • Yes, I want to remove an entire commit
  • No, I want to change an older commit

Removing an entire commit

I call this operation "cherry-pit" since it is the inverse of a"cherry-pick". You must first identify the SHA of the commit you wishto remove. You can do this using gitk--date-order or using git log --graph--decorate --oneline You are looking for the 40 character SHA-1hash ID (or the 7 character abbreviation). Yes, if you know the "^"or "~" shortcuts you may use those.

git rebase -r --onto SHA^ SHA

Obviously replace "SHA" with the reference you want to get rid of.The "^" in that command is literal.

However, please be warned. If some of the commits between SHA andthe tip of your branch are merge commits, it is possiblethat git rebase -r will be unable toproperly recreate them. Please inspect the resulting mergetopology gitk --date-order HEAD ORIG_HEADand contents to ensure that git did want you wanted. If it did not,there is not really any automated recourse. You can reset back to thecommit before the SHA you want to get rid of, and then cherry-pick thenormal commits and manually re-merge the "bad" merges. Or you canjust suffer with the inappropriate topology (perhaps creating fakemerges git merge --ours otherbranch sothat subsequent development work on those branches will be properlymerged in with the correct merge-base).

Do you want to remove/change/rename a particular file/directory from all commits during all of git's history

  • Yes please, I want to make a change involving all git commits
  • No, I only want to change a single commit

Changing all commits during all of git's history

You have not pushed but still somehow want to change all commits inall of git's history? Strange.

  • Not just removing data (eg. re-arranging directory structure for all commits), or just wanting to use standard tools
  • Want to only remove unwanted data (big files, private data, etc) and am willing to use a third party tool to do the job more quickly

Use The BFG to remove unwanted data, like big files or passwords,from Git repository history.

Disclaimer, the author of this document has not qualified this tool(including for safety or usability for any purpose), but recognizesthe need which this tool fills for large repositories.

The BFG is a simpler,faster alternative to git filter-branch,specifically designed for cleansing bad data out of your Git repositoryhistory - it operates over all branches and tags in your project topurge data you don't want retained anywhere. Someexamples:

Remove all blobs bigger than 1 megabyte (to make your repo take up less space):

$ bfg --strip-blobs-bigger-than 1M my-repo.git

Replace all passwords listed in a file with ***REMOVED***wherever they occur in your repository :

$ bfg --replace-text passwords.txt my-repo.git

Arbitrarily changing all commits during all of git's history

git filter-branch is a powerful, complexcommand that allows you to perform arbitary scriptable operations on allcommits in git repository history. This flexibility can make it quite slowon big repos, and makes using the command quite difficult, so I will simplypoint you at the manual pageand remind youthat bestpractice is to always use "--tag-name-filter cat ----all" unless you are really sure you know what you aredoing.

BTW, this is the one command I referred to earlier which willupdate all tags and branches, at least if you use the best practicearguments.

Is a merge commit involved?

If the commit you are trying to change is a merge commit, or ifthere is a merge commit between the commit you are trying to changeand the tip of the branch you are on, then you need to do some specialhandling of the situation.

  • Yes, a merge commit is involved
  • No, only simple commits

Changing a single commit involving only simple commits

You must first identify the SHA of the commit you wish to remove.You can do this using gitk --date-order orusing git log --graph --decorate --onelineYou are looking for the 40 character SHA-1 hash ID (or the 7 characterabbreviation). Yes, if you know the "^" or "~" shortcuts you mayuse those.

git rebase -i SHA^

Obviously replace "SHA" with the reference you want to get rid of.The "^" in that command is literal.

You will be dumped in an editor with a bunch of lines starting withpick. The oldest commit, the one you are probably interested inchanging, is first. You will want to change the "pick" to "reword" or"edit", or perhaps even "squash" depending on what your goal is.Please read the manual pagefor more information. A documenton Post-ProductionEditing using Git goes through much of the major uses of gitrebase is some detail. The use case is a little different, but thefundamental techniques are not.

When using "edit", to change contents or author, when you aredumped into the shell to make your change, well make yourchange, git add as normal, and thenrun git commit --amend (including changingthe author information with --author). When you are satisfied, youshould run git rebase --continue

Changing a single commit involving a merge

Note, that this only applies if you have a merge commit. If afast-forward (ff) merge occurred you only have simple commits, soshould use other instructions.

Oh dear. This is going to get a little complicated. It should allwork out, though. You will need to usea nonce branch as aplaceholder. I will call the nonce branch "nonce" in the followingexample. However, you may use any branch name that is not currentlyin use. You can delete it immediately after you are done.

  • Identify the SHA of the commit you wish to modify.

    You can do this using gitk --date-orderor using git log --graph --decorate--oneline You are looking for the 40 character SHA-1 hash ID(or the 7 character abbreviation). Yes, if you know the "^" or"~" shortcuts you may use those.

  • Remember the name of the branch you are currently on

    The line with a star on it in the gitbranch output is the branch you are currently on. I will use"$master" in this example, but substitute your branch name for"$master" in the following commands.

  • Create and checkout a nonce branch pointing at that commit.

    git checkout -b nonce SHA

    Obviously replace "SHA" with the reference you want to modify.

  • Modify the commit

    You need to get the index into the correct state you wish thecommit to reflect. If you are changing the commit message only, youneed do nothing. If you are changing the file contents, typically youwould modify the working directory and use gitadd as normal.

    Note if you wish to restore a file to a known good state, you canuse git checkout GOODSHA --path/to/filename.

    Once the index is in the correct state, then you canrun git commit --amend to update the lastcommit. Yes, you can use "-a" if you want to avoidthe git add suggested in the previousparagraph.

    If the commit you are updating is a merge commit, ensure that the logmessage reflects that.

  • Put the remaining commits after the new one you just created

    Remembering to substitute the correct branch name for $master

    git rebase -r --onto $(git rev-parse nonce) HEAD^ $master
  • Validate that the topology is still good

    If some of the commits after the commit you changed are mergecommits, please be warned. It is possiblethat git rebase -r will be unable toproperly recreate them. Please inspect the resulting mergetopology gitk --date-order HEAD ORIG_HEADto ensure that git did want you wanted. If it did not, there is notreally any automated recourse. You can reset back to the commitbefore the SHA you want to get rid of, and then cherry-pick the normalcommits and manually re-merge the "bad" merges. Or you can justsuffer with the inappropriate topology (perhaps creating fakemerges git merge --ours otherbranch sothat subsequent development work on those branches will be properlymerged in with the correct merge-base).

  • Delete the nonce branch

    You don't need it. It was just there to communicate an SHA betweentwo steps in the above process. git branch -dnonce

Can you make a positive commit to fix the problem and what is the fix class?

Rewritingpublic history is a bad idea. It requires everyone else to dospecial things and you must publicly announce your failure. Ideallyyou will create either a commit to just fix the problem, or anew git revert commit to create a newcommit which undoes what the commit target of the revert did.

  • Yes, I can make a new commit but the bad commit trashed a particular file in error (among other good things I want to keep)
  • Yes, I can make a new commit and the bad commit is a merge commit I want to totally remove
  • Yes, I can make a new commit but the bad commit is a simple commit I want to totally remove
  • Yes, I can make a new commit and the bad commit has an error in it I want to fix
  • Yes, I can make a new commit but history is all messed up and I have a replacement branch
  • No, I am a bad person and must rewrite published history

Making a new commit to fix an old commit

If the problem in the old commit is just something was doneincorrectly, go ahead and make a normal commit to fix the problem.Feel free to reference the old commit SHA in the commit message, andif you are into the blame-based development methodology, make fun ofthe person who made the mistake (or someone who recently left if youmade the mistake).

Making a new commit to restore a file deleted earlier

The file may have been deleted or every change to that file in thatcommit (and all commits since then) should be destroyed. If so, youcan simply checkout a version of the file which you know is good.

You must first identify the SHA of the commit containing the goodversion of the file. You can do this using gitk--date-order or using git log --graph--decorate --oneline or perhaps git log--oneline -- filename You are looking for the 40 characterSHA-1 hash ID (or the 7 character abbreviation). Yes, if you know the"^" or "~" shortcuts you may use those.

git checkout SHA -- path/to/filename

Obviously replace "SHA" with the reference that is good.You can then add and commit as normal to fix the problem.

Reverting an old simple pushed commit

To create an positive commit to remove the effects of a simple(non-merge) commit, you must first identify the SHA of the commit youwant to revert. You can do this using gitk--date-order or using git log --graph--decorate --oneline You are looking for the 40 character SHA-1hash ID (or the 7 character abbreviation). Yes, if you know the"^" or "~" shortcuts you may use those.

git revert SHA

Obviously replace "SHA" with the reference you want to revert. Ifyou want to revert multiple SHA, you may specify a range or a list ofSHA.

Reverting a merge commit

Note, that this only applies if you have a merge commit. If afast-forward (ff) merge occurred you only have simple commits, soshould use another method.

Oh dear. This is going to get complicated.

To create an positive commit to remove the effects of a mergecommit, you must first identify the SHA of the commit you want torevert. You can do this using gitk--date-order or using git log --graph--decorate --oneline You are looking for the 40 character SHA-1hash ID (or the 7 character abbreviation). Yes, if you know the"^" or "~" shortcuts you may use those.

Undoing the file modifications caused by the merge is about assimple as you might hope. git revert -m 1 SHA.(Obviously replace "SHA" with the reference you want to revert;-m 1 will revert changes from all butthe first parent, which is almost always what you want.)Unfortunately, this is just the tip of the iceberg. The problem is,what happens months later, long after you have exiled this problemfrom your memory, when you try again to merge these branches (or anyother branches they have been merged into)? Because git has ittracked in history that a merge occurred, it is not going to attemptto remerge what it has already merged, and even worse, if you mergefrom the branch where you did the revert you will undo thechanges on the branch where they were made. (Imagine you revert apremature merge of a long-lived topic branch into master and latermerge master into the topic branch to get other changes for testing.)

One option is actually to do this reverse merge immediately,annihilating any changes before the bad merge, and then to "revert therevert" to restore them. This leaves the changes removed from thebranch you mistakenly merged to, but present on their originalbranch, and allows merges in either direction without loss. Thisis the simplest option, and in many cases, can be the best.

A disadvantage of this approach is that gitblame output is not as useful (all the changes will beattributed to the revert of the revert) and gitbisect is similarly impaired. Another disadvantage is thatyou must merge all current changes in the target of the bad merge backinto the source; if your development style is to keep branches clean,this may be undesirable, and if you rebase your branches (e.g. withgit pull --rebase), it could causecomplications unless you are careful to use gitrebase -r to rebase merges (formerly known as preserving merges).

In the following example please replace $destination with the nameof the branch that was the destination of the bad merge, $sourcewith the name of the branch that was the source of the bad merge,and $sha with the SHA-1 hash ID of the bad merge itself.

git checkout $destinationgit revert $sha# save the SHA-1 of the revert commit to un-revert it laterrevert=`git rev-parse HEAD`git checkout $sourcegit merge $destinationgit revert $revert

Another option is to abandon the branch you merged from, recreateit from the previous merge-base with the commits since then rebased orcherry-picked over, and use the recreated branch from now on. Thenthe new branch is unrelated and will merge properly. Of course, ifyou have pushed the donor branch you cannot use the same name (thatwould be rewriting public history and is bad) so everyone needs toremember to use the new branch. Hopefully you have something likegitolite where you can closethe old branch name.

This approach has the advantage that the recreated donor branchwill have cleaner history, but especially if there have been manycommits (and especially merges) to the branch, it can be a lot of work.At this time, I will not walk you through the process of recreatingthe donor branch. Given sufficient demand I can try to add that.However, if you look at howto/revert-a-faulty-merge.txt(also shipped as part of the git distribution) it will provide more wordsthan you can shake a stick at.

Rewriting an old branch with a new branch with a new commit

If the state of a branch is contaminated beyond repair and you havepushed that branch or otherwise do not want to rewrite the existinghistory, then you can make a new commit which overwrites the originalbranch with the new one and pretends this was due to a merge. Thecommand is a bit complicated, and will get rid of all ignored oruntracked files in your working directory, so please be sure you haveproperly backed up everything.

In the following example please replace $destination with the nameof the branch whose contents you want to overwrite. $source should bereplaced with the name of the branch whose contents are good.

You actually are being provided with two methods. The first set ismore portable but generates two commits. The second knows about thecurrent internal files git uses to do the necessary work in onecommit. Only one command is different and a second command runs at adifferent time.

# Portable method to overwrite one branch with another in two commitsgit clean -dfxgit checkout $destinationgit reset --hard $sourcegit reset --soft ORIG_HEADgit add -fA .git commit -m "Rewrite $destination with $source"git merge -s ours $source

or

# Hacky method to overwrite one branch with another in one commitgit clean -dfxgit checkout $destinationgit reset --hard $sourcegit reset --soft ORIG_HEADgit add -fA .git rev-parse $source > .git/MERGE_HEADgit commit -m "Rewrite $destination with $source"

I am a bad person and must rewrite published history

Hopefully you read the previous reference and fully understand whythis is bad and what you have to tell everyone else to do in order torecover from this condition. Assuming this, you simply need to go tothe parts of this document which assume that you have not yetpushed and do them as normal. Then you need to do a "forcepush" git push -f to thrust your updatedhistory upon everyone else. As you read in the reference, this may bedenied by default by your upstream repository(see git configreceive.denyNonFastForwards, but can be disabled (temporarily Isuggest) if you have access to the server. You then will need to sendmail to everyone who might have pulled the history tellingthem that history was rewritten and they needto git pull --rebase and do a bit ofhistory rewriting of their own if they branched or tagged from the nowoutdated history.

Proceed with fixing the old commit.

I have lost some commits I know I made

First make sure that it was not on a different branch.Try git log -Sfoo --all where "foo" isreplaced with something unique in the commits you made. You can alsosearch with gitk --all --date-order to seeif anything looks likely.

Check your stashes, git stash list, tosee if you might have stashed instead of committing. You can alsovisualize what the stashes might be associated with via:

gitk --all --date-order $(git stash list | awk -F: '{print $1};')

Next, you should probably look in other repositories you have lyingaround including ones on other hosts and in testing environments, andin your backups.

Once you are fully convinced that it is well and truly lost, youcan start looking elsewhere in git. Specifically, you should firstlook at the reflog which contains the history of what happened to thetip of your branches for the past two weeks or so. You can of coursesay git log -g or gitreflog to view it, but it may be best visualized with:

gitk --all --date-order $(git reflog --pretty=%H)

Next you can look in git's lost and found. Dangling commits getgenerated for many good reasons including resets and rebases. Stillthose activities might have mislaid the commits you were interestedin. These might be best visualized with gitk--all --date-order $(git fsck | grep "dangling commit" | awk '{print$3;}')

The last place you can look is in dangling blobs. These are fileswhich have been git added but not attachedto a commit for some (usually innocuous) reason. To look at thefiles, one at a time, run:

git fsck | grep "dangling blob" | while read x x s; do git show $s | less;done

Once you find the changes you are interested in, there are severalways you can proceed. You can git reset --hardSHA your current branch to the history and current state ofthat SHA (probably not recommended for stashes), youcan git branch newbranch SHA to link theold history to a new branch name (also not recommended for stashes),you can git stash apply SHA (for thenon-index commit in a git-stash), you can gitstash merge SHA or git cherry-pickSHA (for either part of a stash or non-stashes), etc.

Undoing the last few git operations affecting HEAD/my branch's tip

Practically every git operation which affects the repository isrecorded in the git reflog. You may then use the reflog to look atthe state of the branches at previous times or even go back to thestate of the local branch at the time.

While this happens for every git command affecting HEAD, it isusually most interesting when attempting to recover from a bad rebaseor reset or an --amend'ed commit. There are better ways (listed bythe rest of this document) from recovering from the more mundanereflog updates.

The first thing you need to do is identify the SHA of the goodstate of your branch. You can do this by looking at the outputof git log -g or, my preference, you canlook graphically at gitk --all --date-order $(gitlog -g --pretty=%H)

Once you have found the correct state of your branch, you can getback to that state by running

git reset --hard SHA

You could also link that old state to a new branch name using

git checkout -b newbranch SHA

Obviously replace "SHA" in both commands with the reference youwant to get back to.

Note that any other commits you have performed since you did that"bad" operation will then be lost. You could gitcherry-pick or git rebase -r --ontothose other commits over.

Recovering from a borked/stupid/moribund merge

So, you were in the middle of a merge, have encountered one or moreconflicts, and you have now decided that it was a big mistake and wantto get out of the merge.

The fastest way out of the merge is git merge--abort

Recovering from a borked/stupid/moribund rebase

So, you were in the middle of a rebase, have encountered one or moreconflicts, and you have now decided that it was a big mistake and wantto get out of the rebase.

The fastest way out of the rebase is git rebase--abort

Disclaimer

Information is not promised or guaranteed to be correct, current, orcomplete, and may be out of date and may contain technicalinaccuracies or typographical errors. Any reliance on this materialis at your own risk. No one assumes any responsibility (and everyoneexpressly disclaims responsibility) for updates to keep informationcurrent or to ensure the accuracy or completeness of any postedinformation. Accordingly, you should confirm the accuracy andcompleteness of all posted information before making any decisionrelated to any and all matters described.

Copyright

Copyright ⓒ 2012 Seth Robertson

This document is licensed and distributed to you through the use oftwo licenses. You may pick the license you prefer.

Creative Commons Attribution-ShareAlike 3.0 Generic (CC BY-SA 3.0)https://creativecommons.org/licenses/by-sa/3.0/

OR

GNU Free Documentation v1.3 with no Invariant, Front, or Back Cover texts.https://www.gnu.org/licenses/fdl.html

I would appreciate changes being sent back to me, being notified ifthis is used or highlighted in some special way, and links beingmaintained back to the authoritative source. Thanks.

Not affiliated with Chooseco, LLC's "Choose Your Own Adventure"ⓡ.Good books, but a little light on the details of recovering from gitmerge errors to my taste.

Thanks

Thanks to the experts on #git and my coworkers for review, feedback,and ideas.

Comments

Comments and improvements welcome.

Usethe github issue tracker or discuss with SethRobertson (andothers) on #git

Line eater fodder

Because of my heavy use of anchors for navigation, and the utter lackof flexibility in the markup language this document is written in, itis important that the document be long enough at the bottom tocomplete fill your screen so that the item your link directed you tois at the top of the page.

Hopefully that should do it.

On undoing, fixing, or removing commits in git (2024)
Top Articles
Tropical Storm Debby could bring 'historic' flooding to SC
2007 Honda Odyssey Ocean Mist Metallic
It may surround a charged particle Crossword Clue
Faridpur Govt. Girls' High School, Faridpur Test Examination—2023; English : Paper II
Chicago Neighborhoods: Lincoln Square & Ravenswood - Chicago Moms
Craigslist Motorcycles Jacksonville Florida
South Carolina defeats Caitlin Clark and Iowa to win national championship and complete perfect season
Free VIN Decoder Online | Decode any VIN
35105N Sap 5 50 W Nit
CHESAPEAKE WV :: Topix, Craigslist Replacement
Soap2Day Autoplay
Visustella Battle Core
Jesus Revolution Showtimes Near Chisholm Trail 8
Inside the life of 17-year-old Charli D'Amelio, the most popular TikTok star in the world who now has her own TV show and clothing line
NHS England » Winter and H2 priorities
Carson Municipal Code
Gayla Glenn Harris County Texas Update
Today Was A Good Day With Lyrics
Menus - Sea Level Oyster Bar - NBPT
Okc Body Rub
Yosemite Sam Hood Ornament
Bòlèt Florida Midi 30
What Individuals Need to Know When Raising Money for a Charitable Cause
Sand Dollar Restaurant Anna Maria Island
Cardaras Funeral Homes
Encore Atlanta Cheer Competition
WPoS's Content - Page 34
Dailymotion
Wisconsin Volleyball Team Leaked Uncovered
O'reilly's Wrens Georgia
Craigslist Central Il
#scandalous stars | astrognossienne
Kelly Ripa Necklace 2022
Captain Billy's Whiz Bang, Vol 1, No. 11, August, 1920&#10;America's Magazine of Wit, Humor and Filosophy
Worcester County Circuit Court
Electric Toothbrush Feature Crossword
Sand Castle Parents Guide
Citizens Bank Park - Clio
Swsnj Warehousing Inc
Menu Forest Lake – The Grillium Restaurant
The Machine 2023 Showtimes Near Roxy Lebanon
Meet Robert Oppenheimer, the destroyer of worlds
Dicks Mear Me
Gander Mountain Mastercard Login
Euro area international trade in goods surplus €21.2 bn
Colin Donnell Lpsg
Mit diesen geheimen Codes verständigen sich Crew-Mitglieder
Bradshaw And Range Obituaries
Pulpo Yonke Houston Tx
Ingersoll Greenwood Funeral Home Obituaries
Texas Lottery Daily 4 Winning Numbers
login.microsoftonline.com Reviews | scam or legit check
Latest Posts
Article information

Author: Fr. Dewey Fisher

Last Updated:

Views: 5720

Rating: 4.1 / 5 (62 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Fr. Dewey Fisher

Birthday: 1993-03-26

Address: 917 Hyun Views, Rogahnmouth, KY 91013-8827

Phone: +5938540192553

Job: Administration Developer

Hobby: Embroidery, Horseback riding, Juggling, Urban exploration, Skiing, Cycling, Handball

Introduction: My name is Fr. Dewey Fisher, I am a powerful, open, faithful, combative, spotless, faithful, fair person who loves writing and wants to share my knowledge and understanding with you.