As was mentioned above, one can patch the original source by simply making the changes in the unpacked source directory. A real-life example of this is cron. If you grab cron's source package and look at the .diff.gz you will see that several of the original source's files were changed.

前述したように、展開済みのソースディレクトリに対する変更点を元にパッチを作成することができます。実例としてはcronパッケージがあります。cronのソースパッケージを取得し.diff.gzを見てみれば、オリジナルのソースファイルにさまざまな修正が加えられていることがわかるでしょう。

apt-get source cron
zgrep +++ cron*.diff.gz

But as we mentioned before this is not really the best way to represent patches. One better way is to create individual patch files, but them in debian/patches/ and apply the patches (using patch) in debian/rules. This is what is done for udev:

しかし、前節でも述べたように、これはパッチとしてはいい方法ではありません。より良い方法は、個別にパッチファイルを作成し、debian/patches/ディレクトリに格納し、debian/rulesで(patchコマンドを使うことで)パッチを適用する方法です。これは、udevパッケージで行われています:

apt-get source udev
zgrep +++ udev*.diff.gz
ls udev*/debian/patches/
less udev*/debian/rules

The rules file has the following rules for applying and unapplying the patches: rulesファイルでは、パッチを適用したり、元に戻したりするために、以下のようなルールが作成されています:

# Apply patches to the package
patch: patch-stamp
patch-stamp:
        dh_testdir
        @patches=debian/patches/*.patch; for patch in $$patches; do \
                test -f $$patch || continue; \
                echo "Applying $$patch"; \
                patch -stuN -p1 < $$patch || exit 1; \
        done
        touch $@

# Remove patches from the package
unpatch:
        dh_testdir
        @if test -f patch-stamp; then \
                patches=debian/patches/*.patch; \
                for patch in $$patches; do \
                        reversepatches="$$patch $$reversepatches"; \
                done; \
                for patch in $$reversepatches; do \
                        test -f $$patch || continue; \
                        echo "Reversing $$patch"; \
                        patch -suRf -p1 < $$patch || exit 1; \
                done; \
                rm -f patch-stamp; \
        fi

That is all very nice, but how do we create new patches for udev using this scheme? The general approach is:

これはすべてうまく動きます。では、この方法を使ったudevのための新しいパッチを作成するためにはどうすればいいでしょうか。一般的な方法は:

  1. copy the clean source tree to a temporary directory
  2. apply all patches up to the one you want to edit; if you want to create a new patch, apply all existing ones (this is necessary since in general patches depend on previous patches)
    • if you want, you can use debian/rules for this: remove the patches that come *after* the one you want to edit, and call 'debian/rules patch'. The actual name for the patch target varies, I have seen the following ones so far: patch setup apply-patches unpack patch-stamp. You have to look in debian/rules to see what it is called.

  3. copy the whole source tree again:
    • cp -a /tmp/old /tmp/new
  4. go into /tmp/new, do your modifications
  5. go back into your original source tree, generate the patch with:
    • diff -Nurp /tmp/old /tmp/new > mypatchname.patch
  6. クリーンなソースツリーを一時的に作成したディレクトリにコピーします。
  7. 修正しようとしているパッチまでのパッチをすべて適用します。新規にパッチを作成したい場合は、すべてのパッチを適用します(一般的に、あるパッチはその前のパッチに依存するので、これは必要な作業です)。
    • もし望むなら、これをdebian/rulesを使って行うことも可能です:まず、修正したいと思っているパッチより「後の」パッチをすべて削除します。次に'debian/rules patch'を実行します。patchターゲットの名前は違うかもしれません。これまでに、patch setup apply-patches unpack patch-stampなどを見たことがあります。どのように呼び出すべきかについては、debian/rulesの中を見てください。

  8. 再び、ソースツリーをコピーします:
    • cp -a /tmp/old /tmp/new
  9. /tmp/oldディレクトリに移動し、当初の目的だった修正を行います。
  10. 元のソースツリーに戻り、次のようにパッチを作成します:
    • diff -Nurp /tmp/old /tmp/new > mypatchname.patch

例1

Let us make a new patch for udev called 90_penguins.patch which replaces Linux with Penguin in the udev README file:

例として、udevREADMEファイルのLinuxをすべてPenguinに置き換える、90_penguins.patchを新規に作成してみましょう:

cd udev*/
cp -a . /tmp/old
pushd /tmp/old
debian/rules patch
cp -a . /tmp/new; cd ../new
sed -i 's/Linux/Penguin/g' README
cd ..
diff -Nurp old new > 90_penguins.patch
popd
mv /tmp/90_penguins.patch debian/patches
rm -rf /tmp/old /tmp/new

例2

What happens if we want to edit an existing patch? We can us a similar procedure as Example 1 but we will apply the patch to be edited first:

既存のパッチを修正したい場合はどうなるでしょう。例1と似ているけれども、最初のパッチを編集するという例を見てみましょう(訳注:udevの最新版(113-0ubuntu16)では10-selinux-include-udev-h.patchは存在しません):

cp -a . /tmp/old
pushd /tmp/old
cp -a . /tmp/new; cd ../new
patch -p1 < debian/patches/10-selinux-include-udev-h.patch
sed -i '1 s/$/***** HELLO WORLD ****/' udev_selinux.c
cd ..
diff -Nurp old new > 10-selinux-include-udev-h.patch
popd
mv /tmp/10-selinux-include-udev-h.patch debian/patches
rm -rf /tmp/old /tmp/new

So this way of patching the source, while technically fine, can become very complicated and unmanageable. To make patching easier and more straightforward patch systems were developed. We will take a look at couple popular ones.

このソースに対するパッチの作成方法は、技術的にはうまくいきますが、とても複雑で管理しづらいものになり得ます。もっと簡単で素直にパッチを作成できるパッチシステムが開発されました。次節以降で、もっとも一般的な二つの方法を見ていきましょう。

<=

=>

パッチシステム

パッチシステムを用いないパッチ適用

Simple PatchsysとCDBS

UbuntuJapaneseWiki: UbuntuPackagingGuideJa/ps-scratch (最終更新日時 2012-01-10 11:49:16 更新者 匿名)