代码之家  ›  专栏  ›  技术社区  ›  Tobias Kienzler

如何应用用“git log-p<filename>”创建的补丁文件来创建包含的所有提交?

  •  0
  • Tobias Kienzler  · 技术社区  · 15 年前

    背景: this question . git apply <patchfile> 只需重新创建文件,但不提交历史记录,在本例中这是可取的。有开关吗 git-apply 这样做吗?或者有没有方法将补丁文件转换为 git-am 兼容文件?(目前Git AM抱怨“补丁格式检测失败”)

    2 回复  |  直到 13 年前
        1
  •  1
  •   taw    15 年前

    你问的,所以在这里。

    我用过这个剧本,但都很脆弱。把它当作灵感,而不是合理的解决办法。

    它从的输出中提取(日期/作者/提交消息/修补程序) git log -p 然后运行 patch + git add + git apply 对于所有人,按相反的顺序。

    可能有某种方法可以自动找出正确的 patch_level 但是我没有打扰。并将作者传递给 GIT应用 如果不是所有的你。

    #!/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
      }
    }
    
        2
  •  1
  •   Tobias Kienzler    13 年前

    观察 git quiltimport . 您提供了一个目录,命令在其中查找名为“series”的文件。在这个文件中,您只需提到补丁文件的名称,并按顺序应用它们”。文件中actuall diff之前的文本用作提交注释,文件名(减去.patch)用作标题,它尝试在每个补丁中查找作者,如果找不到作者,则会向您询问。