如何应用`git-log -p <文件名>`创建的补丁文件来创建包含的所有提交? [英] How can a patchfile created with `git-log -p &lt;filename&gt;` be applied to create all the commits included?

查看:234
本文介绍了如何应用`git-log -p <文件名>`创建的补丁文件来创建包含的所有提交?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景:这个问题 git apply< patchfile> 只是重新创建了文件,但没有提交历史记录,在这种情况下,这将是需要的。是否有任何适用于 git-apply 的开关?或者有没有办法将补丁文件转换为 git-am 兼容文件? (目前,git-am抱怨修补程序格式检测失败)

解决方案

您问过,所以在这里。



我使用了这个脚本,但它都很脆弱。

它从 git log的输出中提取(日期/作者/提交信息/补丁),作为灵感,而不是合理的解决方案。 -p ,然后运行修补程序 + git add + git apply for all,in reverse order。



可能有一些方法可以自动计算出正确的 patch_level ,但我没有打扰。如果不是全部,请将作者传递给 git apply

 # !/ usr / bin / env ruby​​ 

class String
def shell_escape
如果为空?
''
elsif%r {\A [0-9A-Za-z +,。/:= @ _-] + \z} =〜self
self
else
result =''
scan(/('+)| [^'] + /){
如果$ 1
结果< %q {\'} * $ 1.length
else
result<< '#{$&}'
结束
}
结果
结束
结束
结束

dir1, dir2,* files = ARGV

patchlog = Dir.chdir(dir1){`git log -p#{files.map(& shell_escape).join()}`}

patches = []
patchlog.each_line {| line |
如果line =〜/ \Acommit /
个补丁<< {}
elsif line =〜/\A(Author|Date):\s*(.*)/
patches [-1] [$ 1] = $ 2
elsif patches [ -1] [:DIFF] .nil?和行!〜/ \Adiff /
(补丁[-1] [:msg] || =)行
else
(patches [-1] [:diff] || =)<< line
end
}

patch_level = 2
skip = 0
dry_run = false

patches.reverse [skip。 。-1]。每个{|补丁|
author = patch [Author]。strip
date = patch [Date]。strip
msg = patch [:msg] .strip
diff = patch [: diff]

如果dry_run
puts [git,commit,-m,msg,--date,date] .join()
下一个
结束

Dir.chdir(dir2){
IO.popen(patch -p#{patch_level},w){| fh |
fh.puts diff

系统git,add,*文件
系统git,commit,-m,msg, - 日期,日期
}
}


Background: this question. git apply <patchfile> just recreates the file but without committing the history, which in this case would be desireable. Is there any switch for git-apply to do so? Or is there a way to convert the patchfile into a git-am compatible file? (Currently, git-am complains "Patch format detection failed")

解决方案

You asked, so here it is.

I used this script, but it's all rather fragile. Treat it an as inspiration, not as a reasonable solution.

It extracts (date / author / commit message / patch) from output of git log -p, and then runs patch+git add+git apply for all, in reverse order.

There's probably some way of automatically figuring out correct patch_level, but I didn't bother. And pass author to git apply if it's not all you.

#!/usr/bin/env ruby

class String
  def shell_escape
    if empty?
      "''"
    elsif %r{\A[0-9A-Za-z+,./:=@_-]+\z} =~ self
      self
    else
      result = ''
      scan(/('+)|[^']+/) {
        if $1
          result << %q{\'} * $1.length
        else
          result << "'#{$&}'"
        end
      }
      result
    end
  end
end

dir1, dir2, *files = ARGV

patchlog = Dir.chdir(dir1){`git log -p #{files.map(&:shell_escape).join(" ")}`}

patches = []
patchlog.each_line{|line|
  if line =~ /\Acommit/
    patches << {}
  elsif line =~ /\A(Author|Date):\s*(.*)/
    patches[-1][$1] = $2
  elsif patches[-1][:diff].nil? and line !~ /\Adiff/
    (patches[-1][:msg] ||= "") << line
  else
    (patches[-1][:diff] ||= "") << line
  end
}

patch_level = 2
skip = 0
dry_run = false

patches.reverse[skip..-1].each{|patch|
  author = patch["Author"].strip
  date = patch["Date"].strip
  msg = patch[:msg].strip
  diff = patch[:diff]

  if dry_run
    puts ["git", "commit", "-m", msg, "--date", date].join(" ")
    next
  end

  Dir.chdir(dir2){
    IO.popen("patch -p#{patch_level}", "w"){|fh|
      fh.puts diff
    }
    system "git", "add", *files
    system "git", "commit", "-m", msg, "--date", date
  }
}

这篇关于如何应用`git-log -p <文件名>`创建的补丁文件来创建包含的所有提交?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