0

There was a big change committed (which included changes in many files and addition and removals of files) by copying code from somewhere and on top of that much work has been done including many merges from other branches. Now we have got to know that wrong version of code was copied earlier.

Is there any way that I can change that commit by copying the right version of code now?

I had a look at this, but there it is a linear history. Also I had a look at this, but example is only for adding new file.

In my case I'm sure there will be conflicts after I change the old commit. I'm also OK to add a new commit instead of changing existing one.

Community
  • 1
  • 1
IsmailS
  • 10,797
  • 21
  • 82
  • 134

2 Answers2

2

I agree with websterridge, modifying history is probably not the way to go; that only makes sense if you want to permanently erase all traces of the old commit (and has its set of problems).

The best solution is probably to create a new commit with the necessary changes. The idea is to create a diff between the version that was committed, and the version that should have been, and apply that diff to the current version.

You could do it like this (untested):

  • Create (and check out) a branch on top of the old commit where the wrong code was committed: git checkout -b fix-branch SHA_OF_OLD_COMMIT
  • Copy the right version of the code that should have been committed into the working directory. You can just overwrite the wrong files without worrying about conflicts, because you have gone back to the old commit with the original code import.
  • Commit this: git add --all . ; git commit -m "Fix import of wrong code."

Now you have the right code in git, but on branch "fix-branch".

You can now use git's tools to get the right code into your current branch (let's say master): either rebase fix-branch on top of master, or merge it into master. In this case a merge is probably better, because that way the repository history contains the original version of the new, correct code import before conflict resolution.

Either way, you'll probably get a lot of conflicts, but there's no way around this.

Good luck!

sleske
  • 81,358
  • 34
  • 189
  • 227
  • Thanks v much. I'm doing this and thankfully there are not so many conflicts as expected. Just wanted to confirm one thing. While merging `fix-branch` into feature branch, if there is a change which I've got from `fix-branch` into my feature branch which is NOT conflicting, then am I right in thinking that that it is NOT overwriting any of the changes which are done top of the wrong commit? Because if that was the case, then there would be a conflict. Am I right? – IsmailS May 23 '14 at 13:17
  • @iSid: Yes, exactly. If there are changes on both "sides" during a merge, git will report a conflict. No conflict - no overwritten changes. – sleske May 23 '14 at 13:27
1

As justified as it sounds, changing history is a bad idea and complicated. Plus folks already have the current history in their stream.

The better practice is to just bite the bullet and correct with a new commit.

websterridge
  • 369
  • 1
  • 5
  • Yes. The easiest solution is probably to create a diff between the version that was committed, and the version that should have been, and apply that diff to the current stat. – sleske May 23 '14 at 11:55
  • This is the kind of conversation that shows that as great and easy as git is, folks who know it well are worth their weight in saved aggravation! I wish I was one :) – websterridge May 23 '14 at 11:59
  • I agree that changing history is not good. So if it is possible without changing history, then that's great. @sleske, Can you plz provide some commands so that I can understand it better? – IsmailS May 23 '14 at 12:01