Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify a previously committed change in git

Tags:

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?

like image 725
cfischer Avatar asked Dec 15 '22 09:12

cfischer


2 Answers

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.

like image 91
Loïc Faure-Lacroix Avatar answered Dec 24 '22 06:12

Loïc Faure-Lacroix


(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.

like image 38
Stuart Golodetz Avatar answered Dec 24 '22 05:12

Stuart Golodetz