10

I finished an android project that requires me to use an api_key. I've added the api key in my build.gradle file like this:

     buildTypes.each {
         it.buildConfigField "String", "MDB_API_KEY", "\"243248324293938243\"" 
     }

(that's a random number btw)

Now that I finished the project I need to upload it to Github, for code review. Before doing so, I was asked to remove the api key, and I did

buildTypes.each {
     it.buildConfigField "String", "MDB_API_KEY", *putYaOwnApiKeyBrothar*
         }

and committed.

But if I push everything to Github, they could access any older commit, and retrieve my api_key.

I've seen similar questions, and the solution seems to be git filter-branch, but it seems that it removes a specific file across the commit history. I want to remove just the key (or that line, for that matter), since I want the *putYaOwnApiKeyBrothar* code available in all my commits. (In case they have to check an older one).

Is that even possible? Is there a simple way? If not, what should I do? Am I being dumb?

ovalb
  • 555
  • 6
  • 15
  • 3
    You should also invalidate the API key and get a new one. – Thilo Nov 29 '16 at 12:06
  • It is possible by `rebasing` and editing the old commits where you have pushed the api key, I guess that should be a single commit in which you have pushed it right? – Deepesh Nov 29 '16 at 12:08
  • I didn't push anything to github (or any other server) yet. I set the api_key in one of the first commits, and it propagated to all of my commits (more than 50). Also I'm not too experienced with git, so I wouldn't know how to do that with `rebase`. The only commit that doesn't have the api_key is the last one (and the first two I think) – ovalb Nov 29 '16 at 12:14

4 Answers4

14

git filter-branch is the way to go. It has various filters and you can remove files from the history, but you can also modify the files as you like. In your case you want to use the --tree-filter option with a command that replaces the String in your file. Something like git filter-branch --tree-filter "sed -i 's/243248324293938243/putYaOwnApiKeyBrothar/' your/file/here" --tag-name-filter cat --all

(if you are on macOS (or any *BSD) add '' after sed -i)

Vampire
  • 35,631
  • 4
  • 76
  • 102
  • I've tried what you said, but the command doesn't really seem to work. I've modified your sed command to sed -i '' 's/blabla... (adding empty -i param) since i have the bsd version of sed (running os x) but still doesn't work. when I run your command and substitute it with my own api key and the app/gradle.build (even tried with absolute path) file, the terminal goes into >dquote (mode). I'm not too experienced with git, so I'm kind of having a hard time understanding how to use properly git filter-branch. – ovalb Nov 30 '16 at 13:27
  • 1
    Ok, I managed to make it work! Thanks for the tips! The command was: `git filter-branch --tree-filter "sed -i "" 's/243248324293938243/putYaOwnApiKeyBrothar/' app/build.gradle" HEAD`. (the "" after -i is probably not needed if you are on linux) – ovalb Nov 30 '16 at 14:07
  • How would I go about pushing these changes after performing this command? – camiblanch Mar 23 '18 at 23:02
  • You have to force-push and anyone having pulled the old history has to rebase manually as described at "How to recover from upstream rebase", or she might reintroduce the old history. – Vampire Mar 24 '18 at 02:03
  • @camiblanch try `git push origin --force --all` – Nuhman Dec 20 '18 at 09:40
6

git filter-branch worked for me:

 git filter-branch --tree-filter "sed -i "" 's/ENTER_API_KEY_TO_REMOVE/STRING_TO_REPLACE_THE_KEY/' filepath"

The file path should include the file name e.g /src/main/Application.java where the key was stored previously. When you try to push these changes to GitHub, they might be rejected, in which case use:

git push --force
Enock Lubowa
  • 679
  • 8
  • 12
2

Git warned me about filter-branch and recommended to use git-filter-repo instead. I installed it and followed the instructions found here. It took me 5 minutes to get the hang of it and felt very simple and intuitive.

Maybe the biggest thing to note is that git-filter-repo doesn't accept inline search-replace statements. You will have to create your own file that should contain the replacements you want to be made (documentation).

rassoh
  • 545
  • 1
  • 5
  • 21
0

In case you have following scenario:

  1. Commit history is not complex for eg. you added sensitive data in a commit and pushed to a feature branch and someone caught the sensitive content during code review.

AND

  1. Your commit doesn't contains lot of changes (ideally it shouldn't)

Then you can

  1. Take backup of changed files
  2. Delete the commit (Refer How to permanently remove few commits from remote branch for ideas)
  3. Copy paste your commit's changes from backup except for sensitive content
  4. git push --force

I followed this approach because filter-branch showed me warning and asked me to use git-filter-repo. And the blog which I followed to use git-filter-repo warned me about damage this script can cause if not used properly.

Smile
  • 3,832
  • 3
  • 25
  • 39