Reputation: 33
I have a repo with three files in it - 1.txt, 2.txt and 3.txt. I created a branch 'new_branch' and made commits (let's call them A, B and C), every of these commits contains changes in several files from my repo. Then I understood, that 1.txt was updated mistakenly. Is it possible to remove changes, made in 1.txt, from commits A, B and C but keep changes in 2.txt and 3.txt?
UPD. I want also to remove changes, made it 1.txt, from commit history. As result 'git log -p' should show, that only 2.txt and 3.txt were modified in commits A, B and C.
Many thanks.
Upvotes: 0
Views: 182
Reputation: 46
Assuming that your revision tree looks like this:
-- S <s.sha> -- A -- B -- C (HEAD)
You can use git filter-branch
to remove the changes from commits A..C
made to a single file.
git filter-branch --tree-filter 'git checkout <s.sha> -- 1.txt' HEAD~3..
This will:
1.txt
file bringing it to the version you want,This obviously rewrites history, so the same considerations are in place as for pushing a rebase.
Upvotes: 2
Reputation: 1729
Here's another not so neat way [Solution provided by Tim best suits the situation though]-
Assuming your top 3 commits are A,B,C, You can do git reset --soft HEAD~3
. All your committed changes will come in your staging area. You can unstage 1.txt and commit rest of the files.
This will lead to change in history with commits A, B and C to be replaced by a new commit D that will have all changes in A, B and C except for the file 1.txt.
Upvotes: 0
Reputation: 521794
You may try checking out 1.txt
at the commit before commit A
, the first commit where you started making unwanted changes:
git checkout abc123 -- 1.txt
This assumes your branch structure looks like this (with commit S
having SHA-1 hash abc123
):
S -- A -- B -- C
Then, just add the change and commit.
Upvotes: 1
Reputation: 11405
git checkout <commit reference> <file>
is what you are looking for.
> git init
Initialized empty Git repository in /Users/ody/temp/git-co/.git/
> touch 1 2 3
> echo foo > 1 > 2 > 3
> git add 1 2 3
> git commit -m "foo"
[master (root-commit) 470f4e8] foo
3 files changed, 3 insertions(+)
create mode 100644 1
create mode 100644 2
create mode 100644 3
> echo bar > 1 > 2 > 3
> git add 1 2 3
> git commit -m "bar"
[master 916819d] bar
3 files changed, 3 insertions(+), 3 deletions(-)
> git checkout :/foo 1
> cat 1
foo
NOTE: The :/
notation lets you reference a commit by a part of its name instead of a commit hash.
Upvotes: 0