将目录及其内容打包为 diff 补丁?

将目录及其内容打包为 diff 补丁?

我有一个包含文本文件的小项目文件夹,我想将其发布到某个地方以便在论坛上提出问题。让我们以最简单的情况为例,我有这样的事情:

mkdir aaa
cd aaa
echo AAA > aaa.txt
mkdir bbb
echo BBB > bbb/bbb.txt

显然,我想要子文件夹结构:

aaa/
├── aaa.txt
└── bbb
    └── bbb.txt

...当我分享这个时要保留。所以我想首先使用https://gist.github.com/并输入每个文件的子目录名称;不幸的是 github 的回应是:

内容文件不能位于子目录中或名称中包含“/”

...而且我不打算在那里注册,只是为了能够通过 签出子目录并将子目录提交到要点中git,例如这样的事情(人们希望他们接受 openID,但是...呃)。

所以,我想,也许我可以以某种方式将整个目录结构和文件内容打包为diff补丁文件;那么作为一个文件,应该很容易上传到要点。但是,我不知道如何指定我的文件夹和空文件夹之间的差异;我试过:

$ diff -Naur /dev/null /tmp/aaa
diff: /tmp/aaa/null: No such file or directory

...但显然,这是行不通的。

然而,原则上它应该是可能的 - 这是一个测试用例git

mkdir aaa
cd aaa
git init
git config user.name test
git config user.email [email protected]

echo AAA > aaa.txt
mkdir bbb
echo BBB > bbb/bbb.txt

git add .
git commit -m 'initial commit'
git format-patch -1 HEAD

此时,0001-initial-commit.patch会出现一个文件,其中包含以下内容:

From 5834ae98fad9a9148648577f366af3498be6d364 Mon Sep 17 00:00:00 2001
From: test <[email protected]>
Date: Wed, 16 Dec 2015 10:25:23 +0100
Subject: [PATCH] initial commit

---
 aaa.txt     | 1 +
 bbb/bbb.txt | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 aaa.txt
 create mode 100644 bbb/bbb.txt

diff --git a/aaa.txt b/aaa.txt
new file mode 100644
index 0000000..43d5a8e
--- /dev/null
+++ b/aaa.txt
@@ -0,0 +1 @@
+AAA
diff --git a/bbb/bbb.txt b/bbb/bbb.txt
new file mode 100644
index 0000000..ba62923
--- /dev/null
+++ b/bbb/bbb.txt
@@ -0,0 +1 @@
+BBB
-- 
1.9.1

...这大约是我的想法,除了 - 我不想要任何git添加的电子邮件标题和统计注释;而且我也不希望git被要求从补丁文件重建文件夹 - 我只希望人们能够使用它patch来重建文件夹及其内容。

所以

  • 是否可以仅使用 vanilla 制作这样的补丁文件diff
  • 如果没有,是否可以git删除所有特定于 git 的注释,并格式化补丁,就像它是diff单独生成的一样?
  • 如果那里有小的二进制文件(即 spinner.gif 等),是否可以指示diff(或git)将二进制数据包含为 base64 或其他可以在发布/粘贴到 gist 等公共服务时幸存的文本编码?

答案1

仅使用diff,您需要一个参考(空)目录来比较:

mkdir /tmp/scratch
diff -urN /tmp/scratch /tmp/aaa

使用git,git diff应该会给你你正在寻找的输出。

要处理二进制文件,请使用git diff --binary;这将产生一个编码补丁,它将git apply知道如何处理。

答案2

是否可以仅使用 vanilla 制作这样的补丁文件diff

对于 GNU diff,是的,如果您包含该-N选项,并且您不关心空目录:

$ tree a b
a
├── aaa
│   ├── aaa.txt
│   └── bbb
│       └── bbb.txt
└── ccc
b

3 directories, 2 files
$ diff -uNr b a | (cd b; patch -p1)
~/devel/b
patching file aaa/aaa.txt
patching file aaa/bbb/bbb.txt
$  tree b
b
└── aaa
    ├── aaa.txt
    └── bbb
        └── bbb.txt

2 directories, 2 files

如果没有,是否可以告诉 git 删除所有特定于 git 的注释,并格式化补丁,就好像它是由 diff 单独生成的一样?

git diff如果有初始空提交,则可以使用:

$ git init
$ git commit --allow-empty -m init
[empty (root-commit) d1d0a97] init
$ git add aaa
$ git commit -m 'foo'
[empty b834eba] foo
 2 files changed, 2 insertions(+)
 create mode 100644 aaa/aaa.txt
 create mode 100644 aaa/bbb/bbb.txt
$ git diff 'HEAD^'
diff --git a/aaa/aaa.txt b/aaa/aaa.txt
new file mode 100644
index 0000000..43d5a8e
--- /dev/null
+++ b/aaa/aaa.txt
@@ -0,0 +1 @@
+AAA
diff --git a/aaa/bbb/bbb.txt b/aaa/bbb/bbb.txt
new file mode 100644
index 0000000..ba62923
--- /dev/null
+++ b/aaa/bbb/bbb.txt
@@ -0,0 +1 @@
+BBB

答案3

以文本形式传送文件和目录的(某种程度上)标准方法是使用 shar(1)。这将创建一个(有些可读的)shell 脚本来重新创建文件/目录。

使用 tar(1) 甚至 zip(1) 打包内容并让收件人解压会更容易。

相关内容