<chapter id="gbp.patches">
  <title>Working with Patches</title>

  <para>
    &gbp-pq; can be used to manage patches that modify the upstream
    source inside
    <filename>debian/patches/</filename>. This is mostly intended for
    3.0 (quilt) format source packages.
  </para>

  <para>
    The basic idea is that patches are imported from you
    &debian-branch; to a patch-queue branch with one patch file
    in <filename>debian/patches/</filename> becoming one commit on the
    the patch-queue branch.  The created branch will be named after
    the branch you imported from
    with <filename>patch-queue/</filename> prepended. So if you do
    your &debian; packaging on <filename>debian/sid</filename> and do
    a
  </para>
<programlisting>
    &gbp-pq-import;
</programlisting>
  <para>
    then the newly created branch will be
    called <filename>patch-queue/debian/sid</filename>.
  </para>

  <para>On the patch-queue branch you can work on the commits using
    familiar &git; commands (rebase, commit --amend, etc). When done,
    &gbp-pq; will be used to turn the commits on the patch-queue
    branch into patch in <filename>debian/patches/</filename> files
    again.
  </para>

  <para>
    This workflow facilitates e.g. the cherry-picking of patches for
    stable releases, the forward-porting of patches to new upstream
    versions by using git rebase on the patch-queue branch (patches
    already applied upstream are detected automatically) as well as
    the reordering, dropping and renaming of patches without having to
    resort to &quilt;.  The generated patches
    in <filename>debian/patches/</filename> have all the necessary
    information to forward them upstream since they use a format similar
    to <command>git-format-patch</command>.
  </para>

  <para>
    The main drawback of this workflow is the lack of history on the
    patch-queue branch since it is frequently droppend and
    recreated. But there is full history on
    the your &debian-branch;, of course.
  </para>

  <para>
    Also, beware that &gbp-pq; currently has incomplete support for
    <ulink url="https://dep-team.pages.debian.net/deps/dep3/">DEP3</ulink> headers.
    Initially, parsing with <command>git-mailinfo(1)</command> is attempted,
    which supports only the <computeroutput>From</computeroutput> and
    <computeroutput>Subject</computeroutput> fields. If neither of these are
    present, &gbp-pq; will attempt to convert the patch from DEP3 format into
    a <command>git-mailinfo(1)</command> compatible format. This involves first
    loading <computeroutput>From</computeroutput> using the
    <computeroutput>Author</computeroutput> field and
    <computeroutput>Subject</computeroutput> using the first line of the
    <computeroutput>Description</computeroutput> field. Then,  any additional
    fields (such as <computeroutput>Origin</computeroutput> and
    <computeroutput>Forwarded</computeroutput>), and the remainder of the
    <computeroutput>Description</computeroutput> (if any), will be appended to
    the body.
  </para>

  <sect1 id="gbp.patches.workflow">
    <title>Basic Workflow</title>

    <para>
      This example assumes you're working on a source 3.0 (quilt)
      format package with patches
      in <filename>debian/patches</filename> parseable
      by <command>git-quiltimport(1)</command>. The git branch
      currently checked out is named <filename>debian/sid</filename>.
    </para>

    <mediaobject>
      <imageobject>
	<imagedata fileref="images/pq-unapplied.png" format="PNG"/>
		   </imageobject>
      <caption>
	<para>
	  The &debian-branch; we start from.
	</para>
      </caption>
    </mediaobject>

    <para>Let's first create the patch-queue branch and import the
      contents of <filename>debian/patches</filename> onto it using
      &gbp-pq;
    </para>

<programlisting>
  <command>cd <replaceable>REPO</replaceable></command>
  &gbp-pq; import
</programlisting>

<para>
  This will generate output like:
<screen>
    gbp:info: Trying to apply patches at 'aaa1011bfd5aa74fea43620aae94709de05f80be'
    gbp:info: 18 patches listed in 'debian/patches/series' imported on 'patch-queue/debian/sid'
</screen>
  What happened is that &gbp-pq; imported each patch file and switched
  you to the newly created patch-queue branch
  (<filename>patch-queue/debian/sid</filename>) automatically.
</para>

  <mediaobject>
    <imageobject>
      <imagedata fileref="images/pq-applied.png" format="PNG"/>
    </imageobject>
    <caption>
      <para>
	The patch-queue branch with patches
	from <filename>debian/patches</filename> applied.
      </para>
    </caption>
  </mediaobject>

<para>
  Now you can work on the patch-queue branch (add, remove, rebase,
  test) to get your patches into shape:
  <itemizedlist>
    <listitem>
      <para>
	To add what will later become a patch
	in <filename>debian/patches/</filename> simply make a
	commit. The first line of the commit message will become the
	patch name later.  The following lines include the details of
	what the patch does.
      </para>
    </listitem>
    <listitem>
      <para>
	To remove or edit commits use git rebase -i . The git
	documentation explains how to work with git-rebase.
      </para>
    </listitem>
  </itemizedlist>
</para>

<para>
  Once satisfied with the commits let's regenerate the patches
  in <filename>debian/patches/</filename> using &gbp-pq;. This will
  switch you back to the branch <filename>debian/sid</filename> and
  regenerate the patches using a method similar
  to <command>git-format-patch</command>:
</para>

<programlisting>
  &gbp-pq; export
</programlisting>

<para>You can now commit the result by using:</para>
<programlisting>
  &gitcmd; add debian/patches
  &gitcmd; commit
</programlisting>
<para>
  If you don't want to commit the result by hand each time you can also
  pass <option>--commit</option> to the &gbp; <option>export</option>
  command above.
</para>

<para>
  Next you can update <filename>debian/changelog</filename> (e.g. by
  running "&gbp-dch; <option>-S</option> <option>-a</option>") and
  build the package as usual.
