@ZouChao

热爱PHP,RUBY,专注于web开发. 撸起袖子加油干!

背景:公司现在的团购站所使用的数据和主站有诸多联系,因此代码里面也有部分相互纠缠不清。现在要把他们单独独立出来。

首先还是介绍下git grep

git grep可以不用checkout就能很方便的查找Git库的一段文字。
例如,我们要查找文件中哪些地方是用到了Redis:

$ git grep Redis
user.rb:    Redis.current.hget(CheckinScoreHashKey, id).to_i
redis_initializer.rb:      Redis.current.client.reconnect
tasks/cheating_scores.rake:    Redis.current.del(fourDaysAgoKey) # 删除四天前的数据
javascripts/dashboard.js:      updateRedisStats(data.redis);
javascripts/dashboard.js:var updateRedisStats = function(data) {

上例只能查出以大写字母开头的Redis相关的代码,可以附加参数-i,如果要显示行号还可以加参数-n:

$ git grep -ni Redis
Gemfile:29:gem "redis", ">= 2.2.0", :require => ["redis", "redis/connection/hiredis"]
Gemfile.lock:199:    redis (3.0.1)
user.rb:35:    Redis.current.hget(CheckinScoreHashKey, id).to_i
redis_initializer.rb:9:      Redis.current.client.reconnect
tasks/cheating_scores.rake:25:    Redis.current.del(fourDaysAgoKey) # 删除四天前的数据
javascripts/dashboard.js:59:      updateRedisStats(data.redis);
javascripts/dashboard.js:123:var updateRedisStats = function(data) {

上面这种查询用的比较多,但是有时候也许我们并不需要这些信息也许我们只要文件名字,并不需要看到这些片段,这时用--name-only这个参数就可以搞定, 但是我想给大家介绍的并不是这个参数,而是-c,这个参数不仅可以简洁的显示文件名,还可以显示所查找的字符串在文件中占了多少行(单行重复出现不做统计)

$ git grep -c Redis
user.rb:1 
redis_initializer.rb:1
tasks/cheating_scores.rake:1
javascripts/dashboard.js:2

可以看到javascripts/dashboard.js后面显示的是2,说明这个文件有2行有Redis,当然你可以配合-i,-n参数使用
git grep还可以在历史的提交号,以及tag中查找,可以通过git loggit tag来查看有那些提交号和tag,使用方法

$ git grep -ni Redis release_201306261815 #这里release_201306261815是tagName
.
.
.
$ git grep -ni Redis aa4a326d4feb0f3b69f423bd66b6bc6558742c8d #提交号也可以简写aa4a326
.
.
.

一个更实用的ruby脚本

这是同事分享的一段ruby脚本可以查询到是哪一行,最后是哪个人操作过这段代码。方便了解功能逻辑,不多废话了,上代码:
文件名: blame_after_grep.rb

#!/usr/local/bin/ruby
 
grep = `git grep -n #{ARGV[0]} #{ARGV[1]}`

interrupt = false 

grep.lines.each do |file_with_line|
  exit if interrupt

  file, line_number, line = file_with_line.split(':', 3)
  author = `git blame --line-porcelain -L #{line_number},#{line_number} #{file} | sed -n 's/^author //p'`
  puts "#{ author.rstrip } #{file} +#{line_number} #{ line.lstrip.rstrip }"
 
  trap('INT'){interrupt = true} 
end

用法:

$ ruby blame_after_grep.rb 'Redis' | grep ZouChao

查询的展示结果如下:

ZouChao user.rb +35:    Redis.current.hget(CheckinScoreHashKey, id).to_i
ZouChao tasks/cheating_scores.rake +25 Redis.current.del(fourDaysAgoKey) # 删除四天前的数据