【问题标题】:Dealing with hunks that only change whitespace处理只改变空格的帅哥
【发布时间】:2020-04-29 07:59:33
【问题描述】:

在我维护的代码中,我有时会收到提交者无缘无故重排段落的拉取请求。这是一个例子:

diff --git a/knuth.tex b/knuth.tex
index 2f6a2f8..7b0827d 100644
--- a/knuth.tex
+++ b/knuth.tex
@@ -1,6 +1,6 @@
 Thus, I came to the conclusion that the designer of a new
 system must not only be the implementer and first
-large||scale user; the designer should also write the first
+large-scale user; the designer should also write the first
 user manual.

 The separation of any of these four components would have
@@ -9,8 +9,7 @@ all these activities, literally hundreds of improvements
 would never have been made, because I would never have
 thought of them or perceived why they were important.

-But a system cannot be successful if it is too strongly
-influenced by a single person. Once the initial design is
-complete and fairly robust, the real test begins as people
-with many different viewpoints undertake their own
-experiments.
+But a system cannot be successful if it is too strongly influenced by
+a single person. Once the initial design is complete and fairly
+robust, the real test begins as people with many different viewpoints
+undertake their own experiments.

如您所见,第一个大块引入了实际更改,将 || 替换为 -,而第二个大块除了换行和空格之外没有任何变化。事实上,第二个大块的word-diff 是空的。

是否可以制定一个政策(例如在 GitHub 或我的 CI 中)拒绝包含此类“空”大块的提交,或者重新格式化补丁以完全忽略这些大块,以便我可以 git apply 它而不他们?

相关:How to git-apply a git word diff

【问题讨论】:

  • 您的问题似乎是关于 GitHub,而不是关于 Git。我建议使用那个标签(也许没有当前的标签)。
  • @torek 该策略不一定必须在 GitHub 上。我也可以在我的 CI 中强制执行它。所以我把GitHub放在括号里。
  • 您是否尝试过更改 core.eol 或 core.safecrlf 或 core.autocrlf 来处理线路断路器问题?这就是你要找的:stackoverflow.com/questions/3515597/…?
  • @YazeedSabri 感谢您指出这一点,但不,您链接的问题不涉及重排文本。
  • @HenriMenke 您可能想尝试将此选项“--word-diff”添加到 diff 命令以处理文本重排。

标签: git diff whitespace patch


【解决方案1】:

如果您正在寻找内置解决方案,我不知道有一个。然而,这并不意味着它不能相对容易地内置到 CI 系统中。

您可以将适当的git diff 命令的输出通过管道传输到如下脚本中,如果输入包含上述第二个大块的补丁,该脚本将退出 1。

#!/usr/bin/env ruby

def filter(arr)
  arr.join.split("\n\n").map { |x| x.gsub(/\s+/, ' ') }.join("\n\n")
end

def should_reject(before, after)
  return false if before.empty? && after.empty?
  before = filter(before)
  after = filter(after)
  return true if before == after
  false
end

chunk = nil
before = []
after = []
while (line = gets)
  trimmed = line[1..-1]
  case line
  when /^(\+\+\+|---)/
    # Do nothing.
  when /^@@ /
    if should_reject(before, after)
      warn "Useless change to hunk #{chunk}"
      exit 1
    end
    chunk = line
    before = []
    after = []
  when /^ /
    before << trimmed
    after << trimmed
  when /^\+/
    after << trimmed
  when /^-/
    before << trimmed
  end
end

if should_reject(before, after)
  warn "Useless change to hunk #{chunk}"
  exit 1
end

它本质上将每个块分割成块,它们之间有一个空行,将所有空白转换为空格,然后比较它们。如果它们相等,它会抱怨并退出非零。您可能希望将其修改为更健壮,例如处理 CRLF 结尾等,但该方法是可行的。

作为旁注,使这些变化更容易被发现的一种方法是使用每行句子的样式。每个句子,无论长度如何,都在一整行,每行只有一个句子。这使得区分任何类型的更改变得更加容易,并且完全避免了包装问题。

【讨论】:

    猜你喜欢
    • 2011-05-02
    • 2017-03-18
    • 2021-09-15
    • 2021-02-16
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    相关资源
    最近更新 更多