解决方案如下:
首先根据文件内容确定该文件对应的blob对象的object ID
git hash-object path/to/file或者直接使用几个shell命令生成:
(echo -e -n "blob $(wc -c path/to/file | awk '{print $1}')\0" ; cat path/to/file) | shasum
得到对应blob对象的object ID以后,使用whatchanged查看该文件的变更历史,默认情况下whatchanged不会输出merge中修改的文件,为了避免遗漏,此处还是用-m来告诉whatchanged还要输出merge的结果:
git whatchanged -m -- path/to/file
此时可以搜索刚刚得到的blob的object ID。需要注意的是由于whatchanged默认显示blob变化信息时只使用blob ID的前7位,因此搜索时也要注意不能使用完整的object ID,也应该使用object ID的前几位。
ruby写了个脚本实现查找:
注:你看到此文章时,该脚本可能已经不是最新版本,需要最新的code请移步loveky's GITHUB
#!/usr/bin/ruby # Author: loveky <ylzcylx@gmail.com> # Blog : http://loveky2012.blogspot.com #Usage: find_it_in_history.rb --file <file> --repo <path/to/repo> --path_in_repo <file/path/in/repo> require 'digest/sha1' require 'optparse' found = false commit = nil options = {} OptionParser.new do |opts| opts.banner = "Find the commit who first introduced the specified version of a file" opts.on('--file FILE', 'Which file to check') do |value| options[:file] = value end opts.on('--repo REPO', 'which repo to check') do |value| options[:repo] = value end opts.on('--path_in_repo PATH', 'the path of the file in repo') do |value| options[:path_in_repo] = value end end.parse! file_content = File.open(options[:file]) {|f| f.read} file_sha1 = Digest::SHA1.hexdigest("blob #{file_content.length}\0" + file_content) puts("#{options[:file]} => #{file_sha1}") Dir.chdir(options[:repo]) IO.popen("git whatchanged --oneline -m -- #{options[:path_in_repo]}") do |git_whatchanged| git_whatchanged.each_line do |line| if line[0,1] == ':' new_blob = (/\.\.\. ([0-9a-fA-F]{7})\.\.\./.match(line))[1] if new_blob == file_sha1[0,7] puts "Found blob(#{file_sha1[0,7]}) in commit " + commit found = true elsif found == true exit 0 end else commit = line[0,7] end end end
没有评论:
发表评论