Skip to content

Instantly share code, notes, and snippets.

@mcmatrix
Forked from silent1mezzo/0fixup.md
Created July 27, 2018 13:38
Show Gist options
  • Save mcmatrix/7fff7a4594b5d35fb2cb918d95a0bfd3 to your computer and use it in GitHub Desktop.
Save mcmatrix/7fff7a4594b5d35fb2cb918d95a0bfd3 to your computer and use it in GitHub Desktop.

Revisions

  1. @SethRobertson SethRobertson revised this gist Jan 23, 2012. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -361,8 +361,9 @@ The "^" in that command is literal.
    You will be dumped in an editor with a bunch of lines starting with
    pick. The oldest commit, the one you are probably interested in
    changing, is first. You will want to change the "pick" to "reword" or
    "edit" depending on what your goal is. Please read the [manual
    page](http://jk.gs/git-rebase.html) for more information.
    "edit", or perhaps even "squash" depending on what your goal is.
    Please read the [manual page](http://jk.gs/git-rebase.html) for more
    information.

    When using "edit", to change contents or author, when you are dumped
    into the shell to make your change, well make your change, `git add`
  2. @SethRobertson SethRobertson revised this gist Jan 23, 2012. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -729,13 +729,13 @@ The fastest way out of the merge is `git rebase --abort`

    Information is not promised or guaranteed to be correct, current, or
    complete, and may be out of date and may contain technical
    inaccuracies or typographical errors. Any reliance on the material on
    this site is at your own risk. No one assumes any responsibility (and
    everyone expressly disclaims responsibility) for updating this site to
    keep information current or to ensure the accuracy or completeness of
    any posted information. Accordingly, you should confirm the accuracy
    and completeness of all posted information before making any decision
    related to any and all matters described in this site.
    inaccuracies or typographical errors. Any reliance on this material
    is at your own risk. No one assumes any responsibility (and everyone
    expressly disclaims responsibility) for updates to keep information
    current or to ensure the accuracy or completeness of any posted
    information. Accordingly, you should confirm the accuracy and
    completeness of all posted information before making any decision
    related to any and all matters described.


    <a name="copyright" />
  3. @SethRobertson SethRobertson revised this gist Jan 23, 2012. 1 changed file with 14 additions and 0 deletions.
    14 changes: 14 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -724,6 +724,20 @@ to get out of the merge.
    The fastest way out of the merge is `git rebase --abort`


    <a name="disclaimer" />
    ## Disclaimer

    Information is not promised or guaranteed to be correct, current, or
    complete, and may be out of date and may contain technical
    inaccuracies or typographical errors. Any reliance on the material on
    this site is at your own risk. No one assumes any responsibility (and
    everyone expressly disclaims responsibility) for updating this site to
    keep information current or to ensure the accuracy or completeness of
    any posted information. Accordingly, you should confirm the accuracy
    and completeness of all posted information before making any decision
    related to any and all matters described in this site.


    <a name="copyright" />
    ## Copyright

  4. @SethRobertson SethRobertson revised this gist Jan 22, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -455,7 +455,7 @@ idea](https://gist.github.com/1540906#pubonce). It requires everyone
    else to do special things and you must publicly announce your failure.
    Ideally you will create either a commit to just fix the problem, or a
    new `git revert` commit to create a new commit which undoes what the
    commit you reverted did.
    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)](#pushed_restore_file)
    * [Yes, I can make a new commit and the bad commit is a merge commit I want to totally remove](#pushed_new_merge)
  5. @SethRobertson SethRobertson revised this gist Jan 20, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -640,9 +640,9 @@ in your backups.
    Once you are fully convinced that it is well and truly lost, you can
    start looking elsewhere in git. Specifically, you should first look
    at the reflog which contains the history of what happened to the tip
    of your branch for the past two weeks or so. You can of course say
    `git log -g` to view it, but it may be best visualized with `gitk
    --all --date-order $(git log -g --pretty=%H)`
    of your branches for the past two weeks or so. You can of course say
    `git log -g` or `git reflog` 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 get
    generated for many good reasons including resets and rebases. Still
  6. @SethRobertson SethRobertson revised this gist Jan 19, 2012. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -585,7 +585,9 @@ git add -fA .
    git commit -m "Rewrite $destination with $source"
    git merge -s ours $source
    ```

    or

    ```shell
    # Hacky method to overwrite one branch with another in one commit
    git clean -dfx
  7. @SethRobertson SethRobertson revised this gist Jan 19, 2012. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    # [On undoing, fixing, or removing commits in git](https://gist.github.com/1612395)
    A git choose-your-own-adventure!

    This document is an attempt to be a fairly comprehensive guide to
    recovering from what you did not mean to do when using git. It isn't
    @@ -738,7 +739,8 @@ maintained back to the authoritative source. Thanks.
    <a name="thanks" />
    ## Thanks

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


    <a name="comments" />
  8. @SethRobertson SethRobertson revised this gist Jan 19, 2012. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -540,14 +540,14 @@ Another option is to abandon the branch you merged from, recreate it
    from the previous merge-base with the commits since then rebased or
    cherry-picked over, and use the recreated branch from now on. Then
    the new branch is unrelated and will merge properly. Of course, if
    you have pushed the doner branch you cannot use the same name (that
    you have pushed the donor branch you cannot use the same name (that
    would be rewriting public history and is bad) so everyone needs to
    remember to use the new branch. Hopefully you have something like
    [gitolite](https://github.com/sitaramc/gitolite) where you can close
    the old branch name.

    At this time, I will not walk you through the process of recreating
    the doner branch. Given sufficient demand I can try to add that.
    the donor branch. Given sufficient demand I can try to add that.
    However, if you look at howto/revert-a-faulty-merge.txt which is
    shipped as part of the git distribution, it will provide more words
    than you can shake a stick at.
  9. @SethRobertson SethRobertson revised this gist Jan 19, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -82,7 +82,7 @@ untracked and ignored files are not stashed by default. See
    "--include-untracked" and "--all" for stash options to handle those
    two cases.

    However, perhaps you hare confident (or arrogant) enough to know for
    However, perhaps you are confident (or arrogant) enough to know for
    sure that you will never ever want the uncommitted changes. If so,
    you can run `git reset --hard`, however please be quite aware that
    this is almost certainly a completely unrecoverable operation. Any
  10. @SethRobertson SethRobertson revised this gist Jan 18, 2012. 1 changed file with 14 additions and 12 deletions.
    26 changes: 14 additions & 12 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -234,7 +234,7 @@ with the most recent commit.
    ## Do you want to remove or change the commit message/contents of the last commit?

    * [I want to remove the last commit](#remove_last)
    * [I want to update the message/contents of the last commit](#update_last)
    * [I want to update the author/message/contents of the last commit](#update_last)


    <a name="remove_last" />
    @@ -252,19 +252,20 @@ branch newbranchname` BEFORE doing the `git reset`.
    <a name="update_last" />
    ## Updating the last commit's contents or commit message

    To update the last commit's contents or commit message for a commit
    which you have not pushed or otherwise published, first you need to
    get the index into the correct state you wish the commit to reflect.
    If you are changing the commit message only, you need do nothing. If
    you are changing the file contents, typically you would modify the
    working directory and use `git add` as normal.
    To update the last commit's contents, author, or commit message for a
    commit which you have not pushed or otherwise published, first you
    need to get the index into the correct state you wish the commit to
    reflect. If you are changing the commit message only, you need do
    nothing. If you are changing the file contents, typically you would
    modify the working directory and use `git add` as normal.

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

    Once the index is in the correct state, then you can run `git commit
    --amend` to update the last commit. Yes, you can use "-a" if you want
    to avoid the `git add` suggested in the previous paragraph.
    to avoid the `git add` suggested in the previous paragraph. You can
    also use --author to change the author information.


    <a name="change_deep" />
    @@ -362,10 +363,11 @@ changing, is first. You will want to change the "pick" to "reword" or
    "edit" depending on what your goal is. Please read the [manual
    page](http://jk.gs/git-rebase.html) for more information.

    When using "edit", when you are dumped into the shell to make your
    change, well make your change, `git add` as normal, and then run `git
    commit --amend`. When you are satisfied, you should run `git rebase
    --continue`
    When using "edit", to change contents or author, when you are dumped
    into the shell to make your change, well make your change, `git add`
    as normal, and then run `git commit --amend` (including changing the
    author information with --author). When you are satisfied, you should
    run `git rebase --continue`


    <a name="change_single_deep_merge" />
  11. @SethRobertson SethRobertson revised this gist Jan 18, 2012. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,13 @@ might have done is so large that different techniques are needed
    depending on exactly what you have done and what you want to have
    happen.

    If you have problems after clicking through this document, please
    document what the links you clicked on are when asking for further
    help (on #git or elsewhere) which will explain very precisely what you
    were trying to do and that you at least tried to help yourself.
    Sorry, due to the limitations of github we cannot gather the history
    for simple copy-paste.


    ## First step

  12. @SethRobertson SethRobertson revised this gist Jan 18, 2012. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -218,6 +218,7 @@ on the most recent, there are some convenient shortcuts you can take
    with the most recent commit.

    * [I want to change the most recent commit](#change_last)
    * [I want to discard the most recent commit(s)](#remove_last)
    * [I want to undo the last git operation(s) affecting the HEAD/tip of my branch (most useful for rebase, reset, or --amend)](#undo_tip)
    * [I want to change an older commit](#change_deep)

    @@ -237,6 +238,9 @@ To remove the last commit from git, you can simply run `git reset
    can run `git reset HEAD~2` to remove the last two commits. You can
    increase the number to remove even more commits.

    If you want to save the commits on a new branch name, then run `git
    branch newbranchname` BEFORE doing the `git reset`.


    <a name="update_last" />
    ## Updating the last commit's contents or commit message
  13. @SethRobertson SethRobertson revised this gist Jan 18, 2012. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -351,6 +351,11 @@ changing, is first. You will want to change the "pick" to "reword" or
    "edit" depending on what your goal is. Please read the [manual
    page](http://jk.gs/git-rebase.html) for more information.

    When using "edit", when you are dumped into the shell to make your
    change, well make your change, `git add` as normal, and then run `git
    commit --amend`. When you are satisfied, you should run `git rebase
    --continue`


    <a name="change_single_deep_merge" />
    ## Changing a single commit involving a merge
  14. @SethRobertson SethRobertson revised this gist Jan 18, 2012. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -635,6 +635,15 @@ which have been `git add`ed but not attached to a commit for some
    read x x s; do git show $s | less; done` will show you the files, one
    at a time.

    Once you find the changes you are interested in, there are several
    ways you can proceed. . You can `git reset --hard SHA` your current
    branch to the history and current state of that SHA (probably not
    recommended for stashes), you can `git branch newbranch SHA` to link
    the old history to a new branch name (also not recommended for
    stashes), you can `git stash apply SHA` (for the non-index commit in a
    git-stash), you can `git stash merge SHA` or `git cherry-pick SHA`
    (for either part of a stash or non-stashes), etc.


    <a name="undo_tip" />
    ## Undoing the last few git operations affecting HEAD/my branch's tip
  15. @SethRobertson SethRobertson revised this gist Jan 18, 2012. 1 changed file with 31 additions and 3 deletions.
    34 changes: 31 additions & 3 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -45,9 +45,9 @@ If you have not yet committed that which you do not want, git does not
    know anything about what you have done yet, so it is pretty easy to
    undo what you have done.

    * [I am in the middle of a bad merge](#badmerge)
    * [I am in the middle of a bad rebase](#badrebase)
    * [Yes, I committed](#committed)
    * [I am in the middle of a borked merge](#badmerge)
    * [I am in the middle of a borked rebase](#badrebase)
    * [No, I have not yet committed](#uncommitted)


    @@ -168,9 +168,14 @@ with immediate pruning.

    There is a shortcut in case you want to discard all changes made on
    this branch since you have last pushed or in any event, to make your
    local branch identical to "upstream".
    local branch identical to "upstream". Upstream, for local tracking
    branches, is the place you get history from when you `git pull`:
    typically for master it might be origin/master. There is a variant of
    this option which lets you make your local branch identical to some
    other branch or ref.

    * [I want to discard all unpushed changes](#discard_all_unpushed)
    * [I want to make my branch identical to some non-upstream ref](#replace_all_unpushed)
    * [I want to fix some unpushed changes](#fix_unpushed)


    @@ -182,6 +187,29 @@ local branch identical to the "upstream" of this branch, simply run
    `git reset --hard @{u}`


    <a name="replace_all_unpushed" />
    ## Replacing all branch history/contents

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

    The first thing you need to do is identify the SHA or ref of the good
    state of your branch. You can do this by looking at the output of
    `git branch -a; git tag`, `git log --all` or, my preference, you can
    look graphically at `gitk --all --date-order`

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

    ```shell
    git reset --hard REF
    ```

    Obviously replace "ref" in both commands with the reference or SHA you
    want to get back to.


    <a name="fix_unpushed" />
    ## Is the commit you want to fix the most recent?

  16. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -190,7 +190,7 @@ on the most recent, there are some convenient shortcuts you can take
    with the most recent commit.

    * [I want to change the most recent commit](#change_last)
    * [I want to undo the last git operation(s) affecting the HEAD/tip of my branch (most useful for rebase or reset)](#undo_tip)
    * [I want to undo the last git operation(s) affecting the HEAD/tip of my branch (most useful for rebase, reset, or --amend)](#undo_tip)
    * [I want to change an older commit](#change_deep)


    @@ -618,7 +618,7 @@ state of the local branch at the time.

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

    The first thing you need to do is identify the SHA of the good state
  17. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 8 additions and 1 deletion.
    9 changes: 8 additions & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -632,7 +632,14 @@ to that state by running
    ```shell
    git reset --hard SHA
    ```
    Obviously replace "SHA" with the reference you want to get back to.

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

    ```shell
    git checkout -b newbranch SHA
    ```

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

    Note that any other commits you have performed since you did that
    "bad" operation will then be lost. You could `git cherry-pick` or
  18. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 9 additions and 5 deletions.
    14 changes: 9 additions & 5 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -17,13 +17,17 @@ working directory and .git to avoid any possibility of losing data as
    a result of the use or misuse of these instructions. We promise to
    laugh at you if you fail to take a backup and regret it later.

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

    [Proceed to the first question](#start)


    <a name="start" />
    ## 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 lost some
  19. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # [On undoing, fixing, or removing commits in git]()
    # [On undoing, fixing, or removing commits in git](https://gist.github.com/1612395)

    This document is an attempt to be a fairly comprehensive guide to
    recovering from what you did not mean to do when using git. It isn't
  20. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # On undoing, fixing, or removing commits in git
    # [On undoing, fixing, or removing commits in git]()

    This document is an attempt to be a fairly comprehensive guide to
    recovering from what you did not mean to do when using git. It isn't
  21. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 21 additions and 0 deletions.
    21 changes: 21 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -42,6 +42,8 @@ know anything about what you have done yet, so it is pretty easy to
    undo what you have done.

    * [Yes, I committed](#committed)
    * [I am in the middle of a borked merge](#badmerge)
    * [I am in the middle of a borked rebase](#badrebase)
    * [No, I have not yet committed](#uncommitted)


    @@ -633,6 +635,25 @@ Note that any other commits you have performed since you did that
    `git rebase -p --onto` those other commits over.


    <a name="badmerge" />
    ## Recovering from a borked/stupid/moribund merge

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

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


    <a name="badrebase" />
    ## Recovering from a borked/stupid/moribund rebase

    So, you were in the middle of a rebase, have encountered one or more
    conflicts, and you have now decided that it was a big mistake and want
    to get out of the merge.

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


    <a name="copyright" />
    ## Copyright
  22. @SethRobertson SethRobertson revised this gist Jan 17, 2012. 1 changed file with 33 additions and 0 deletions.
    33 changes: 33 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -184,6 +184,7 @@ on the most recent, there are some convenient shortcuts you can take
    with the most recent commit.

    * [I want to change the most recent commit](#change_last)
    * [I want to undo the last git operation(s) affecting the HEAD/tip of my branch (most useful for rebase or reset)](#undo_tip)
    * [I want to change an older commit](#change_deep)


    @@ -601,6 +602,38 @@ read x x s; do git show $s | less; done` will show you the files, one
    at a time.


    <a name="undo_tip" />
    ## Undoing the last few git operations affecting HEAD/my branch's tip

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

    While this happens for every git command affecting HEAD, it is usually
    most interesting when attempting to recover from a bad rebase or
    reset. There are better ways (listed by the rest of this document)
    from recovering from the more mundane reflog updates.

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

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

    ```shell
    git reset --hard SHA
    ```
    Obviously replace "SHA" with the reference you want to get back to.

    Note that any other commits you have performed since you did that
    "bad" operation will then be lost. You could `git cherry-pick` or
    `git rebase -p --onto` those other commits over.



    <a name="copyright" />
    ## Copyright

  23. @SethRobertson SethRobertson revised this gist Jan 16, 2012. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -522,7 +522,7 @@ commit. Only one command is different and a second command runs at a
    different time.

    ```shell
    # Portable method to overwrite one branch with another
    # Portable method to overwrite one branch with another in two commits
    git clean -dfx
    git checkout $destination
    git reset --hard $source
    @@ -531,9 +531,9 @@ git add -fA .
    git commit -m "Rewrite $destination with $source"
    git merge -s ours $source
    ```

    or
    ```shell
    # Hacky method to overwrite one branch with another
    # Hacky method to overwrite one branch with another in one commit
    git clean -dfx
    git checkout $destination
    git reset --hard $source
  24. @SethRobertson SethRobertson revised this gist Jan 16, 2012. 1 changed file with 9 additions and 4 deletions.
    13 changes: 9 additions & 4 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -551,10 +551,15 @@ Hopefully you read the previous reference and fully understand why
    this is bad and what you have to tell everyone else to do in order to
    recover from this condition. Assuming this, you simply need to go to
    the parts of this document which assume that you have *not* yet pushed
    and do them as normal. Then you need to do a "force push" to thrust
    your updated history upon everyone else. As you read in the
    reference, this may be denied by default by your upstream repository,
    but can be disabled (temporarily I suggest).
    and do them as normal. Then you need to do a "force push" `git push
    -f` to thrust your updated history upon everyone else. As you read in
    the reference, this may be denied by default by your upstream
    repository (see `git config receive.denyNonFastForwards`, but can be
    disabled (temporarily I suggest) if you have access to the server.
    You then will need to send mail to everyone who *might* have pulled
    the history telling them that history was rewritten and they need to
    `git pull --rebase` and do a bit of history rewriting of their own if
    they branched or tagged from the now outdated history.

    Proceed with [fixing the old commit](#unpushed).

  25. @SethRobertson SethRobertson revised this gist Jan 16, 2012. 1 changed file with 8 additions and 1 deletion.
    9 changes: 8 additions & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -38,7 +38,7 @@ have made some changes which you would like to fix.
    ## Have you committed?

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

    * [Yes, I committed](#committed)
    @@ -146,6 +146,13 @@ not be modified. You must deal with those separately. Look at `gitk
    --all --date-order` to help visualize everything what other git
    references might need to be updated.

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

    * [Yes, I pushed](#pushed)
    * [No, I did not push](#unpushed)

  26. @SethRobertson SethRobertson revised this gist Jan 15, 2012. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -206,6 +206,9 @@ If you are changing the commit message only, you need do nothing. If
    you are changing the file contents, typically you would modify the
    working directory and use `git add` as normal.

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

    Once the index is in the correct state, then you can run `git commit
    --amend` to update the last commit. Yes, you can use "-a" if you want
    to avoid the `git add` suggested in the previous paragraph.
    @@ -345,6 +348,9 @@ git checkout nonce SHA
    nothing. If you are changing the file contents, typically you would
    modify the working directory and use `git add` as normal.

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

    Once the index is in the correct state, then you can run `git commit
    --amend` to update the last commit. Yes, you can use "-a" if you want
    to avoid the `git add` suggested in the previous paragraph.
  27. @SethRobertson SethRobertson revised this gist Jan 15, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -531,7 +531,7 @@ git commit -m "Rewrite $destination with $source"
    ```


    <a name="pushed_old />
    <a name="pushed_old" />
    ## I am a bad person and must rewrite published history

    Hopefully you read the previous reference and fully understand why
  28. @SethRobertson SethRobertson revised this gist Jan 15, 2012. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -336,6 +336,8 @@ You can delete it immediately after you are done.
    git checkout 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 the commit
    @@ -424,6 +426,7 @@ 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.


    @@ -441,6 +444,8 @@ you know the "^" or "~" shortcuts you may use those.
    git revert SHA
    ```

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


    <a name="pushed_new_merge" />
    ## Reverting a merge commit
  29. @SethRobertson SethRobertson revised this gist Jan 15, 2012. 1 changed file with 32 additions and 32 deletions.
    64 changes: 32 additions & 32 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -319,63 +319,63 @@ 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-order` or 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.
    You can do this using `gitk --date-order` or 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 `git branch` 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.
    The line with a star on it in the `git branch` 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.

    ```shell
    ```shell
    git checkout nonce SHA
    ```

    * Modify the commit

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

    Once the index is in the correct state, then you can run `git commit
    --amend` to update the last commit. Yes, you can use "-a" if you want
    to avoid the `git add` suggested in the previous paragraph.
    Once the index is in the correct state, then you can run `git commit
    --amend` to update the last commit. Yes, you can use "-a" if you want
    to avoid the `git add` suggested in the previous paragraph.

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

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

    Remembering to substitute the correct branch name for $master
    Remembering to substitute the correct branch name for $master

    ```shell
    ```shell
    git rebase -p --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 merge commits,
    please be warned. It is possible that `git rebase -p` will be unable to
    properly recreate them. Please inspect the resulting merge topology
    `gitk --date-order HEAD ORIG_HEAD` to ensure that git did want you
    wanted. If it did not, there is not really any automated recourse.
    You can reset back to the commit before the SHA you want to get rid
    of, and then cherry-pick the normal commits and manually re-merge the
    "bad" merges. Or you can just suffer with the inappropriate topology
    (perhaps creating fake merges `git merge --ours otherbranch` so that
    subsequent development work on those branches will be properly merged
    in with the correct merge-base).
    If some of the commits after the commit you changed are merge commits,
    please be warned. It is possible that `git rebase -p` will be unable to
    properly recreate them. Please inspect the resulting merge topology
    `gitk --date-order HEAD ORIG_HEAD` to ensure that git did want you
    wanted. If it did not, there is not really any automated recourse.
    You can reset back to the commit before the SHA you want to get rid
    of, and then cherry-pick the normal commits and manually re-merge the
    "bad" merges. Or you can just suffer with the inappropriate topology
    (perhaps creating fake merges `git merge --ours otherbranch` so that
    subsequent development work on those branches will be properly merged
    in with the correct merge-base).

    * Delete the nonce branch

    You don't need it. It was just there to communicate an SHA between
    two steps in the above process. `git branch -d nonce`
    You don't need it. It was just there to communicate an SHA between
    two steps in the above process. `git branch -d nonce`


    <a name="pushed" />
  30. @SethRobertson SethRobertson revised this gist Jan 15, 2012. 1 changed file with 296 additions and 6 deletions.
    302 changes: 296 additions & 6 deletions 0fixup.md
    Original file line number Diff line number Diff line change
    @@ -215,18 +215,18 @@ to avoid the `git add` suggested in the previous paragraph.
    ## Do you want to remove an entire commit?

    * [I want to remove an entire commit](#remove_deep)
    * [I want to change an older commit](#change_deep)
    * [I want to change an older commit](#modify_deep)


    <a name="remove_deep" />
    ## 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 command you
    "cherry-pick". You must first identify the SHA of the commit you
    wish to remove. You can do this using `gitk --date-order` or 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 can use those.
    you know the "^" or "~" shortcuts you may use those.

    ```shell
    git rebase -p --onto SHA^ SHA
    @@ -236,7 +236,7 @@ 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 and the
    tip of your branch are merge commits, it is possible that `git rebase`
    tip of your branch are merge commits, it is possible that `git rebase -p`
    will be unable to properly recreate them. Please inspect the
    resulting merge topology `gitk --date-order HEAD ORIG_HEAD` to ensure
    that git did want you wanted. If it did not, there is not really any
    @@ -247,7 +247,7 @@ inappropriate topology (perhaps creating fake merges `git merge --ours
    otherbranch` so that subsequent development work on those branches
    will be properly merged in with the correct merge-base).

    <a name="change_deep" />
    <a name="modify_deep" />
    ## 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](#filterbranch)
    @@ -271,6 +271,7 @@ BTW, this is the one command I referred to earlier which will update
    all tags and branches, at least if you use the best practice
    arguments.


    <a name="change_single_deep" />
    ## Is a merge commit involved?

    @@ -283,10 +284,299 @@ handling of the situation.
    * [No, only simple commits](#change_single_deep_simple)


    <a name="change_single_deep_merge" />
    <a name="change_single_deep_simple" />
    ## 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` or 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.

    ```shell
    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 with
    pick. The oldest commit, the one you are probably interested in
    changing, is first. You will want to change the "pick" to "reword" or
    "edit" depending on what your goal is. Please read the [manual
    page](http://jk.gs/git-rebase.html) for more information.


    <a name="change_single_deep_merge" />
    ## Changing a single commit involving a merge

    Oh dear. This is going to get a little complicated. It should all
    work out, though. You will need to use a
    [nonce](http://en.wiktionary.org/wiki/nonce) branch as a placeholder.
    I will call the nonce branch "nonce" in the following example.
    However, you may use any branch name that is not currently in 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-order` or 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 `git branch` 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.

    ```shell
    git checkout nonce SHA
    ```

    * Modify the commit

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

    Once the index is in the correct state, then you can run `git commit
    --amend` to update the last commit. Yes, you can use "-a" if you want
    to avoid the `git add` suggested in the previous paragraph.

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

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

    Remembering to substitute the correct branch name for $master

    ```shell
    git rebase -p --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 merge commits,
    please be warned. It is possible that `git rebase -p` will be unable to
    properly recreate them. Please inspect the resulting merge topology
    `gitk --date-order HEAD ORIG_HEAD` to ensure that git did want you
    wanted. If it did not, there is not really any automated recourse.
    You can reset back to the commit before the SHA you want to get rid
    of, and then cherry-pick the normal commits and manually re-merge the
    "bad" merges. Or you can just suffer with the inappropriate topology
    (perhaps creating fake merges `git merge --ours otherbranch` so that
    subsequent development work on those branches will be properly merged
    in with the correct merge-base).

    * Delete the nonce branch

    You don't need it. It was just there to communicate an SHA between
    two steps in the above process. `git branch -d nonce`


    <a name="pushed" />
    ## Can you make a positive commit to fix the problem and what is the fix class?

    [Rewriting public history is a bad
    idea](https://gist.github.com/1540906#pubonce). It requires everyone
    else to do special things and you must publicly announce your failure.
    Ideally you will create either a commit to just fix the problem, or a
    new `git revert` commit to create a new commit which undoes what the
    commit you reverted 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)](#pushed_restore_file)
    * [Yes, I can make a new commit and the bad commit is a merge commit I want to totally remove](#pushed_new_merge)
    * [Yes, I can make a new commit but the bad commit is a simple commit I want to totally remove](#pushed_new_simple)
    * [Yes, I can make a new commit and the bad commit has an error in it I want to fix](#pushed_fixit)
    * [Yes, I can make a new commit but history is all messed up and I have a replacement branch](#branch_overlay_merge)
    * [No, I am a bad person and must rewrite published history](#pushed_old)


    <a name="pushed_fixit" />
    ## Making a new commit to fix an old commit

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


    <a name="pushed_restore_file" />
    ## Making a new commit to restore a file deleted earlier

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

    You must first identify the SHA of the commit containing the good
    version of the file. You can do this using `gitk --date-order` or
    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.

    ```shell
    git checkout SHA -- path/to/filename
    ```

    You can then add and commit as normal to fix the problem.


    <a name="pushed_new_simple" />
    ## 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 you
    want 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-1 hash ID (or the 7 character abbreviation). Yes, if
    you know the "^" or "~" shortcuts you may use those.

    ```shell
    git revert SHA
    ```


    <a name="pushed_new_merge" />
    ## Reverting a merge commit

    Oh dear. This is going to get complicated.

    To create an positive commit to remove the effects of a merge commit,
    you must first identify the SHA of the commit you want 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-1 hash
    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 as simple
    as you might hope. `git revert SHA`. Unfortunately, this is just the
    tip of the iceberg. The problem is, what happens if you want to merge
    that branch later, perhaps months later long after you have exiled
    this problem from your memory, either to this branch or to some other
    branch this branch merged into. Well, the problem is git has it
    tracked in history that a merge occurred, so it is not going to
    attempt to remerge what it has already merged. The fact that it was
    later reverted is irrelevant. You could revert the revert, but that
    supposes that you remember that you need to do so.

    Another option is to abandon the branch you merged from, recreate it
    from the previous merge-base with the commits since then rebased or
    cherry-picked over, and use the recreated branch from now on. Then
    the new branch is unrelated and will merge properly. Of course, if
    you have pushed the doner branch you cannot use the same name (that
    would be rewriting public history and is bad) so everyone needs to
    remember to use the new branch. Hopefully you have something like
    [gitolite](https://github.com/sitaramc/gitolite) where you can close
    the old branch name.

    At this time, I will not walk you through the process of recreating
    the doner branch. Given sufficient demand I can try to add that.
    However, if you look at howto/revert-a-faulty-merge.txt which is
    shipped as part of the git distribution, it will provide more words
    than you can shake a stick at.


    <a name="branch_overlay_merge" />
    ## Rewriting an old branch with a new branch with a new commit

    If the state of a branch is contaminated beyond repair and you have
    pushed that branch or otherwise do not want to rewrite the existing
    history, then you can make a new commit which overwrites the original
    branch with the new one and pretends this was due to a merge. The
    command is a bit complicated, and will get rid of all ignored or
    untracked files in your working directory, so please be sure you have
    properly backed up everything.

    In the follow example please replace $destination with the name of the
    branch whose contents you want to overwrite. $source should be
    replaced with the name of the branch whose contents are good.

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

    ```shell
    # Portable method to overwrite one branch with another
    git clean -dfx
    git checkout $destination
    git reset --hard $source
    git reset --soft ORIG_HEAD
    git add -fA .
    git commit -m "Rewrite $destination with $source"
    git merge -s ours $source
    ```

    ```shell
    # Hacky method to overwrite one branch with another
    git clean -dfx
    git checkout $destination
    git reset --hard $source
    git reset --soft ORIG_HEAD
    git add -fA .
    git rev-parse $source > .git/MERGE_HEAD
    git commit -m "Rewrite $destination with $source"
    ```


    <a name="pushed_old />
    ## I am a bad person and must rewrite published history

    Hopefully you read the previous reference and fully understand why
    this is bad and what you have to tell everyone else to do in order to
    recover from this condition. Assuming this, you simply need to go to
    the parts of this document which assume that you have *not* yet pushed
    and do them as normal. Then you need to do a "force push" to thrust
    your updated history upon everyone else. As you read in the
    reference, this may be denied by default by your upstream repository,
    but can be disabled (temporarily I suggest).

    Proceed with [fixing the old commit](#unpushed).


    <a name="lostnfound" />
    ## 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" is replaced with something unique in the
    commits you made. You can also search with `gitk --all --date-order`
    to see if anything looks likely.

    Check your stashes, `git stash list`, to see if you might have stashed
    instead of committing. You can also run `gitk --all --date-order
    $(git stash list | awk -F: '{print $1};')` to visualize what the
    stashes might be associated with.

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

    Once you are fully convinced that it is well and truly lost, you can
    start looking elsewhere in git. Specifically, you should first look
    at the reflog which contains the history of what happened to the tip
    of your branch for the past two weeks or so. You can of course say
    `git log -g` to view it, but it may be best visualized with `gitk
    --all --date-order $(git log -g --pretty=%H)`

    Next you can look in git's lost and found. Dangling commits get
    generated for many good reasons including resets and rebases. Still
    those activities might have mislaid the commits you were interested
    in. 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 files
    which have been `git add`ed but not attached to a commit for some
    (usually innocuous)reason. `git fsck | grep "dangling blob" | while
    read x x s; do git show $s | less; done` will show you the files, one
    at a time.


    <a name="copyright" />
    ## Copyright