I want to fix a file in past commit. This might affect all ascending commits.
Is there an easy way to do that? Can you give me a guideline of how to do that?
Many times when I commit twice I find that I've had error in the first commit, and I wish to fix the error without having to 'git reset' my last good commit.
For clarification. I want to change the actual commit, that is, I want the content of the past commit to be changed. IOW I want to change history!
-
If you only want to amend the second to last commit (eg. not long ago, especially not before many branches and merges), then I use this procedure:
git checkout -b tmp bad-commit- fix the files
git commit --amendgit rebase tmp master
If you have merges in between, you may wanna try
rebase -i -p, but the results may vary.Elazar Leibovich : nope, that won't fix the *commit*. It will fix the tip of the branch but my history will be polluted with errors. I want to fix the actual commit before pushing it to the server. I want to change history!jpalecek : This WILL change your history. After the rebase, the commit accessible from the tip of your branch, with the right name, will be the fixed commit. When you push, the bad commit won't be sent to the server.Elazar Leibovich : My bad, you're correct of course.Charles Bailey : It think the last rebase command should be `rebase --onto tmp bad-commit master`. As it currently stands the rebase would try to apply the bad commit to the fixed commit which may have not effect but might either cause conflicts or preserve and unwanted change depending on how radical the 'fix' was.jpalecek : @Charles Bailey: To be 100 % sure, you'd have to use your command. However, I usually don't bother and it causes a conflict (which is easy to solve).Rob : Tbh this even works when several merges have been performed, I had to fix a commit that was 2 weeks old, there were a few conflicts after running rebase but sorted within 10 minutes. life saver! -
It looks like:
- a
filter-branch(complex command which could do what you want) - and amend and rebase as described by jpalecek. You will find the same solution slightly more detailed in this other related question.
You can find an example of rebase interactive in this comment: you could then avoid the temporary branch, but again, it is more complex.
I also rebase often to clean up the history of development so that changes are correct and grouped properly.
A made-up example:
I rename functionfootobarand commit it with a comment that says, "renamed foo to bar".
Then I move on to the next feature or fix, and commit that, and move on to the next.
Halfway through that, I find that I missed an instance offoo!
I commit my work in progress (or use git-stash), fix the missing 'foo' and commit that, then usegit-rebase --interactiveto merge the all thefoofixes together into one clean commit.
If I didn't usegit-stash, then I'll usegit-commit --amend(another form of rebasing) when I finally finish the feature that was in progress.When my patches are pushed for review, all the pieces are correct and tell a coherent story. Sometimes I use
git-rebase --interactivejust to make adjacent temporally-separated changes which affect the same bits, so that changes are in context. - a
0 comments:
Post a Comment