今日やったことのメモです。
要件
REAMDE.mdという名前のファイルをリポジトリーAに作っていくつかコミットしたが、事情が変わり別のリポジトリーBに同じ内容の変更を加えたい。しかし以下の懸念事項が:
- コミットメッセージやdiffの内容は極力維持したい
- ただし、リポジトリーBにはすでに
README.mdというファイルがあるのでCODE_OF_CONDUCT.mdというファイルにリネームした状態でコミットしたことにしたい
使ったコマンドのバージョン
> git --version
git version 2.24.1.windows.2
> perl --version
This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-msys-thread-multi
1. git format-patchで各コミットをpatchファイルとして書き出す
参考: git showを使用して複数のコミットにまたがってパッチを作成して適用する
今回はmasterブランチから生やした各コミットを、patchファイルとして再利用したかったのでgit format-patchコマンドを次のように使った:
git format-patch master
これで、masterから現在の最新のコミット(つまりHEAD)までの各コミットが、連番がファイル名の先頭に着いた.patchファイルとして書き出される。
2. リポジトリーAのREADME.mdをリポジトリーBにCODE_OF_CONDUCT.mdとしてコピーする
git format-patchで作ったpatchファイルは、例えリポジトリーが異なろうとgit amコマンドでコミットとして適用できるはずだが、そのためには、適用するコミットのうち、最初のコミットが変更を加えるファイルが、不整合しない状態で存在していなければならない。
つまり今回の場合、変更を加える前のリポジトリーAにおけるREADME.mdが、リポジトリーBにおいて、変換後の名前、CODE_OF_CONDUCT.mdとして、あらかじめコミットされている必要がある。
そこでリポジトリーAにおいてREADME.mdに変更を加える前の状態、masterブランチに戻って、リポジトリーBにCODE_OF_CONDUCT.mdとしてコピー・コミットした:
# リポジトリーAでの作業
cd /path/to/repository-a
git checkout master
cp README.md /path/to/repository-b/CODE_OF_CONDUCT.md
# リポジトリーBでの作業
cd /path/to/repository-b/
git add CODE_OF_CONDUCT.md
git commit -m"Add CODE_OF_CONDUCT.md"
3. git format-patchで作成したパッチファイルを一括置換する
今度は、最初にgit format-patchコマンドで書き出したREADME.mdに対する各patchファイルを、CODE_OF_CONDUCT.md向けに変換しよう。
やり方は単純で、perlコマンドでREADME.mdと書かれていた部分をCODE_OF_CONDUCT.mdに書き換えれば良い(もちろんsedでもなんでもいい):
perl -i.bk -pe 's/README.md/CODE_OF_CONDUCT.md/g' *.patch
当然、コミット内容にREADME.mdという文字列が含まれている場合はその部分まで変換されてしまうので少し気を遣う必要があるが、今回は特に気にする必要がなかったので、思いっきり一括置換した。
-i.bkというオプションでバックアップファイルを作るかはお好みで。
4. git amコマンドでリポジトリーBに適用する
あとは、変換した.patchファイルをリポジトリーBに移してgit amすればよい:
mv *.patch /path/to/repository-b/
cd /path/to/repository-b/
git am *.patch
以上!