Chapter 13
Advanced uses of Mercurial Queues

Mercurial Queues にするのはですがかせてったでのつようあまり利用されないつかしようといます

このではLinux ネルけの Infiniband デバイスドライバにおいていていた使としてげまこのデバイスドライバデバイスドライバ程度にはきく 35 スファイルにまたがった 25,000 からなってお少数によりされています

このっているLinux したものですがしていないくのがあるできるでしょう

13.1 The problem of many targets

Linux ネルされにはしてしていませんリリったいますこのため Linux ネルリリするドライバしてにおいてはコンパイルすららないがあります

ドライバうためにはいくつかのLinux するがあります

13.1.1 Tempting approaches that don’t work well

なるとしなければならないソフトウェアにはつの 方法があります

方法それぞれがとするブランチする方法ですこの方法リポジトリでの 1 おいてでもってることですしいバグ真新しいリポジトリめなければならずそのてのバックポリポジトリさせますバックポでのそのブランチされま ブランチされるようなバックポけのおそらくドライバコンパイルげるでしょ

方法するしてえるためのめられたスツする方法ですこれらの “ifdef” Linux ネルツリではされていないのでこれらをいてツリ生成するためのないしですこのされるドベ となるでしょう

これらのいずれのスツリコピしていないにはしませんネルされ Linux ドライバLinus スツリとみなすコピからされますリポジトリにおける ドライバLinus スツリされるまでにはらないうちにらぬによってなるされているかもしれません

これらのリポジトリへのパッチえるのをしくしてしまうというっています

Mercurial Queues これまでべてきたでのするためのえますまさにこのようなにおい MQ にするつかのっています

13.2 によるパッチ

おそらくくのするする方法ごとにされるパッチ選択できることえるで しょうMQ quilt guards コマンド由来しますばれるしますまずはじめ のためのリポジトリしましょう

1  $ hg qinit
2  $ hg qnew hello.patch
3  $ echo hello > hello
4  $ hg add hello
5  $ hg qrefresh
6  $ hg qnew goodbye.patch
7  $ echo goodbye > goodbye
8  $ hg add goodbye
9  $ hg qrefresh

このによりなるファイルするのでいにはつのパッチさなリポジトリられま

からなるされた ” (tag) パッチしておきパッチ使 すべきMQ してえるというものですあらかじめ選択しておいたじてMQ されたパッチ するかるかをします

パッチつことができそれぞれのポジティブ選択パッチする ネガティブ選択パッチのどちらかですたないパッチされま

13.3 パッチする

hg qguardコマンドどのパッチするかをするかさもなくばします 現在パッチします

1  $ hg qguard
2  goodbye.patch: unguarded

パッチポジティブするにはとして +します

1  $ hg qguard +foo
2  $ hg qguard
3  goodbye.patch: +foo

パッチネガティブするにはとして -します

1  $ hg qguard hello.patch -quux
2  hg qguard: option -u not recognized
3  hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]...
4  
5  set or print guards for a patch
6  
7      Guards control whether a patch can be pushed. A patch with no
8      guards is always pushed. A patch with a positive guard ("+foo") is
9      pushed only if the qselect command has activated it. A patch with
10      a negative guard ("-foo") is never pushed if the qselect command
11      has activated it.
12  
13      With no arguments, print the currently active guards.
14      With arguments, set guards for the named patch.
15      NOTE: Specifying negative guards now requires ’--’.
16  
17      To set guards on another patch:
18        hg qguard -- other.patch +2.6.17 -stable
19  
20  options:
21  
22   -l --list  list all patches and guards
23   -n --none  drop all guards
24  
25  use "hg -v help qguard" to show global options
26  $ hg qguard hello.patch
27  hello.patch: unguarded
: hg qguardコマンドパッチしますがパッチしたりはしませんつまりパッチ hg qguard +a +bした パッチhg qguard +cしたこのパッチされている +c だけとなります

