shelve: only keep the latest N shelve backups
This will keep the backup directory from growing indefinitely. The number of
backups to keep can be set using the shelve.maxbackups config option (defaults
to 10 backups).
--- a/hgext/shelve.py Wed Jul 01 13:13:02 2015 -0700
+++ b/hgext/shelve.py Wed Jul 01 13:14:03 2015 -0700
@@ -40,6 +40,8 @@
# leave the attribute unspecified.
testedwith = 'internal'
+backupdir = 'shelve-backup'
+
class shelvedfile(object):
"""Helper for the file storing a single shelve
@@ -49,7 +51,7 @@
self.repo = repo
self.name = name
self.vfs = scmutil.vfs(repo.join('shelved'))
- self.backupvfs = scmutil.vfs(repo.join('shelve-backup'))
+ self.backupvfs = scmutil.vfs(repo.join(backupdir))
self.ui = self.repo.ui
if filetype:
self.fname = name + '.' + filetype
@@ -156,6 +158,20 @@
def clear(cls, repo):
util.unlinkpath(repo.join(cls._filename), ignoremissing=True)
+def cleanupoldbackups(repo):
+ vfs = scmutil.vfs(repo.join(backupdir))
+ maxbackups = repo.ui.configint('shelve', 'maxbackups', 10)
+ hgfiles = [f for f in vfs.listdir() if f.endswith('.hg')]
+ hgfiles = sorted([(vfs.stat(f).st_mtime, f) for f in hgfiles])
+ for mtime, f in hgfiles[:len(hgfiles) - maxbackups]:
+ base = f[:-3]
+ for ext in 'hg patch'.split():
+ try:
+ vfs.unlink(base + '.' + ext)
+ except OSError as err:
+ if err.errno != errno.ENOENT:
+ raise
+
def createcmd(ui, repo, pats, opts):
"""subcommand that creates a new shelve"""
@@ -298,6 +314,7 @@
suffix = name.rsplit('.', 1)[-1]
if suffix in ('hg', 'patch'):
shelvedfile(repo, name).movetobackup()
+ cleanupoldbackups(repo)
finally:
lockmod.release(wlock)
@@ -310,6 +327,7 @@
for name in pats:
for suffix in 'hg patch'.split():
shelvedfile(repo, name, suffix).movetobackup()
+ cleanupoldbackups(repo)
except OSError as err:
if err.errno != errno.ENOENT:
raise
@@ -459,6 +477,7 @@
if not opts['keep']:
for filetype in 'hg patch'.split():
shelvedfile(repo, name, filetype).movetobackup()
+ cleanupoldbackups(repo)
def unshelvecontinue(ui, repo, state, opts):
"""subcommand to continue an in-progress unshelve"""
@@ -534,6 +553,11 @@
(Alternatively, you can use ``--abort`` to abandon an unshelve
that causes a conflict. This reverts the unshelved changes, and
leaves the bundle in place.)
+
+ After a successful unshelve, the shelved changes are stored in a
+ backup directory. Only the N most recent backups are kept. N
+ defaults to 10 but can be overridden using the shelve.maxbackups
+ configuration option.
"""
abortf = opts['abort']
continuef = opts['continue']
--- a/tests/test-shelve.t Wed Jul 01 13:13:02 2015 -0700
+++ b/tests/test-shelve.t Wed Jul 01 13:14:03 2015 -0700
@@ -5,6 +5,8 @@
> [defaults]
> diff = --nodates --git
> qnew = --date '0 0'
+ > [shelve]
+ > maxbackups = 2
> EOF
$ hg init repo
@@ -248,6 +250,14 @@
c
R b/b
+ensure old shelve backups are being deleted automatically
+
+ $ ls .hg/shelve-backup/
+ default-01.hg
+ default-01.patch
+ wibble.hg
+ wibble.patch
+
cause unshelving to result in a merge with 'a' conflicting
$ hg shelve -q