annotate hgext/journal.py @ 29502:8361131b4768

journal: add dirstate tracking Note that now the default action for `hg journal` is to list the working copy history, not all bookmarks. In its place is the `--all` switch which lists all name changes recorded, including the name for which the change was recorded on each line. Locking is switched to using a dedicated lock to avoid issues with the dirstate being written during wlock unlocking (you can't re-lock during that process).
author Martijn Pieters <mjpieters@fb.com>
date Mon, 11 Jul 2016 13:39:24 +0100
parents cf092a3d202a
children 0103b673d6ca
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
1 # journal.py
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
2 #
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
3 # Copyright 2014-2016 Facebook, Inc.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
4 #
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
7 """Track previous positions of bookmarks (EXPERIMENTAL)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
8
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
9 This extension adds a new command: `hg journal`, which shows you where
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
10 bookmarks were previously located.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
11
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
12 """
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
13
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
14 from __future__ import absolute_import
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
15
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
16 import collections
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
17 import os
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
18 import weakref
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
19
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
20 from mercurial.i18n import _
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
21
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
22 from mercurial import (
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
23 bookmarks,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
24 cmdutil,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
25 commands,
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
26 dirstate,
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
27 dispatch,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
28 error,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
29 extensions,
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
30 localrepo,
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
31 lock,
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
32 node,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
33 util,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
34 )
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
35
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
36 cmdtable = {}
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
37 command = cmdutil.command(cmdtable)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
38
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
39 # Note for extension authors: ONLY specify testedwith = 'internal' for
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
40 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
41 # be specifying the version(s) of Mercurial they are tested with, or
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
42 # leave the attribute unspecified.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
43 testedwith = 'internal'
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
44
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
45 # storage format version; increment when the format changes
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
46 storageversion = 0
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
47
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
48 # namespaces
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
49 bookmarktype = 'bookmark'
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
50 wdirparenttype = 'wdirparent'
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
51
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
52 # Journal recording, register hooks and storage object
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
53 def extsetup(ui):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
54 extensions.wrapfunction(dispatch, 'runcommand', runcommand)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
55 extensions.wrapfunction(bookmarks.bmstore, '_write', recordbookmarks)
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
56 extensions.wrapfunction(
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
57 dirstate.dirstate, '_writedirstate', recorddirstateparents)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
58 extensions.wrapfunction(
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
59 localrepo.localrepository.dirstate, 'func', wrapdirstate)
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
60
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
61 def reposetup(ui, repo):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
62 if repo.local():
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
63 repo.journal = journalstorage(repo)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
64
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
65 def runcommand(orig, lui, repo, cmd, fullargs, *args):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
66 """Track the command line options for recording in the journal"""
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
67 journalstorage.recordcommand(*fullargs)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
68 return orig(lui, repo, cmd, fullargs, *args)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
69
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
70 # hooks to record dirstate changes
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
71 def wrapdirstate(orig, repo):
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
72 """Make journal storage available to the dirstate object"""
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
73 dirstate = orig(repo)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
74 if util.safehasattr(repo, 'journal'):
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
75 dirstate.journalstorage = repo.journal
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
76 return dirstate
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
77
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
78 def recorddirstateparents(orig, dirstate, dirstatefp):
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
79 """Records all dirstate parent changes in the journal."""
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
80 if util.safehasattr(dirstate, 'journalstorage'):
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
81 old = [node.nullid, node.nullid]
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
82 nodesize = len(node.nullid)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
83 try:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
84 # The only source for the old state is in the dirstate file still
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
85 # on disk; the in-memory dirstate object only contains the new
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
86 # state. dirstate._opendirstatefile() switches beteen .hg/dirstate
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
87 # and .hg/dirstate.pending depending on the transaction state.
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
88 with dirstate._opendirstatefile() as fp:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
89 state = fp.read(2 * nodesize)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
90 if len(state) == 2 * nodesize:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
91 old = [state[:nodesize], state[nodesize:]]
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
92 except IOError:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
93 pass
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
94
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
95 new = dirstate.parents()
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
96 if old != new:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
97 # only record two hashes if there was a merge
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
98 oldhashes = old[:1] if old[1] == node.nullid else old
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
99 newhashes = new[:1] if new[1] == node.nullid else new
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
100 dirstate.journalstorage.record(
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
101 wdirparenttype, '.', oldhashes, newhashes)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
102
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
103 return orig(dirstate, dirstatefp)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
104
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
105 # hooks to record bookmark changes (both local and remote)
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
106 def recordbookmarks(orig, store, fp):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
107 """Records all bookmark changes in the journal."""
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
108 repo = store._repo
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
109 if util.safehasattr(repo, 'journal'):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
110 oldmarks = bookmarks.bmstore(repo)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
111 for mark, value in store.iteritems():
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
112 oldvalue = oldmarks.get(mark, node.nullid)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
113 if value != oldvalue:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
114 repo.journal.record(bookmarktype, mark, oldvalue, value)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
115 return orig(store, fp)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
116
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
117 class journalentry(collections.namedtuple(
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
118 'journalentry',
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
119 'timestamp user command namespace name oldhashes newhashes')):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
120 """Individual journal entry
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
121
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
122 * timestamp: a mercurial (time, timezone) tuple
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
123 * user: the username that ran the command
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
124 * namespace: the entry namespace, an opaque string
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
125 * name: the name of the changed item, opaque string with meaning in the
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
126 namespace
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
127 * command: the hg command that triggered this record
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
128 * oldhashes: a tuple of one or more binary hashes for the old location
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
129 * newhashes: a tuple of one or more binary hashes for the new location
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
130
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
131 Handles serialisation from and to the storage format. Fields are
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
132 separated by newlines, hashes are written out in hex separated by commas,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
133 timestamp and timezone are separated by a space.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
134
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
135 """
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
136 @classmethod
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
137 def fromstorage(cls, line):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
138 (time, user, command, namespace, name,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
139 oldhashes, newhashes) = line.split('\n')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
140 timestamp, tz = time.split()
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
141 timestamp, tz = float(timestamp), int(tz)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
142 oldhashes = tuple(node.bin(hash) for hash in oldhashes.split(','))
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
143 newhashes = tuple(node.bin(hash) for hash in newhashes.split(','))
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
144 return cls(
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
145 (timestamp, tz), user, command, namespace, name,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
146 oldhashes, newhashes)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
147
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
148 def __str__(self):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
149 """String representation for storage"""
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
150 time = ' '.join(map(str, self.timestamp))
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
151 oldhashes = ','.join([node.hex(hash) for hash in self.oldhashes])
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
152 newhashes = ','.join([node.hex(hash) for hash in self.newhashes])
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
153 return '\n'.join((
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
154 time, self.user, self.command, self.namespace, self.name,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
155 oldhashes, newhashes))
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
156
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
157 class journalstorage(object):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
158 """Storage for journal entries
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
159
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
160 Entries are stored with NUL bytes as separators. See the journalentry
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
161 class for the per-entry structure.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
162
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
163 The file format starts with an integer version, delimited by a NUL.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
164
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
165 This storage uses a dedicated lock; this makes it easier to avoid issues
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
166 with adding entries that added when the regular wlock is unlocked (e.g.
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
167 the dirstate).
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
168
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
169 """
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
170 _currentcommand = ()
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
171 _lockref = None
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
172
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
173 def __init__(self, repo):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
174 self.user = util.getuser()
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
175 self.ui = repo.ui
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
176 self.vfs = repo.vfs
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
177
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
178 # track the current command for recording in journal entries
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
179 @property
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
180 def command(self):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
181 commandstr = ' '.join(
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
182 map(util.shellquote, journalstorage._currentcommand))
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
183 if '\n' in commandstr:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
184 # truncate multi-line commands
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
185 commandstr = commandstr.partition('\n')[0] + ' ...'
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
186 return commandstr
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
187
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
188 @classmethod
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
189 def recordcommand(cls, *fullargs):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
190 """Set the current hg arguments, stored with recorded entries"""
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
191 # Set the current command on the class because we may have started
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
192 # with a non-local repo (cloning for example).
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
193 cls._currentcommand = fullargs
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
194
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
195 def jlock(self):
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
196 """Create a lock for the journal file"""
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
197 if self._lockref and self._lockref():
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
198 raise error.Abort(_('journal lock does not support nesting'))
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
199 desc = _('journal of %s') % self.vfs.base
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
200 try:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
201 l = lock.lock(self.vfs, 'journal.lock', 0, desc=desc)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
202 except error.LockHeld as inst:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
203 self.ui.warn(
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
204 _("waiting for lock on %s held by %r\n") % (desc, inst.locker))
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
205 # default to 600 seconds timeout
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
206 l = lock.lock(
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
207 self.vfs, 'journal.lock',
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
208 int(self.ui.config("ui", "timeout", "600")), desc=desc)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
209 self.ui.warn(_("got lock after %s seconds\n") % l.delay)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
210 self._lockref = weakref.ref(l)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
211 return l
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
212
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
213 def record(self, namespace, name, oldhashes, newhashes):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
214 """Record a new journal entry
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
215
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
216 * namespace: an opaque string; this can be used to filter on the type
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
217 of recorded entries.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
218 * name: the name defining this entry; for bookmarks, this is the
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
219 bookmark name. Can be filtered on when retrieving entries.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
220 * oldhashes and newhashes: each a single binary hash, or a list of
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
221 binary hashes. These represent the old and new position of the named
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
222 item.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
223
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
224 """
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
225 if not isinstance(oldhashes, list):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
226 oldhashes = [oldhashes]
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
227 if not isinstance(newhashes, list):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
228 newhashes = [newhashes]
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
229
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
230 entry = journalentry(
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
231 util.makedate(), self.user, self.command, namespace, name,
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
232 oldhashes, newhashes)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
233
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
234 with self.jlock():
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
235 version = None
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
236 # open file in amend mode to ensure it is created if missing
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
237 with self.vfs('journal', mode='a+b', atomictemp=True) as f:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
238 f.seek(0, os.SEEK_SET)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
239 # Read just enough bytes to get a version number (up to 2
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
240 # digits plus separator)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
241 version = f.read(3).partition('\0')[0]
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
242 if version and version != str(storageversion):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
243 # different version of the storage. Exit early (and not
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
244 # write anything) if this is not a version we can handle or
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
245 # the file is corrupt. In future, perhaps rotate the file
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
246 # instead?
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
247 self.ui.warn(
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
248 _("unsupported journal file version '%s'\n") % version)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
249 return
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
250 if not version:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
251 # empty file, write version first
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
252 f.write(str(storageversion) + '\0')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
253 f.seek(0, os.SEEK_END)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
254 f.write(str(entry) + '\0')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
255
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
256 def filtered(self, namespace=None, name=None):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
257 """Yield all journal entries with the given namespace or name
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
258
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
259 Both the namespace and the name are optional; if neither is given all
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
260 entries in the journal are produced.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
261
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
262 """
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
263 for entry in self:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
264 if namespace is not None and entry.namespace != namespace:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
265 continue
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
266 if name is not None and entry.name != name:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
267 continue
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
268 yield entry
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
269
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
270 def __iter__(self):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
271 """Iterate over the storage
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
272
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
273 Yields journalentry instances for each contained journal record.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
274
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
275 """
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
276 if not self.vfs.exists('journal'):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
277 return
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
278
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
279 with self.vfs('journal') as f:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
280 raw = f.read()
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
281
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
282 lines = raw.split('\0')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
283 version = lines and lines[0]
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
284 if version != str(storageversion):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
285 version = version or _('not available')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
286 raise error.Abort(_("unknown journal file version '%s'") % version)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
287
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
288 # Skip the first line, it's a version number. Reverse the rest.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
289 lines = reversed(lines[1:])
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
290 for line in lines:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
291 if not line:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
292 continue
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
293 yield journalentry.fromstorage(line)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
294
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
295 # journal reading
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
296 # log options that don't make sense for journal
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
297 _ignoreopts = ('no-merges', 'graph')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
298 @command(
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
299 'journal', [
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
300 ('', 'all', None, 'show history for all names'),
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
301 ('c', 'commits', None, 'show commit metadata'),
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
302 ] + [opt for opt in commands.logopts if opt[1] not in _ignoreopts],
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
303 '[OPTION]... [BOOKMARKNAME]')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
304 def journal(ui, repo, *args, **opts):
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
305 """show the previous position of bookmarks and the working copy
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
306
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
307 The journal is used to see the previous commits that bookmarks and the
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
308 working copy pointed to. By default the previous locations for the working
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
309 copy. Passing a bookmark name will show all the previous positions of
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
310 that bookmark. Use the --all switch to show previous locations for all
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
311 bookmarks and the working copy; each line will then include the bookmark
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
312 name, or '.' for the working copy, as well.
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
313
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
314 By default hg journal only shows the commit hash and the command that was
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
315 running at that time. -v/--verbose will show the prior hash, the user, and
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
316 the time at which it happened.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
317
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
318 Use -c/--commits to output log information on each commit hash; at this
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
319 point you can use the usual `--patch`, `--git`, `--stat` and `--template`
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
320 switches to alter the log output for these.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
321
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
322 `hg journal -T json` can be used to produce machine readable output.
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
323
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
324 """
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
325 name = '.'
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
326 if opts.get('all'):
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
327 if args:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
328 raise error.Abort(
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
329 _("You can't combine --all and filtering on a name"))
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
330 name = None
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
331 if args:
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
332 name = args[0]
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
333
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
334 fm = ui.formatter('journal', opts)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
335
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
336 if opts.get("template") != "json":
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
337 if name is None:
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
338 displayname = _('the working copy and bookmarks')
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
339 else:
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
340 displayname = "'%s'" % name
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
341 ui.status(_("previous locations of %s:\n") % displayname)
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
342
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
343 limit = cmdutil.loglimit(opts)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
344 entry = None
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
345 for count, entry in enumerate(repo.journal.filtered(name=name)):
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
346 if count == limit:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
347 break
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
348 newhashesstr = ','.join([node.short(hash) for hash in entry.newhashes])
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
349 oldhashesstr = ','.join([node.short(hash) for hash in entry.oldhashes])
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
350
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
351 fm.startitem()
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
352 fm.condwrite(ui.verbose, 'oldhashes', '%s -> ', oldhashesstr)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
353 fm.write('newhashes', '%s', newhashesstr)
29502
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
354 fm.condwrite(ui.verbose, 'user', ' %-8s', entry.user)
8361131b4768 journal: add dirstate tracking
Martijn Pieters <mjpieters@fb.com>
parents: 29443
diff changeset
355 fm.condwrite(opts.get('all'), 'name', ' %-8s', entry.name)
29443
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
356
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
357 timestring = util.datestr(entry.timestamp, '%Y-%m-%d %H:%M %1%2')
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
358 fm.condwrite(ui.verbose, 'date', ' %s', timestring)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
359 fm.write('command', ' %s\n', entry.command)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
360
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
361 if opts.get("commits"):
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
362 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=False)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
363 for hash in entry.newhashes:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
364 try:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
365 ctx = repo[hash]
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
366 displayer.show(ctx)
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
367 except error.RepoLookupError as e:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
368 fm.write('repolookuperror', "%s\n\n", str(e))
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
369 displayer.close()
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
370
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
371 fm.end()
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
372
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
373 if entry is None:
cf092a3d202a journal: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
374 ui.status(_("no recorded locations\n"))