4

My problem: I stupidly made lots of changes to a file and committed them all at once.

I've since realized that much of the changes were crap ... but a lot of them were good, too.

How do I selectively revert some portion of the changes?

Matt Fenwick
  • 48,199
  • 22
  • 128
  • 192
  • Amend the commit to several commits? – Woodrow Douglass Jul 30 '12 at 20:33
  • @MattFenwick: I don't have any git points, that's correct, but differentiating between different changes like a human would is one of those problems that is very difficult for computers to solve algorithmically. I don't know the limits of git's revision comparison and traversal but I'd hazard an educated guess that you're going to have to put human brainpower into this problem, the computer won't be able to help further than maybe giving you a mechanical summary of the differences. – Wug Jul 30 '12 at 20:37
  • @Wug, you're trying to make this problem much more complicated than it actually is. I already know which lines to keep and which to revert. No automagic differentiation algorithm needed. – Matt Fenwick Jul 31 '12 at 20:00

3 Answers3

3

Assuming you haven't committed anything else since, I would undo your commit, add whatever parts of the file you want using git add -p, and then recommit.

Gordon Bailey
  • 3,881
  • 20
  • 28
2

Breaking an earlier commit into parts is doable with git rebase -i, but it should only be used on branch's whose history you can rewrite. The order of operations is something like this:

git rebase -i <commit>~1

Where <commit> is the commit you want to break apart. In the interactive mode, change pick to edit or e for the commit you want fracture. Then close the editor and let the rebase continue. When rebase reaches the affected commit, it'll pause, allowing you to make any edits you'd like at that point. This includes things like git reset HEAD <file> to unstage <file>, git reset HEAD to unstage everything, and git checkout -- <file> to discard change in the working directory.

From here, you can commit the changes in any order you please. I'd recommend git add -p to interactively add patch sets, if multiple changes to the same file are best committed over multiple commits.

Finally, when you've committed everything you'd like in the fractured commit, and are ready to let the rebase continue, just issue git rebase --continue.

If you want to avoid rewriting history, this answer shows you how to use git revert --no-commit to revert just parts of a commit.

Community
  • 1
  • 1
Christopher
  • 42,720
  • 11
  • 81
  • 99
0

enter image description hereWhen you open a file in some IDEs like netbeans, you can see all the changes live, as color codes just at the start of each line. Right-clicking one of those color markers shows you what was there before. The context menu on right click also lets you undo ONLY that portion of the changes to the file. Because you have already committed your changes, you can do git reset soft HEAD^ and then open the file in netbeans, undo changes selectively, and then do git commit.

Does someone know how to do this in emacs? (That's what I was looking for when I came across this post.)

Abhishek Anand
  • 3,789
  • 2
  • 21
  • 29