cfischer
cfischer

Reputation: 24892

Modify a previously committed change in git

I realised I made a mistake in a previously committed change. There are several other commits that depend on this (wrong) one.

Can I modify it and have those changes propagated up to the working copy?

Upvotes: 4

Views: 147

Answers (4)

Balog Pal
Balog Pal

Reputation: 17163

Start by making your change and committing as fixup! Original's commit message.

Then decide what you want to see in the repo (and what is allowed). If you're not allowed to rewrite history, then full stop, you dud what is possible.

If it is allowed, start an interactive rebase on the parent of the original commit. You'll see the first two entries a pick original and fixup with the fix. Set all other commits to 'edit', and launch.

The process will stop at each further commit, where you compile, rewrite content to be aware of the change, work fine. and use rebase --continue. Then force-push the branch (and do all the rituals prescribed for history-rewriting cases).

Upvotes: 2

Loïc Faure-Lacroix
Loïc Faure-Lacroix

Reputation: 13600

It can be done, but I'd rather not do it. Changing the past has side effects. Your branch or commit tree will not be fast forward and you'll have to override the branch on a server if any. In other words, unless you're the last one who seen it and it's only on your computer. It might create more problem and you risk of loosing things if anything goes wrong.

If you're ready to enter the world of time travel and alternative reality!

Welcome to git rebase

First to get started, create a new branch where you want to rebase, this will create a copy of the branch you want to change in case anything goes wrong just delete the rebase and nothing will ever change. You could just note the commit hash.

The easiest way to get started is with git rebase -i HEAD~N where N is how many commits in the past you want to change.

It should open an editor, you can change the first word of each line to something like edit. Then save the file and you're rebasing!

When rebasing, you can do anything change add files, remove files and so on. When you commit, if there is no conflict, it should automatically continue. And once everything is done then you'll have a rebased branch with the commit either deleted edited, renamed or whatever you wanted. Then if all is right. Delete the old branch (not rebased) Push the new rebased branch and voila.

Edit

Unless it's not very clear, when it opens the editor. Deleting a line will delete the selected commit. If you delete everything in the file, it will do nothing. At any time during the rebasing you can abort it and the state of the git project shouldn't change. Rebasing is quite a safe thing to do as It doesn't actually change anything. If you keep references to old commit, then they will not disappear. After rebasing, it creates an alternative path. You will have one old path and a new path. The old path could get dereferenced and anything referenced to this old path should be moved to the new path.

Important

Btw, one thing I'd do instead, is to just commit something that fix the old commit. I consider that rebasing has to be used only when needed. For example, when your colleague accidentally commited a 4gb database backup.

Upvotes: 6

Stuart Golodetz
Stuart Golodetz

Reputation: 20616

(With the usual caveats about modifying public history...)

Given the need for modifying the commit, one of the easiest ways to do it is as follows:

1) Check out the commit you want to modify using git checkout <SHA> (find the right SHA using gitk or git log).

2) Create a new branch at this commit using git checkout -b <new branch name>.

3) Modify the code as desired.

4) Use git commit --amend to amend the commit.

5) Perform an "onto" rebase to move the remaining commits from the original branch across. To do this, recall the SHA of the changing commit before you modified it from above, and:

  • Switch to the original branch using git checkout <original branch name>.
  • Run git rebase --onto <new branch name> <before SHA of the modified commit>.

This will have the effect of replaying the commits after that SHA on the original branch on top of the new branch. You may need to resolve merge conflicts (as usual) during the rebase.

6) Delete the new branch using git branch -d <new branch name>.

As usual with this kind of thing, look at what's going on in gitk to make sure it's what you think, and (for safety) tag the original branch before doing the rebase.

Upvotes: 3

Gabriele Petronella
Gabriele Petronella

Reputation: 108091

If the commit has already been pushed you can revert it by

git revert <commit hash>

In order to get the commit hash, just use the git log command

Upvotes: 1

Related Questions