git:在文件中更改一行以获取完整的历史记录

tbo*_*der 38 git commit git-amend

当我开始我的git repo时,我提交了一些文件作为初始提交.现在,很多提交后来,我注意到我在这些文件中包含了一条信息,其中包含我不想发布的信息(与其他代码不同).所以我想删除/更改这一行保留其余的代码.

在我周围搜索我找到了这个解决方案:插入一个空提交作为初始提交(这里描述:在Git中根提交之前插入一个提交?),对它做一个rebase,然后通过修改编辑旧的第一次提交.不幸的是,在rebase期间出现了许多残酷的合并冲突(如下所述:git:解决由rebase引起的冲突).

有没有不同的方法来解决我的问题,或者必须手动变基和编辑所有冲突?

提前致谢 :)

Kar*_*ldt 48

这是一个命令,它将删除所有分支中文件历史记录中的违规行:

git filter-branch --tree-filter 'sed -i "/sensitive information/ d" filename' -- --all
Run Code Online (Sandbox Code Playgroud)

这将检出每个修订,在其sed上运行命令,然后提交该修订版本.

sed在这种情况下,命令匹配包含sensitive information命名文件中的模式的任何行,filename并删除这些行.

注意:如果你有一个备份,那就好了,首先尝试sed自己的脚本以确保它正在做你想要的,因为它可能需要很长时间才能运行很长的历史记录.

  • 并且稍微修改了`sed`命令+我在macOS上使用的args:`git filter-branch -f --tree-filter'test -f yourfile.json && sed -i"""s/oldText/newText/g" yourfile.json || echo"skipping file"' - --all` (5认同)
  • 我不知道`-q`选项是否这样做.你可能必须把它包装在shell中,然后就像`if [-e file]; 然后sed ...; fi` (3认同)
  • 如果您知道错误被引入的提交,您可以`git filter-branch --tree-filter'sed -i"/ sensitive information/d"filename'<commit> .. HEAD` (3认同)
  • 在 Windows 上,我不断收到错误“没有这样的文件或目录”。我最终发现使用文件名的完整文件路径(例如:c:\filename.txt)并将其放在双引号中使其工作。 (2认同)

Ted*_*urt 8

我做了这个命令,当文件不存在时不会出错:

 filename=./path/to/your/filename
 filter=your_regex_here

 git filter-branch --tree-filter 'test -f $filename && sed -i.bak "/$filter/d" $filename  || echo “skipping file“' -- --all
Run Code Online (Sandbox Code Playgroud)


Jac*_*ern 6

我的回答结合了一切最好的东西。它仅替换给定的过滤字符串而不是整行,并且如果在提交中找不到该文件,它会很好地跳过。有很多转义的引号,但另一个答案有非常奇怪的引号,对我不起作用。

 git filter-branch --tree-filter "test -f \"$filename\" && sed -i \"s/$filter//g\" \"$filename\" || echo \"skipping $filename\"" -- --all
Run Code Online (Sandbox Code Playgroud)