2012-03-11 126 views
32

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

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

我想将是很好的接口:混帐SED的/旧方法名/新方法名/ G'

回答

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重复产卵。

+5

我怀疑你需要在命令末尾有一个'$ i'。此外,您不必重复启动Perl。它会处理您提供的所有文件作为参数。因此'perl -i.orig -pe's/\ bold_method_name \ b/new_method_name/g'$(git grep - full-name -l old_method_name)'应该就足够了。 – tchrist 2012-03-11 03:53:11

+0

好多了。我在代码段中修复了$ i。 – 2012-03-11 04:32:31

+0

把它推在git-extras中:https://github.com/tj/git-extras/pull/466 – anarcat 2015-10-08 20:14:21

42

你可以结合使用git ls-filesxargssed

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

太棒了!我需要担心文件名中的空白吗? – 2012-03-11 02:35:55

+3

是的。如果文件名中有空格,请使用'git ls-files -z | xargs -0 sed ...'。 – 2012-03-11 02:38:56

+1

也许可以,但我认为你可以将-z传递给'ls-files'和'-0'给xargs以使其工作。 – 2012-03-11 02:39:56

15

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

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

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

要使用:

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

这在Linux中可用,但在OS X上,它复制了存储库中的所有文件,并将'-e'添加到他们结束了。这似乎更好:'git grep -z --full-name -l'。' | xargs -0 sed -i'''。 – 2016-11-29 04:46:18

9

这里是一个融合了这些溶液Noufal和claytontstanley和避免触摸不会改变的文件。

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

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 
+0

我是否也可以将其用于一般替换,例如:包括空格的替代? – 2016-12-20 21:37:08

+0

是的,但取决于你的shell,你可能需要调整你引用参数的次数。 – 2017-01-05 16:53:59

1

需要注意的是启动git 2.1 (Q3 2014),您可以git grep设置 “full-name” 默认情况下。
(由Andreas Schwabcommit 6453f7b

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\"' - 
1

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

$ sudo apt-get install git-extras 

使用它像波纹管例如,迅速纠正拼写问题:

$ git sed 'qoute' 'quote' 

遗憾的是它不支持的文件过滤像什么混帐grep的作用:

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

同样的功能也存在于Mac等操作系统。结帐installation page

相关问题