有没有'git sed'或同等价值?

时间:2012-03-11 02:27:57

标签: linux git bash sed

假设我想重命名git存储库中包含的源代码中的方法。我可以手动执行此操作,但方法名称可能位于多个位置(例如,单元测试,文档,实际方法)。要检查方法的使用位置,我使用'git grep'。我得到'git grep'只显示我想要更改的行,然后我没有自动更改这些行的工作流程。

我正在寻找一种自动化方式(希望使用git工具)来完成最后一步。我希望有某种'git sed'或等同物,但我找不到任何东西。

我认为的界面会很好:git sed's / old-method-name / new-method-name / g'

9 个答案:

答案 0 :(得分:48)

您可以将git ls-filesxargssed结合使用:

git ls-files -z | xargs -0 sed -i -e 's/old-method-name/new-method-name/g'

答案 1 :(得分:18)

感谢Noufal和Greg的帖子。我结合他们的解决方案,发现一个使用git grep(比我的repo更健壮的git ls文件,因为它似乎只列出了其中包含实际src代码的文件 - 例如,不是子模块文件夹),并且还有仅在一个地方使用旧方法名称和新方法名称:

[alias]文件的~/.gitconfig块中:

sed = ! git grep -z --full-name -l '.' | xargs -0 sed -i -e

使用:

git sed 's/old-method-name/new-method-name/ig'

答案 2 :(得分:11)

你可以做一个

for i in $(git grep --full-name -l old_method_name)
do
 perl -p -i -e 's/old_method_name/new_method_name/g' $i
done

将其粘贴到某个文件中,然后在配置中将其别名为git sed

更新:以下tchrist的评论是一个更好的解决方案,因为它可以防止perl重复产生。

答案 3 :(得分:9)

这是一个结合了Noufal和claytontstanley的解决方案,避免触及不会改变的文件。

[alias]文件的~/.gitconfig块中:

psed = !sh -c 'git grep --null --full-name --name-only --perl-regexp -e \"$1\" | xargs -0 perl -i -p -e \"s/$1/$2/g\"' -

使用:

git psed old_method_name new_method_name

答案 4 :(得分:3)

是的,有。在Ubuntu中,包git-extras提供了命令。安装它:

$ sudo apt-get install git-extras

像下面这样使用它,例如快速纠正拼写问题:

$ git sed 'qoute' 'quote'

不幸的是,它不支持像git grep那样的文件过滤器:

$ git grep -e 'class' -- '*.py'

Mac和其他操作系统上也存在相同的功能。查看其installation page

答案 5 :(得分:2)

对提供的大多数其他解决方案(基本上只是git跟踪文件上的字符串替换)不满意,我编写了自己的脚本:git-sed

  • 它支持sed支持的任何表达式(例如git sed '1{/^$/d}'
  • 可以在仓库(git sed 's/foo/bar' src tests)中的一部分路径上运行
  • 多个表达式(git sed -e 's/foo/bar' -e '/bar/d')。
  • 等...

只需将其放在PATH中的任何位置即可使用它,或添加指向完整路径的别名。

答案 6 :(得分:1)

请注意,从git 2.1 (Q3 2014)开始,您可以为git grep默认设置“full-name”。
commit 6453f7b提供Andreas Schwab

  

git grep”了解grep.fullname个配置变量,强制“--full-name”为默认值。
  这可能会导致脚本用户的回归不期望这种新行为。

这意味着之前的解决方案可以从中受益:

git config grep.full-name true

并使用:

psed = !sh -c 'git grep --null --name-only --perl-regexp -e \"$1\" | xargs -0 perl -i -p -e \"s/$1/$2/g\"' -

答案 7 :(得分:0)

请参阅github上的git-search-replace - 它是为此而设计的。

答案 8 :(得分:0)

我写了一个支持文件过滤的git sed:

#!/bin/bash

split=$(($# + 1))

for i in $(seq 1 $#); do
   if [[ "${!i}" = "--" ]]; then
       split=$i
   fi
done

git ls-files -z "${@:$split:$#}" | xargs -0 sed -b -i "${@:1:$(($split - 1))}"

(您可能不希望在非Windows平台上使用-b参数;在Windows上必须保留Windows风格的换行符。)

然后您可以在.gitconfig中添加别名:

[alias]
    sed = ! <path to git-sed>

以便您可以像git sed -e <your expression> -- <path filter>一样使用它。