3

I still have some difficulties to understand completely the process to modified an already pushed commit.
I am not working on the master branch (don't know if that matter), and I committed and pushed wrong data (say, clear password...) in the Commit_2 (see below).
I would like to change files from this commit only, and don't change the others.
Of course, I have read the documentation git-rebase, cherry-pick etc.. as well as some very nice answers from SO, like here or here, but I am still not sure how to do it.

So, basically, how can I change files from, and only from Commit_2 ?

commit 54sdf4f4d5f4dsf4555q5aaaa44fr
Author: me <me@me.com>
Date:   Wed Sep 14 10:25:09 2016 +0200

    Commit_3

commit ghgzf4x1522qx1x5f222y4d
Author: me <me@me.com>
Date:   Tue Sep 13 15:01:42 2016 +0200

    Commit_2

commit dfsdc4ycx45ds4fyc6d4fysfsd
Author: me <me@me.com>
Date:   Tue Sep 13 14:57:08 2016 +0200

     Commit_1
Mornor
  • 3,471
  • 8
  • 31
  • 69
  • Change the password. If you've pushed it, it's been compromised by pushing. You can't uncompromise anything. – Jan Hudec Sep 19 '16 at 12:11
  • Private repo only shared with a little team, so not important. But want to make sure I can do it in case if it is really needed. – Mornor Sep 19 '16 at 12:13

3 Answers3

2

I like interactive rebase

git rebase -i ghgzf4x1522qx1x5f222y4d^

Set that commit from pick to e for edit. Then make your changes (delete password). Then continue.

git rebase --continue

Now that you have rewritten history, you will have to force push to the remote.

git push <remote> <branch> --force

And others will need to non-fast-forward pull.

git fetch <remote>
git reset --hard <remote>/<branch>

Or maybe

git pull --rebase
Jeff Puckett
  • 37,464
  • 17
  • 118
  • 167
1

There is no way to change anything in a commit. Ever. The commit is identified by a sha1 checksum derived from all its content and history, so when you change anything, it will have a different sha1 and therefore be a different commit, and so will everything that follows it.

So the only thing you can do is delete the problematic commit from the repository and replace it with better version. You do that by force pushing (git push -f) a new version that does not contain it to every branch that did. You create that new version with git commit --amend (if it is the latest commit), git rebase -i (if it is not) or git filter-branch if it is deeper down the history.

However, if anybody already fetched that commit from the repository, they get to keep it. You can't stop them.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • If i `git rebase -i [commit_id]`, do the changes and then `git push -f`, will I loose information from more recent commit? – Mornor Sep 19 '16 at 12:07
  • @Mornor, you will replace all the commits that were part of that rebase with new versions that don't contain the information. But only the commits in that rebase - if there are any other commits based on the old commit, they remain based on the old commit. – Jan Hudec Sep 19 '16 at 12:11
  • He can `git revert` which will functionally undo the commit, though the original commit will still be there as you mentioned. – Tim Biegeleisen Sep 19 '16 at 12:11
  • 1
    @TimBiegeleisen, he can rewind and remove it even from history of all current heads, but since the information was ever there, it might have been already fetched and must be treated as compromised anyway. – Jan Hudec Sep 19 '16 at 12:13
1

One approach might be to revert Commit_2, which would add a new commit which would completely undo the changes to every file modified in Commit_2. This would be perfect if you wanted to remove all changes, but you want to retain some of the changes.

Run the following command to see which files were changed in Commit_2:

git show --pretty="" --name-only dfsdc4yc

Now identify which files you want to keep, and then for each file type the following:

git checkout 54sdf4f4 file/to/restore

where 54sdf4f4 is the SHA-1 hash of Commit_3. This will effectively redo everything which was done to files you want to keep.

Now you can commit this change. You could amend the revert commit since you haven't yet pushed your local work, via:

git commit --amend -m 'Undo of certain files from Commit_2'
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • 1
    This is usually preferred, but I think the case of sanitizing a mistakenly committed password would require a rewrite, otherwise the password would still be available in history for others to exploit. – Jeff Puckett Sep 19 '16 at 12:18
  • 2
    @JeffPuckettII, mistakenly *pushed* password requires **CHANGING THAT PASSWORD**. – Jan Hudec Sep 19 '16 at 13:02