Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace a string in a whole Git history?

Tags:

git

bash

replace

I have one of my passwords commited in probably few files in my Git repo. Is there some way to replace this password with some other string in whole history automatically so that there is no trace of it? Ideally if I could write simple bash script receiving strings to find and replace by and doing whole work itself, something like:

./replaceStringInWholeGitHistory.sh "my_password" "xxxxxxxx"

Edit: this question is not a duplicate of that one, because I am asking about replacing strings without removing whole files.

like image 599
Karol Selak Avatar asked Oct 26 '17 09:10

Karol Selak


People also ask

How do I replace in git?

The replace command lets you specify an object in Git and say "every time you refer to this object, pretend it's a different object". This is most commonly useful for replacing one commit in your history with another one without having to rebuild the entire history with, say, git filter-branch .

How do I replace all in git bash?

If you read the git-config man page, you see: git config [<file-option>] [type] --replace-all name value [value_regex] [...] --replace-all Default behavior is to replace at most one line. This replaces all lines matching the key (and optionally the value_regex).

How do I search for a string in git log?

Simply run git log with the -L option, and it will show you the history of a function or line of code in your codebase.

How do I see my full git history?

`git log` command is used to view the commit history and display the necessary information of the git repository. This command displays the latest git commits information in chronological order, and the last commit will be displayed first.


1 Answers

First, find all the files that could contain the password. Suppose the password is abc123 and the branch is master. You may need to exclude those files which have abc123 only as a normal string.

git log -S "abc123" master --name-only --pretty=format: | sort -u

Then replace "abc123" with "******". Suppose one of the files is foo/bar.txt.

git filter-branch --tree-filter "if [ -f foo/bar.txt ];then sed -i s/abc123/******/g foo/bar.txt;fi"

Finally, force push master to the remote repository if it exists.

git push origin -f master:master

I made a simple test and it worked but I'm not sure if it's okay with your case. You need to deal with all the files from all branches. As to the tags, you may have to delete all the old ones, and create new ones.

like image 69
ElpieKay Avatar answered Sep 30 '22 17:09

ElpieKay