Bash

將目錄及其內容打包為差異更新檔?

  • January 26, 2020

我有一個帶有文本文件的小型項目文件夾,我想將其發佈在某個地方以便在論壇上提問。在最簡單的情況下,讓我們假設我有這樣的事情:

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 回應:

內容文件不能在子目錄中或名稱中包含“/”

…而且我不打算在那裡註冊,只是為了能夠通過 簽出子目錄並將子目錄送出到 gist git,例如這樣的事情(希望他們接受 openID,但是……嗯)。

所以,我想,也許我可以以某種方式將整個目錄結構和文件內容打包為一個diff更新檔文件;然後作為單個文件,應該很容易上傳到 gist。但是,我不知道如何指定我的文件夾和空文件夾之間的差異;我試過:

$ 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 test@test.com

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 <test@test.com>
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 等公共服務時保留的文本編碼?

使用 only diff,您需要一個參考(空)目錄來比較事物:

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

使用git,git diff應該會給你你正在尋找的輸出。

要處理二進製文件,請使用git diff --binary; 這將產生一個git apply知道如何處理的編碼更新檔。

是否可以只使用 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

引用自:https://unix.stackexchange.com/questions/249683