2012-03-11 299 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

相關問題