</para>

</sect1>
<sect1 id="gbp.patches.newupstream">
  <title>Importing a new upstream version</title>

  <para>
    To update your patches for a new upstream version one
  </para>
  <orderedlist>
    <listitem>
      <para>
	Imports the current patches onto the patch-queue branch (if
	not done already) using &gbp-pq-import;. This will allow you
	to rebase the patches on the new upstream version later.
      </para>
    </listitem>
    <listitem>
      <para>
	Imports the new upstream version with
	&gbp-import-orig; <option>--uscan</option>.
      </para>
    </listitem>
    <listitem>
      <para>
	Rebases the patches onto the new upstream version using
	&gbp-pq-rebase;. This will bring the patches up to date
	regarding the new upstream version. Patches already applied
	upstream can be dropped and remaining patches can be modified
	to apply to the new version.
      </para>
    </listitem>
    <listitem>
      <para>
	Exports the patches to <filename>debian/patches</filename> using
	&gbp-pq-export;.
      </para>
    </listitem>
  </orderedlist>

  <para>
    But don't worry if you forgot to do so before importing the new
    version (or if another team member imported the version already).
  </para>

  <para>
    In this case you can make &gbp-pq; figure out where to apply the
    patches by using the <option>--time-machine=</option> option. The
    following command
  </para>

<programlisting>
    &gbp-pq-import; --force --time-machine=10
</programlisting>

  <para>
    would drop your current patch-queue branch (if existent) and
    create a new one by going back in your commit history as far as 10
    commits to find a place where your patches still
    apply <footnote><para>This is not necessarily
    your debian-branch; HEAD since the new upstream
    version might have changed so that the patches no longer apply
    cleanly there.</para></footnote>. If it finds such a commit on
    your &debian-branch; it will create the patch-queue branch from
    there and switch you to that branch. You can now rework your
    patches to apply to the new upstream version by using
    &gbp-pq-rebase;:
  </para>

  <mediaobject>
    <imageobject>
      <imagedata fileref="images/pq-time-machine.png" format="PNG"/>
		 </imageobject>
    <caption>
      <para>
	The patch-queue branch and &debian-branch; after importing the
	patches.
      </para>
    </caption>
  </mediaobject>

<programlisting>
    &gbp-pq-rebase;
</programlisting>

<para>
  or you can invoke &gitcmd; <option>rebase</option> directly:
</para>

<programlisting>
    &gitcmd; rebase -i debian/sid
</programlisting>

  <para>
    Should the rebase fail (e.g. because the upstream source changed
    at the same place your patches modify the code) you can resolve
    this by using  the options of &gitcmd; <option>rebase</option> (if
    you simply want to abort use
    &gitcmd; <option>rebase</option> <option>--abort</option>).
  </para>

  <mediaobject>
    <imageobject>
      <imagedata fileref="images/pq-rebase.png" format="PNG"/>
		 </imageobject>
    <caption>
      <para>
	The patch-queue branch after rebasing the patches. Patches
	that were merged upstream were dropped.
      </para>
    </caption>
  </mediaobject>

  <para>
    Once done you can export your commits to patch files again:
  </para>
<programlisting>
  &gbp-pq-export; --commit
</programlisting>

  <para>
    The export will also switch you back to the &debian-branch;.
  </para>
  <mediaobject>
    <imageobject>
      <imagedata fileref="images/pq-export.png" format="PNG"/>
		 </imageobject>
    <caption>
      <para>
	The &debian-branch; after exporting the patches and committing the changes.
      </para>
    </caption>
  </mediaobject>

  <para>
    See this in action in a
    <ulink url="https://honk.sigxcpu.org/piki/projects/git-buildpackage/videos/gbp-pq-new-upstream-version.ogv">short
      video</ulink>.
  </para>

</sect1>
<sect1 id="gbp.patches.firstpatch">
  <title>Adding your first patch</title>

  <para>
    If a package doesn't have any patches yet, these are the steps to add
    your first patch:
  </para>
  <orderedlist>
    <listitem>
      <para>Launch an import. If there's nothing to import &gbp-pq; will just
	create an empty branch and switch your working copy to it:
<programlisting>
  &gbp-pq-import;
</programlisting>
      </para>
    </listitem>
    <listitem>
      <para>
	Create your first patch: edit files, test, commit your changes
	using <command>git commit</command>
      </para>
    </listitem>
    <listitem>
      <para>
	To generate the new Quilt patch set use
      </para>
<programlisting>
  &gbp-pq-export; --commit
</programlisting>
<para>
  This will switch you back to your &debian-branch; branch, generate the
  patches and commit them right away to this branch.
</para>

<para>
  Skip the <option>--commit</option> if you don't want to commit
  right away. If you want to pick the changelog message from the patch
  see
  <filename>/usr/share/doc/git-buildpackage/examples/gbp-add-patch</filename>.
</para>
    </listitem>
  </orderedlist>
</sect1>

  <sect1 id="gbp.patches.team">
    <title>Team maintenance</title>

    <para>The easiest way is to not push out any patch-queue/* branches at all.
      They can be recreated by any team member easily by using</para>

<programlisting>
  &gbp-pq-import; --force
</programlisting>

<para>
  The patch-queue branch can also be re-created when pulling (this
  will additionally drop your current patch-queue branch and recreate it
  from <filename>debian/patches</filename>):</para>
<programlisting>
  &gbp-pull; --redo-pq
</programlisting>

<para>
  Note that you can push out patch-queue branches. Other team
  members must just be aware that branches in the patch-queue/
  namespace are being rebased frequently and therefore cause
  non fast-forward updates.
</para>
  </sect1>
</chapter>
