berimbolo
berimbolo

Reputation: 3869

git: remove files from an older commit

I am working on a branch and I have made a couple of commits, in the first commit I had changed an interface to add a new method and then changed the implementation class as well.

I have since found an existing method in the codebase that does pretty much what I want so I would like to check the files out in the first commit.

I have only reset files in the previous commit before so I am not sure how to do this, in the past I had checked out the files I wanted to remove from an older commit but that created a new commit and also meant the file showed in crucible as part of the code review but without any changes to it.

Could someone explain to me how to do this please?

Upvotes: 2

Views: 4375

Answers (1)

Mark Adelsberger
Mark Adelsberger

Reputation: 45819

If you don't want the fact that the files were changed (and then changed back) to be part of the history, then you'll need to do a history rewrite. If the commits in question have been pushed (and possibly shared with other devs), then the problems created by the rewrite will likely be worse than the problems you've outlined above, that you're trying to avoid.

The most basic way to do this is with an interactive rebase. If you have

... A --- B --- C --- D <--(current_branch)

where current_branch is whatever branch you're working on, and B is the commit in which you added the method, you can say

git rebase -i A current_branch

(replacing A with the SHA ID of the corresponding commit). This brings up a text editor with a TODO list, each line representing a commit.

Find the command for B (it should be the first line). If the only thing in the commit is the change you want to revert, delete the line. Otherwise, change the first word on the line from "pick" to "edit".

Then save and quit from the editor. Now follow the prompts. If you said to edit B, you'll get a prompt telling you to make your changes; so revert the files in question. If removal of changes from B causes conflicts, you'll be prompted to resolve those conflicts.

Eventually you get a successful rebase, but important to note: IF current_branch had previously been pushed, then you now have

... A --- B --- C --- D <--(origin/current_branch)
     \
      B' --- C' --- D' <--(current_branch)

When you try to push, git will complain (because the update to current_branch would not be a fast-forward). And if you force the push, everyone else using the branch must now recover from an "upstream rebase" (see the git rebase docs under "recovering from upstream rebase").

When I say you need to coordinate with the other repo users, I'm not directing you to be nice; I'm warning you that if you don't, and they mis-handle the resulting recovery process, your work will be undone.

Upvotes: 2

Related Questions