git format-patchなどで複数のコミットを別のリポジトリーに変換して移植する

by YAMAMOTO Yuji on October 20, 2020

Tagged as: git.

この記事は、こちらのページにも同時投稿しています。


今日やったことのメモです。

要件

REAMDE.mdという名前のファイルをリポジトリーAに作っていくつかコミットしたが、事情が変わり別のリポジトリーBに同じ内容の変更を加えたい。しかし以下の懸念事項が:

使ったコマンドのバージョン

> 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

以上!


I'm a Haskeller Supported By Haskell-jp.