Mercurial Patches for gem5/garnet


Mercurial patches allow you to develop code as patches, and push/pop the appropriate patches. This allows you to develop your code as a set of patches which keeps it clean and easier to debug. If you do use patches, it would make sense to have different patches for each feature you add, rather than having one large patch with everything.

Note: We will release new features for Garnet2.0, that are not part of the gem5 repo, as patches that you can apply to the codebase.
See Importing a Patch below.

On this page, we describe basic features of the Mercurial patch queue required to create, import and update patches. More advanced features can be found on the Mercurial page.


Getting Started

The following two steps only need to be done once.

Step 1: Create a file with the name .hgrc in your $HOME with the following lines. [Update the username with yours].

[extensions]
hgext.mq=
hgext.extdiff=
hgext.patchbomb=
[ui]
username = Tushar Krishna <tushar@ece.gatech.edu>

Step 2: In your gem5 folder, type the following:
hg qinit

You have initialized the patch queues now.


Patches folder

Patches are essentially text files, storing diffs. Patches are organized as a queue, and you can create new patches, update existing patches, push patches, and pop patches.

All your patches will be here inside the gem5 folder:
.hg/patches

You can see the list of all your patches, and the order in which they will be applied in the following text file:
.hg/patches/series


Importing a patch

Suppose you want to import a patch foo and apply it to your code.
For example, this may be a new feature you want to add to Garnet2.0.

  • Step 1: Copy the patch foo into the .hg/patches folder.
  • Step 2: Add the name of the patch (foo) manually into the series file: $echo foo >> .hg/patches/series.txt
  • Step 3: Apply the patch to your code by typing hg qpush
  • Step 4: Create a new patch (see Creating and Updating a Patch below) so that any new changes you make in the new patch, and not the imported one. Example:$hg qnew -f my_patch

Creating and updating a patch

Creating a new empty patch. You can give it any name. This name appears in the series file.
$hg qnew patch_name

This command only allowed if you do not have any pending changes.
Now start making changes to your code.

To commit your changes to this patch:
$hg qrefresh

If you want to commit your pending changes to a new patch.
$hg qnew -f new_patch_name

Your series file will contain the following patches:
$cat .hg/patches series
patch_name
new_patch_name


Managing Patches

To see all patches currently applied:
$hg qapp

To see the current patch which is at the head of the queue:
$hg qtop

This is the patch into which your changes will be committed if you do type hg qrefresh

To pop the top patch:
$hg qpop

To push the next patch
$hg qpush

Note: hg qpush and hg qpop are only allowed if there are no pending changes. So you need to do a hg qrefresh before proceeding to adding, popping or pushing a patch


Example and Best Practices

A recommended scenario for using different patches will be as follows:

  • Create a new patch:
    $hg qnew feature1
  • Starting coding feature1
  • Commit this code into the patch:
    $hg qrefresh
  • Keep making changes and committing
    $hg qrefresh
  • Start a new patch for the next feature:
    $hg qnew feature2
  • Start coding feature2
  • Commit this code into the patch:
    $hg qrefresh

Why having different patches for different features is useful:

Suppose you realize that feature2’s implementation is incorrect, and you want to rewrite it completely.
You can do the following:

  • Pop out the patch (after committing any pending changes)
    $hg qpop
  • Create a new patch:
    $hg qnew feature2_new
  • Manually delete the line feature2 from the series file. Otherwise typing hg qpush again will try and push the old broken patch in, and give conflicts since feature2_new would have most likely modified the same lines.

Advanced

You can also add guards to different patches, so that only the ones with a certain guard are applied to your codebase. This is useful when you may have multiple disjoint set of patches for different features, and want to apply one or the other. Interested readers can refer to the Mercurial page.

The whole is greater than the sum of its parts