Mercurial series しますえるならhg qguardコマン 利用するseries ファイルしてもいません)。

1  $ cat .hg/patches/series
2  hello.patch
3  goodbye.patch #+foo

13.4 使する選択

hg qselectコマンドにするしますすることでhg qpushしたMQ するパッチされますこのコマンドはそれきをしませんみのパッチしてはいませ

されないhg qselectコマンドになっているつづつします されるとみなされます

1   $ hg qpop -a
2  patch queue now empty
3  $ hg qselect
4  no active guards
5  $ hg qselect foo
6  number of unguarded, unapplied patches has changed from 1 to 2
7  $ hg qselect
8  foo

現在選択されているguards ファイルされていますのでがあればてみるのもいでしょ

1  $ cat .hg/patches/guards
2  foo

hg qpushすることで選択ることができます

1  $ hg qpush -a
2  applying hello.patch
3  applying goodbye.patch
4  now at: goodbye.patch

+ないし -まるにはできませんむものもにはなれませんがそれいがいの 使です使MQ によりされます

1  $ hg qselect +foo
2  abort: guard ’+foo’ starts with invalid character: ’+’

選択されるパッチえます

1  $ hg qselect quux
2  number of guarded, applied patches has changed from 0 to 1
3  $ hg qpop -a
4  patch queue now empty
5  $ hg qpush -a
6  applying hello.patch
7  skipping goodbye.patch - guarded by [’+foo’]
8  now at: hello.patch

ネガティブポジティブすることを以下ることができます

1   $ hg qselect foo bar
2  number of unguarded, unapplied patches has changed from 0 to 1
3  $ hg qpop -a
4  patch queue now empty
5  $ hg qpush -a
6  applying hello.patch
7  applying goodbye.patch
8  now at: goodbye.patch

13.5 MQ パッチ

パッチ有無するMQ 以下使します

13.6 Trimming the work environment

べた Linux ネルけの Infiniband デバイスドライバでのパッチではLinux ネルスツリ使 しませんそのわりInfiniband デバイスドライバするヘッダのみをリポジトリそこにして パッチするようにしますこのリポジトリサイズネルリポジトリ1% まるためうのも

リポジトリしたならばパッチとなるジョン選択しま 2 XXXXXXXXXXXX This is a snapshot of the Linux kernel tree as of a revision of my choosing. XXXXXXXXXXXX 選択するリビジョンネルリポジトリにおけるチェンジセット ID コミットメッセ 3 しておきますネルツリするしてスナップショットによって できるため リポジトリネルツリのいずれにしてもパッチになりますXXXXXX Since the snapshot preserves the “shape” and content of the relevant parts of the kernel tree, I can apply my patches on top of either my tiny repository or a normal kernel tree.

パッチとなるスツリにはリポジトリスナップショット使すべきですそうすることでしたパッチリポジトリするあるいはくなるでしょ

13.7 Dividing up the series file

series されるパッチつかの論理なまとまりにしていますそれぞれのパッチそのされる パッチしたコメントブロックされます

っているパッチ以下のようなびになっています順序なのでしたしま

ではここでパッチをこのにするりましょうコンテキストすることでスタックパッチへの 5 になることがいようにスタックにあるパッチほどしていてしいものですされにくいパッチseries ファイ くことでこのすることができます

パッチリポジトリスツリうためにスツリわれるパッチ ですみのパッチくのしているのはそのためです

バックポおよび パッチseries としますバックポトパッチてのパッチ されなければなりませんしそのパッチいようにまりけるがありま

13.8 Maintaining the patch series

にはパッチするために使しています

これらのによりにどのようなスツリられるかをするなからぬることができま くの選択されていますがけに調うことも です

13.8.1 The art of writing backport patches

MQ 使することでバックポトパッチとなりますネルにおいてもドライバ正常 るようにネルにおいてされていない使するバックポトパッチのすべきことのてで

