0

I looked all over and couldn't find a solution to what I'm trying to do. Maybe I just missed it.

Say I have:

Commit A: 
- file 1
- file 2
- file 3
Commit B:
- file 4
Commit C:
- file 5
- file 6
HEAD: has files 1-6. 

Is there a way to interactively go back to Commit A to uncommit file 2 and file 3, then replay the remaining commits? So that I'm left with

Commit A: 
- file 1
Commit B:
- file 4
Commit C:
- file 5
- file 6
HEAD: has files 1-6, with file2 and file3 as unstaged.

Incomplete solutions I found:

- git reset --soft <commit A>
- make changes
- git commit

but this leaves me without the remaining commits (B, C).

- git rebase -i HEAD~n
- edit <commit>
- make changes
- git commit --amend
- git rebase --continue

but changes here are on top of the committed files at that commit, and I don't want to undo the file changes, just uncommit/unstage them.

- git revert -n <commit> 

but this undoes the changes.

- git rebase drop <commit> 

but this drops the entire commit.

I'm looking for the playback/--continue of rebase, but the editability of a soft reset. Is there a way to do that?

Thanks

1 Answers1

0

I would recommend:

git rm -- file_2 file_3
git commit

This creates a new commit that removes the two files. History is not altered.

To recover the two files in your working tree:

git checkout HEAD^ -- file_2 file_3
git reset HEAD -- file_2 file_3

git checkout recovers the files and git reset removes them from the staging areas so that you won't commit them.

Alternatively, if you have not pushed these commits to a shared repository yet, and wish to change history, use git rebase -i

git rebase -i HEAD~n #n should be one more than the number of commits to change
#mark commit A to edit 
git reset -- file_2 file_3 # remove file_2 and file_3 from staging so they won't be committed
git commit --amend
git rebase --continue

I believe this will leave file_1 and file_2 in your working tree. If not, they can be recovered from your pre-rebase commit using git checkout as above.

David Sugar
  • 1,042
  • 6
  • 8
  • Thanks, I see what this is doing. But in my case I had 50 files I wanted to uncommit. I want to 'travel back in time' to the see all the staged files for Commit A before they are committed to Commit A. Then I could selectively (re)commit only the files I want. Is that possible or asking too much of git? – user9979488 Jun 24 '20 at 19:02
  • That is possible. Do `git reset -- .` to unstage everything then `git add -- ` followed by `git commit --amend` and `git rebase --continue` – David Sugar Jun 24 '20 at 19:06
  • Thanks for the quick replies, @DavidSugar! I just tried `git rebase -i HEAD~n` -> edit commit. I get the message: ```You can amend the commit now, with git commit --amend Once you are satisfied with your changes, run git rebase --continue``` and then ran `git reset -- .` but got no files unstaged. This is one of the things I tried before posting, but I'm not sure what I'm doing. Did I miss a step? Am I doing something wrong? – user9979488 Jun 24 '20 at 22:28
  • sorry..that should be `git reset HEAD^ --.` You want to reset the files to the previous commit--not the current one (which would result in no change to those files in the staging area). – David Sugar Jun 26 '20 at 02:29
  • Perfect, thank you so much! :) This created new staged files that undid the committed files, while retaining the original changes in unstaged files. I was able to `git commit --amend` and keep the changed files. – user9979488 Jun 26 '20 at 15:28