【问题标题】:patching text files修补文本文件
【发布时间】:2011-01-17 20:47:11
【问题描述】:

我正在尝试连续构建一个带有差异补丁的文本文件。 从一个空的文本文件开始,我需要应用 600 多个补丁来完成最终文档(我编写的文本 + 用 mercurial 跟踪更改)。文件中的每一次更改都需要添加额外的信息,所以我不能简单地在命令行中使用 diffpatch

我花了一整天的时间来编写(和重写)一个分析差异文件并相应地对文本文件进行更改的工具,但是其中一个差异文件使我的程序以我无法做到的方式运行有任何意义。

每个差异文件都会调用此函数:

# filename = name of the diff file
# date = extra information to be added as a prefix to each added line
def process_diff(filename, date):
    # that's the file all the patches will be applied to
    merge_file = open("thesis_merged.txt", "r")
    # map its content to a list to manipulate it in memory
    merge_file_lines = []
    for line in merge_file:
        line = line.rstrip()
        merge_file_lines.append(line)
    merge_file.close()

    # open for writing:
    merge_file = open("thesis_merged.txt", "w")

    # that's the diff file, containing all the changes
    diff_file = open(filename, "r")
    print "-", filename, "-" * 20

    # also map it to a list
    diff_file_lines = []
    for line in diff_file:
        line = line.rstrip()

        if not line.startswith("\\ No newline at end of file"): # useless information ... or not?
        diff_file_lines.append(line)

    # ignore header:
    #--- thesis_words_0.txt 2010-12-04 18:16:26.020000000 +0100
    #+++ thesis_words_1.txt 2010-12-04 18:16:26.197000000 +0100
    diff_file_lines = diff_file_lines[2:]

    hunks = []
    for i, line in enumerate(diff_file_lines):
        if line.startswith("@@"):
            hunks.append( get_hunk(diff_file_lines, i) )

    for hunk in hunks:
        head = hunk[0]
        # @@ -252,10 +251,9 @@
        tmp = head[3:-3].split(" ") # [-252,10] [+251,9]
        line_nr_minus = tmp[0].split(",")[0]
        line_nr_minus = int(line_nr_minus[1:]) # 252
        line_nr_plus = tmp[1].split(",")[0]
        line_nr_plus = int(line_nr_plus[1:]) # 251

        for j, line in enumerate(hunk[1:]):
            if line.startswith("-"):
            # delete line from the file in memory
            del merge_file_lines[line_nr_minus-1]

        plus_counter = 0 # counts the number of added lines
        for k, line in enumerate(hunk[1:]):
            if line.startswith("+"):
                # insert line, one after another
                merge_file_lines.insert((line_nr_plus-1)+plus_counter, line[1:])
                plus_counter += 1

    for line in merge_file_lines:
        # write the updated file back to the disk
        merge_file.write(line.rstrip() + "\n")

    merge_file.close()
    diff_file.close()
    print "\n\n"


    def get_hunk(lines, i):
        hunk = []
        hunk.append(lines[i])
        # @@ -252,10 +251,9 @@

        lines = lines[i+1:]

        for line in lines:
            if line.startswith("@@"):
                # next hunk begins, so stop here
                break
            else:
                hunk.append(line)

            return hunk

差异文件看起来像这样——这是麻烦制造者:

--- thesis_words_12.txt 2011-01-17 20:35:50.804000000 +0100
+++ thesis_words_13.txt 2011-01-17 20:35:51.057000000 +0100
@@ -245 +245,2 @@
-As
+Per
+definition
@@ -248,3 +249 @@
-already
-proposes,
-"generative"
+generative
@@ -252,10 +251,9 @@
-that
-something
-is
-created
-based
-on
-a
-set
-of
-rules.
+"having
+the
+ability
+to
+originate,
+produce,
+or
+procreate."
+<http://www.thefreedictionary.com/generative>

输出:

[...]

Per
definition
the
"generative"
generative
means
"having
the
ability
to
originate,
produce,
or
procreate."
<http://www.thefreedictionary.com/generative>
that

[...]

所有以前的补丁都按预期重现了文本。我已经重写了很多次,但是这种错误行为仍然存在——所以现在我一无所知。

非常感谢有关如何以不同方式执行此操作的提示和技巧。提前非常感谢!

编辑: - 最后每一行应该是这样的:{date_and_time_of_text_change}word

它基本上是关于跟踪一个单词被添加到文本中的日期和时间。

【问题讨论】:

  • 您不能使用diff 应用一个补丁吗,进行必要的更改并对下一个补丁文件执行相同的操作。需要添加哪些额外信息?
  • 如果 Elalfer 的建议由于某种原因不起作用,请查看 python-patch。或者更好的是,使用 mercurial lib 本身——它是用 Python 编写的。
  • 为什么不使用patch(1)linux.die.net/man/1/patch
  • 我还认为 diff / patch 一定可以,但显然不是:linuxquestions.org/questions/linux-software-2/…
  • 你问错问题了。正确的问题是,“为什么哦,为什么我使用单个空格进行缩进?”

标签: python diff patch


【解决方案1】:

代码中确实有一个错误——我没有正确解释差异文件(没有意识到需要换行,当一个差异文件中有多个大块时)

def process_diff(filename, date, step_nr):
    merge_file = open("thesis_merged.txt", "r")
    merge_file_lines = [line.rstrip() for line in merge_file]
    merge_file.close()

    diff_file = open(filename, "r")
    print "-", filename, "-"*2, step_nr, "-"*2, date

    diff_file_lines = [line.rstrip() for line in diff_file]
    hunks = []
    for i, line in enumerate(diff_file_lines):
        if line.startswith("@@"):
            hunks.append( get_hunk(diff_file_lines, i) )
    diff_file.close()

    line_shift = 0
    for hunk in hunks:
        head = hunk[0]
        # @@ -252,10 +251,9 @@
        tmp = head[3:-3].split(" ") # [-252,10] [+251,9]

        line_nr_minus = tmp[0].split(",")[0]
        minusses = 1
        if len( tmp[0].split(",") ) > 1:
            minusses = int( tmp[0].split(",")[1] )
        line_nr_minus = int(line_nr_minus[1:]) # 252

        line_nr_plus = tmp[1].split(",")[0]
        plusses = 1
        if len( tmp[1].split(",") ) > 1:
            plusses = int( tmp[1].split(",")[1] )
        line_nr_plus = int(line_nr_plus[1:]) # 251

        line_nr_minus += line_shift

        #@@ -248,3 +249 @@
        #-already
        #-proposes,
        #-"generative"
        #+generative

        if hunk[1]: # -
            for line in hunk[1]:
                del merge_file_lines[line_nr_minus-1]

        plus_counter = 0
        if hunk[2]: # +
            for line in hunk[2]:
                prefix = ""
                if len(line) > 1:
                    prefix = "{" + date + "}"
                merge_file_lines.insert((line_nr_plus-1)+plus_counter, prefix + line[1:])
                plus_counter += 1

        line_shift += plusses - minusses

【讨论】:

    【解决方案2】:

    尝试使用来自python-patch 的解析器 - 至少您可以手动一个一个地应用大块,看看哪个失败了。 API 不稳定,但解析器稳定,因此您只需将 patch.py​​ 从 trunk/ 复制到您的项目。不过,如果能获得一些有关所需 API 的建议,那就太好了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-17
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      相关资源
      最近更新 更多