16

I made a mistake and one file on a project in a git repository contains a password. It is not a problem because is not a public repo but I would like to get rid of that password in the repo.

The repository history is very simple as I'm the only developer so it only has 12 commits and one of the commits is tagged.

The change in this case will not affect anything on the history (the diff will remain the same) as the password I want to delete is present just from the very first commit. I would like to remove that string as if it hasn't been there anytime.

Is there some kind of command to do this or I must regenerate the history just from the beginning with a new starting point without the password and applying the diffs on top of that?

Pedro Reyes
  • 361
  • 2
  • 9
  • 1
    I flagged this as duplicate of http://stackoverflow.com/questions/1186535/how-to-modify-a-specified-commit where you have your answer. – zmo Dec 23 '12 at 12:19
  • 1
    @zmo: link that you gave has nothing to do with this question. it may very well be a duplicate of something, but not of this one – mvp Dec 24 '12 at 04:38

3 Answers3

9

See https://help.github.com/articles/remove-sensitive-data. the file will be present in all commits, if you haven't deleted it, as all commits contain the state of the whole repo.

Basically, what you need to do is run a filter-branch across all your commits and then force push that into repo. The command is destructive and will change all commits where the file has been present at the repo, so be careful.

eis
  • 51,991
  • 13
  • 150
  • 199
  • 1
    To expand on that: you are looking for `git filter-branch --tree-filter`. Pass a script to that that does the change you want, and git will check out every commit, run your script and recreate the commit with your changes. – Chronial Dec 24 '12 at 04:14
5

Thanks that was exactly the command I was looking for and reading that article and the filter-branch documentation I got the exactly syntax I wanted making use of sed to remove the string from the file.

git filter-branch --tree-filter "sed -i 's/\<password\>//g' ./path_to_file/filename" --prune-empty --tag-name-filter cat -- --all

where:

"password" -> Is the string that needs to be removed

"./path_to_file/filename" -> Is the path to the file inside the repo that needs to be modified

runned in the repo root did the trick like a charm.

After the change has been made it must be pushed to remote server. This need to be forced so the server accepts the totally new rewritten refs and tags.

So a forced push of the repo to the remote server (origin in most cases)

git push origin --all --force

And a forced push of tags to the remote server

git push origin --tags --force
Pedro Reyes
  • 361
  • 2
  • 9
  • 1
    note that you also have to a) force push that into the repo and b) clean any local clones of the repo afterwards. this is why I linked to a longer article and did not try to include all here. – eis Dec 24 '12 at 13:26
  • yes, after the command I did a forced push of both refs and tags. I'm going to edit this answer for completeness. Thanks. – Pedro Reyes Dec 24 '12 at 13:47
  • on MacOS, just subtract -i option, this command is also working – cyan-kinesin May 18 '23 at 02:55
3

I would do the following:

git rebase --interactive

Change the command pick in front of the first commit (the commit with the password) to edit and keep all other lines as-is. Save the file and exit.

Then remove the password from the file (and do any other required changes), then:

git add name-of-file-with-password
git commit --amend
git rebase --continue
nrz
  • 10,435
  • 4
  • 39
  • 71