バックポトパッチとするネルけにいたかのようにあなたの するようなパッチにすることですパッチがでしゃばらないになります #ifdefじてされるによる けるためにバックポトパッチくのであれ ジョン#ifdef パッチむべきではありませんジョン#ifdef 使する りにパッチジョンしないうようにしてパッチによってすべきで

パッチそのするバックポトパッチとをグルするのにはつのがありま これらのパッチざりったリポジトリへのパッチ patchbomb のような使うことがしくなるためですパッチコンテキス 9 バッ クポトパッチさせてしまいパッチされたバックポトパッチきではパッチすること ができなくなってしまうためです

13.9 Useful tips for developing with MQ

13.9.1 Organising patches in directories

MQ 利用したするプロジェクトをしているのであればくのパッチすることもしいことではありません 250 えるパッチえたパッチリポジトリっています

パッチ論理なまとまりにできるのであればMQ パッチパスりが まれていてもないのでそれぞれのパッチなるディレクトリすることもできま 10

13.9.2 Viewing the history of a patch

期間にわたってパッチ12.11 べたようにパッチリポジトリするのがいでしょうその パッチhg diff使えないことにくことでしょうこれは() ていることにもタイムスタンプパッチディレクトリすることで MQ えてしまっていること があります

Mercurial されているextdiff 使うことでつのパッチみやすいものにすることがで きますこの使うためにはドパティパッケであるpatchutils [Wau] ですこのパッ するinterdiff というコマンドつのとしてしますつの 11 してこのコマンドするとからへとするための生成します

いつものようにhgrcファイル[extensions]セクションすることでextdiff することができま

1  [extensions]
2  extdiff =

interdiff コマンドつのファイルですがextdiff それぞれファイル ディレクトリしてするプログラムですそのためこれらつのディレクトリファイル interdiff するさなプログラムですスコドリポジトリにおけるexamples ディレクトリ hg-interdiff としてされています

1  #!/usr/bin/env python
2  #
3  # Adapter for using interdiff with mercurial’s extdiff extension.
4  #
5  # Copyright 2006 Bryan O’Sullivan <bos@serpentine.com>
6  #
7  # This software may be used and distributed according to the terms of
8  # the GNU General Public License, incorporated herein by reference.
9  
10  import os, sys
11  
12  def walk(base):
13      # yield all non-directories below the base path.
14      for root, dirs, files in os.walk(base):
15          for f in files:
16              path = os.path.join(root, f)
17              yield path[len(base)+1:], path
18  
19  # create list of unique file names under both directories.
20  files = dict(walk(sys.argv[1]))
21  files.update(walk(sys.argv[2]))
22  files = files.keys()
23  files.sort()
24  
25  def name(base, f):
26      # interdiff requires two files; use /dev/null if one is missing.
27      path = os.path.join(base, f)
28      if os.path.exists(path):
29          return path
30      return ’/dev/null’
31  
32  ret = 0
33  
34  for f in files:
35      if os.system(’interdiff "%s" "%s"’ % (name(sys.argv[1], f),
36                                            name(sys.argv[2], f))):
37          ret = 1
38  
39  sys.exit(ret)

hg-interdiff シェルコマンドパスMQ パッチディレクトリから以下のようにしてすることができ ます

1  hg extdiff -p hg-interdiff -r A:B my-change.patch

おそらくこのたらしいコマンド使うことになるでしょうからhgrcしてhgext Mercurial コマ ンド使えるようにしましょう

1  [extdiff]
2  cmd.interdiff = hg-interdiff

このにより interdiff hgext から利用できるようになりますのでhg extdiffくなって使いやすく なるでしょう

1  hg interdiff -r A:B my-change.patch
: interdiff コマンドだけしくしますThe interdiff command works well only if the underlying files against which versions of a patch are generated remain the same. パッチ生成ファイルおよびパッチ ったinterdiff 有用生成しないことがあります

extdiff MQ パッチまらない有用なものですextdiff する14.2 してく ださい