mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
infinitepush: add summary of not-backed-up files to smartlog
Summary: Allow summarisation of commits that have not been backed up by infinitepush. 1. Add a template keyword (backupstatus) which evaluates to one of "Public", "Backed up", "Backup pending", or "Not backed up" depending on the backup state of the commit. Commits are pending for 10 minutes, after which they are declared not backed up. 2. Add a summary to the end of smartlog that shows the number of commits that are not backed up. Configuration options allow the addition of an education message to inform users what to do about their failing backups, and the message can also be suppressed. Test Plan: New unit test for both the keyword and the summary. Reviewers: #fbhgext, stash Subscribers: mitrandir, quark, akushner Differential Revision: https://phab.mercurial-scm.org/D184
This commit is contained in:
parent
72f38ebdf0
commit
c8581c4465
@ -139,6 +139,7 @@ configscratchpush = 'infinitepush-scratchpush'
|
||||
confignonforwardmove = 'non-forward-move'
|
||||
|
||||
cmdtable = infinitepushcommands.cmdtable
|
||||
revsetpredicate = backupcommands.revsetpredicate
|
||||
_scratchbranchmatcher = lambda x: False
|
||||
_maybehash = re.compile(r'^[a-f0-9]+$').search
|
||||
|
||||
@ -316,6 +317,18 @@ def clientextsetup(ui):
|
||||
partorder.insert(
|
||||
index, partorder.pop(partorder.index(scratchbranchparttype)))
|
||||
|
||||
def wrapsmartlog(loaded):
|
||||
if not loaded:
|
||||
return
|
||||
smartlogmod = extensions.find('smartlog')
|
||||
wrapcommand(smartlogmod.cmdtable, 'smartlog', _smartlog)
|
||||
extensions.afterloaded('smartlog', wrapsmartlog)
|
||||
|
||||
def _smartlog(orig, ui, repo, **opts):
|
||||
res = orig(ui, repo, **opts)
|
||||
backupcommands.smartlogsummary(ui, repo)
|
||||
return res
|
||||
|
||||
def _showbookmarks(ui, bookmarks, **opts):
|
||||
# Copy-paste from commands.py
|
||||
fm = ui.formatter('bookmarks', opts)
|
||||
|
@ -23,6 +23,10 @@
|
||||
# Hostname value to use. If not specified then socket.gethostname() will
|
||||
# be used
|
||||
hostname = ''
|
||||
|
||||
# Enable reporting of infinitepush backup status as a summary at the end
|
||||
# of smartlog.
|
||||
enablestatus = False
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
@ -57,13 +61,14 @@ from mercurial import (
|
||||
from collections import defaultdict, namedtuple
|
||||
from mercurial import policy
|
||||
from mercurial.extensions import wrapfunction, unwrapfunction
|
||||
from mercurial.node import bin, hex, nullrev
|
||||
from mercurial.node import bin, hex, nullrev, short
|
||||
from mercurial.i18n import _
|
||||
|
||||
osutil = policy.importmod(r'osutil')
|
||||
|
||||
cmdtable = {}
|
||||
command = registrar.command(cmdtable)
|
||||
revsetpredicate = registrar.revsetpredicate()
|
||||
|
||||
backupbookmarktuple = namedtuple('backupbookmarktuple',
|
||||
['hostname', 'reporoot', 'localbookmark'])
|
||||
@ -301,6 +306,39 @@ def isbackedup(ui, repo, **opts):
|
||||
ui.write(_('backed up' if r in backeduprevs else 'not backed up'))
|
||||
ui.write(_('\n'))
|
||||
|
||||
@revsetpredicate('backedup')
|
||||
def backedup(repo, subset, x):
|
||||
"""Draft changesets that have been backed up by infinitepush"""
|
||||
bkpstate = _readlocalbackupstate(repo.ui, repo)
|
||||
visiblebkpheads = [head for head in bkpstate.heads if head in repo]
|
||||
return subset & repo.revs('draft() and ::%ls', visiblebkpheads)
|
||||
|
||||
def smartlogsummary(ui, repo):
|
||||
if not ui.configbool('infinitepushbackup', 'enablestatus'):
|
||||
return
|
||||
|
||||
bkpstate = _readlocalbackupstate(ui, repo)
|
||||
visiblebkpheads = [head for head in bkpstate.heads if head in repo]
|
||||
unbackeduprevs = repo.revs('draft() and not ::%ls', visiblebkpheads)
|
||||
|
||||
# Count the number of changesets that haven't been backed up for 10 minutes.
|
||||
# If there is only one, also print out its hash.
|
||||
backuptime = time.time() - 10 * 60 # 10 minutes ago
|
||||
count = 0
|
||||
singleunbackeduprev = None
|
||||
for rev in unbackeduprevs:
|
||||
if repo[rev].date()[0] <= backuptime:
|
||||
singleunbackeduprev = rev
|
||||
count += 1
|
||||
if count > 0:
|
||||
if count > 1:
|
||||
ui.warn(_('note: %d changesets are not backed up.\n') % count)
|
||||
else:
|
||||
ui.warn(_('note: changeset %s is not backed up.\n') %
|
||||
short(repo[singleunbackeduprev].node()))
|
||||
ui.warn(_('Run `hg pushbackup` to perform a backup. If this fails,\n'
|
||||
'please report to the Source Control @ FB group.\n'))
|
||||
|
||||
def _dobackup(ui, repo, dest, **opts):
|
||||
ui.status(_('starting backup %s\n') % time.strftime('%H:%M:%S %d %b %Y %Z'))
|
||||
start = time.time()
|
||||
@ -657,7 +695,7 @@ def _readlocalbackupstate(ui, repo):
|
||||
raise ValueError('bad types of bookmarks or heads')
|
||||
|
||||
result = backupstate()
|
||||
result.heads = set(state['heads'])
|
||||
result.heads = set(map(str, state['heads']))
|
||||
result.localbookmarks = state['bookmarks']
|
||||
return result
|
||||
except (ValueError, KeyError, TypeError) as e:
|
||||
|
119
tests/test-infinitepush-backup-status.t
Normal file
119
tests/test-infinitepush-backup-status.t
Normal file
@ -0,0 +1,119 @@
|
||||
|
||||
$ setup() {
|
||||
> cat << EOF >> .hg/hgrc
|
||||
> [extensions]
|
||||
> fbamend=$TESTDIR/../hgext3rd/fbamend
|
||||
> smartlog=$TESTDIR/../hgext3rd/smartlog.py
|
||||
> [infinitepushbackup]
|
||||
> enablestatus = True
|
||||
> [experimental]
|
||||
> evolution=createmarkers
|
||||
> EOF
|
||||
> }
|
||||
$ . "$TESTDIR/library.sh"
|
||||
$ . "$TESTDIR/library-infinitepush.sh"
|
||||
$ setupcommon
|
||||
|
||||
Setup server
|
||||
$ hg init repo
|
||||
$ cd repo
|
||||
$ setupserver
|
||||
$ cd ..
|
||||
|
||||
Setup client
|
||||
$ hg clone ssh://user@dummy/repo client -q
|
||||
$ cd client
|
||||
$ setup
|
||||
$ now=`date +%s`
|
||||
$ touch file1
|
||||
$ hg add file1
|
||||
$ commit_time=`expr $now - 15 \* 60`
|
||||
$ hg commit -d "$commit_time 0" -m "Public changeset"
|
||||
$ hg push
|
||||
pushing to ssh://user@dummy/repo
|
||||
searching for changes
|
||||
remote: adding changesets
|
||||
remote: adding manifests
|
||||
remote: adding file changes
|
||||
remote: added 1 changesets with 1 changes to 1 files
|
||||
$ echo a > file1
|
||||
$ changeset_time=`expr $now - 13 \* 60`
|
||||
$ hg commit -d "$commit_time 0" -m "Backed up changeset"
|
||||
$ hg pushbackup
|
||||
starting backup .* (re)
|
||||
searching for changes
|
||||
remote: pushing 1 commit:
|
||||
remote: * Backed up changeset (glob)
|
||||
finished in \d+\.(\d+)? seconds (re)
|
||||
$ echo b > file1
|
||||
$ commit_time=`expr $now - 11 \* 60`
|
||||
$ hg commit -d "$commit_time 0" -m "Not backed up changeset"
|
||||
$ echo c > file1
|
||||
$ commit_time=`expr $now - 9 \* 60`
|
||||
$ hg commit -d "$commit_time 0" -m "Backup pending changeset"
|
||||
|
||||
Check backup status of commits
|
||||
$ hg log -T '{rev} {desc}\n' -r 'backedup()'
|
||||
1 Backed up changeset
|
||||
$ hg log -T '{rev} {desc}\n' -r 'draft() - backedup()'
|
||||
2 Not backed up changeset
|
||||
3 Backup pending changeset
|
||||
|
||||
Check smartlog output
|
||||
$ hg smartlog
|
||||
@ changeset: 3:* (glob)
|
||||
| tag: tip
|
||||
| user: test
|
||||
| date: * (glob)
|
||||
| summary: Backup pending changeset
|
||||
|
|
||||
o changeset: 2:* (glob)
|
||||
| user: test
|
||||
| date: * (glob)
|
||||
| summary: Not backed up changeset
|
||||
|
|
||||
o changeset: 1:* (glob)
|
||||
| user: test
|
||||
| date: * (glob)
|
||||
| summary: Backed up changeset
|
||||
|
|
||||
o changeset: 0:* (glob)
|
||||
user: test
|
||||
date: * (glob)
|
||||
summary: Public changeset
|
||||
|
||||
note: changeset * is not backed up. (glob)
|
||||
Run `hg pushbackup` to perform a backup. If this fails,
|
||||
please report to the Source Control @ FB group.
|
||||
|
||||
Check smartlog summary can be suppressed
|
||||
$ hg smartlog -T '{rev}: {desc}\n' --config infinitepushbackup.enablestatus=no
|
||||
@ 3: Backup pending changeset
|
||||
|
|
||||
o 2: Not backed up changeset
|
||||
|
|
||||
o 1: Backed up changeset
|
||||
|
|
||||
o 0: Public changeset
|
||||
|
||||
Check smartlog summary with multiple unbacked up changesets
|
||||
$ hg up 2
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
$ echo b2 > file1
|
||||
$ commit_time=`expr $now - 11 \* 60`
|
||||
$ hg commit -d "$commit_time 0" -m "Not backed up changeset 2"
|
||||
created new head
|
||||
$ hg smartlog -T '{rev}: {desc}\n'
|
||||
@ 4: Not backed up changeset 2
|
||||
|
|
||||
| o 3: Backup pending changeset
|
||||
|/
|
||||
o 2: Not backed up changeset
|
||||
|
|
||||
o 1: Backed up changeset
|
||||
|
|
||||
o 0: Public changeset
|
||||
|
||||
note: 2 changesets are not backed up.
|
||||
Run `hg pushbackup` to perform a backup. If this fails,
|
||||
please report to the Source Control @ FB group.
|
Loading…
Reference in New Issue
Block a user