2

I'm new to git and not sure how to approach this.

I want to undo a series of specific commits (relating to a single file) that we decided are not a good solution to a problem but I want to preserve all other commits introduced since.

I don't want to just edit the file to remove that piece of code as I feel reverting here is more explicit and commnicates better the intention.

It goes something like this:

X -> Y -> X -> -X -> Y -> X -> X

Where Y refers to commits relating to that particular feature and X are all commits we want to keep intact, ending up with:

X -> X -> -X -> X -> X

I'm not sure how rebase would work here since I don't want to just include all commits from a certain point onwards.

Would cherry-pick be a better approach?

EDIT: Probably worth mentioning that all those commits are pushed.

Nobilis
  • 7,310
  • 1
  • 33
  • 67

4 Answers4

2

You can use the interactive rebase in order to fix your mistakes if your commits are not yet shared (still are local commits in your repository)

The syntaxe is : git rebase --interactive commit's hash (or just git rebase -i commit's hash)

In you case lets say the hash of your first x commit is x1 (use git log to git the hash code for this commit), then you can use : git rebase -i x1

enter image description here

For each commit you want to remove replace pick by drop

Then leave the edit mode (by using ESC key) and :wq

youness
  • 146
  • 4
1

You can use git rebase --onto as explained here: https://blog.pivotal.io/labs/labs/git-rebase-onto

In your particular case:

X1 -> Y1 -> X2 -> X3 -> Y2 -> X4 -> X5

The commands would be:

git rebase --onto X3 Y2 # strips Y2
git rebase --onto X1 Y1 # strips Y1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Just to confirm, this needs to be done in reverse chronological order? From latest to earliest? – Nobilis Dec 01 '16 at 14:09
  • @Nobilis: You can do it in either order, but editing earlier history may change later hashes, so I chose to do it this way because you can write down the hashes at the start of the process and then use them without having to check them again. If you do it the other way around it shouldn't do anything terrible, but I think it might fail and you'd have to look up the hashes again before each step. – John Zwinck Dec 01 '16 at 14:13
  • Thank you for the tip, I shall consider rebase --onto which I wasn't aware of in the future but having pushed those commits it seems that rewriting history is not an advisable option in our case. I'll have to go down the `revert` path. – Nobilis Dec 02 '16 at 09:17
1

You can revert a specific file to a previous commit:

git reset <commit hash> <filename>

It might be good to review the changes made to the file first:

git diff <commit hash> <file name>

You can get commit hashes with git log.

Alternatively, you can just checkout the previous version of the file from version control:

git checkout -- <file name>

Edit: More info here.

Community
  • 1
  • 1
Sherwood Callaway
  • 1,428
  • 1
  • 14
  • 18
0

Me personally I prefer git rebase -i HEAD~10 (interactive rebase of the last 10 commits) where I would drop the bad commits by just commenting their lines.

Note that this requires a push --force which is always something to be very careful about.

sashok_bg
  • 2,436
  • 1
  • 22
  • 33