git
における、いにしえのメールによるコミットをやってみようの記事です。
オフラインで git を使う必要がある場面もあるのです。。。
前準備
とりあえず適当にコミットを作成する。
この時 patches
ディレクトリを .gitignore
に追加しておくとよい。
$ mkdir test-git
$ cd ./test-git
$ git init
$ echo "patches" >> ".gitignore"
$ echo "Hello git!" >> README.md
$ git add --all
$ git commit -m "first commit"
$ echo -e "\nadd text" >> README.md
$ git add --all
$ git commit -m "second commit"
$ echo -e "\nadd text" >> README.md
$ git add --all
$ git commit -m "third commit"
コマンド覚えると、記事にするのにとても楽...。やはり人はCLIを求める。。。
patch ファイルを生成する(git format-patch)
これらから patch ファイルを生成する。format-patch
というものを利用する。
とりあえず全部でやってみる。
# 全部
$ git format-patch --root -o patches
# 特定のコミット以降(含まない)(5ddf3638)
# git format-patch 5ddf3638 -o patches
# 特定のブランチ全部 (master)
# git format-patch master --all -o patches
# 直近nつ分(2)
# git format-patch -2 -o patches
1コミットごとにファイルが生成されるので、これらを cat
で結合する。
$ cat ./patches/* > all_commits.patch
このファイルの中身は git diff
のような内容になってる。
この all_commits.patch
を別のPCへ送る...(省略)
patch ファイルを反映する(git am)
別のフォルダに受け側の git を作る。
$ mkdir test-git-clone
$ cd test-git-clone
$ git init
この git に先ほどのパッチを反映する。
$ git am ./test-git/all_commits.patch
すると先ほどの git が反映される!!
気になること
patch の反映忘れはどうなるの?
2nd コミットを反映せずに 3rd パッチを充てるとエラーが出てくる。
エラーは一時的に状態がキャッシュされるので abort
や skip
で処理しないと、一生 am できない体になる。
$ git am ../test-git/patches/0003-third-commit.patch
Applying: third commit
error: patch failed: README.md:1
error: README.md: patch does not apply
Patch failed at 0001 third commit
hint: Use 'git am --show-current-patch=diff' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
$ git am ../test-git/patches/0003-third-commit.patch
fatal: previous rebase directory .git/rebase-apply still exists but mbox given.
$ git am --abort
すでに適用している patch はどうなるの?
同様にエラーになるっぽい。
$ git am ../test-git/patches/0003-third-commit.patch
Applying: third commit
error: patch failed: README.md:1
error: README.md: patch does not apply
Patch failed at 0001 third commit
hint: Use 'git am --show-current-patch=diff' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
別ブランチはどうなるの?
先ほどのをベースにこんなブランチを作ってみた。
# git format-patch dbf70290 -o patches
fatal: ambiguous argument 'dbf70290': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
別のブランチのコミットは参照できないみたい。
あくまでも現在のブランチに限る。
おわりに
さすが git というところだが、手数が多くて大変かもしれん。
補助ツールなどがあるとよいのだが。