Attic Extension

This extension is not distributed with Mercurial.

Author: Bill Barry (BillBarry)

Repository: https://bitbucket.org/Bill_Barry/hgattic

Mailing list: http://groups.google.com/group/hgattic

Overview

This module deals with a set of patches in the folder .hg/attic. At any time you can shelve your current working copy changes there or unshelve a patch from the folder.

Configuration

Enable the extension by adding following lines to your configuration file (hgrc):

[extensions]
hgattic=/path/to/attic.py

Usage

The extension adds a couple of commands, all starting with attic- so that they are grouped together in hg help, but all have shorter aliases:

hg attic-shelve

Shelve will take the current changes to the working copy and create a patch in the attic:

hg shelve [name]

You need to supply a name for the patch when you first shelve it, but you can forget it if you are already working on a patch as, in that case, changes are added to the current patch.

This command comes with a lot of options, some are:

-m or --message

Use <text> as the commit message

-e or --edit

Bring up an editor to supply the commit message

-r or --refresh

Refresh the current patch without stowing it away

-i or --interactive

Use the 'record' extension to interactively select hunks for a shelf

as well as some for setting the user and the date. See the command help for more details.

hg attic-unshelve

Unshelve is the mirrored partner to shelve

hg unshelve [name]

(if any HUNK gets rejected because, for example, somebody else made changes to your files, you can consider using mpatch http://oss.oracle.com/~mason/mpatch/ to handle rejected files)

You need to supply a name if it isn't the same as the last patch you were working on. Ex:

... do some work
hg shelve patch1
... fix a bug
hg ci -m "fixed bug"
hg unshelve
... name is not needed here because it is assumed to be patch1

vs.

... do some work
hg shelve patch1
... work on something else
hg shelve patch2
... switch back to patch1
hg unshelve patch1
... name is needed here because it is assumed to be patch2

hg attic-display

The attic command displays the list of patches in the attic:

hg attic

There are some options to change what it displays:

-c or --current

Show information about the current shelf being worked on

-d or --header

Show information about a given patch by name

Comparison with similar functionality

Attic is much like several other extensions, but still is different enough that you have a reason to choose one above the other.

Mq

Attic and mq are alike in that: 1. They both deal with patches and you can use patches from one wherever you can use patches from the other. 2. Both are designed to enable sharing patches.

Yet, these two extensions are very different. Mq is designed to work with a series of patches and attic is designed to work with a set of patches. If for example you have 3 patches that have nothing to do with each other in your series file in mq:

feature1
feature2
feature3

and you find that you are working on feature1 and suddenly realize there is a bug in feature2, you would:

hg qpush
... working on feature1 and realize bug
hg qrefresh
hg qpop
... reorder feature2 and feature1 (put feature2 first)
hg qpush
... fix feature2
hg qrefresh
hg qpop
... reorder feature2 and feature1 (put feature1 first)
hg qpush
... continue working on feature1

whereas with attic:

hg unshelve feature1
... working on feature1 and realize bug
hg shelve
hg unshelve feature2
... fix feature2
hg shelve
hg unshelve feature1
... go back to feature1

While this process is workable in mq with only 3 patches, it grows unwieldly as your patch count increases.

In addition to providing different usecases to mq, attic works well alongside mq, for example: splitting a patch in mq (one way of many):

hg qgoto patchtosplit
hg qpop
... move patchtosplit from .hg\patches to .hg\attic and remove it from series
hg unshelve patchtosplit
hg shelve -f --interactive patch1
hg shelve --interactive patch2
hg shelve therest
hg unshelve --delete patchtosplit
hg up -C qtip
hg qimport .hg\attic\patch1
hg qimport .hg\attic\patch2
hg qimport .hg\attic\therest

working on feature1 and realize a fix for feature3, but you aren't ready to switch to it yet:

hg qpush
... work on feature1, realize fix for feature3
hg qrefresh
... make fix for feature3
hg shelve feature3-fix
... continue on feature1, eventually doing
hg qrefresh
hg qgoto feature3
hg unshelve --delete feature3-fix
... now test the changes and qrefresh

see also MqExtension

Pbranch

Though I (BillBarry) do not know enough about pbranch yet to provide an in depth discussion on it, I do know enough to say that pbranch can do just about everything that attic can do (perhaps interactive shelving is the only thing attic can do that pbranch cannot) and can also be used to provide long term support for patches (attic is designed for mostly quick and dirty stuff). Pbranch is more powerful than attic in multiple ways (one quick example: pbranch can deal with a full patch graph whereas attic only deals with one patch at a time). However, with the power of pbranch comes the complexity of pbranch.

see also PatchBranchExtension

Shelve

Shelve (the interactive shelving extension) is almost entirely a subset of attic. In fact attic's hg shelve --interactive is calling 3 methods directly pulled from the hgshelve extension source code.

see also ShelveExtension

Potential usecases

temporarily shelving something away to fix something else:

... working on something, bug comes in
hg shelve mywork
... make fix
hg ci -m "fixed bug"
hg unshelve
... continue

splitting patches:

... put bigpatch into .hg/attic
hg unshelve bigpatch
hg shelve -f --interactive patch1
hg shelve --interactive patch2
hg shelve finalpatch

cherry picking:

all devs have attic under version control and 1 dev can pull from them:
dev1 finishes feature:
hg shelve -m "the message I want for the commit" -u featurea
cd .hg/attic
hg addrem
hg ci -m "featurea ready"
hg push   (or whatever to make the patch public, example with shared repo assumed)

dev2 finishes feature:
hg shelve -m "the message I want for the commit" -u featureb
cd .hg/attic
hg addrem
hg ci -m "featureb ready"
hg push

picker:
cd .hg/attic
hg pull
cd ../..
hg unshelve featurea
... checks, it is ok
hg ci                (or move to mq, etc)
hg unshelve featureb
... not ok
hg shelve
cd .hg/attic
hg rm featurea
hg ci -m "brought featurea into mainline"
hg push

folding patches:

... patch1, patch2 and patch3 in attic
hg unshelve --delete patch1
hg unshelve --delete -f patch2
hg unshelve --delete -f patch3
hg shelve foldedpatch

considering multiple implementations:

... do implementation 1
hg shelve impl1
... do implementation 2
hg shelve impl2
... do implementation 3
hg shelve impl3
... converse with people about which patch is best
hg unshelve impl2
hg ci -m "impl2 was best"
cd .hg/attic
rm impl1
rm impl3

Technical details

Restrictions on patches

Don't create a patch with a name that starts with a period. It will not be shown with the attic-display command (and it could conflict with special files in the attic). Any special file in the attic is expected to start with a period (this is reserved for future usage as well).

Versioning the attic directory

You can put the attic under revision control, just ignore files that start with a period. This is particularly useful for sharing patches with a group of people.

Special files

Currently there are two special files:

.applied

contains the name of the current applied patch

.current

contains the name of the assumed default patch

See also

ShelveExtension, PatchBranchExtension, MqExtension


CategoryExtensionsByOthers

AtticExtension (last edited 2010-02-05 10:49:51 by Pierre-YvesDavid)