如何为整个目录创建补丁来更新它?

Posted

技术标签:

【中文标题】如何为整个目录创建补丁来更新它?【英文标题】:How to create a patch for a whole directory to update it? 【发布时间】:2012-04-16 08:02:36 【问题描述】:

我知道已经有几个线程,但是没有人完全解释过如何执行初始差异来创建补丁文件,然后如何应用该补丁到初始目录更新它。

在我的例子中,有一个任何人都可以从网上下载的文件目录。我已获取该目录并对其进行了更改,并希望创建一个补丁文件,以便其他人可以将其应用到下载的目录中,以准确重现我修改后的目录中的内容。

帮助?关于如何应用我的补丁,我需要告诉其他人什么?

【问题讨论】:

【参考方案1】:

我也遇到了同样的问题 - 很多关于如何做到一半的建议。好吧,这是我为使修补和取消修补工作所做的工作:

创建补丁文件:

    将两个目录的副本放在 /tmp 中,这样我们就可以创建补丁了 文件,或者如果勇敢,将它们并排放置 - 在一个目录中。

    在新旧两个目录上运行适当的差异:

    diff -ruN orig/ new/ > file.patch
    # -r == recursive, so do subdirectories
    # -u == unified style, if your system lacks it or if recipient
    #       may not have it, use "-c"
    # -N == treat absent files as empty
    

如果一个人有 orig/ 目录,他们可以通过运行补丁重新创建新的。

从旧文件夹和补丁文件重新创建新文件夹:

    将补丁文件移动到 orig/ 文件夹所在的目录

    此文件夹将被破坏,因此请在某处进行备份,或者 使用副本。

    patch -s -p0 < file.patch
    # -s == silent except errors
    # -p0 == needed to find the proper folder
    

    此时, orig/ 文件夹包含了 new/ 内容,但仍然 有它的旧名字,所以:

    mv orig/ new/    # if the folder names are different
    

【讨论】:

希望我能和你握手。非常感谢! 我是 Mac 用户所以不知道。您需要做的是检查 Cygwin 上的补丁和差异选项。这就是为什么我在上面添加了关于选项含义的 cmets - 因此,如果一个或另一个程序提供不同的选项,您可以弄清楚要更改哪些内容才能使其正常工作。从概念上讲,所有补丁/差异程序都应该支持该功能。 @CharanPai "diff" 不支持二进制文件,所以我认为不支持。您也许可以创建自己的命令文件包装器来执行此操作。你要做的是 binhex 你的二进制数据文件 - 为每个 binhex 或类似的 ascii 格式创建一个文本文件。然后比较这些文件,并在应用补丁后,将(可能已修改的)binhex 文件坏为二进制文件。 @DavidH 是否可以省略那些外部目录名称?或者补丁是否必须包含新的和原始目录名称? patch 正在为我修补new/ 而不是orig/ 目录,但我找到了-d 选项,它允许您在应用修补程序之前先在该目录中说cd那么您可以相应地调整-p N 参数。【参考方案2】:

我需要创建一个补丁文件并将其发送给某人,以便他们可以更新他们的目录以匹配我的目录。但是,diff 和 patch 有很多警告,所以最终我花了几个小时才弄清楚概念上如此简单的东西。绝对路径似乎比相对路径更受欢迎,而且许多选项似乎是从小众用例演变而来的。我终于想出了一个基于David H's answer的解决方案,还有来自Lakshmanan Ganapathy的额外提示):

将您的directory 备份到directory.orig 修改您的directory 以达到所需状态 将directory.origdirectory 的差异保存在file.patch 中,以便收件人的名称匹配

这是我的笔记:

# to create patch:
# copy <directory> backup to something like <directory>.orig alongside it
cp -r <path_to>/<directory> <path_to>/<directory>.orig
# create/update/delete files/folders in <directory> until desired state is reached
# change working directory to <directory>
cd <path_to>/<directory>
# create patch file alongside <directory>
diff -Naru ../<directory>.orig . > ../file.patch
# -N --new-file Treat absent files as empty.
# -a --text Treat all files as text.
# -r --recursive Recursively compare any subdirectories found.
# -u -U NUM --unified[=NUM] Output NUM (default 3) lines of unified context.

# to apply patch:
# change working directory to <directory>
cd <path_to>/<directory>
patch -s -p0 < <path_to>/file.patch
# -s or --silent or --quiet Work silently, unless an error occurs.
# -pN or --strip=N Strip smallest prefix containing num leading slashes from files.

# to undo patch (note that directories created by patch must be removed manually):
# change working directory to <directory>
cd <path_to>/<directory>
patch -Rs -p0 < <path_to>/file.patch
# -R or --reverse Assume that patch was created with the old and new files swapped.
# -s or --silent or --quiet Work silently, unless an error occurs.
# -pN or --strip=N Strip smallest prefix containing num leading slashes from files.

【讨论】:

【参考方案3】:

查看开源 Scarab C++ 库:https://github.com/loyso/Scarab

它完全符合您的描述。 它使用 xdelta 库构建每个文件的差异并将其放入存档包。您可以重新分发该包并应用差异。有 Win32 的二进制文件。

我是 Scarab 项目的作者。

【讨论】:

以上是关于如何为整个目录创建补丁来更新它?的主要内容,如果未能解决你的问题,请参考以下文章

如何为使用 makefile 构建的整个项目生成一个大型依赖映射?

如何为特定提交生成 Git 补丁?

如何为当前工作目录的文件夹创建一个名为的变量?

如何为直播创建本地媒体服务器?

如何为我的项目创建 PSR-4 自动加载器?

K6 负载测试 - 如何为整个测试运行创建顺序 ID