##// END OF EJS Templates
bookmarks: keep bookmarks in .hg/store if new config set...
Martin von Zweigbergk -
r42897:526750cd default
parent child Browse files
Show More
@@ -1,181 +1,185 b''
1 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
1 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
2 #
2 #
3 # This software may be used and distributed according to the terms of the
3 # This software may be used and distributed according to the terms of the
4 # GNU General Public License version 2 or any later version.
4 # GNU General Public License version 2 or any later version.
5
5
6 '''share a common history between several working directories
6 '''share a common history between several working directories
7
7
8 Automatic Pooled Storage for Clones
8 Automatic Pooled Storage for Clones
9 -----------------------------------
9 -----------------------------------
10
10
11 When this extension is active, :hg:`clone` can be configured to
11 When this extension is active, :hg:`clone` can be configured to
12 automatically share/pool storage across multiple clones. This
12 automatically share/pool storage across multiple clones. This
13 mode effectively converts :hg:`clone` to :hg:`clone` + :hg:`share`.
13 mode effectively converts :hg:`clone` to :hg:`clone` + :hg:`share`.
14 The benefit of using this mode is the automatic management of
14 The benefit of using this mode is the automatic management of
15 store paths and intelligent pooling of related repositories.
15 store paths and intelligent pooling of related repositories.
16
16
17 The following ``share.`` config options influence this feature:
17 The following ``share.`` config options influence this feature:
18
18
19 ``share.pool``
19 ``share.pool``
20 Filesystem path where shared repository data will be stored. When
20 Filesystem path where shared repository data will be stored. When
21 defined, :hg:`clone` will automatically use shared repository
21 defined, :hg:`clone` will automatically use shared repository
22 storage instead of creating a store inside each clone.
22 storage instead of creating a store inside each clone.
23
23
24 ``share.poolnaming``
24 ``share.poolnaming``
25 How directory names in ``share.pool`` are constructed.
25 How directory names in ``share.pool`` are constructed.
26
26
27 "identity" means the name is derived from the first changeset in the
27 "identity" means the name is derived from the first changeset in the
28 repository. In this mode, different remotes share storage if their
28 repository. In this mode, different remotes share storage if their
29 root/initial changeset is identical. In this mode, the local shared
29 root/initial changeset is identical. In this mode, the local shared
30 repository is an aggregate of all encountered remote repositories.
30 repository is an aggregate of all encountered remote repositories.
31
31
32 "remote" means the name is derived from the source repository's
32 "remote" means the name is derived from the source repository's
33 path or URL. In this mode, storage is only shared if the path or URL
33 path or URL. In this mode, storage is only shared if the path or URL
34 requested in the :hg:`clone` command matches exactly to a repository
34 requested in the :hg:`clone` command matches exactly to a repository
35 that was cloned before.
35 that was cloned before.
36
36
37 The default naming mode is "identity".
37 The default naming mode is "identity".
38 '''
38 '''
39
39
40 from __future__ import absolute_import
40 from __future__ import absolute_import
41
41
42 import errno
42 import errno
43 from mercurial.i18n import _
43 from mercurial.i18n import _
44 from mercurial import (
44 from mercurial import (
45 bookmarks,
45 bookmarks,
46 commands,
46 commands,
47 error,
47 error,
48 extensions,
48 extensions,
49 hg,
49 hg,
50 registrar,
50 registrar,
51 txnutil,
51 txnutil,
52 util,
52 util,
53 )
53 )
54
54
55 cmdtable = {}
55 cmdtable = {}
56 command = registrar.command(cmdtable)
56 command = registrar.command(cmdtable)
57 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
57 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
58 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
58 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
59 # be specifying the version(s) of Mercurial they are tested with, or
59 # be specifying the version(s) of Mercurial they are tested with, or
60 # leave the attribute unspecified.
60 # leave the attribute unspecified.
61 testedwith = 'ships-with-hg-core'
61 testedwith = 'ships-with-hg-core'
62
62
63 @command('share',
63 @command('share',
64 [('U', 'noupdate', None, _('do not create a working directory')),
64 [('U', 'noupdate', None, _('do not create a working directory')),
65 ('B', 'bookmarks', None, _('also share bookmarks')),
65 ('B', 'bookmarks', None, _('also share bookmarks')),
66 ('', 'relative', None, _('point to source using a relative path '
66 ('', 'relative', None, _('point to source using a relative path '
67 '(EXPERIMENTAL)')),
67 '(EXPERIMENTAL)')),
68 ],
68 ],
69 _('[-U] [-B] SOURCE [DEST]'),
69 _('[-U] [-B] SOURCE [DEST]'),
70 helpcategory=command.CATEGORY_REPO_CREATION,
70 helpcategory=command.CATEGORY_REPO_CREATION,
71 norepo=True)
71 norepo=True)
72 def share(ui, source, dest=None, noupdate=False, bookmarks=False,
72 def share(ui, source, dest=None, noupdate=False, bookmarks=False,
73 relative=False):
73 relative=False):
74 """create a new shared repository
74 """create a new shared repository
75
75
76 Initialize a new repository and working directory that shares its
76 Initialize a new repository and working directory that shares its
77 history (and optionally bookmarks) with another repository.
77 history (and optionally bookmarks) with another repository.
78
78
79 .. note::
79 .. note::
80
80
81 using rollback or extensions that destroy/modify history (mq,
81 using rollback or extensions that destroy/modify history (mq,
82 rebase, etc.) can cause considerable confusion with shared
82 rebase, etc.) can cause considerable confusion with shared
83 clones. In particular, if two shared clones are both updated to
83 clones. In particular, if two shared clones are both updated to
84 the same changeset, and one of them destroys that changeset
84 the same changeset, and one of them destroys that changeset
85 with rollback, the other clone will suddenly stop working: all
85 with rollback, the other clone will suddenly stop working: all
86 operations will fail with "abort: working directory has unknown
86 operations will fail with "abort: working directory has unknown
87 parent". The only known workaround is to use debugsetparents on
87 parent". The only known workaround is to use debugsetparents on
88 the broken clone to reset it to a changeset that still exists.
88 the broken clone to reset it to a changeset that still exists.
89 """
89 """
90
90
91 hg.share(ui, source, dest=dest, update=not noupdate,
91 hg.share(ui, source, dest=dest, update=not noupdate,
92 bookmarks=bookmarks, relative=relative)
92 bookmarks=bookmarks, relative=relative)
93 return 0
93 return 0
94
94
95 @command('unshare', [], '', helpcategory=command.CATEGORY_MAINTENANCE)
95 @command('unshare', [], '', helpcategory=command.CATEGORY_MAINTENANCE)
96 def unshare(ui, repo):
96 def unshare(ui, repo):
97 """convert a shared repository to a normal one
97 """convert a shared repository to a normal one
98
98
99 Copy the store data to the repo and remove the sharedpath data.
99 Copy the store data to the repo and remove the sharedpath data.
100 """
100 """
101
101
102 if not repo.shared():
102 if not repo.shared():
103 raise error.Abort(_("this is not a shared repo"))
103 raise error.Abort(_("this is not a shared repo"))
104
104
105 hg.unshare(ui, repo)
105 hg.unshare(ui, repo)
106
106
107 # Wrap clone command to pass auto share options.
107 # Wrap clone command to pass auto share options.
108 def clone(orig, ui, source, *args, **opts):
108 def clone(orig, ui, source, *args, **opts):
109 pool = ui.config('share', 'pool')
109 pool = ui.config('share', 'pool')
110 if pool:
110 if pool:
111 pool = util.expandpath(pool)
111 pool = util.expandpath(pool)
112
112
113 opts[r'shareopts'] = {
113 opts[r'shareopts'] = {
114 'pool': pool,
114 'pool': pool,
115 'mode': ui.config('share', 'poolnaming'),
115 'mode': ui.config('share', 'poolnaming'),
116 }
116 }
117
117
118 return orig(ui, source, *args, **opts)
118 return orig(ui, source, *args, **opts)
119
119
120 def extsetup(ui):
120 def extsetup(ui):
121 extensions.wrapfunction(bookmarks, '_getbkfile', getbkfile)
121 extensions.wrapfunction(bookmarks, '_getbkfile', getbkfile)
122 extensions.wrapfunction(bookmarks.bmstore, '_recordchange', recordchange)
122 extensions.wrapfunction(bookmarks.bmstore, '_recordchange', recordchange)
123 extensions.wrapfunction(bookmarks.bmstore, '_writerepo', writerepo)
123 extensions.wrapfunction(bookmarks.bmstore, '_writerepo', writerepo)
124 extensions.wrapcommand(commands.table, 'clone', clone)
124 extensions.wrapcommand(commands.table, 'clone', clone)
125
125
126 def _hassharedbookmarks(repo):
126 def _hassharedbookmarks(repo):
127 """Returns whether this repo has shared bookmarks"""
127 """Returns whether this repo has shared bookmarks"""
128 if bookmarks.bookmarksinstore(repo):
129 # Kind of a lie, but it means that we skip our custom reads and writes
130 # from/to the source repo.
131 return False
128 try:
132 try:
129 shared = repo.vfs.read('shared').splitlines()
133 shared = repo.vfs.read('shared').splitlines()
130 except IOError as inst:
134 except IOError as inst:
131 if inst.errno != errno.ENOENT:
135 if inst.errno != errno.ENOENT:
132 raise
136 raise
133 return False
137 return False
134 return hg.sharedbookmarks in shared
138 return hg.sharedbookmarks in shared
135
139
136 def getbkfile(orig, repo):
140 def getbkfile(orig, repo):
137 if _hassharedbookmarks(repo):
141 if _hassharedbookmarks(repo):
138 srcrepo = hg.sharedreposource(repo)
142 srcrepo = hg.sharedreposource(repo)
139 if srcrepo is not None:
143 if srcrepo is not None:
140 # just orig(srcrepo) doesn't work as expected, because
144 # just orig(srcrepo) doesn't work as expected, because
141 # HG_PENDING refers repo.root.
145 # HG_PENDING refers repo.root.
142 try:
146 try:
143 fp, pending = txnutil.trypending(repo.root, repo.vfs,
147 fp, pending = txnutil.trypending(repo.root, repo.vfs,
144 'bookmarks')
148 'bookmarks')
145 if pending:
149 if pending:
146 # only in this case, bookmark information in repo
150 # only in this case, bookmark information in repo
147 # is up-to-date.
151 # is up-to-date.
148 return fp
152 return fp
149 fp.close()
153 fp.close()
150 except IOError as inst:
154 except IOError as inst:
151 if inst.errno != errno.ENOENT:
155 if inst.errno != errno.ENOENT:
152 raise
156 raise
153
157
154 # otherwise, we should read bookmarks from srcrepo,
158 # otherwise, we should read bookmarks from srcrepo,
155 # because .hg/bookmarks in srcrepo might be already
159 # because .hg/bookmarks in srcrepo might be already
156 # changed via another sharing repo
160 # changed via another sharing repo
157 repo = srcrepo
161 repo = srcrepo
158
162
159 # TODO: Pending changes in repo are still invisible in
163 # TODO: Pending changes in repo are still invisible in
160 # srcrepo, because bookmarks.pending is written only into repo.
164 # srcrepo, because bookmarks.pending is written only into repo.
161 # See also https://www.mercurial-scm.org/wiki/SharedRepository
165 # See also https://www.mercurial-scm.org/wiki/SharedRepository
162 return orig(repo)
166 return orig(repo)
163
167
164 def recordchange(orig, self, tr):
168 def recordchange(orig, self, tr):
165 # Continue with write to local bookmarks file as usual
169 # Continue with write to local bookmarks file as usual
166 orig(self, tr)
170 orig(self, tr)
167
171
168 if _hassharedbookmarks(self._repo):
172 if _hassharedbookmarks(self._repo):
169 srcrepo = hg.sharedreposource(self._repo)
173 srcrepo = hg.sharedreposource(self._repo)
170 if srcrepo is not None:
174 if srcrepo is not None:
171 category = 'share-bookmarks'
175 category = 'share-bookmarks'
172 tr.addpostclose(category, lambda tr: self._writerepo(srcrepo))
176 tr.addpostclose(category, lambda tr: self._writerepo(srcrepo))
173
177
174 def writerepo(orig, self, repo):
178 def writerepo(orig, self, repo):
175 # First write local bookmarks file in case we ever unshare
179 # First write local bookmarks file in case we ever unshare
176 orig(self, repo)
180 orig(self, repo)
177
181
178 if _hassharedbookmarks(self._repo):
182 if _hassharedbookmarks(self._repo):
179 srcrepo = hg.sharedreposource(self._repo)
183 srcrepo = hg.sharedreposource(self._repo)
180 if srcrepo is not None:
184 if srcrepo is not None:
181 orig(self, srcrepo)
185 orig(self, srcrepo)
@@ -1,939 +1,960 b''
1 # Mercurial bookmark support code
1 # Mercurial bookmark support code
2 #
2 #
3 # Copyright 2008 David Soria Parra <dsp@php.net>
3 # Copyright 2008 David Soria Parra <dsp@php.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import struct
11 import struct
12
12
13 from .i18n import _
13 from .i18n import _
14 from .node import (
14 from .node import (
15 bin,
15 bin,
16 hex,
16 hex,
17 short,
17 short,
18 wdirid,
18 wdirid,
19 )
19 )
20 from . import (
20 from . import (
21 encoding,
21 encoding,
22 error,
22 error,
23 obsutil,
23 obsutil,
24 pycompat,
24 pycompat,
25 scmutil,
25 scmutil,
26 txnutil,
26 txnutil,
27 util,
27 util,
28 )
28 )
29
29
30 # label constants
30 # label constants
31 # until 3.5, bookmarks.current was the advertised name, not
31 # until 3.5, bookmarks.current was the advertised name, not
32 # bookmarks.active, so we must use both to avoid breaking old
32 # bookmarks.active, so we must use both to avoid breaking old
33 # custom styles
33 # custom styles
34 activebookmarklabel = 'bookmarks.active bookmarks.current'
34 activebookmarklabel = 'bookmarks.active bookmarks.current'
35
35
36 BOOKMARKS_IN_STORE_REQUIREMENT = 'bookmarksinstore'
37
38 def bookmarksinstore(repo):
39 return BOOKMARKS_IN_STORE_REQUIREMENT in repo.requirements
40
41 def bookmarksvfs(repo):
42 return repo.svfs if bookmarksinstore(repo) else repo.vfs
43
36 def _getbkfile(repo):
44 def _getbkfile(repo):
37 """Hook so that extensions that mess with the store can hook bm storage.
45 """Hook so that extensions that mess with the store can hook bm storage.
38
46
39 For core, this just handles wether we should see pending
47 For core, this just handles wether we should see pending
40 bookmarks or the committed ones. Other extensions (like share)
48 bookmarks or the committed ones. Other extensions (like share)
41 may need to tweak this behavior further.
49 may need to tweak this behavior further.
42 """
50 """
43 fp, pending = txnutil.trypending(repo.root, repo.vfs, 'bookmarks')
51 fp, pending = txnutil.trypending(repo.root, bookmarksvfs(repo), 'bookmarks')
44 return fp
52 return fp
45
53
46 class bmstore(object):
54 class bmstore(object):
47 r"""Storage for bookmarks.
55 r"""Storage for bookmarks.
48
56
49 This object should do all bookmark-related reads and writes, so
57 This object should do all bookmark-related reads and writes, so
50 that it's fairly simple to replace the storage underlying
58 that it's fairly simple to replace the storage underlying
51 bookmarks without having to clone the logic surrounding
59 bookmarks without having to clone the logic surrounding
52 bookmarks. This type also should manage the active bookmark, if
60 bookmarks. This type also should manage the active bookmark, if
53 any.
61 any.
54
62
55 This particular bmstore implementation stores bookmarks as
63 This particular bmstore implementation stores bookmarks as
56 {hash}\s{name}\n (the same format as localtags) in
64 {hash}\s{name}\n (the same format as localtags) in
57 .hg/bookmarks. The mapping is stored as {name: nodeid}.
65 .hg/bookmarks. The mapping is stored as {name: nodeid}.
58 """
66 """
59
67
60 def __init__(self, repo):
68 def __init__(self, repo):
61 self._repo = repo
69 self._repo = repo
62 self._refmap = refmap = {} # refspec: node
70 self._refmap = refmap = {} # refspec: node
63 self._nodemap = nodemap = {} # node: sorted([refspec, ...])
71 self._nodemap = nodemap = {} # node: sorted([refspec, ...])
64 self._clean = True
72 self._clean = True
65 self._aclean = True
73 self._aclean = True
66 nm = repo.changelog.nodemap
74 nm = repo.changelog.nodemap
67 tonode = bin # force local lookup
75 tonode = bin # force local lookup
68 try:
76 try:
69 with _getbkfile(repo) as bkfile:
77 with _getbkfile(repo) as bkfile:
70 for line in bkfile:
78 for line in bkfile:
71 line = line.strip()
79 line = line.strip()
72 if not line:
80 if not line:
73 continue
81 continue
74 try:
82 try:
75 sha, refspec = line.split(' ', 1)
83 sha, refspec = line.split(' ', 1)
76 node = tonode(sha)
84 node = tonode(sha)
77 if node in nm:
85 if node in nm:
78 refspec = encoding.tolocal(refspec)
86 refspec = encoding.tolocal(refspec)
79 refmap[refspec] = node
87 refmap[refspec] = node
80 nrefs = nodemap.get(node)
88 nrefs = nodemap.get(node)
81 if nrefs is None:
89 if nrefs is None:
82 nodemap[node] = [refspec]
90 nodemap[node] = [refspec]
83 else:
91 else:
84 nrefs.append(refspec)
92 nrefs.append(refspec)
85 if nrefs[-2] > refspec:
93 if nrefs[-2] > refspec:
86 # bookmarks weren't sorted before 4.5
94 # bookmarks weren't sorted before 4.5
87 nrefs.sort()
95 nrefs.sort()
88 except (TypeError, ValueError):
96 except (TypeError, ValueError):
89 # TypeError:
97 # TypeError:
90 # - bin(...)
98 # - bin(...)
91 # ValueError:
99 # ValueError:
92 # - node in nm, for non-20-bytes entry
100 # - node in nm, for non-20-bytes entry
93 # - split(...), for string without ' '
101 # - split(...), for string without ' '
94 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
102 bookmarkspath = '.hg/bookmarks'
95 % pycompat.bytestr(line))
103 if bookmarksinstore(repo):
104 bookmarkspath = '.hg/store/bookmarks'
105 repo.ui.warn(_('malformed line in %s: %r\n')
106 % (bookmarkspath, pycompat.bytestr(line)))
96 except IOError as inst:
107 except IOError as inst:
97 if inst.errno != errno.ENOENT:
108 if inst.errno != errno.ENOENT:
98 raise
109 raise
99 self._active = _readactive(repo, self)
110 self._active = _readactive(repo, self)
100
111
101 @property
112 @property
102 def active(self):
113 def active(self):
103 return self._active
114 return self._active
104
115
105 @active.setter
116 @active.setter
106 def active(self, mark):
117 def active(self, mark):
107 if mark is not None and mark not in self._refmap:
118 if mark is not None and mark not in self._refmap:
108 raise AssertionError('bookmark %s does not exist!' % mark)
119 raise AssertionError('bookmark %s does not exist!' % mark)
109
120
110 self._active = mark
121 self._active = mark
111 self._aclean = False
122 self._aclean = False
112
123
113 def __len__(self):
124 def __len__(self):
114 return len(self._refmap)
125 return len(self._refmap)
115
126
116 def __iter__(self):
127 def __iter__(self):
117 return iter(self._refmap)
128 return iter(self._refmap)
118
129
119 def iteritems(self):
130 def iteritems(self):
120 return self._refmap.iteritems()
131 return self._refmap.iteritems()
121
132
122 def items(self):
133 def items(self):
123 return self._refmap.items()
134 return self._refmap.items()
124
135
125 # TODO: maybe rename to allnames()?
136 # TODO: maybe rename to allnames()?
126 def keys(self):
137 def keys(self):
127 return self._refmap.keys()
138 return self._refmap.keys()
128
139
129 # TODO: maybe rename to allnodes()? but nodes would have to be deduplicated
140 # TODO: maybe rename to allnodes()? but nodes would have to be deduplicated
130 # could be self._nodemap.keys()
141 # could be self._nodemap.keys()
131 def values(self):
142 def values(self):
132 return self._refmap.values()
143 return self._refmap.values()
133
144
134 def __contains__(self, mark):
145 def __contains__(self, mark):
135 return mark in self._refmap
146 return mark in self._refmap
136
147
137 def __getitem__(self, mark):
148 def __getitem__(self, mark):
138 return self._refmap[mark]
149 return self._refmap[mark]
139
150
140 def get(self, mark, default=None):
151 def get(self, mark, default=None):
141 return self._refmap.get(mark, default)
152 return self._refmap.get(mark, default)
142
153
143 def _set(self, mark, node):
154 def _set(self, mark, node):
144 self._clean = False
155 self._clean = False
145 if mark in self._refmap:
156 if mark in self._refmap:
146 self._del(mark)
157 self._del(mark)
147 self._refmap[mark] = node
158 self._refmap[mark] = node
148 nrefs = self._nodemap.get(node)
159 nrefs = self._nodemap.get(node)
149 if nrefs is None:
160 if nrefs is None:
150 self._nodemap[node] = [mark]
161 self._nodemap[node] = [mark]
151 else:
162 else:
152 nrefs.append(mark)
163 nrefs.append(mark)
153 nrefs.sort()
164 nrefs.sort()
154
165
155 def _del(self, mark):
166 def _del(self, mark):
156 self._clean = False
167 self._clean = False
157 node = self._refmap.pop(mark)
168 node = self._refmap.pop(mark)
158 nrefs = self._nodemap[node]
169 nrefs = self._nodemap[node]
159 if len(nrefs) == 1:
170 if len(nrefs) == 1:
160 assert nrefs[0] == mark
171 assert nrefs[0] == mark
161 del self._nodemap[node]
172 del self._nodemap[node]
162 else:
173 else:
163 nrefs.remove(mark)
174 nrefs.remove(mark)
164
175
165 def names(self, node):
176 def names(self, node):
166 """Return a sorted list of bookmarks pointing to the specified node"""
177 """Return a sorted list of bookmarks pointing to the specified node"""
167 return self._nodemap.get(node, [])
178 return self._nodemap.get(node, [])
168
179
169 def changectx(self, mark):
180 def changectx(self, mark):
170 node = self._refmap[mark]
181 node = self._refmap[mark]
171 return self._repo[node]
182 return self._repo[node]
172
183
173 def applychanges(self, repo, tr, changes):
184 def applychanges(self, repo, tr, changes):
174 """Apply a list of changes to bookmarks
185 """Apply a list of changes to bookmarks
175 """
186 """
176 bmchanges = tr.changes.get('bookmarks')
187 bmchanges = tr.changes.get('bookmarks')
177 for name, node in changes:
188 for name, node in changes:
178 old = self._refmap.get(name)
189 old = self._refmap.get(name)
179 if node is None:
190 if node is None:
180 self._del(name)
191 self._del(name)
181 else:
192 else:
182 self._set(name, node)
193 self._set(name, node)
183 if bmchanges is not None:
194 if bmchanges is not None:
184 # if a previous value exist preserve the "initial" value
195 # if a previous value exist preserve the "initial" value
185 previous = bmchanges.get(name)
196 previous = bmchanges.get(name)
186 if previous is not None:
197 if previous is not None:
187 old = previous[0]
198 old = previous[0]
188 bmchanges[name] = (old, node)
199 bmchanges[name] = (old, node)
189 self._recordchange(tr)
200 self._recordchange(tr)
190
201
191 def _recordchange(self, tr):
202 def _recordchange(self, tr):
192 """record that bookmarks have been changed in a transaction
203 """record that bookmarks have been changed in a transaction
193
204
194 The transaction is then responsible for updating the file content."""
205 The transaction is then responsible for updating the file content."""
206 location = '' if bookmarksinstore(self._repo) else 'plain'
195 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
207 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
196 location='plain')
208 location=location)
197 tr.hookargs['bookmark_moved'] = '1'
209 tr.hookargs['bookmark_moved'] = '1'
198
210
199 def _writerepo(self, repo):
211 def _writerepo(self, repo):
200 """Factored out for extensibility"""
212 """Factored out for extensibility"""
201 rbm = repo._bookmarks
213 rbm = repo._bookmarks
202 if rbm.active not in self._refmap:
214 if rbm.active not in self._refmap:
203 rbm.active = None
215 rbm.active = None
204 rbm._writeactive()
216 rbm._writeactive()
205
217
206 with repo.wlock():
218 if bookmarksinstore(repo):
207 with repo.vfs('bookmarks', 'w', atomictemp=True,
219 vfs = repo.svfs
208 checkambig=True) as f:
220 lock = repo.lock()
221 else:
222 vfs = repo.vfs
223 lock = repo.wlock()
224 with lock:
225 with vfs('bookmarks', 'w', atomictemp=True, checkambig=True) as f:
209 self._write(f)
226 self._write(f)
210
227
211 def _writeactive(self):
228 def _writeactive(self):
212 if self._aclean:
229 if self._aclean:
213 return
230 return
214 with self._repo.wlock():
231 with self._repo.wlock():
215 if self._active is not None:
232 if self._active is not None:
216 with self._repo.vfs('bookmarks.current', 'w', atomictemp=True,
233 with self._repo.vfs('bookmarks.current', 'w', atomictemp=True,
217 checkambig=True) as f:
234 checkambig=True) as f:
218 f.write(encoding.fromlocal(self._active))
235 f.write(encoding.fromlocal(self._active))
219 else:
236 else:
220 self._repo.vfs.tryunlink('bookmarks.current')
237 self._repo.vfs.tryunlink('bookmarks.current')
221 self._aclean = True
238 self._aclean = True
222
239
223 def _write(self, fp):
240 def _write(self, fp):
224 for name, node in sorted(self._refmap.iteritems()):
241 for name, node in sorted(self._refmap.iteritems()):
225 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
242 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
226 self._clean = True
243 self._clean = True
227 self._repo.invalidatevolatilesets()
244 self._repo.invalidatevolatilesets()
228
245
229 def expandname(self, bname):
246 def expandname(self, bname):
230 if bname == '.':
247 if bname == '.':
231 if self.active:
248 if self.active:
232 return self.active
249 return self.active
233 else:
250 else:
234 raise error.RepoLookupError(_("no active bookmark"))
251 raise error.RepoLookupError(_("no active bookmark"))
235 return bname
252 return bname
236
253
237 def checkconflict(self, mark, force=False, target=None):
254 def checkconflict(self, mark, force=False, target=None):
238 """check repo for a potential clash of mark with an existing bookmark,
255 """check repo for a potential clash of mark with an existing bookmark,
239 branch, or hash
256 branch, or hash
240
257
241 If target is supplied, then check that we are moving the bookmark
258 If target is supplied, then check that we are moving the bookmark
242 forward.
259 forward.
243
260
244 If force is supplied, then forcibly move the bookmark to a new commit
261 If force is supplied, then forcibly move the bookmark to a new commit
245 regardless if it is a move forward.
262 regardless if it is a move forward.
246
263
247 If divergent bookmark are to be deleted, they will be returned as list.
264 If divergent bookmark are to be deleted, they will be returned as list.
248 """
265 """
249 cur = self._repo['.'].node()
266 cur = self._repo['.'].node()
250 if mark in self._refmap and not force:
267 if mark in self._refmap and not force:
251 if target:
268 if target:
252 if self._refmap[mark] == target and target == cur:
269 if self._refmap[mark] == target and target == cur:
253 # re-activating a bookmark
270 # re-activating a bookmark
254 return []
271 return []
255 rev = self._repo[target].rev()
272 rev = self._repo[target].rev()
256 anc = self._repo.changelog.ancestors([rev])
273 anc = self._repo.changelog.ancestors([rev])
257 bmctx = self.changectx(mark)
274 bmctx = self.changectx(mark)
258 divs = [self._refmap[b] for b in self._refmap
275 divs = [self._refmap[b] for b in self._refmap
259 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
276 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
260
277
261 # allow resolving a single divergent bookmark even if moving
278 # allow resolving a single divergent bookmark even if moving
262 # the bookmark across branches when a revision is specified
279 # the bookmark across branches when a revision is specified
263 # that contains a divergent bookmark
280 # that contains a divergent bookmark
264 if bmctx.rev() not in anc and target in divs:
281 if bmctx.rev() not in anc and target in divs:
265 return divergent2delete(self._repo, [target], mark)
282 return divergent2delete(self._repo, [target], mark)
266
283
267 deletefrom = [b for b in divs
284 deletefrom = [b for b in divs
268 if self._repo[b].rev() in anc or b == target]
285 if self._repo[b].rev() in anc or b == target]
269 delbms = divergent2delete(self._repo, deletefrom, mark)
286 delbms = divergent2delete(self._repo, deletefrom, mark)
270 if validdest(self._repo, bmctx, self._repo[target]):
287 if validdest(self._repo, bmctx, self._repo[target]):
271 self._repo.ui.status(
288 self._repo.ui.status(
272 _("moving bookmark '%s' forward from %s\n") %
289 _("moving bookmark '%s' forward from %s\n") %
273 (mark, short(bmctx.node())))
290 (mark, short(bmctx.node())))
274 return delbms
291 return delbms
275 raise error.Abort(_("bookmark '%s' already exists "
292 raise error.Abort(_("bookmark '%s' already exists "
276 "(use -f to force)") % mark)
293 "(use -f to force)") % mark)
277 if ((mark in self._repo.branchmap() or
294 if ((mark in self._repo.branchmap() or
278 mark == self._repo.dirstate.branch()) and not force):
295 mark == self._repo.dirstate.branch()) and not force):
279 raise error.Abort(
296 raise error.Abort(
280 _("a bookmark cannot have the name of an existing branch"))
297 _("a bookmark cannot have the name of an existing branch"))
281 if len(mark) > 3 and not force:
298 if len(mark) > 3 and not force:
282 try:
299 try:
283 shadowhash = scmutil.isrevsymbol(self._repo, mark)
300 shadowhash = scmutil.isrevsymbol(self._repo, mark)
284 except error.LookupError: # ambiguous identifier
301 except error.LookupError: # ambiguous identifier
285 shadowhash = False
302 shadowhash = False
286 if shadowhash:
303 if shadowhash:
287 self._repo.ui.warn(
304 self._repo.ui.warn(
288 _("bookmark %s matches a changeset hash\n"
305 _("bookmark %s matches a changeset hash\n"
289 "(did you leave a -r out of an 'hg bookmark' "
306 "(did you leave a -r out of an 'hg bookmark' "
290 "command?)\n")
307 "command?)\n")
291 % mark)
308 % mark)
292 return []
309 return []
293
310
294 def _readactive(repo, marks):
311 def _readactive(repo, marks):
295 """
312 """
296 Get the active bookmark. We can have an active bookmark that updates
313 Get the active bookmark. We can have an active bookmark that updates
297 itself as we commit. This function returns the name of that bookmark.
314 itself as we commit. This function returns the name of that bookmark.
298 It is stored in .hg/bookmarks.current
315 It is stored in .hg/bookmarks.current
299 """
316 """
300 # No readline() in osutil.posixfile, reading everything is
317 # No readline() in osutil.posixfile, reading everything is
301 # cheap.
318 # cheap.
302 content = repo.vfs.tryread('bookmarks.current')
319 content = repo.vfs.tryread('bookmarks.current')
303 mark = encoding.tolocal((content.splitlines() or [''])[0])
320 mark = encoding.tolocal((content.splitlines() or [''])[0])
304 if mark == '' or mark not in marks:
321 if mark == '' or mark not in marks:
305 mark = None
322 mark = None
306 return mark
323 return mark
307
324
308 def activate(repo, mark):
325 def activate(repo, mark):
309 """
326 """
310 Set the given bookmark to be 'active', meaning that this bookmark will
327 Set the given bookmark to be 'active', meaning that this bookmark will
311 follow new commits that are made.
328 follow new commits that are made.
312 The name is recorded in .hg/bookmarks.current
329 The name is recorded in .hg/bookmarks.current
313 """
330 """
314 repo._bookmarks.active = mark
331 repo._bookmarks.active = mark
315 repo._bookmarks._writeactive()
332 repo._bookmarks._writeactive()
316
333
317 def deactivate(repo):
334 def deactivate(repo):
318 """
335 """
319 Unset the active bookmark in this repository.
336 Unset the active bookmark in this repository.
320 """
337 """
321 repo._bookmarks.active = None
338 repo._bookmarks.active = None
322 repo._bookmarks._writeactive()
339 repo._bookmarks._writeactive()
323
340
324 def isactivewdirparent(repo):
341 def isactivewdirparent(repo):
325 """
342 """
326 Tell whether the 'active' bookmark (the one that follows new commits)
343 Tell whether the 'active' bookmark (the one that follows new commits)
327 points to one of the parents of the current working directory (wdir).
344 points to one of the parents of the current working directory (wdir).
328
345
329 While this is normally the case, it can on occasion be false; for example,
346 While this is normally the case, it can on occasion be false; for example,
330 immediately after a pull, the active bookmark can be moved to point
347 immediately after a pull, the active bookmark can be moved to point
331 to a place different than the wdir. This is solved by running `hg update`.
348 to a place different than the wdir. This is solved by running `hg update`.
332 """
349 """
333 mark = repo._activebookmark
350 mark = repo._activebookmark
334 marks = repo._bookmarks
351 marks = repo._bookmarks
335 parents = [p.node() for p in repo[None].parents()]
352 parents = [p.node() for p in repo[None].parents()]
336 return (mark in marks and marks[mark] in parents)
353 return (mark in marks and marks[mark] in parents)
337
354
338 def divergent2delete(repo, deletefrom, bm):
355 def divergent2delete(repo, deletefrom, bm):
339 """find divergent versions of bm on nodes in deletefrom.
356 """find divergent versions of bm on nodes in deletefrom.
340
357
341 the list of bookmark to delete."""
358 the list of bookmark to delete."""
342 todelete = []
359 todelete = []
343 marks = repo._bookmarks
360 marks = repo._bookmarks
344 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
361 divergent = [b for b in marks if b.split('@', 1)[0] == bm.split('@', 1)[0]]
345 for mark in divergent:
362 for mark in divergent:
346 if mark == '@' or '@' not in mark:
363 if mark == '@' or '@' not in mark:
347 # can't be divergent by definition
364 # can't be divergent by definition
348 continue
365 continue
349 if mark and marks[mark] in deletefrom:
366 if mark and marks[mark] in deletefrom:
350 if mark != bm:
367 if mark != bm:
351 todelete.append(mark)
368 todelete.append(mark)
352 return todelete
369 return todelete
353
370
354 def headsforactive(repo):
371 def headsforactive(repo):
355 """Given a repo with an active bookmark, return divergent bookmark nodes.
372 """Given a repo with an active bookmark, return divergent bookmark nodes.
356
373
357 Args:
374 Args:
358 repo: A repository with an active bookmark.
375 repo: A repository with an active bookmark.
359
376
360 Returns:
377 Returns:
361 A list of binary node ids that is the full list of other
378 A list of binary node ids that is the full list of other
362 revisions with bookmarks divergent from the active bookmark. If
379 revisions with bookmarks divergent from the active bookmark. If
363 there were no divergent bookmarks, then this list will contain
380 there were no divergent bookmarks, then this list will contain
364 only one entry.
381 only one entry.
365 """
382 """
366 if not repo._activebookmark:
383 if not repo._activebookmark:
367 raise ValueError(
384 raise ValueError(
368 'headsforactive() only makes sense with an active bookmark')
385 'headsforactive() only makes sense with an active bookmark')
369 name = repo._activebookmark.split('@', 1)[0]
386 name = repo._activebookmark.split('@', 1)[0]
370 heads = []
387 heads = []
371 for mark, n in repo._bookmarks.iteritems():
388 for mark, n in repo._bookmarks.iteritems():
372 if mark.split('@', 1)[0] == name:
389 if mark.split('@', 1)[0] == name:
373 heads.append(n)
390 heads.append(n)
374 return heads
391 return heads
375
392
376 def calculateupdate(ui, repo):
393 def calculateupdate(ui, repo):
377 '''Return a tuple (activemark, movemarkfrom) indicating the active bookmark
394 '''Return a tuple (activemark, movemarkfrom) indicating the active bookmark
378 and where to move the active bookmark from, if needed.'''
395 and where to move the active bookmark from, if needed.'''
379 checkout, movemarkfrom = None, None
396 checkout, movemarkfrom = None, None
380 activemark = repo._activebookmark
397 activemark = repo._activebookmark
381 if isactivewdirparent(repo):
398 if isactivewdirparent(repo):
382 movemarkfrom = repo['.'].node()
399 movemarkfrom = repo['.'].node()
383 elif activemark:
400 elif activemark:
384 ui.status(_("updating to active bookmark %s\n") % activemark)
401 ui.status(_("updating to active bookmark %s\n") % activemark)
385 checkout = activemark
402 checkout = activemark
386 return (checkout, movemarkfrom)
403 return (checkout, movemarkfrom)
387
404
388 def update(repo, parents, node):
405 def update(repo, parents, node):
389 deletefrom = parents
406 deletefrom = parents
390 marks = repo._bookmarks
407 marks = repo._bookmarks
391 active = marks.active
408 active = marks.active
392 if not active:
409 if not active:
393 return False
410 return False
394
411
395 bmchanges = []
412 bmchanges = []
396 if marks[active] in parents:
413 if marks[active] in parents:
397 new = repo[node]
414 new = repo[node]
398 divs = [marks.changectx(b) for b in marks
415 divs = [marks.changectx(b) for b in marks
399 if b.split('@', 1)[0] == active.split('@', 1)[0]]
416 if b.split('@', 1)[0] == active.split('@', 1)[0]]
400 anc = repo.changelog.ancestors([new.rev()])
417 anc = repo.changelog.ancestors([new.rev()])
401 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
418 deletefrom = [b.node() for b in divs if b.rev() in anc or b == new]
402 if validdest(repo, marks.changectx(active), new):
419 if validdest(repo, marks.changectx(active), new):
403 bmchanges.append((active, new.node()))
420 bmchanges.append((active, new.node()))
404
421
405 for bm in divergent2delete(repo, deletefrom, active):
422 for bm in divergent2delete(repo, deletefrom, active):
406 bmchanges.append((bm, None))
423 bmchanges.append((bm, None))
407
424
408 if bmchanges:
425 if bmchanges:
409 with repo.lock(), repo.transaction('bookmark') as tr:
426 with repo.lock(), repo.transaction('bookmark') as tr:
410 marks.applychanges(repo, tr, bmchanges)
427 marks.applychanges(repo, tr, bmchanges)
411 return bool(bmchanges)
428 return bool(bmchanges)
412
429
413 def listbinbookmarks(repo):
430 def listbinbookmarks(repo):
414 # We may try to list bookmarks on a repo type that does not
431 # We may try to list bookmarks on a repo type that does not
415 # support it (e.g., statichttprepository).
432 # support it (e.g., statichttprepository).
416 marks = getattr(repo, '_bookmarks', {})
433 marks = getattr(repo, '_bookmarks', {})
417
434
418 hasnode = repo.changelog.hasnode
435 hasnode = repo.changelog.hasnode
419 for k, v in marks.iteritems():
436 for k, v in marks.iteritems():
420 # don't expose local divergent bookmarks
437 # don't expose local divergent bookmarks
421 if hasnode(v) and ('@' not in k or k.endswith('@')):
438 if hasnode(v) and ('@' not in k or k.endswith('@')):
422 yield k, v
439 yield k, v
423
440
424 def listbookmarks(repo):
441 def listbookmarks(repo):
425 d = {}
442 d = {}
426 for book, node in listbinbookmarks(repo):
443 for book, node in listbinbookmarks(repo):
427 d[book] = hex(node)
444 d[book] = hex(node)
428 return d
445 return d
429
446
430 def pushbookmark(repo, key, old, new):
447 def pushbookmark(repo, key, old, new):
431 with repo.wlock(), repo.lock(), repo.transaction('bookmarks') as tr:
448 if bookmarksinstore(repo):
449 wlock = util.nullcontextmanager()
450 else:
451 wlock = repo.wlock()
452 with wlock, repo.lock(), repo.transaction('bookmarks') as tr:
432 marks = repo._bookmarks
453 marks = repo._bookmarks
433 existing = hex(marks.get(key, ''))
454 existing = hex(marks.get(key, ''))
434 if existing != old and existing != new:
455 if existing != old and existing != new:
435 return False
456 return False
436 if new == '':
457 if new == '':
437 changes = [(key, None)]
458 changes = [(key, None)]
438 else:
459 else:
439 if new not in repo:
460 if new not in repo:
440 return False
461 return False
441 changes = [(key, repo[new].node())]
462 changes = [(key, repo[new].node())]
442 marks.applychanges(repo, tr, changes)
463 marks.applychanges(repo, tr, changes)
443 return True
464 return True
444
465
445 def comparebookmarks(repo, srcmarks, dstmarks, targets=None):
466 def comparebookmarks(repo, srcmarks, dstmarks, targets=None):
446 '''Compare bookmarks between srcmarks and dstmarks
467 '''Compare bookmarks between srcmarks and dstmarks
447
468
448 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
469 This returns tuple "(addsrc, adddst, advsrc, advdst, diverge,
449 differ, invalid)", each are list of bookmarks below:
470 differ, invalid)", each are list of bookmarks below:
450
471
451 :addsrc: added on src side (removed on dst side, perhaps)
472 :addsrc: added on src side (removed on dst side, perhaps)
452 :adddst: added on dst side (removed on src side, perhaps)
473 :adddst: added on dst side (removed on src side, perhaps)
453 :advsrc: advanced on src side
474 :advsrc: advanced on src side
454 :advdst: advanced on dst side
475 :advdst: advanced on dst side
455 :diverge: diverge
476 :diverge: diverge
456 :differ: changed, but changeset referred on src is unknown on dst
477 :differ: changed, but changeset referred on src is unknown on dst
457 :invalid: unknown on both side
478 :invalid: unknown on both side
458 :same: same on both side
479 :same: same on both side
459
480
460 Each elements of lists in result tuple is tuple "(bookmark name,
481 Each elements of lists in result tuple is tuple "(bookmark name,
461 changeset ID on source side, changeset ID on destination
482 changeset ID on source side, changeset ID on destination
462 side)". Each changeset IDs are 40 hexadecimal digit string or
483 side)". Each changeset IDs are 40 hexadecimal digit string or
463 None.
484 None.
464
485
465 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
486 Changeset IDs of tuples in "addsrc", "adddst", "differ" or
466 "invalid" list may be unknown for repo.
487 "invalid" list may be unknown for repo.
467
488
468 If "targets" is specified, only bookmarks listed in it are
489 If "targets" is specified, only bookmarks listed in it are
469 examined.
490 examined.
470 '''
491 '''
471
492
472 if targets:
493 if targets:
473 bset = set(targets)
494 bset = set(targets)
474 else:
495 else:
475 srcmarkset = set(srcmarks)
496 srcmarkset = set(srcmarks)
476 dstmarkset = set(dstmarks)
497 dstmarkset = set(dstmarks)
477 bset = srcmarkset | dstmarkset
498 bset = srcmarkset | dstmarkset
478
499
479 results = ([], [], [], [], [], [], [], [])
500 results = ([], [], [], [], [], [], [], [])
480 addsrc = results[0].append
501 addsrc = results[0].append
481 adddst = results[1].append
502 adddst = results[1].append
482 advsrc = results[2].append
503 advsrc = results[2].append
483 advdst = results[3].append
504 advdst = results[3].append
484 diverge = results[4].append
505 diverge = results[4].append
485 differ = results[5].append
506 differ = results[5].append
486 invalid = results[6].append
507 invalid = results[6].append
487 same = results[7].append
508 same = results[7].append
488
509
489 for b in sorted(bset):
510 for b in sorted(bset):
490 if b not in srcmarks:
511 if b not in srcmarks:
491 if b in dstmarks:
512 if b in dstmarks:
492 adddst((b, None, dstmarks[b]))
513 adddst((b, None, dstmarks[b]))
493 else:
514 else:
494 invalid((b, None, None))
515 invalid((b, None, None))
495 elif b not in dstmarks:
516 elif b not in dstmarks:
496 addsrc((b, srcmarks[b], None))
517 addsrc((b, srcmarks[b], None))
497 else:
518 else:
498 scid = srcmarks[b]
519 scid = srcmarks[b]
499 dcid = dstmarks[b]
520 dcid = dstmarks[b]
500 if scid == dcid:
521 if scid == dcid:
501 same((b, scid, dcid))
522 same((b, scid, dcid))
502 elif scid in repo and dcid in repo:
523 elif scid in repo and dcid in repo:
503 sctx = repo[scid]
524 sctx = repo[scid]
504 dctx = repo[dcid]
525 dctx = repo[dcid]
505 if sctx.rev() < dctx.rev():
526 if sctx.rev() < dctx.rev():
506 if validdest(repo, sctx, dctx):
527 if validdest(repo, sctx, dctx):
507 advdst((b, scid, dcid))
528 advdst((b, scid, dcid))
508 else:
529 else:
509 diverge((b, scid, dcid))
530 diverge((b, scid, dcid))
510 else:
531 else:
511 if validdest(repo, dctx, sctx):
532 if validdest(repo, dctx, sctx):
512 advsrc((b, scid, dcid))
533 advsrc((b, scid, dcid))
513 else:
534 else:
514 diverge((b, scid, dcid))
535 diverge((b, scid, dcid))
515 else:
536 else:
516 # it is too expensive to examine in detail, in this case
537 # it is too expensive to examine in detail, in this case
517 differ((b, scid, dcid))
538 differ((b, scid, dcid))
518
539
519 return results
540 return results
520
541
521 def _diverge(ui, b, path, localmarks, remotenode):
542 def _diverge(ui, b, path, localmarks, remotenode):
522 '''Return appropriate diverged bookmark for specified ``path``
543 '''Return appropriate diverged bookmark for specified ``path``
523
544
524 This returns None, if it is failed to assign any divergent
545 This returns None, if it is failed to assign any divergent
525 bookmark name.
546 bookmark name.
526
547
527 This reuses already existing one with "@number" suffix, if it
548 This reuses already existing one with "@number" suffix, if it
528 refers ``remotenode``.
549 refers ``remotenode``.
529 '''
550 '''
530 if b == '@':
551 if b == '@':
531 b = ''
552 b = ''
532 # try to use an @pathalias suffix
553 # try to use an @pathalias suffix
533 # if an @pathalias already exists, we overwrite (update) it
554 # if an @pathalias already exists, we overwrite (update) it
534 if path.startswith("file:"):
555 if path.startswith("file:"):
535 path = util.url(path).path
556 path = util.url(path).path
536 for p, u in ui.configitems("paths"):
557 for p, u in ui.configitems("paths"):
537 if u.startswith("file:"):
558 if u.startswith("file:"):
538 u = util.url(u).path
559 u = util.url(u).path
539 if path == u:
560 if path == u:
540 return '%s@%s' % (b, p)
561 return '%s@%s' % (b, p)
541
562
542 # assign a unique "@number" suffix newly
563 # assign a unique "@number" suffix newly
543 for x in range(1, 100):
564 for x in range(1, 100):
544 n = '%s@%d' % (b, x)
565 n = '%s@%d' % (b, x)
545 if n not in localmarks or localmarks[n] == remotenode:
566 if n not in localmarks or localmarks[n] == remotenode:
546 return n
567 return n
547
568
548 return None
569 return None
549
570
550 def unhexlifybookmarks(marks):
571 def unhexlifybookmarks(marks):
551 binremotemarks = {}
572 binremotemarks = {}
552 for name, node in marks.items():
573 for name, node in marks.items():
553 binremotemarks[name] = bin(node)
574 binremotemarks[name] = bin(node)
554 return binremotemarks
575 return binremotemarks
555
576
556 _binaryentry = struct.Struct('>20sH')
577 _binaryentry = struct.Struct('>20sH')
557
578
558 def binaryencode(bookmarks):
579 def binaryencode(bookmarks):
559 """encode a '(bookmark, node)' iterable into a binary stream
580 """encode a '(bookmark, node)' iterable into a binary stream
560
581
561 the binary format is:
582 the binary format is:
562
583
563 <node><bookmark-length><bookmark-name>
584 <node><bookmark-length><bookmark-name>
564
585
565 :node: is a 20 bytes binary node,
586 :node: is a 20 bytes binary node,
566 :bookmark-length: an unsigned short,
587 :bookmark-length: an unsigned short,
567 :bookmark-name: the name of the bookmark (of length <bookmark-length>)
588 :bookmark-name: the name of the bookmark (of length <bookmark-length>)
568
589
569 wdirid (all bits set) will be used as a special value for "missing"
590 wdirid (all bits set) will be used as a special value for "missing"
570 """
591 """
571 binarydata = []
592 binarydata = []
572 for book, node in bookmarks:
593 for book, node in bookmarks:
573 if not node: # None or ''
594 if not node: # None or ''
574 node = wdirid
595 node = wdirid
575 binarydata.append(_binaryentry.pack(node, len(book)))
596 binarydata.append(_binaryentry.pack(node, len(book)))
576 binarydata.append(book)
597 binarydata.append(book)
577 return ''.join(binarydata)
598 return ''.join(binarydata)
578
599
579 def binarydecode(stream):
600 def binarydecode(stream):
580 """decode a binary stream into an '(bookmark, node)' iterable
601 """decode a binary stream into an '(bookmark, node)' iterable
581
602
582 the binary format is:
603 the binary format is:
583
604
584 <node><bookmark-length><bookmark-name>
605 <node><bookmark-length><bookmark-name>
585
606
586 :node: is a 20 bytes binary node,
607 :node: is a 20 bytes binary node,
587 :bookmark-length: an unsigned short,
608 :bookmark-length: an unsigned short,
588 :bookmark-name: the name of the bookmark (of length <bookmark-length>))
609 :bookmark-name: the name of the bookmark (of length <bookmark-length>))
589
610
590 wdirid (all bits set) will be used as a special value for "missing"
611 wdirid (all bits set) will be used as a special value for "missing"
591 """
612 """
592 entrysize = _binaryentry.size
613 entrysize = _binaryentry.size
593 books = []
614 books = []
594 while True:
615 while True:
595 entry = stream.read(entrysize)
616 entry = stream.read(entrysize)
596 if len(entry) < entrysize:
617 if len(entry) < entrysize:
597 if entry:
618 if entry:
598 raise error.Abort(_('bad bookmark stream'))
619 raise error.Abort(_('bad bookmark stream'))
599 break
620 break
600 node, length = _binaryentry.unpack(entry)
621 node, length = _binaryentry.unpack(entry)
601 bookmark = stream.read(length)
622 bookmark = stream.read(length)
602 if len(bookmark) < length:
623 if len(bookmark) < length:
603 if entry:
624 if entry:
604 raise error.Abort(_('bad bookmark stream'))
625 raise error.Abort(_('bad bookmark stream'))
605 if node == wdirid:
626 if node == wdirid:
606 node = None
627 node = None
607 books.append((bookmark, node))
628 books.append((bookmark, node))
608 return books
629 return books
609
630
610 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()):
631 def updatefromremote(ui, repo, remotemarks, path, trfunc, explicit=()):
611 ui.debug("checking for updated bookmarks\n")
632 ui.debug("checking for updated bookmarks\n")
612 localmarks = repo._bookmarks
633 localmarks = repo._bookmarks
613 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same
634 (addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same
614 ) = comparebookmarks(repo, remotemarks, localmarks)
635 ) = comparebookmarks(repo, remotemarks, localmarks)
615
636
616 status = ui.status
637 status = ui.status
617 warn = ui.warn
638 warn = ui.warn
618 if ui.configbool('ui', 'quietbookmarkmove'):
639 if ui.configbool('ui', 'quietbookmarkmove'):
619 status = warn = ui.debug
640 status = warn = ui.debug
620
641
621 explicit = set(explicit)
642 explicit = set(explicit)
622 changed = []
643 changed = []
623 for b, scid, dcid in addsrc:
644 for b, scid, dcid in addsrc:
624 if scid in repo: # add remote bookmarks for changes we already have
645 if scid in repo: # add remote bookmarks for changes we already have
625 changed.append((b, scid, status,
646 changed.append((b, scid, status,
626 _("adding remote bookmark %s\n") % (b)))
647 _("adding remote bookmark %s\n") % (b)))
627 elif b in explicit:
648 elif b in explicit:
628 explicit.remove(b)
649 explicit.remove(b)
629 ui.warn(_("remote bookmark %s points to locally missing %s\n")
650 ui.warn(_("remote bookmark %s points to locally missing %s\n")
630 % (b, hex(scid)[:12]))
651 % (b, hex(scid)[:12]))
631
652
632 for b, scid, dcid in advsrc:
653 for b, scid, dcid in advsrc:
633 changed.append((b, scid, status,
654 changed.append((b, scid, status,
634 _("updating bookmark %s\n") % (b)))
655 _("updating bookmark %s\n") % (b)))
635 # remove normal movement from explicit set
656 # remove normal movement from explicit set
636 explicit.difference_update(d[0] for d in changed)
657 explicit.difference_update(d[0] for d in changed)
637
658
638 for b, scid, dcid in diverge:
659 for b, scid, dcid in diverge:
639 if b in explicit:
660 if b in explicit:
640 explicit.discard(b)
661 explicit.discard(b)
641 changed.append((b, scid, status,
662 changed.append((b, scid, status,
642 _("importing bookmark %s\n") % (b)))
663 _("importing bookmark %s\n") % (b)))
643 else:
664 else:
644 db = _diverge(ui, b, path, localmarks, scid)
665 db = _diverge(ui, b, path, localmarks, scid)
645 if db:
666 if db:
646 changed.append((db, scid, warn,
667 changed.append((db, scid, warn,
647 _("divergent bookmark %s stored as %s\n") %
668 _("divergent bookmark %s stored as %s\n") %
648 (b, db)))
669 (b, db)))
649 else:
670 else:
650 warn(_("warning: failed to assign numbered name "
671 warn(_("warning: failed to assign numbered name "
651 "to divergent bookmark %s\n") % (b))
672 "to divergent bookmark %s\n") % (b))
652 for b, scid, dcid in adddst + advdst:
673 for b, scid, dcid in adddst + advdst:
653 if b in explicit:
674 if b in explicit:
654 explicit.discard(b)
675 explicit.discard(b)
655 changed.append((b, scid, status,
676 changed.append((b, scid, status,
656 _("importing bookmark %s\n") % (b)))
677 _("importing bookmark %s\n") % (b)))
657 for b, scid, dcid in differ:
678 for b, scid, dcid in differ:
658 if b in explicit:
679 if b in explicit:
659 explicit.remove(b)
680 explicit.remove(b)
660 ui.warn(_("remote bookmark %s points to locally missing %s\n")
681 ui.warn(_("remote bookmark %s points to locally missing %s\n")
661 % (b, hex(scid)[:12]))
682 % (b, hex(scid)[:12]))
662
683
663 if changed:
684 if changed:
664 tr = trfunc()
685 tr = trfunc()
665 changes = []
686 changes = []
666 for b, node, writer, msg in sorted(changed):
687 for b, node, writer, msg in sorted(changed):
667 changes.append((b, node))
688 changes.append((b, node))
668 writer(msg)
689 writer(msg)
669 localmarks.applychanges(repo, tr, changes)
690 localmarks.applychanges(repo, tr, changes)
670
691
671 def incoming(ui, repo, peer):
692 def incoming(ui, repo, peer):
672 '''Show bookmarks incoming from other to repo
693 '''Show bookmarks incoming from other to repo
673 '''
694 '''
674 ui.status(_("searching for changed bookmarks\n"))
695 ui.status(_("searching for changed bookmarks\n"))
675
696
676 with peer.commandexecutor() as e:
697 with peer.commandexecutor() as e:
677 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
698 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
678 'namespace': 'bookmarks',
699 'namespace': 'bookmarks',
679 }).result())
700 }).result())
680
701
681 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
702 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
682 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
703 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
683
704
684 incomings = []
705 incomings = []
685 if ui.debugflag:
706 if ui.debugflag:
686 getid = lambda id: id
707 getid = lambda id: id
687 else:
708 else:
688 getid = lambda id: id[:12]
709 getid = lambda id: id[:12]
689 if ui.verbose:
710 if ui.verbose:
690 def add(b, id, st):
711 def add(b, id, st):
691 incomings.append(" %-25s %s %s\n" % (b, getid(id), st))
712 incomings.append(" %-25s %s %s\n" % (b, getid(id), st))
692 else:
713 else:
693 def add(b, id, st):
714 def add(b, id, st):
694 incomings.append(" %-25s %s\n" % (b, getid(id)))
715 incomings.append(" %-25s %s\n" % (b, getid(id)))
695 for b, scid, dcid in addsrc:
716 for b, scid, dcid in addsrc:
696 # i18n: "added" refers to a bookmark
717 # i18n: "added" refers to a bookmark
697 add(b, hex(scid), _('added'))
718 add(b, hex(scid), _('added'))
698 for b, scid, dcid in advsrc:
719 for b, scid, dcid in advsrc:
699 # i18n: "advanced" refers to a bookmark
720 # i18n: "advanced" refers to a bookmark
700 add(b, hex(scid), _('advanced'))
721 add(b, hex(scid), _('advanced'))
701 for b, scid, dcid in diverge:
722 for b, scid, dcid in diverge:
702 # i18n: "diverged" refers to a bookmark
723 # i18n: "diverged" refers to a bookmark
703 add(b, hex(scid), _('diverged'))
724 add(b, hex(scid), _('diverged'))
704 for b, scid, dcid in differ:
725 for b, scid, dcid in differ:
705 # i18n: "changed" refers to a bookmark
726 # i18n: "changed" refers to a bookmark
706 add(b, hex(scid), _('changed'))
727 add(b, hex(scid), _('changed'))
707
728
708 if not incomings:
729 if not incomings:
709 ui.status(_("no changed bookmarks found\n"))
730 ui.status(_("no changed bookmarks found\n"))
710 return 1
731 return 1
711
732
712 for s in sorted(incomings):
733 for s in sorted(incomings):
713 ui.write(s)
734 ui.write(s)
714
735
715 return 0
736 return 0
716
737
717 def outgoing(ui, repo, other):
738 def outgoing(ui, repo, other):
718 '''Show bookmarks outgoing from repo to other
739 '''Show bookmarks outgoing from repo to other
719 '''
740 '''
720 ui.status(_("searching for changed bookmarks\n"))
741 ui.status(_("searching for changed bookmarks\n"))
721
742
722 remotemarks = unhexlifybookmarks(other.listkeys('bookmarks'))
743 remotemarks = unhexlifybookmarks(other.listkeys('bookmarks'))
723 r = comparebookmarks(repo, repo._bookmarks, remotemarks)
744 r = comparebookmarks(repo, repo._bookmarks, remotemarks)
724 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
745 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
725
746
726 outgoings = []
747 outgoings = []
727 if ui.debugflag:
748 if ui.debugflag:
728 getid = lambda id: id
749 getid = lambda id: id
729 else:
750 else:
730 getid = lambda id: id[:12]
751 getid = lambda id: id[:12]
731 if ui.verbose:
752 if ui.verbose:
732 def add(b, id, st):
753 def add(b, id, st):
733 outgoings.append(" %-25s %s %s\n" % (b, getid(id), st))
754 outgoings.append(" %-25s %s %s\n" % (b, getid(id), st))
734 else:
755 else:
735 def add(b, id, st):
756 def add(b, id, st):
736 outgoings.append(" %-25s %s\n" % (b, getid(id)))
757 outgoings.append(" %-25s %s\n" % (b, getid(id)))
737 for b, scid, dcid in addsrc:
758 for b, scid, dcid in addsrc:
738 # i18n: "added refers to a bookmark
759 # i18n: "added refers to a bookmark
739 add(b, hex(scid), _('added'))
760 add(b, hex(scid), _('added'))
740 for b, scid, dcid in adddst:
761 for b, scid, dcid in adddst:
741 # i18n: "deleted" refers to a bookmark
762 # i18n: "deleted" refers to a bookmark
742 add(b, ' ' * 40, _('deleted'))
763 add(b, ' ' * 40, _('deleted'))
743 for b, scid, dcid in advsrc:
764 for b, scid, dcid in advsrc:
744 # i18n: "advanced" refers to a bookmark
765 # i18n: "advanced" refers to a bookmark
745 add(b, hex(scid), _('advanced'))
766 add(b, hex(scid), _('advanced'))
746 for b, scid, dcid in diverge:
767 for b, scid, dcid in diverge:
747 # i18n: "diverged" refers to a bookmark
768 # i18n: "diverged" refers to a bookmark
748 add(b, hex(scid), _('diverged'))
769 add(b, hex(scid), _('diverged'))
749 for b, scid, dcid in differ:
770 for b, scid, dcid in differ:
750 # i18n: "changed" refers to a bookmark
771 # i18n: "changed" refers to a bookmark
751 add(b, hex(scid), _('changed'))
772 add(b, hex(scid), _('changed'))
752
773
753 if not outgoings:
774 if not outgoings:
754 ui.status(_("no changed bookmarks found\n"))
775 ui.status(_("no changed bookmarks found\n"))
755 return 1
776 return 1
756
777
757 for s in sorted(outgoings):
778 for s in sorted(outgoings):
758 ui.write(s)
779 ui.write(s)
759
780
760 return 0
781 return 0
761
782
762 def summary(repo, peer):
783 def summary(repo, peer):
763 '''Compare bookmarks between repo and other for "hg summary" output
784 '''Compare bookmarks between repo and other for "hg summary" output
764
785
765 This returns "(# of incoming, # of outgoing)" tuple.
786 This returns "(# of incoming, # of outgoing)" tuple.
766 '''
787 '''
767 with peer.commandexecutor() as e:
788 with peer.commandexecutor() as e:
768 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
789 remotemarks = unhexlifybookmarks(e.callcommand('listkeys', {
769 'namespace': 'bookmarks',
790 'namespace': 'bookmarks',
770 }).result())
791 }).result())
771
792
772 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
793 r = comparebookmarks(repo, remotemarks, repo._bookmarks)
773 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
794 addsrc, adddst, advsrc, advdst, diverge, differ, invalid, same = r
774 return (len(addsrc), len(adddst))
795 return (len(addsrc), len(adddst))
775
796
776 def validdest(repo, old, new):
797 def validdest(repo, old, new):
777 """Is the new bookmark destination a valid update from the old one"""
798 """Is the new bookmark destination a valid update from the old one"""
778 repo = repo.unfiltered()
799 repo = repo.unfiltered()
779 if old == new:
800 if old == new:
780 # Old == new -> nothing to update.
801 # Old == new -> nothing to update.
781 return False
802 return False
782 elif not old:
803 elif not old:
783 # old is nullrev, anything is valid.
804 # old is nullrev, anything is valid.
784 # (new != nullrev has been excluded by the previous check)
805 # (new != nullrev has been excluded by the previous check)
785 return True
806 return True
786 elif repo.obsstore:
807 elif repo.obsstore:
787 return new.node() in obsutil.foreground(repo, [old.node()])
808 return new.node() in obsutil.foreground(repo, [old.node()])
788 else:
809 else:
789 # still an independent clause as it is lazier (and therefore faster)
810 # still an independent clause as it is lazier (and therefore faster)
790 return old.isancestorof(new)
811 return old.isancestorof(new)
791
812
792 def checkformat(repo, mark):
813 def checkformat(repo, mark):
793 """return a valid version of a potential bookmark name
814 """return a valid version of a potential bookmark name
794
815
795 Raises an abort error if the bookmark name is not valid.
816 Raises an abort error if the bookmark name is not valid.
796 """
817 """
797 mark = mark.strip()
818 mark = mark.strip()
798 if not mark:
819 if not mark:
799 raise error.Abort(_("bookmark names cannot consist entirely of "
820 raise error.Abort(_("bookmark names cannot consist entirely of "
800 "whitespace"))
821 "whitespace"))
801 scmutil.checknewlabel(repo, mark, 'bookmark')
822 scmutil.checknewlabel(repo, mark, 'bookmark')
802 return mark
823 return mark
803
824
804 def delete(repo, tr, names):
825 def delete(repo, tr, names):
805 """remove a mark from the bookmark store
826 """remove a mark from the bookmark store
806
827
807 Raises an abort error if mark does not exist.
828 Raises an abort error if mark does not exist.
808 """
829 """
809 marks = repo._bookmarks
830 marks = repo._bookmarks
810 changes = []
831 changes = []
811 for mark in names:
832 for mark in names:
812 if mark not in marks:
833 if mark not in marks:
813 raise error.Abort(_("bookmark '%s' does not exist") % mark)
834 raise error.Abort(_("bookmark '%s' does not exist") % mark)
814 if mark == repo._activebookmark:
835 if mark == repo._activebookmark:
815 deactivate(repo)
836 deactivate(repo)
816 changes.append((mark, None))
837 changes.append((mark, None))
817 marks.applychanges(repo, tr, changes)
838 marks.applychanges(repo, tr, changes)
818
839
819 def rename(repo, tr, old, new, force=False, inactive=False):
840 def rename(repo, tr, old, new, force=False, inactive=False):
820 """rename a bookmark from old to new
841 """rename a bookmark from old to new
821
842
822 If force is specified, then the new name can overwrite an existing
843 If force is specified, then the new name can overwrite an existing
823 bookmark.
844 bookmark.
824
845
825 If inactive is specified, then do not activate the new bookmark.
846 If inactive is specified, then do not activate the new bookmark.
826
847
827 Raises an abort error if old is not in the bookmark store.
848 Raises an abort error if old is not in the bookmark store.
828 """
849 """
829 marks = repo._bookmarks
850 marks = repo._bookmarks
830 mark = checkformat(repo, new)
851 mark = checkformat(repo, new)
831 if old not in marks:
852 if old not in marks:
832 raise error.Abort(_("bookmark '%s' does not exist") % old)
853 raise error.Abort(_("bookmark '%s' does not exist") % old)
833 changes = []
854 changes = []
834 for bm in marks.checkconflict(mark, force):
855 for bm in marks.checkconflict(mark, force):
835 changes.append((bm, None))
856 changes.append((bm, None))
836 changes.extend([(mark, marks[old]), (old, None)])
857 changes.extend([(mark, marks[old]), (old, None)])
837 marks.applychanges(repo, tr, changes)
858 marks.applychanges(repo, tr, changes)
838 if repo._activebookmark == old and not inactive:
859 if repo._activebookmark == old and not inactive:
839 activate(repo, mark)
860 activate(repo, mark)
840
861
841 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False):
862 def addbookmarks(repo, tr, names, rev=None, force=False, inactive=False):
842 """add a list of bookmarks
863 """add a list of bookmarks
843
864
844 If force is specified, then the new name can overwrite an existing
865 If force is specified, then the new name can overwrite an existing
845 bookmark.
866 bookmark.
846
867
847 If inactive is specified, then do not activate any bookmark. Otherwise, the
868 If inactive is specified, then do not activate any bookmark. Otherwise, the
848 first bookmark is activated.
869 first bookmark is activated.
849
870
850 Raises an abort error if old is not in the bookmark store.
871 Raises an abort error if old is not in the bookmark store.
851 """
872 """
852 marks = repo._bookmarks
873 marks = repo._bookmarks
853 cur = repo['.'].node()
874 cur = repo['.'].node()
854 newact = None
875 newact = None
855 changes = []
876 changes = []
856 hiddenrev = None
877 hiddenrev = None
857
878
858 # unhide revs if any
879 # unhide revs if any
859 if rev:
880 if rev:
860 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
881 repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
861
882
862 for mark in names:
883 for mark in names:
863 mark = checkformat(repo, mark)
884 mark = checkformat(repo, mark)
864 if newact is None:
885 if newact is None:
865 newact = mark
886 newact = mark
866 if inactive and mark == repo._activebookmark:
887 if inactive and mark == repo._activebookmark:
867 deactivate(repo)
888 deactivate(repo)
868 return
889 return
869 tgt = cur
890 tgt = cur
870 if rev:
891 if rev:
871 ctx = scmutil.revsingle(repo, rev)
892 ctx = scmutil.revsingle(repo, rev)
872 if ctx.hidden():
893 if ctx.hidden():
873 hiddenrev = ctx.hex()[:12]
894 hiddenrev = ctx.hex()[:12]
874 tgt = ctx.node()
895 tgt = ctx.node()
875 for bm in marks.checkconflict(mark, force, tgt):
896 for bm in marks.checkconflict(mark, force, tgt):
876 changes.append((bm, None))
897 changes.append((bm, None))
877 changes.append((mark, tgt))
898 changes.append((mark, tgt))
878
899
879 if hiddenrev:
900 if hiddenrev:
880 repo.ui.warn(_("bookmarking hidden changeset %s\n") % hiddenrev)
901 repo.ui.warn(_("bookmarking hidden changeset %s\n") % hiddenrev)
881
902
882 if ctx.obsolete():
903 if ctx.obsolete():
883 msg = obsutil._getfilteredreason(repo, "%s" % hiddenrev, ctx)
904 msg = obsutil._getfilteredreason(repo, "%s" % hiddenrev, ctx)
884 repo.ui.warn("(%s)\n" % msg)
905 repo.ui.warn("(%s)\n" % msg)
885
906
886 marks.applychanges(repo, tr, changes)
907 marks.applychanges(repo, tr, changes)
887 if not inactive and cur == marks[newact] and not rev:
908 if not inactive and cur == marks[newact] and not rev:
888 activate(repo, newact)
909 activate(repo, newact)
889 elif cur != tgt and newact == repo._activebookmark:
910 elif cur != tgt and newact == repo._activebookmark:
890 deactivate(repo)
911 deactivate(repo)
891
912
892 def _printbookmarks(ui, repo, fm, bmarks):
913 def _printbookmarks(ui, repo, fm, bmarks):
893 """private method to print bookmarks
914 """private method to print bookmarks
894
915
895 Provides a way for extensions to control how bookmarks are printed (e.g.
916 Provides a way for extensions to control how bookmarks are printed (e.g.
896 prepend or postpend names)
917 prepend or postpend names)
897 """
918 """
898 hexfn = fm.hexfunc
919 hexfn = fm.hexfunc
899 if len(bmarks) == 0 and fm.isplain():
920 if len(bmarks) == 0 and fm.isplain():
900 ui.status(_("no bookmarks set\n"))
921 ui.status(_("no bookmarks set\n"))
901 for bmark, (n, prefix, label) in sorted(bmarks.iteritems()):
922 for bmark, (n, prefix, label) in sorted(bmarks.iteritems()):
902 fm.startitem()
923 fm.startitem()
903 fm.context(repo=repo)
924 fm.context(repo=repo)
904 if not ui.quiet:
925 if not ui.quiet:
905 fm.plain(' %s ' % prefix, label=label)
926 fm.plain(' %s ' % prefix, label=label)
906 fm.write('bookmark', '%s', bmark, label=label)
927 fm.write('bookmark', '%s', bmark, label=label)
907 pad = " " * (25 - encoding.colwidth(bmark))
928 pad = " " * (25 - encoding.colwidth(bmark))
908 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
929 fm.condwrite(not ui.quiet, 'rev node', pad + ' %d:%s',
909 repo.changelog.rev(n), hexfn(n), label=label)
930 repo.changelog.rev(n), hexfn(n), label=label)
910 fm.data(active=(activebookmarklabel in label))
931 fm.data(active=(activebookmarklabel in label))
911 fm.plain('\n')
932 fm.plain('\n')
912
933
913 def printbookmarks(ui, repo, fm, names=None):
934 def printbookmarks(ui, repo, fm, names=None):
914 """print bookmarks by the given formatter
935 """print bookmarks by the given formatter
915
936
916 Provides a way for extensions to control how bookmarks are printed.
937 Provides a way for extensions to control how bookmarks are printed.
917 """
938 """
918 marks = repo._bookmarks
939 marks = repo._bookmarks
919 bmarks = {}
940 bmarks = {}
920 for bmark in (names or marks):
941 for bmark in (names or marks):
921 if bmark not in marks:
942 if bmark not in marks:
922 raise error.Abort(_("bookmark '%s' does not exist") % bmark)
943 raise error.Abort(_("bookmark '%s' does not exist") % bmark)
923 active = repo._activebookmark
944 active = repo._activebookmark
924 if bmark == active:
945 if bmark == active:
925 prefix, label = '*', activebookmarklabel
946 prefix, label = '*', activebookmarklabel
926 else:
947 else:
927 prefix, label = ' ', ''
948 prefix, label = ' ', ''
928
949
929 bmarks[bmark] = (marks[bmark], prefix, label)
950 bmarks[bmark] = (marks[bmark], prefix, label)
930 _printbookmarks(ui, repo, fm, bmarks)
951 _printbookmarks(ui, repo, fm, bmarks)
931
952
932 def preparehookargs(name, old, new):
953 def preparehookargs(name, old, new):
933 if new is None:
954 if new is None:
934 new = ''
955 new = ''
935 if old is None:
956 if old is None:
936 old = ''
957 old = ''
937 return {'bookmark': name,
958 return {'bookmark': name,
938 'node': hex(new),
959 'node': hex(new),
939 'oldnode': hex(old)}
960 'oldnode': hex(old)}
@@ -1,1490 +1,1493 b''
1 # configitems.py - centralized declaration of configuration option
1 # configitems.py - centralized declaration of configuration option
2 #
2 #
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import functools
10 import functools
11 import re
11 import re
12
12
13 from . import (
13 from . import (
14 encoding,
14 encoding,
15 error,
15 error,
16 )
16 )
17
17
18 def loadconfigtable(ui, extname, configtable):
18 def loadconfigtable(ui, extname, configtable):
19 """update config item known to the ui with the extension ones"""
19 """update config item known to the ui with the extension ones"""
20 for section, items in sorted(configtable.items()):
20 for section, items in sorted(configtable.items()):
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
21 knownitems = ui._knownconfig.setdefault(section, itemregister())
22 knownkeys = set(knownitems)
22 knownkeys = set(knownitems)
23 newkeys = set(items)
23 newkeys = set(items)
24 for key in sorted(knownkeys & newkeys):
24 for key in sorted(knownkeys & newkeys):
25 msg = "extension '%s' overwrite config item '%s.%s'"
25 msg = "extension '%s' overwrite config item '%s.%s'"
26 msg %= (extname, section, key)
26 msg %= (extname, section, key)
27 ui.develwarn(msg, config='warn-config')
27 ui.develwarn(msg, config='warn-config')
28
28
29 knownitems.update(items)
29 knownitems.update(items)
30
30
31 class configitem(object):
31 class configitem(object):
32 """represent a known config item
32 """represent a known config item
33
33
34 :section: the official config section where to find this item,
34 :section: the official config section where to find this item,
35 :name: the official name within the section,
35 :name: the official name within the section,
36 :default: default value for this item,
36 :default: default value for this item,
37 :alias: optional list of tuples as alternatives,
37 :alias: optional list of tuples as alternatives,
38 :generic: this is a generic definition, match name using regular expression.
38 :generic: this is a generic definition, match name using regular expression.
39 """
39 """
40
40
41 def __init__(self, section, name, default=None, alias=(),
41 def __init__(self, section, name, default=None, alias=(),
42 generic=False, priority=0):
42 generic=False, priority=0):
43 self.section = section
43 self.section = section
44 self.name = name
44 self.name = name
45 self.default = default
45 self.default = default
46 self.alias = list(alias)
46 self.alias = list(alias)
47 self.generic = generic
47 self.generic = generic
48 self.priority = priority
48 self.priority = priority
49 self._re = None
49 self._re = None
50 if generic:
50 if generic:
51 self._re = re.compile(self.name)
51 self._re = re.compile(self.name)
52
52
53 class itemregister(dict):
53 class itemregister(dict):
54 """A specialized dictionary that can handle wild-card selection"""
54 """A specialized dictionary that can handle wild-card selection"""
55
55
56 def __init__(self):
56 def __init__(self):
57 super(itemregister, self).__init__()
57 super(itemregister, self).__init__()
58 self._generics = set()
58 self._generics = set()
59
59
60 def update(self, other):
60 def update(self, other):
61 super(itemregister, self).update(other)
61 super(itemregister, self).update(other)
62 self._generics.update(other._generics)
62 self._generics.update(other._generics)
63
63
64 def __setitem__(self, key, item):
64 def __setitem__(self, key, item):
65 super(itemregister, self).__setitem__(key, item)
65 super(itemregister, self).__setitem__(key, item)
66 if item.generic:
66 if item.generic:
67 self._generics.add(item)
67 self._generics.add(item)
68
68
69 def get(self, key):
69 def get(self, key):
70 baseitem = super(itemregister, self).get(key)
70 baseitem = super(itemregister, self).get(key)
71 if baseitem is not None and not baseitem.generic:
71 if baseitem is not None and not baseitem.generic:
72 return baseitem
72 return baseitem
73
73
74 # search for a matching generic item
74 # search for a matching generic item
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
75 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
76 for item in generics:
76 for item in generics:
77 # we use 'match' instead of 'search' to make the matching simpler
77 # we use 'match' instead of 'search' to make the matching simpler
78 # for people unfamiliar with regular expression. Having the match
78 # for people unfamiliar with regular expression. Having the match
79 # rooted to the start of the string will produce less surprising
79 # rooted to the start of the string will produce less surprising
80 # result for user writing simple regex for sub-attribute.
80 # result for user writing simple regex for sub-attribute.
81 #
81 #
82 # For example using "color\..*" match produces an unsurprising
82 # For example using "color\..*" match produces an unsurprising
83 # result, while using search could suddenly match apparently
83 # result, while using search could suddenly match apparently
84 # unrelated configuration that happens to contains "color."
84 # unrelated configuration that happens to contains "color."
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
85 # anywhere. This is a tradeoff where we favor requiring ".*" on
86 # some match to avoid the need to prefix most pattern with "^".
86 # some match to avoid the need to prefix most pattern with "^".
87 # The "^" seems more error prone.
87 # The "^" seems more error prone.
88 if item._re.match(key):
88 if item._re.match(key):
89 return item
89 return item
90
90
91 return None
91 return None
92
92
93 coreitems = {}
93 coreitems = {}
94
94
95 def _register(configtable, *args, **kwargs):
95 def _register(configtable, *args, **kwargs):
96 item = configitem(*args, **kwargs)
96 item = configitem(*args, **kwargs)
97 section = configtable.setdefault(item.section, itemregister())
97 section = configtable.setdefault(item.section, itemregister())
98 if item.name in section:
98 if item.name in section:
99 msg = "duplicated config item registration for '%s.%s'"
99 msg = "duplicated config item registration for '%s.%s'"
100 raise error.ProgrammingError(msg % (item.section, item.name))
100 raise error.ProgrammingError(msg % (item.section, item.name))
101 section[item.name] = item
101 section[item.name] = item
102
102
103 # special value for case where the default is derived from other values
103 # special value for case where the default is derived from other values
104 dynamicdefault = object()
104 dynamicdefault = object()
105
105
106 # Registering actual config items
106 # Registering actual config items
107
107
108 def getitemregister(configtable):
108 def getitemregister(configtable):
109 f = functools.partial(_register, configtable)
109 f = functools.partial(_register, configtable)
110 # export pseudo enum as configitem.*
110 # export pseudo enum as configitem.*
111 f.dynamicdefault = dynamicdefault
111 f.dynamicdefault = dynamicdefault
112 return f
112 return f
113
113
114 coreconfigitem = getitemregister(coreitems)
114 coreconfigitem = getitemregister(coreitems)
115
115
116 def _registerdiffopts(section, configprefix=''):
116 def _registerdiffopts(section, configprefix=''):
117 coreconfigitem(section, configprefix + 'nodates',
117 coreconfigitem(section, configprefix + 'nodates',
118 default=False,
118 default=False,
119 )
119 )
120 coreconfigitem(section, configprefix + 'showfunc',
120 coreconfigitem(section, configprefix + 'showfunc',
121 default=False,
121 default=False,
122 )
122 )
123 coreconfigitem(section, configprefix + 'unified',
123 coreconfigitem(section, configprefix + 'unified',
124 default=None,
124 default=None,
125 )
125 )
126 coreconfigitem(section, configprefix + 'git',
126 coreconfigitem(section, configprefix + 'git',
127 default=False,
127 default=False,
128 )
128 )
129 coreconfigitem(section, configprefix + 'ignorews',
129 coreconfigitem(section, configprefix + 'ignorews',
130 default=False,
130 default=False,
131 )
131 )
132 coreconfigitem(section, configprefix + 'ignorewsamount',
132 coreconfigitem(section, configprefix + 'ignorewsamount',
133 default=False,
133 default=False,
134 )
134 )
135 coreconfigitem(section, configprefix + 'ignoreblanklines',
135 coreconfigitem(section, configprefix + 'ignoreblanklines',
136 default=False,
136 default=False,
137 )
137 )
138 coreconfigitem(section, configprefix + 'ignorewseol',
138 coreconfigitem(section, configprefix + 'ignorewseol',
139 default=False,
139 default=False,
140 )
140 )
141 coreconfigitem(section, configprefix + 'nobinary',
141 coreconfigitem(section, configprefix + 'nobinary',
142 default=False,
142 default=False,
143 )
143 )
144 coreconfigitem(section, configprefix + 'noprefix',
144 coreconfigitem(section, configprefix + 'noprefix',
145 default=False,
145 default=False,
146 )
146 )
147 coreconfigitem(section, configprefix + 'word-diff',
147 coreconfigitem(section, configprefix + 'word-diff',
148 default=False,
148 default=False,
149 )
149 )
150
150
151 coreconfigitem('alias', '.*',
151 coreconfigitem('alias', '.*',
152 default=dynamicdefault,
152 default=dynamicdefault,
153 generic=True,
153 generic=True,
154 )
154 )
155 coreconfigitem('auth', 'cookiefile',
155 coreconfigitem('auth', 'cookiefile',
156 default=None,
156 default=None,
157 )
157 )
158 _registerdiffopts(section='annotate')
158 _registerdiffopts(section='annotate')
159 # bookmarks.pushing: internal hack for discovery
159 # bookmarks.pushing: internal hack for discovery
160 coreconfigitem('bookmarks', 'pushing',
160 coreconfigitem('bookmarks', 'pushing',
161 default=list,
161 default=list,
162 )
162 )
163 # bundle.mainreporoot: internal hack for bundlerepo
163 # bundle.mainreporoot: internal hack for bundlerepo
164 coreconfigitem('bundle', 'mainreporoot',
164 coreconfigitem('bundle', 'mainreporoot',
165 default='',
165 default='',
166 )
166 )
167 coreconfigitem('censor', 'policy',
167 coreconfigitem('censor', 'policy',
168 default='abort',
168 default='abort',
169 )
169 )
170 coreconfigitem('chgserver', 'idletimeout',
170 coreconfigitem('chgserver', 'idletimeout',
171 default=3600,
171 default=3600,
172 )
172 )
173 coreconfigitem('chgserver', 'skiphash',
173 coreconfigitem('chgserver', 'skiphash',
174 default=False,
174 default=False,
175 )
175 )
176 coreconfigitem('cmdserver', 'log',
176 coreconfigitem('cmdserver', 'log',
177 default=None,
177 default=None,
178 )
178 )
179 coreconfigitem('cmdserver', 'max-log-files',
179 coreconfigitem('cmdserver', 'max-log-files',
180 default=7,
180 default=7,
181 )
181 )
182 coreconfigitem('cmdserver', 'max-log-size',
182 coreconfigitem('cmdserver', 'max-log-size',
183 default='1 MB',
183 default='1 MB',
184 )
184 )
185 coreconfigitem('cmdserver', 'max-repo-cache',
185 coreconfigitem('cmdserver', 'max-repo-cache',
186 default=0,
186 default=0,
187 )
187 )
188 coreconfigitem('cmdserver', 'message-encodings',
188 coreconfigitem('cmdserver', 'message-encodings',
189 default=list,
189 default=list,
190 )
190 )
191 coreconfigitem('cmdserver', 'track-log',
191 coreconfigitem('cmdserver', 'track-log',
192 default=lambda: ['chgserver', 'cmdserver', 'repocache'],
192 default=lambda: ['chgserver', 'cmdserver', 'repocache'],
193 )
193 )
194 coreconfigitem('color', '.*',
194 coreconfigitem('color', '.*',
195 default=None,
195 default=None,
196 generic=True,
196 generic=True,
197 )
197 )
198 coreconfigitem('color', 'mode',
198 coreconfigitem('color', 'mode',
199 default='auto',
199 default='auto',
200 )
200 )
201 coreconfigitem('color', 'pagermode',
201 coreconfigitem('color', 'pagermode',
202 default=dynamicdefault,
202 default=dynamicdefault,
203 )
203 )
204 _registerdiffopts(section='commands', configprefix='commit.interactive.')
204 _registerdiffopts(section='commands', configprefix='commit.interactive.')
205 coreconfigitem('commands', 'commit.post-status',
205 coreconfigitem('commands', 'commit.post-status',
206 default=False,
206 default=False,
207 )
207 )
208 coreconfigitem('commands', 'grep.all-files',
208 coreconfigitem('commands', 'grep.all-files',
209 default=False,
209 default=False,
210 )
210 )
211 coreconfigitem('commands', 'resolve.confirm',
211 coreconfigitem('commands', 'resolve.confirm',
212 default=False,
212 default=False,
213 )
213 )
214 coreconfigitem('commands', 'resolve.explicit-re-merge',
214 coreconfigitem('commands', 'resolve.explicit-re-merge',
215 default=False,
215 default=False,
216 )
216 )
217 coreconfigitem('commands', 'resolve.mark-check',
217 coreconfigitem('commands', 'resolve.mark-check',
218 default='none',
218 default='none',
219 )
219 )
220 _registerdiffopts(section='commands', configprefix='revert.interactive.')
220 _registerdiffopts(section='commands', configprefix='revert.interactive.')
221 coreconfigitem('commands', 'show.aliasprefix',
221 coreconfigitem('commands', 'show.aliasprefix',
222 default=list,
222 default=list,
223 )
223 )
224 coreconfigitem('commands', 'status.relative',
224 coreconfigitem('commands', 'status.relative',
225 default=False,
225 default=False,
226 )
226 )
227 coreconfigitem('commands', 'status.skipstates',
227 coreconfigitem('commands', 'status.skipstates',
228 default=[],
228 default=[],
229 )
229 )
230 coreconfigitem('commands', 'status.terse',
230 coreconfigitem('commands', 'status.terse',
231 default='',
231 default='',
232 )
232 )
233 coreconfigitem('commands', 'status.verbose',
233 coreconfigitem('commands', 'status.verbose',
234 default=False,
234 default=False,
235 )
235 )
236 coreconfigitem('commands', 'update.check',
236 coreconfigitem('commands', 'update.check',
237 default=None,
237 default=None,
238 )
238 )
239 coreconfigitem('commands', 'update.requiredest',
239 coreconfigitem('commands', 'update.requiredest',
240 default=False,
240 default=False,
241 )
241 )
242 coreconfigitem('committemplate', '.*',
242 coreconfigitem('committemplate', '.*',
243 default=None,
243 default=None,
244 generic=True,
244 generic=True,
245 )
245 )
246 coreconfigitem('convert', 'bzr.saverev',
246 coreconfigitem('convert', 'bzr.saverev',
247 default=True,
247 default=True,
248 )
248 )
249 coreconfigitem('convert', 'cvsps.cache',
249 coreconfigitem('convert', 'cvsps.cache',
250 default=True,
250 default=True,
251 )
251 )
252 coreconfigitem('convert', 'cvsps.fuzz',
252 coreconfigitem('convert', 'cvsps.fuzz',
253 default=60,
253 default=60,
254 )
254 )
255 coreconfigitem('convert', 'cvsps.logencoding',
255 coreconfigitem('convert', 'cvsps.logencoding',
256 default=None,
256 default=None,
257 )
257 )
258 coreconfigitem('convert', 'cvsps.mergefrom',
258 coreconfigitem('convert', 'cvsps.mergefrom',
259 default=None,
259 default=None,
260 )
260 )
261 coreconfigitem('convert', 'cvsps.mergeto',
261 coreconfigitem('convert', 'cvsps.mergeto',
262 default=None,
262 default=None,
263 )
263 )
264 coreconfigitem('convert', 'git.committeractions',
264 coreconfigitem('convert', 'git.committeractions',
265 default=lambda: ['messagedifferent'],
265 default=lambda: ['messagedifferent'],
266 )
266 )
267 coreconfigitem('convert', 'git.extrakeys',
267 coreconfigitem('convert', 'git.extrakeys',
268 default=list,
268 default=list,
269 )
269 )
270 coreconfigitem('convert', 'git.findcopiesharder',
270 coreconfigitem('convert', 'git.findcopiesharder',
271 default=False,
271 default=False,
272 )
272 )
273 coreconfigitem('convert', 'git.remoteprefix',
273 coreconfigitem('convert', 'git.remoteprefix',
274 default='remote',
274 default='remote',
275 )
275 )
276 coreconfigitem('convert', 'git.renamelimit',
276 coreconfigitem('convert', 'git.renamelimit',
277 default=400,
277 default=400,
278 )
278 )
279 coreconfigitem('convert', 'git.saverev',
279 coreconfigitem('convert', 'git.saverev',
280 default=True,
280 default=True,
281 )
281 )
282 coreconfigitem('convert', 'git.similarity',
282 coreconfigitem('convert', 'git.similarity',
283 default=50,
283 default=50,
284 )
284 )
285 coreconfigitem('convert', 'git.skipsubmodules',
285 coreconfigitem('convert', 'git.skipsubmodules',
286 default=False,
286 default=False,
287 )
287 )
288 coreconfigitem('convert', 'hg.clonebranches',
288 coreconfigitem('convert', 'hg.clonebranches',
289 default=False,
289 default=False,
290 )
290 )
291 coreconfigitem('convert', 'hg.ignoreerrors',
291 coreconfigitem('convert', 'hg.ignoreerrors',
292 default=False,
292 default=False,
293 )
293 )
294 coreconfigitem('convert', 'hg.revs',
294 coreconfigitem('convert', 'hg.revs',
295 default=None,
295 default=None,
296 )
296 )
297 coreconfigitem('convert', 'hg.saverev',
297 coreconfigitem('convert', 'hg.saverev',
298 default=False,
298 default=False,
299 )
299 )
300 coreconfigitem('convert', 'hg.sourcename',
300 coreconfigitem('convert', 'hg.sourcename',
301 default=None,
301 default=None,
302 )
302 )
303 coreconfigitem('convert', 'hg.startrev',
303 coreconfigitem('convert', 'hg.startrev',
304 default=None,
304 default=None,
305 )
305 )
306 coreconfigitem('convert', 'hg.tagsbranch',
306 coreconfigitem('convert', 'hg.tagsbranch',
307 default='default',
307 default='default',
308 )
308 )
309 coreconfigitem('convert', 'hg.usebranchnames',
309 coreconfigitem('convert', 'hg.usebranchnames',
310 default=True,
310 default=True,
311 )
311 )
312 coreconfigitem('convert', 'ignoreancestorcheck',
312 coreconfigitem('convert', 'ignoreancestorcheck',
313 default=False,
313 default=False,
314 )
314 )
315 coreconfigitem('convert', 'localtimezone',
315 coreconfigitem('convert', 'localtimezone',
316 default=False,
316 default=False,
317 )
317 )
318 coreconfigitem('convert', 'p4.encoding',
318 coreconfigitem('convert', 'p4.encoding',
319 default=dynamicdefault,
319 default=dynamicdefault,
320 )
320 )
321 coreconfigitem('convert', 'p4.startrev',
321 coreconfigitem('convert', 'p4.startrev',
322 default=0,
322 default=0,
323 )
323 )
324 coreconfigitem('convert', 'skiptags',
324 coreconfigitem('convert', 'skiptags',
325 default=False,
325 default=False,
326 )
326 )
327 coreconfigitem('convert', 'svn.debugsvnlog',
327 coreconfigitem('convert', 'svn.debugsvnlog',
328 default=True,
328 default=True,
329 )
329 )
330 coreconfigitem('convert', 'svn.trunk',
330 coreconfigitem('convert', 'svn.trunk',
331 default=None,
331 default=None,
332 )
332 )
333 coreconfigitem('convert', 'svn.tags',
333 coreconfigitem('convert', 'svn.tags',
334 default=None,
334 default=None,
335 )
335 )
336 coreconfigitem('convert', 'svn.branches',
336 coreconfigitem('convert', 'svn.branches',
337 default=None,
337 default=None,
338 )
338 )
339 coreconfigitem('convert', 'svn.startrev',
339 coreconfigitem('convert', 'svn.startrev',
340 default=0,
340 default=0,
341 )
341 )
342 coreconfigitem('debug', 'dirstate.delaywrite',
342 coreconfigitem('debug', 'dirstate.delaywrite',
343 default=0,
343 default=0,
344 )
344 )
345 coreconfigitem('defaults', '.*',
345 coreconfigitem('defaults', '.*',
346 default=None,
346 default=None,
347 generic=True,
347 generic=True,
348 )
348 )
349 coreconfigitem('devel', 'all-warnings',
349 coreconfigitem('devel', 'all-warnings',
350 default=False,
350 default=False,
351 )
351 )
352 coreconfigitem('devel', 'bundle2.debug',
352 coreconfigitem('devel', 'bundle2.debug',
353 default=False,
353 default=False,
354 )
354 )
355 coreconfigitem('devel', 'bundle.delta',
355 coreconfigitem('devel', 'bundle.delta',
356 default='',
356 default='',
357 )
357 )
358 coreconfigitem('devel', 'cache-vfs',
358 coreconfigitem('devel', 'cache-vfs',
359 default=None,
359 default=None,
360 )
360 )
361 coreconfigitem('devel', 'check-locks',
361 coreconfigitem('devel', 'check-locks',
362 default=False,
362 default=False,
363 )
363 )
364 coreconfigitem('devel', 'check-relroot',
364 coreconfigitem('devel', 'check-relroot',
365 default=False,
365 default=False,
366 )
366 )
367 coreconfigitem('devel', 'default-date',
367 coreconfigitem('devel', 'default-date',
368 default=None,
368 default=None,
369 )
369 )
370 coreconfigitem('devel', 'deprec-warn',
370 coreconfigitem('devel', 'deprec-warn',
371 default=False,
371 default=False,
372 )
372 )
373 coreconfigitem('devel', 'disableloaddefaultcerts',
373 coreconfigitem('devel', 'disableloaddefaultcerts',
374 default=False,
374 default=False,
375 )
375 )
376 coreconfigitem('devel', 'warn-empty-changegroup',
376 coreconfigitem('devel', 'warn-empty-changegroup',
377 default=False,
377 default=False,
378 )
378 )
379 coreconfigitem('devel', 'legacy.exchange',
379 coreconfigitem('devel', 'legacy.exchange',
380 default=list,
380 default=list,
381 )
381 )
382 coreconfigitem('devel', 'servercafile',
382 coreconfigitem('devel', 'servercafile',
383 default='',
383 default='',
384 )
384 )
385 coreconfigitem('devel', 'serverexactprotocol',
385 coreconfigitem('devel', 'serverexactprotocol',
386 default='',
386 default='',
387 )
387 )
388 coreconfigitem('devel', 'serverrequirecert',
388 coreconfigitem('devel', 'serverrequirecert',
389 default=False,
389 default=False,
390 )
390 )
391 coreconfigitem('devel', 'strip-obsmarkers',
391 coreconfigitem('devel', 'strip-obsmarkers',
392 default=True,
392 default=True,
393 )
393 )
394 coreconfigitem('devel', 'warn-config',
394 coreconfigitem('devel', 'warn-config',
395 default=None,
395 default=None,
396 )
396 )
397 coreconfigitem('devel', 'warn-config-default',
397 coreconfigitem('devel', 'warn-config-default',
398 default=None,
398 default=None,
399 )
399 )
400 coreconfigitem('devel', 'user.obsmarker',
400 coreconfigitem('devel', 'user.obsmarker',
401 default=None,
401 default=None,
402 )
402 )
403 coreconfigitem('devel', 'warn-config-unknown',
403 coreconfigitem('devel', 'warn-config-unknown',
404 default=None,
404 default=None,
405 )
405 )
406 coreconfigitem('devel', 'debug.copies',
406 coreconfigitem('devel', 'debug.copies',
407 default=False,
407 default=False,
408 )
408 )
409 coreconfigitem('devel', 'debug.extensions',
409 coreconfigitem('devel', 'debug.extensions',
410 default=False,
410 default=False,
411 )
411 )
412 coreconfigitem('devel', 'debug.peer-request',
412 coreconfigitem('devel', 'debug.peer-request',
413 default=False,
413 default=False,
414 )
414 )
415 _registerdiffopts(section='diff')
415 _registerdiffopts(section='diff')
416 coreconfigitem('email', 'bcc',
416 coreconfigitem('email', 'bcc',
417 default=None,
417 default=None,
418 )
418 )
419 coreconfigitem('email', 'cc',
419 coreconfigitem('email', 'cc',
420 default=None,
420 default=None,
421 )
421 )
422 coreconfigitem('email', 'charsets',
422 coreconfigitem('email', 'charsets',
423 default=list,
423 default=list,
424 )
424 )
425 coreconfigitem('email', 'from',
425 coreconfigitem('email', 'from',
426 default=None,
426 default=None,
427 )
427 )
428 coreconfigitem('email', 'method',
428 coreconfigitem('email', 'method',
429 default='smtp',
429 default='smtp',
430 )
430 )
431 coreconfigitem('email', 'reply-to',
431 coreconfigitem('email', 'reply-to',
432 default=None,
432 default=None,
433 )
433 )
434 coreconfigitem('email', 'to',
434 coreconfigitem('email', 'to',
435 default=None,
435 default=None,
436 )
436 )
437 coreconfigitem('experimental', 'archivemetatemplate',
437 coreconfigitem('experimental', 'archivemetatemplate',
438 default=dynamicdefault,
438 default=dynamicdefault,
439 )
439 )
440 coreconfigitem('experimental', 'auto-publish',
440 coreconfigitem('experimental', 'auto-publish',
441 default='publish',
441 default='publish',
442 )
442 )
443 coreconfigitem('experimental', 'bundle-phases',
443 coreconfigitem('experimental', 'bundle-phases',
444 default=False,
444 default=False,
445 )
445 )
446 coreconfigitem('experimental', 'bundle2-advertise',
446 coreconfigitem('experimental', 'bundle2-advertise',
447 default=True,
447 default=True,
448 )
448 )
449 coreconfigitem('experimental', 'bundle2-output-capture',
449 coreconfigitem('experimental', 'bundle2-output-capture',
450 default=False,
450 default=False,
451 )
451 )
452 coreconfigitem('experimental', 'bundle2.pushback',
452 coreconfigitem('experimental', 'bundle2.pushback',
453 default=False,
453 default=False,
454 )
454 )
455 coreconfigitem('experimental', 'bundle2lazylocking',
455 coreconfigitem('experimental', 'bundle2lazylocking',
456 default=False,
456 default=False,
457 )
457 )
458 coreconfigitem('experimental', 'bundlecomplevel',
458 coreconfigitem('experimental', 'bundlecomplevel',
459 default=None,
459 default=None,
460 )
460 )
461 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
461 coreconfigitem('experimental', 'bundlecomplevel.bzip2',
462 default=None,
462 default=None,
463 )
463 )
464 coreconfigitem('experimental', 'bundlecomplevel.gzip',
464 coreconfigitem('experimental', 'bundlecomplevel.gzip',
465 default=None,
465 default=None,
466 )
466 )
467 coreconfigitem('experimental', 'bundlecomplevel.none',
467 coreconfigitem('experimental', 'bundlecomplevel.none',
468 default=None,
468 default=None,
469 )
469 )
470 coreconfigitem('experimental', 'bundlecomplevel.zstd',
470 coreconfigitem('experimental', 'bundlecomplevel.zstd',
471 default=None,
471 default=None,
472 )
472 )
473 coreconfigitem('experimental', 'changegroup3',
473 coreconfigitem('experimental', 'changegroup3',
474 default=False,
474 default=False,
475 )
475 )
476 coreconfigitem('experimental', 'cleanup-as-archived',
476 coreconfigitem('experimental', 'cleanup-as-archived',
477 default=False,
477 default=False,
478 )
478 )
479 coreconfigitem('experimental', 'clientcompressionengines',
479 coreconfigitem('experimental', 'clientcompressionengines',
480 default=list,
480 default=list,
481 )
481 )
482 coreconfigitem('experimental', 'copytrace',
482 coreconfigitem('experimental', 'copytrace',
483 default='on',
483 default='on',
484 )
484 )
485 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
485 coreconfigitem('experimental', 'copytrace.movecandidateslimit',
486 default=100,
486 default=100,
487 )
487 )
488 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
488 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
489 default=100,
489 default=100,
490 )
490 )
491 coreconfigitem('experimental', 'copies.read-from',
491 coreconfigitem('experimental', 'copies.read-from',
492 default="filelog-only",
492 default="filelog-only",
493 )
493 )
494 coreconfigitem('experimental', 'copies.write-to',
494 coreconfigitem('experimental', 'copies.write-to',
495 default='filelog-only',
495 default='filelog-only',
496 )
496 )
497 coreconfigitem('experimental', 'crecordtest',
497 coreconfigitem('experimental', 'crecordtest',
498 default=None,
498 default=None,
499 )
499 )
500 coreconfigitem('experimental', 'directaccess',
500 coreconfigitem('experimental', 'directaccess',
501 default=False,
501 default=False,
502 )
502 )
503 coreconfigitem('experimental', 'directaccess.revnums',
503 coreconfigitem('experimental', 'directaccess.revnums',
504 default=False,
504 default=False,
505 )
505 )
506 coreconfigitem('experimental', 'editortmpinhg',
506 coreconfigitem('experimental', 'editortmpinhg',
507 default=False,
507 default=False,
508 )
508 )
509 coreconfigitem('experimental', 'evolution',
509 coreconfigitem('experimental', 'evolution',
510 default=list,
510 default=list,
511 )
511 )
512 coreconfigitem('experimental', 'evolution.allowdivergence',
512 coreconfigitem('experimental', 'evolution.allowdivergence',
513 default=False,
513 default=False,
514 alias=[('experimental', 'allowdivergence')]
514 alias=[('experimental', 'allowdivergence')]
515 )
515 )
516 coreconfigitem('experimental', 'evolution.allowunstable',
516 coreconfigitem('experimental', 'evolution.allowunstable',
517 default=None,
517 default=None,
518 )
518 )
519 coreconfigitem('experimental', 'evolution.createmarkers',
519 coreconfigitem('experimental', 'evolution.createmarkers',
520 default=None,
520 default=None,
521 )
521 )
522 coreconfigitem('experimental', 'evolution.effect-flags',
522 coreconfigitem('experimental', 'evolution.effect-flags',
523 default=True,
523 default=True,
524 alias=[('experimental', 'effect-flags')]
524 alias=[('experimental', 'effect-flags')]
525 )
525 )
526 coreconfigitem('experimental', 'evolution.exchange',
526 coreconfigitem('experimental', 'evolution.exchange',
527 default=None,
527 default=None,
528 )
528 )
529 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
529 coreconfigitem('experimental', 'evolution.bundle-obsmarker',
530 default=False,
530 default=False,
531 )
531 )
532 coreconfigitem('experimental', 'log.topo',
532 coreconfigitem('experimental', 'log.topo',
533 default=False,
533 default=False,
534 )
534 )
535 coreconfigitem('experimental', 'evolution.report-instabilities',
535 coreconfigitem('experimental', 'evolution.report-instabilities',
536 default=True,
536 default=True,
537 )
537 )
538 coreconfigitem('experimental', 'evolution.track-operation',
538 coreconfigitem('experimental', 'evolution.track-operation',
539 default=True,
539 default=True,
540 )
540 )
541 # repo-level config to exclude a revset visibility
541 # repo-level config to exclude a revset visibility
542 #
542 #
543 # The target use case is to use `share` to expose different subset of the same
543 # The target use case is to use `share` to expose different subset of the same
544 # repository, especially server side. See also `server.view`.
544 # repository, especially server side. See also `server.view`.
545 coreconfigitem('experimental', 'extra-filter-revs',
545 coreconfigitem('experimental', 'extra-filter-revs',
546 default=None,
546 default=None,
547 )
547 )
548 coreconfigitem('experimental', 'maxdeltachainspan',
548 coreconfigitem('experimental', 'maxdeltachainspan',
549 default=-1,
549 default=-1,
550 )
550 )
551 coreconfigitem('experimental', 'mergetempdirprefix',
551 coreconfigitem('experimental', 'mergetempdirprefix',
552 default=None,
552 default=None,
553 )
553 )
554 coreconfigitem('experimental', 'mmapindexthreshold',
554 coreconfigitem('experimental', 'mmapindexthreshold',
555 default=None,
555 default=None,
556 )
556 )
557 coreconfigitem('experimental', 'narrow',
557 coreconfigitem('experimental', 'narrow',
558 default=False,
558 default=False,
559 )
559 )
560 coreconfigitem('experimental', 'nonnormalparanoidcheck',
560 coreconfigitem('experimental', 'nonnormalparanoidcheck',
561 default=False,
561 default=False,
562 )
562 )
563 coreconfigitem('experimental', 'exportableenviron',
563 coreconfigitem('experimental', 'exportableenviron',
564 default=list,
564 default=list,
565 )
565 )
566 coreconfigitem('experimental', 'extendedheader.index',
566 coreconfigitem('experimental', 'extendedheader.index',
567 default=None,
567 default=None,
568 )
568 )
569 coreconfigitem('experimental', 'extendedheader.similarity',
569 coreconfigitem('experimental', 'extendedheader.similarity',
570 default=False,
570 default=False,
571 )
571 )
572 coreconfigitem('experimental', 'graphshorten',
572 coreconfigitem('experimental', 'graphshorten',
573 default=False,
573 default=False,
574 )
574 )
575 coreconfigitem('experimental', 'graphstyle.parent',
575 coreconfigitem('experimental', 'graphstyle.parent',
576 default=dynamicdefault,
576 default=dynamicdefault,
577 )
577 )
578 coreconfigitem('experimental', 'graphstyle.missing',
578 coreconfigitem('experimental', 'graphstyle.missing',
579 default=dynamicdefault,
579 default=dynamicdefault,
580 )
580 )
581 coreconfigitem('experimental', 'graphstyle.grandparent',
581 coreconfigitem('experimental', 'graphstyle.grandparent',
582 default=dynamicdefault,
582 default=dynamicdefault,
583 )
583 )
584 coreconfigitem('experimental', 'hook-track-tags',
584 coreconfigitem('experimental', 'hook-track-tags',
585 default=False,
585 default=False,
586 )
586 )
587 coreconfigitem('experimental', 'httppeer.advertise-v2',
587 coreconfigitem('experimental', 'httppeer.advertise-v2',
588 default=False,
588 default=False,
589 )
589 )
590 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
590 coreconfigitem('experimental', 'httppeer.v2-encoder-order',
591 default=None,
591 default=None,
592 )
592 )
593 coreconfigitem('experimental', 'httppostargs',
593 coreconfigitem('experimental', 'httppostargs',
594 default=False,
594 default=False,
595 )
595 )
596 coreconfigitem('experimental', 'mergedriver',
596 coreconfigitem('experimental', 'mergedriver',
597 default=None,
597 default=None,
598 )
598 )
599 coreconfigitem('experimental', 'nointerrupt', default=False)
599 coreconfigitem('experimental', 'nointerrupt', default=False)
600 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
600 coreconfigitem('experimental', 'nointerrupt-interactiveonly', default=True)
601
601
602 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
602 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
603 default=False,
603 default=False,
604 )
604 )
605 coreconfigitem('experimental', 'remotenames',
605 coreconfigitem('experimental', 'remotenames',
606 default=False,
606 default=False,
607 )
607 )
608 coreconfigitem('experimental', 'removeemptydirs',
608 coreconfigitem('experimental', 'removeemptydirs',
609 default=True,
609 default=True,
610 )
610 )
611 coreconfigitem('experimental', 'revert.interactive.select-to-keep',
611 coreconfigitem('experimental', 'revert.interactive.select-to-keep',
612 default=False,
612 default=False,
613 )
613 )
614 coreconfigitem('experimental', 'revisions.prefixhexnode',
614 coreconfigitem('experimental', 'revisions.prefixhexnode',
615 default=False,
615 default=False,
616 )
616 )
617 coreconfigitem('experimental', 'revlogv2',
617 coreconfigitem('experimental', 'revlogv2',
618 default=None,
618 default=None,
619 )
619 )
620 coreconfigitem('experimental', 'revisions.disambiguatewithin',
620 coreconfigitem('experimental', 'revisions.disambiguatewithin',
621 default=None,
621 default=None,
622 )
622 )
623 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
623 coreconfigitem('experimental', 'server.filesdata.recommended-batch-size',
624 default=50000,
624 default=50000,
625 )
625 )
626 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
626 coreconfigitem('experimental', 'server.manifestdata.recommended-batch-size',
627 default=100000,
627 default=100000,
628 )
628 )
629 coreconfigitem('experimental', 'server.stream-narrow-clones',
629 coreconfigitem('experimental', 'server.stream-narrow-clones',
630 default=False,
630 default=False,
631 )
631 )
632 coreconfigitem('experimental', 'single-head-per-branch',
632 coreconfigitem('experimental', 'single-head-per-branch',
633 default=False,
633 default=False,
634 )
634 )
635 coreconfigitem('experimental', 'sshserver.support-v2',
635 coreconfigitem('experimental', 'sshserver.support-v2',
636 default=False,
636 default=False,
637 )
637 )
638 coreconfigitem('experimental', 'sparse-read',
638 coreconfigitem('experimental', 'sparse-read',
639 default=False,
639 default=False,
640 )
640 )
641 coreconfigitem('experimental', 'sparse-read.density-threshold',
641 coreconfigitem('experimental', 'sparse-read.density-threshold',
642 default=0.50,
642 default=0.50,
643 )
643 )
644 coreconfigitem('experimental', 'sparse-read.min-gap-size',
644 coreconfigitem('experimental', 'sparse-read.min-gap-size',
645 default='65K',
645 default='65K',
646 )
646 )
647 coreconfigitem('experimental', 'treemanifest',
647 coreconfigitem('experimental', 'treemanifest',
648 default=False,
648 default=False,
649 )
649 )
650 coreconfigitem('experimental', 'update.atomic-file',
650 coreconfigitem('experimental', 'update.atomic-file',
651 default=False,
651 default=False,
652 )
652 )
653 coreconfigitem('experimental', 'sshpeer.advertise-v2',
653 coreconfigitem('experimental', 'sshpeer.advertise-v2',
654 default=False,
654 default=False,
655 )
655 )
656 coreconfigitem('experimental', 'web.apiserver',
656 coreconfigitem('experimental', 'web.apiserver',
657 default=False,
657 default=False,
658 )
658 )
659 coreconfigitem('experimental', 'web.api.http-v2',
659 coreconfigitem('experimental', 'web.api.http-v2',
660 default=False,
660 default=False,
661 )
661 )
662 coreconfigitem('experimental', 'web.api.debugreflect',
662 coreconfigitem('experimental', 'web.api.debugreflect',
663 default=False,
663 default=False,
664 )
664 )
665 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
665 coreconfigitem('experimental', 'worker.wdir-get-thread-safe',
666 default=False,
666 default=False,
667 )
667 )
668 coreconfigitem('experimental', 'xdiff',
668 coreconfigitem('experimental', 'xdiff',
669 default=False,
669 default=False,
670 )
670 )
671 coreconfigitem('extensions', '.*',
671 coreconfigitem('extensions', '.*',
672 default=None,
672 default=None,
673 generic=True,
673 generic=True,
674 )
674 )
675 coreconfigitem('extdata', '.*',
675 coreconfigitem('extdata', '.*',
676 default=None,
676 default=None,
677 generic=True,
677 generic=True,
678 )
678 )
679 coreconfigitem('format', 'bookmarks-in-store',
680 default=False,
681 )
679 coreconfigitem('format', 'chunkcachesize',
682 coreconfigitem('format', 'chunkcachesize',
680 default=None,
683 default=None,
681 )
684 )
682 coreconfigitem('format', 'dotencode',
685 coreconfigitem('format', 'dotencode',
683 default=True,
686 default=True,
684 )
687 )
685 coreconfigitem('format', 'generaldelta',
688 coreconfigitem('format', 'generaldelta',
686 default=False,
689 default=False,
687 )
690 )
688 coreconfigitem('format', 'manifestcachesize',
691 coreconfigitem('format', 'manifestcachesize',
689 default=None,
692 default=None,
690 )
693 )
691 coreconfigitem('format', 'maxchainlen',
694 coreconfigitem('format', 'maxchainlen',
692 default=dynamicdefault,
695 default=dynamicdefault,
693 )
696 )
694 coreconfigitem('format', 'obsstore-version',
697 coreconfigitem('format', 'obsstore-version',
695 default=None,
698 default=None,
696 )
699 )
697 coreconfigitem('format', 'sparse-revlog',
700 coreconfigitem('format', 'sparse-revlog',
698 default=True,
701 default=True,
699 )
702 )
700 coreconfigitem('format', 'revlog-compression',
703 coreconfigitem('format', 'revlog-compression',
701 default='zlib',
704 default='zlib',
702 alias=[('experimental', 'format.compression')]
705 alias=[('experimental', 'format.compression')]
703 )
706 )
704 coreconfigitem('format', 'usefncache',
707 coreconfigitem('format', 'usefncache',
705 default=True,
708 default=True,
706 )
709 )
707 coreconfigitem('format', 'usegeneraldelta',
710 coreconfigitem('format', 'usegeneraldelta',
708 default=True,
711 default=True,
709 )
712 )
710 coreconfigitem('format', 'usestore',
713 coreconfigitem('format', 'usestore',
711 default=True,
714 default=True,
712 )
715 )
713 coreconfigitem('format', 'internal-phase',
716 coreconfigitem('format', 'internal-phase',
714 default=False,
717 default=False,
715 )
718 )
716 coreconfigitem('fsmonitor', 'warn_when_unused',
719 coreconfigitem('fsmonitor', 'warn_when_unused',
717 default=True,
720 default=True,
718 )
721 )
719 coreconfigitem('fsmonitor', 'warn_update_file_count',
722 coreconfigitem('fsmonitor', 'warn_update_file_count',
720 default=50000,
723 default=50000,
721 )
724 )
722 coreconfigitem('help', br'hidden-command\..*',
725 coreconfigitem('help', br'hidden-command\..*',
723 default=False,
726 default=False,
724 generic=True,
727 generic=True,
725 )
728 )
726 coreconfigitem('help', br'hidden-topic\..*',
729 coreconfigitem('help', br'hidden-topic\..*',
727 default=False,
730 default=False,
728 generic=True,
731 generic=True,
729 )
732 )
730 coreconfigitem('hooks', '.*',
733 coreconfigitem('hooks', '.*',
731 default=dynamicdefault,
734 default=dynamicdefault,
732 generic=True,
735 generic=True,
733 )
736 )
734 coreconfigitem('hgweb-paths', '.*',
737 coreconfigitem('hgweb-paths', '.*',
735 default=list,
738 default=list,
736 generic=True,
739 generic=True,
737 )
740 )
738 coreconfigitem('hostfingerprints', '.*',
741 coreconfigitem('hostfingerprints', '.*',
739 default=list,
742 default=list,
740 generic=True,
743 generic=True,
741 )
744 )
742 coreconfigitem('hostsecurity', 'ciphers',
745 coreconfigitem('hostsecurity', 'ciphers',
743 default=None,
746 default=None,
744 )
747 )
745 coreconfigitem('hostsecurity', 'disabletls10warning',
748 coreconfigitem('hostsecurity', 'disabletls10warning',
746 default=False,
749 default=False,
747 )
750 )
748 coreconfigitem('hostsecurity', 'minimumprotocol',
751 coreconfigitem('hostsecurity', 'minimumprotocol',
749 default=dynamicdefault,
752 default=dynamicdefault,
750 )
753 )
751 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
754 coreconfigitem('hostsecurity', '.*:minimumprotocol$',
752 default=dynamicdefault,
755 default=dynamicdefault,
753 generic=True,
756 generic=True,
754 )
757 )
755 coreconfigitem('hostsecurity', '.*:ciphers$',
758 coreconfigitem('hostsecurity', '.*:ciphers$',
756 default=dynamicdefault,
759 default=dynamicdefault,
757 generic=True,
760 generic=True,
758 )
761 )
759 coreconfigitem('hostsecurity', '.*:fingerprints$',
762 coreconfigitem('hostsecurity', '.*:fingerprints$',
760 default=list,
763 default=list,
761 generic=True,
764 generic=True,
762 )
765 )
763 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
766 coreconfigitem('hostsecurity', '.*:verifycertsfile$',
764 default=None,
767 default=None,
765 generic=True,
768 generic=True,
766 )
769 )
767
770
768 coreconfigitem('http_proxy', 'always',
771 coreconfigitem('http_proxy', 'always',
769 default=False,
772 default=False,
770 )
773 )
771 coreconfigitem('http_proxy', 'host',
774 coreconfigitem('http_proxy', 'host',
772 default=None,
775 default=None,
773 )
776 )
774 coreconfigitem('http_proxy', 'no',
777 coreconfigitem('http_proxy', 'no',
775 default=list,
778 default=list,
776 )
779 )
777 coreconfigitem('http_proxy', 'passwd',
780 coreconfigitem('http_proxy', 'passwd',
778 default=None,
781 default=None,
779 )
782 )
780 coreconfigitem('http_proxy', 'user',
783 coreconfigitem('http_proxy', 'user',
781 default=None,
784 default=None,
782 )
785 )
783
786
784 coreconfigitem('http', 'timeout',
787 coreconfigitem('http', 'timeout',
785 default=None,
788 default=None,
786 )
789 )
787
790
788 coreconfigitem('logtoprocess', 'commandexception',
791 coreconfigitem('logtoprocess', 'commandexception',
789 default=None,
792 default=None,
790 )
793 )
791 coreconfigitem('logtoprocess', 'commandfinish',
794 coreconfigitem('logtoprocess', 'commandfinish',
792 default=None,
795 default=None,
793 )
796 )
794 coreconfigitem('logtoprocess', 'command',
797 coreconfigitem('logtoprocess', 'command',
795 default=None,
798 default=None,
796 )
799 )
797 coreconfigitem('logtoprocess', 'develwarn',
800 coreconfigitem('logtoprocess', 'develwarn',
798 default=None,
801 default=None,
799 )
802 )
800 coreconfigitem('logtoprocess', 'uiblocked',
803 coreconfigitem('logtoprocess', 'uiblocked',
801 default=None,
804 default=None,
802 )
805 )
803 coreconfigitem('merge', 'checkunknown',
806 coreconfigitem('merge', 'checkunknown',
804 default='abort',
807 default='abort',
805 )
808 )
806 coreconfigitem('merge', 'checkignored',
809 coreconfigitem('merge', 'checkignored',
807 default='abort',
810 default='abort',
808 )
811 )
809 coreconfigitem('experimental', 'merge.checkpathconflicts',
812 coreconfigitem('experimental', 'merge.checkpathconflicts',
810 default=False,
813 default=False,
811 )
814 )
812 coreconfigitem('merge', 'followcopies',
815 coreconfigitem('merge', 'followcopies',
813 default=True,
816 default=True,
814 )
817 )
815 coreconfigitem('merge', 'on-failure',
818 coreconfigitem('merge', 'on-failure',
816 default='continue',
819 default='continue',
817 )
820 )
818 coreconfigitem('merge', 'preferancestor',
821 coreconfigitem('merge', 'preferancestor',
819 default=lambda: ['*'],
822 default=lambda: ['*'],
820 )
823 )
821 coreconfigitem('merge', 'strict-capability-check',
824 coreconfigitem('merge', 'strict-capability-check',
822 default=False,
825 default=False,
823 )
826 )
824 coreconfigitem('merge-tools', '.*',
827 coreconfigitem('merge-tools', '.*',
825 default=None,
828 default=None,
826 generic=True,
829 generic=True,
827 )
830 )
828 coreconfigitem('merge-tools', br'.*\.args$',
831 coreconfigitem('merge-tools', br'.*\.args$',
829 default="$local $base $other",
832 default="$local $base $other",
830 generic=True,
833 generic=True,
831 priority=-1,
834 priority=-1,
832 )
835 )
833 coreconfigitem('merge-tools', br'.*\.binary$',
836 coreconfigitem('merge-tools', br'.*\.binary$',
834 default=False,
837 default=False,
835 generic=True,
838 generic=True,
836 priority=-1,
839 priority=-1,
837 )
840 )
838 coreconfigitem('merge-tools', br'.*\.check$',
841 coreconfigitem('merge-tools', br'.*\.check$',
839 default=list,
842 default=list,
840 generic=True,
843 generic=True,
841 priority=-1,
844 priority=-1,
842 )
845 )
843 coreconfigitem('merge-tools', br'.*\.checkchanged$',
846 coreconfigitem('merge-tools', br'.*\.checkchanged$',
844 default=False,
847 default=False,
845 generic=True,
848 generic=True,
846 priority=-1,
849 priority=-1,
847 )
850 )
848 coreconfigitem('merge-tools', br'.*\.executable$',
851 coreconfigitem('merge-tools', br'.*\.executable$',
849 default=dynamicdefault,
852 default=dynamicdefault,
850 generic=True,
853 generic=True,
851 priority=-1,
854 priority=-1,
852 )
855 )
853 coreconfigitem('merge-tools', br'.*\.fixeol$',
856 coreconfigitem('merge-tools', br'.*\.fixeol$',
854 default=False,
857 default=False,
855 generic=True,
858 generic=True,
856 priority=-1,
859 priority=-1,
857 )
860 )
858 coreconfigitem('merge-tools', br'.*\.gui$',
861 coreconfigitem('merge-tools', br'.*\.gui$',
859 default=False,
862 default=False,
860 generic=True,
863 generic=True,
861 priority=-1,
864 priority=-1,
862 )
865 )
863 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
866 coreconfigitem('merge-tools', br'.*\.mergemarkers$',
864 default='basic',
867 default='basic',
865 generic=True,
868 generic=True,
866 priority=-1,
869 priority=-1,
867 )
870 )
868 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
871 coreconfigitem('merge-tools', br'.*\.mergemarkertemplate$',
869 default=dynamicdefault, # take from ui.mergemarkertemplate
872 default=dynamicdefault, # take from ui.mergemarkertemplate
870 generic=True,
873 generic=True,
871 priority=-1,
874 priority=-1,
872 )
875 )
873 coreconfigitem('merge-tools', br'.*\.priority$',
876 coreconfigitem('merge-tools', br'.*\.priority$',
874 default=0,
877 default=0,
875 generic=True,
878 generic=True,
876 priority=-1,
879 priority=-1,
877 )
880 )
878 coreconfigitem('merge-tools', br'.*\.premerge$',
881 coreconfigitem('merge-tools', br'.*\.premerge$',
879 default=dynamicdefault,
882 default=dynamicdefault,
880 generic=True,
883 generic=True,
881 priority=-1,
884 priority=-1,
882 )
885 )
883 coreconfigitem('merge-tools', br'.*\.symlink$',
886 coreconfigitem('merge-tools', br'.*\.symlink$',
884 default=False,
887 default=False,
885 generic=True,
888 generic=True,
886 priority=-1,
889 priority=-1,
887 )
890 )
888 coreconfigitem('pager', 'attend-.*',
891 coreconfigitem('pager', 'attend-.*',
889 default=dynamicdefault,
892 default=dynamicdefault,
890 generic=True,
893 generic=True,
891 )
894 )
892 coreconfigitem('pager', 'ignore',
895 coreconfigitem('pager', 'ignore',
893 default=list,
896 default=list,
894 )
897 )
895 coreconfigitem('pager', 'pager',
898 coreconfigitem('pager', 'pager',
896 default=dynamicdefault,
899 default=dynamicdefault,
897 )
900 )
898 coreconfigitem('patch', 'eol',
901 coreconfigitem('patch', 'eol',
899 default='strict',
902 default='strict',
900 )
903 )
901 coreconfigitem('patch', 'fuzz',
904 coreconfigitem('patch', 'fuzz',
902 default=2,
905 default=2,
903 )
906 )
904 coreconfigitem('paths', 'default',
907 coreconfigitem('paths', 'default',
905 default=None,
908 default=None,
906 )
909 )
907 coreconfigitem('paths', 'default-push',
910 coreconfigitem('paths', 'default-push',
908 default=None,
911 default=None,
909 )
912 )
910 coreconfigitem('paths', '.*',
913 coreconfigitem('paths', '.*',
911 default=None,
914 default=None,
912 generic=True,
915 generic=True,
913 )
916 )
914 coreconfigitem('phases', 'checksubrepos',
917 coreconfigitem('phases', 'checksubrepos',
915 default='follow',
918 default='follow',
916 )
919 )
917 coreconfigitem('phases', 'new-commit',
920 coreconfigitem('phases', 'new-commit',
918 default='draft',
921 default='draft',
919 )
922 )
920 coreconfigitem('phases', 'publish',
923 coreconfigitem('phases', 'publish',
921 default=True,
924 default=True,
922 )
925 )
923 coreconfigitem('profiling', 'enabled',
926 coreconfigitem('profiling', 'enabled',
924 default=False,
927 default=False,
925 )
928 )
926 coreconfigitem('profiling', 'format',
929 coreconfigitem('profiling', 'format',
927 default='text',
930 default='text',
928 )
931 )
929 coreconfigitem('profiling', 'freq',
932 coreconfigitem('profiling', 'freq',
930 default=1000,
933 default=1000,
931 )
934 )
932 coreconfigitem('profiling', 'limit',
935 coreconfigitem('profiling', 'limit',
933 default=30,
936 default=30,
934 )
937 )
935 coreconfigitem('profiling', 'nested',
938 coreconfigitem('profiling', 'nested',
936 default=0,
939 default=0,
937 )
940 )
938 coreconfigitem('profiling', 'output',
941 coreconfigitem('profiling', 'output',
939 default=None,
942 default=None,
940 )
943 )
941 coreconfigitem('profiling', 'showmax',
944 coreconfigitem('profiling', 'showmax',
942 default=0.999,
945 default=0.999,
943 )
946 )
944 coreconfigitem('profiling', 'showmin',
947 coreconfigitem('profiling', 'showmin',
945 default=dynamicdefault,
948 default=dynamicdefault,
946 )
949 )
947 coreconfigitem('profiling', 'sort',
950 coreconfigitem('profiling', 'sort',
948 default='inlinetime',
951 default='inlinetime',
949 )
952 )
950 coreconfigitem('profiling', 'statformat',
953 coreconfigitem('profiling', 'statformat',
951 default='hotpath',
954 default='hotpath',
952 )
955 )
953 coreconfigitem('profiling', 'time-track',
956 coreconfigitem('profiling', 'time-track',
954 default=dynamicdefault,
957 default=dynamicdefault,
955 )
958 )
956 coreconfigitem('profiling', 'type',
959 coreconfigitem('profiling', 'type',
957 default='stat',
960 default='stat',
958 )
961 )
959 coreconfigitem('progress', 'assume-tty',
962 coreconfigitem('progress', 'assume-tty',
960 default=False,
963 default=False,
961 )
964 )
962 coreconfigitem('progress', 'changedelay',
965 coreconfigitem('progress', 'changedelay',
963 default=1,
966 default=1,
964 )
967 )
965 coreconfigitem('progress', 'clear-complete',
968 coreconfigitem('progress', 'clear-complete',
966 default=True,
969 default=True,
967 )
970 )
968 coreconfigitem('progress', 'debug',
971 coreconfigitem('progress', 'debug',
969 default=False,
972 default=False,
970 )
973 )
971 coreconfigitem('progress', 'delay',
974 coreconfigitem('progress', 'delay',
972 default=3,
975 default=3,
973 )
976 )
974 coreconfigitem('progress', 'disable',
977 coreconfigitem('progress', 'disable',
975 default=False,
978 default=False,
976 )
979 )
977 coreconfigitem('progress', 'estimateinterval',
980 coreconfigitem('progress', 'estimateinterval',
978 default=60.0,
981 default=60.0,
979 )
982 )
980 coreconfigitem('progress', 'format',
983 coreconfigitem('progress', 'format',
981 default=lambda: ['topic', 'bar', 'number', 'estimate'],
984 default=lambda: ['topic', 'bar', 'number', 'estimate'],
982 )
985 )
983 coreconfigitem('progress', 'refresh',
986 coreconfigitem('progress', 'refresh',
984 default=0.1,
987 default=0.1,
985 )
988 )
986 coreconfigitem('progress', 'width',
989 coreconfigitem('progress', 'width',
987 default=dynamicdefault,
990 default=dynamicdefault,
988 )
991 )
989 coreconfigitem('push', 'pushvars.server',
992 coreconfigitem('push', 'pushvars.server',
990 default=False,
993 default=False,
991 )
994 )
992 coreconfigitem('rewrite', 'backup-bundle',
995 coreconfigitem('rewrite', 'backup-bundle',
993 default=True,
996 default=True,
994 alias=[('ui', 'history-editing-backup')],
997 alias=[('ui', 'history-editing-backup')],
995 )
998 )
996 coreconfigitem('rewrite', 'update-timestamp',
999 coreconfigitem('rewrite', 'update-timestamp',
997 default=False,
1000 default=False,
998 )
1001 )
999 coreconfigitem('storage', 'new-repo-backend',
1002 coreconfigitem('storage', 'new-repo-backend',
1000 default='revlogv1',
1003 default='revlogv1',
1001 )
1004 )
1002 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
1005 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
1003 default=True,
1006 default=True,
1004 alias=[('format', 'aggressivemergedeltas')],
1007 alias=[('format', 'aggressivemergedeltas')],
1005 )
1008 )
1006 coreconfigitem('storage', 'revlog.reuse-external-delta',
1009 coreconfigitem('storage', 'revlog.reuse-external-delta',
1007 default=True,
1010 default=True,
1008 )
1011 )
1009 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
1012 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
1010 default=None,
1013 default=None,
1011 )
1014 )
1012 coreconfigitem('storage', 'revlog.zlib.level',
1015 coreconfigitem('storage', 'revlog.zlib.level',
1013 default=None,
1016 default=None,
1014 )
1017 )
1015 coreconfigitem('storage', 'revlog.zstd.level',
1018 coreconfigitem('storage', 'revlog.zstd.level',
1016 default=None,
1019 default=None,
1017 )
1020 )
1018 coreconfigitem('server', 'bookmarks-pushkey-compat',
1021 coreconfigitem('server', 'bookmarks-pushkey-compat',
1019 default=True,
1022 default=True,
1020 )
1023 )
1021 coreconfigitem('server', 'bundle1',
1024 coreconfigitem('server', 'bundle1',
1022 default=True,
1025 default=True,
1023 )
1026 )
1024 coreconfigitem('server', 'bundle1gd',
1027 coreconfigitem('server', 'bundle1gd',
1025 default=None,
1028 default=None,
1026 )
1029 )
1027 coreconfigitem('server', 'bundle1.pull',
1030 coreconfigitem('server', 'bundle1.pull',
1028 default=None,
1031 default=None,
1029 )
1032 )
1030 coreconfigitem('server', 'bundle1gd.pull',
1033 coreconfigitem('server', 'bundle1gd.pull',
1031 default=None,
1034 default=None,
1032 )
1035 )
1033 coreconfigitem('server', 'bundle1.push',
1036 coreconfigitem('server', 'bundle1.push',
1034 default=None,
1037 default=None,
1035 )
1038 )
1036 coreconfigitem('server', 'bundle1gd.push',
1039 coreconfigitem('server', 'bundle1gd.push',
1037 default=None,
1040 default=None,
1038 )
1041 )
1039 coreconfigitem('server', 'bundle2.stream',
1042 coreconfigitem('server', 'bundle2.stream',
1040 default=True,
1043 default=True,
1041 alias=[('experimental', 'bundle2.stream')]
1044 alias=[('experimental', 'bundle2.stream')]
1042 )
1045 )
1043 coreconfigitem('server', 'compressionengines',
1046 coreconfigitem('server', 'compressionengines',
1044 default=list,
1047 default=list,
1045 )
1048 )
1046 coreconfigitem('server', 'concurrent-push-mode',
1049 coreconfigitem('server', 'concurrent-push-mode',
1047 default='strict',
1050 default='strict',
1048 )
1051 )
1049 coreconfigitem('server', 'disablefullbundle',
1052 coreconfigitem('server', 'disablefullbundle',
1050 default=False,
1053 default=False,
1051 )
1054 )
1052 coreconfigitem('server', 'maxhttpheaderlen',
1055 coreconfigitem('server', 'maxhttpheaderlen',
1053 default=1024,
1056 default=1024,
1054 )
1057 )
1055 coreconfigitem('server', 'pullbundle',
1058 coreconfigitem('server', 'pullbundle',
1056 default=False,
1059 default=False,
1057 )
1060 )
1058 coreconfigitem('server', 'preferuncompressed',
1061 coreconfigitem('server', 'preferuncompressed',
1059 default=False,
1062 default=False,
1060 )
1063 )
1061 coreconfigitem('server', 'streamunbundle',
1064 coreconfigitem('server', 'streamunbundle',
1062 default=False,
1065 default=False,
1063 )
1066 )
1064 coreconfigitem('server', 'uncompressed',
1067 coreconfigitem('server', 'uncompressed',
1065 default=True,
1068 default=True,
1066 )
1069 )
1067 coreconfigitem('server', 'uncompressedallowsecret',
1070 coreconfigitem('server', 'uncompressedallowsecret',
1068 default=False,
1071 default=False,
1069 )
1072 )
1070 coreconfigitem('server', 'view',
1073 coreconfigitem('server', 'view',
1071 default='served',
1074 default='served',
1072 )
1075 )
1073 coreconfigitem('server', 'validate',
1076 coreconfigitem('server', 'validate',
1074 default=False,
1077 default=False,
1075 )
1078 )
1076 coreconfigitem('server', 'zliblevel',
1079 coreconfigitem('server', 'zliblevel',
1077 default=-1,
1080 default=-1,
1078 )
1081 )
1079 coreconfigitem('server', 'zstdlevel',
1082 coreconfigitem('server', 'zstdlevel',
1080 default=3,
1083 default=3,
1081 )
1084 )
1082 coreconfigitem('share', 'pool',
1085 coreconfigitem('share', 'pool',
1083 default=None,
1086 default=None,
1084 )
1087 )
1085 coreconfigitem('share', 'poolnaming',
1088 coreconfigitem('share', 'poolnaming',
1086 default='identity',
1089 default='identity',
1087 )
1090 )
1088 coreconfigitem('smtp', 'host',
1091 coreconfigitem('smtp', 'host',
1089 default=None,
1092 default=None,
1090 )
1093 )
1091 coreconfigitem('smtp', 'local_hostname',
1094 coreconfigitem('smtp', 'local_hostname',
1092 default=None,
1095 default=None,
1093 )
1096 )
1094 coreconfigitem('smtp', 'password',
1097 coreconfigitem('smtp', 'password',
1095 default=None,
1098 default=None,
1096 )
1099 )
1097 coreconfigitem('smtp', 'port',
1100 coreconfigitem('smtp', 'port',
1098 default=dynamicdefault,
1101 default=dynamicdefault,
1099 )
1102 )
1100 coreconfigitem('smtp', 'tls',
1103 coreconfigitem('smtp', 'tls',
1101 default='none',
1104 default='none',
1102 )
1105 )
1103 coreconfigitem('smtp', 'username',
1106 coreconfigitem('smtp', 'username',
1104 default=None,
1107 default=None,
1105 )
1108 )
1106 coreconfigitem('sparse', 'missingwarning',
1109 coreconfigitem('sparse', 'missingwarning',
1107 default=True,
1110 default=True,
1108 )
1111 )
1109 coreconfigitem('subrepos', 'allowed',
1112 coreconfigitem('subrepos', 'allowed',
1110 default=dynamicdefault, # to make backporting simpler
1113 default=dynamicdefault, # to make backporting simpler
1111 )
1114 )
1112 coreconfigitem('subrepos', 'hg:allowed',
1115 coreconfigitem('subrepos', 'hg:allowed',
1113 default=dynamicdefault,
1116 default=dynamicdefault,
1114 )
1117 )
1115 coreconfigitem('subrepos', 'git:allowed',
1118 coreconfigitem('subrepos', 'git:allowed',
1116 default=dynamicdefault,
1119 default=dynamicdefault,
1117 )
1120 )
1118 coreconfigitem('subrepos', 'svn:allowed',
1121 coreconfigitem('subrepos', 'svn:allowed',
1119 default=dynamicdefault,
1122 default=dynamicdefault,
1120 )
1123 )
1121 coreconfigitem('templates', '.*',
1124 coreconfigitem('templates', '.*',
1122 default=None,
1125 default=None,
1123 generic=True,
1126 generic=True,
1124 )
1127 )
1125 coreconfigitem('templateconfig', '.*',
1128 coreconfigitem('templateconfig', '.*',
1126 default=dynamicdefault,
1129 default=dynamicdefault,
1127 generic=True,
1130 generic=True,
1128 )
1131 )
1129 coreconfigitem('trusted', 'groups',
1132 coreconfigitem('trusted', 'groups',
1130 default=list,
1133 default=list,
1131 )
1134 )
1132 coreconfigitem('trusted', 'users',
1135 coreconfigitem('trusted', 'users',
1133 default=list,
1136 default=list,
1134 )
1137 )
1135 coreconfigitem('ui', '_usedassubrepo',
1138 coreconfigitem('ui', '_usedassubrepo',
1136 default=False,
1139 default=False,
1137 )
1140 )
1138 coreconfigitem('ui', 'allowemptycommit',
1141 coreconfigitem('ui', 'allowemptycommit',
1139 default=False,
1142 default=False,
1140 )
1143 )
1141 coreconfigitem('ui', 'archivemeta',
1144 coreconfigitem('ui', 'archivemeta',
1142 default=True,
1145 default=True,
1143 )
1146 )
1144 coreconfigitem('ui', 'askusername',
1147 coreconfigitem('ui', 'askusername',
1145 default=False,
1148 default=False,
1146 )
1149 )
1147 coreconfigitem('ui', 'clonebundlefallback',
1150 coreconfigitem('ui', 'clonebundlefallback',
1148 default=False,
1151 default=False,
1149 )
1152 )
1150 coreconfigitem('ui', 'clonebundleprefers',
1153 coreconfigitem('ui', 'clonebundleprefers',
1151 default=list,
1154 default=list,
1152 )
1155 )
1153 coreconfigitem('ui', 'clonebundles',
1156 coreconfigitem('ui', 'clonebundles',
1154 default=True,
1157 default=True,
1155 )
1158 )
1156 coreconfigitem('ui', 'color',
1159 coreconfigitem('ui', 'color',
1157 default='auto',
1160 default='auto',
1158 )
1161 )
1159 coreconfigitem('ui', 'commitsubrepos',
1162 coreconfigitem('ui', 'commitsubrepos',
1160 default=False,
1163 default=False,
1161 )
1164 )
1162 coreconfigitem('ui', 'debug',
1165 coreconfigitem('ui', 'debug',
1163 default=False,
1166 default=False,
1164 )
1167 )
1165 coreconfigitem('ui', 'debugger',
1168 coreconfigitem('ui', 'debugger',
1166 default=None,
1169 default=None,
1167 )
1170 )
1168 coreconfigitem('ui', 'editor',
1171 coreconfigitem('ui', 'editor',
1169 default=dynamicdefault,
1172 default=dynamicdefault,
1170 )
1173 )
1171 coreconfigitem('ui', 'fallbackencoding',
1174 coreconfigitem('ui', 'fallbackencoding',
1172 default=None,
1175 default=None,
1173 )
1176 )
1174 coreconfigitem('ui', 'forcecwd',
1177 coreconfigitem('ui', 'forcecwd',
1175 default=None,
1178 default=None,
1176 )
1179 )
1177 coreconfigitem('ui', 'forcemerge',
1180 coreconfigitem('ui', 'forcemerge',
1178 default=None,
1181 default=None,
1179 )
1182 )
1180 coreconfigitem('ui', 'formatdebug',
1183 coreconfigitem('ui', 'formatdebug',
1181 default=False,
1184 default=False,
1182 )
1185 )
1183 coreconfigitem('ui', 'formatjson',
1186 coreconfigitem('ui', 'formatjson',
1184 default=False,
1187 default=False,
1185 )
1188 )
1186 coreconfigitem('ui', 'formatted',
1189 coreconfigitem('ui', 'formatted',
1187 default=None,
1190 default=None,
1188 )
1191 )
1189 coreconfigitem('ui', 'graphnodetemplate',
1192 coreconfigitem('ui', 'graphnodetemplate',
1190 default=None,
1193 default=None,
1191 )
1194 )
1192 coreconfigitem('ui', 'interactive',
1195 coreconfigitem('ui', 'interactive',
1193 default=None,
1196 default=None,
1194 )
1197 )
1195 coreconfigitem('ui', 'interface',
1198 coreconfigitem('ui', 'interface',
1196 default=None,
1199 default=None,
1197 )
1200 )
1198 coreconfigitem('ui', 'interface.chunkselector',
1201 coreconfigitem('ui', 'interface.chunkselector',
1199 default=None,
1202 default=None,
1200 )
1203 )
1201 coreconfigitem('ui', 'large-file-limit',
1204 coreconfigitem('ui', 'large-file-limit',
1202 default=10000000,
1205 default=10000000,
1203 )
1206 )
1204 coreconfigitem('ui', 'logblockedtimes',
1207 coreconfigitem('ui', 'logblockedtimes',
1205 default=False,
1208 default=False,
1206 )
1209 )
1207 coreconfigitem('ui', 'logtemplate',
1210 coreconfigitem('ui', 'logtemplate',
1208 default=None,
1211 default=None,
1209 )
1212 )
1210 coreconfigitem('ui', 'merge',
1213 coreconfigitem('ui', 'merge',
1211 default=None,
1214 default=None,
1212 )
1215 )
1213 coreconfigitem('ui', 'mergemarkers',
1216 coreconfigitem('ui', 'mergemarkers',
1214 default='basic',
1217 default='basic',
1215 )
1218 )
1216 coreconfigitem('ui', 'mergemarkertemplate',
1219 coreconfigitem('ui', 'mergemarkertemplate',
1217 default=('{node|short} '
1220 default=('{node|short} '
1218 '{ifeq(tags, "tip", "", '
1221 '{ifeq(tags, "tip", "", '
1219 'ifeq(tags, "", "", "{tags} "))}'
1222 'ifeq(tags, "", "", "{tags} "))}'
1220 '{if(bookmarks, "{bookmarks} ")}'
1223 '{if(bookmarks, "{bookmarks} ")}'
1221 '{ifeq(branch, "default", "", "{branch} ")}'
1224 '{ifeq(branch, "default", "", "{branch} ")}'
1222 '- {author|user}: {desc|firstline}')
1225 '- {author|user}: {desc|firstline}')
1223 )
1226 )
1224 coreconfigitem('ui', 'message-output',
1227 coreconfigitem('ui', 'message-output',
1225 default='stdio',
1228 default='stdio',
1226 )
1229 )
1227 coreconfigitem('ui', 'nontty',
1230 coreconfigitem('ui', 'nontty',
1228 default=False,
1231 default=False,
1229 )
1232 )
1230 coreconfigitem('ui', 'origbackuppath',
1233 coreconfigitem('ui', 'origbackuppath',
1231 default=None,
1234 default=None,
1232 )
1235 )
1233 coreconfigitem('ui', 'paginate',
1236 coreconfigitem('ui', 'paginate',
1234 default=True,
1237 default=True,
1235 )
1238 )
1236 coreconfigitem('ui', 'patch',
1239 coreconfigitem('ui', 'patch',
1237 default=None,
1240 default=None,
1238 )
1241 )
1239 coreconfigitem('ui', 'pre-merge-tool-output-template',
1242 coreconfigitem('ui', 'pre-merge-tool-output-template',
1240 default=None,
1243 default=None,
1241 )
1244 )
1242 coreconfigitem('ui', 'portablefilenames',
1245 coreconfigitem('ui', 'portablefilenames',
1243 default='warn',
1246 default='warn',
1244 )
1247 )
1245 coreconfigitem('ui', 'promptecho',
1248 coreconfigitem('ui', 'promptecho',
1246 default=False,
1249 default=False,
1247 )
1250 )
1248 coreconfigitem('ui', 'quiet',
1251 coreconfigitem('ui', 'quiet',
1249 default=False,
1252 default=False,
1250 )
1253 )
1251 coreconfigitem('ui', 'quietbookmarkmove',
1254 coreconfigitem('ui', 'quietbookmarkmove',
1252 default=False,
1255 default=False,
1253 )
1256 )
1254 coreconfigitem('ui', 'relative-paths',
1257 coreconfigitem('ui', 'relative-paths',
1255 default='legacy',
1258 default='legacy',
1256 )
1259 )
1257 coreconfigitem('ui', 'remotecmd',
1260 coreconfigitem('ui', 'remotecmd',
1258 default='hg',
1261 default='hg',
1259 )
1262 )
1260 coreconfigitem('ui', 'report_untrusted',
1263 coreconfigitem('ui', 'report_untrusted',
1261 default=True,
1264 default=True,
1262 )
1265 )
1263 coreconfigitem('ui', 'rollback',
1266 coreconfigitem('ui', 'rollback',
1264 default=True,
1267 default=True,
1265 )
1268 )
1266 coreconfigitem('ui', 'signal-safe-lock',
1269 coreconfigitem('ui', 'signal-safe-lock',
1267 default=True,
1270 default=True,
1268 )
1271 )
1269 coreconfigitem('ui', 'slash',
1272 coreconfigitem('ui', 'slash',
1270 default=False,
1273 default=False,
1271 )
1274 )
1272 coreconfigitem('ui', 'ssh',
1275 coreconfigitem('ui', 'ssh',
1273 default='ssh',
1276 default='ssh',
1274 )
1277 )
1275 coreconfigitem('ui', 'ssherrorhint',
1278 coreconfigitem('ui', 'ssherrorhint',
1276 default=None,
1279 default=None,
1277 )
1280 )
1278 coreconfigitem('ui', 'statuscopies',
1281 coreconfigitem('ui', 'statuscopies',
1279 default=False,
1282 default=False,
1280 )
1283 )
1281 coreconfigitem('ui', 'strict',
1284 coreconfigitem('ui', 'strict',
1282 default=False,
1285 default=False,
1283 )
1286 )
1284 coreconfigitem('ui', 'style',
1287 coreconfigitem('ui', 'style',
1285 default='',
1288 default='',
1286 )
1289 )
1287 coreconfigitem('ui', 'supportcontact',
1290 coreconfigitem('ui', 'supportcontact',
1288 default=None,
1291 default=None,
1289 )
1292 )
1290 coreconfigitem('ui', 'textwidth',
1293 coreconfigitem('ui', 'textwidth',
1291 default=78,
1294 default=78,
1292 )
1295 )
1293 coreconfigitem('ui', 'timeout',
1296 coreconfigitem('ui', 'timeout',
1294 default='600',
1297 default='600',
1295 )
1298 )
1296 coreconfigitem('ui', 'timeout.warn',
1299 coreconfigitem('ui', 'timeout.warn',
1297 default=0,
1300 default=0,
1298 )
1301 )
1299 coreconfigitem('ui', 'traceback',
1302 coreconfigitem('ui', 'traceback',
1300 default=False,
1303 default=False,
1301 )
1304 )
1302 coreconfigitem('ui', 'tweakdefaults',
1305 coreconfigitem('ui', 'tweakdefaults',
1303 default=False,
1306 default=False,
1304 )
1307 )
1305 coreconfigitem('ui', 'username',
1308 coreconfigitem('ui', 'username',
1306 alias=[('ui', 'user')]
1309 alias=[('ui', 'user')]
1307 )
1310 )
1308 coreconfigitem('ui', 'verbose',
1311 coreconfigitem('ui', 'verbose',
1309 default=False,
1312 default=False,
1310 )
1313 )
1311 coreconfigitem('verify', 'skipflags',
1314 coreconfigitem('verify', 'skipflags',
1312 default=None,
1315 default=None,
1313 )
1316 )
1314 coreconfigitem('web', 'allowbz2',
1317 coreconfigitem('web', 'allowbz2',
1315 default=False,
1318 default=False,
1316 )
1319 )
1317 coreconfigitem('web', 'allowgz',
1320 coreconfigitem('web', 'allowgz',
1318 default=False,
1321 default=False,
1319 )
1322 )
1320 coreconfigitem('web', 'allow-pull',
1323 coreconfigitem('web', 'allow-pull',
1321 alias=[('web', 'allowpull')],
1324 alias=[('web', 'allowpull')],
1322 default=True,
1325 default=True,
1323 )
1326 )
1324 coreconfigitem('web', 'allow-push',
1327 coreconfigitem('web', 'allow-push',
1325 alias=[('web', 'allow_push')],
1328 alias=[('web', 'allow_push')],
1326 default=list,
1329 default=list,
1327 )
1330 )
1328 coreconfigitem('web', 'allowzip',
1331 coreconfigitem('web', 'allowzip',
1329 default=False,
1332 default=False,
1330 )
1333 )
1331 coreconfigitem('web', 'archivesubrepos',
1334 coreconfigitem('web', 'archivesubrepos',
1332 default=False,
1335 default=False,
1333 )
1336 )
1334 coreconfigitem('web', 'cache',
1337 coreconfigitem('web', 'cache',
1335 default=True,
1338 default=True,
1336 )
1339 )
1337 coreconfigitem('web', 'comparisoncontext',
1340 coreconfigitem('web', 'comparisoncontext',
1338 default=5,
1341 default=5,
1339 )
1342 )
1340 coreconfigitem('web', 'contact',
1343 coreconfigitem('web', 'contact',
1341 default=None,
1344 default=None,
1342 )
1345 )
1343 coreconfigitem('web', 'deny_push',
1346 coreconfigitem('web', 'deny_push',
1344 default=list,
1347 default=list,
1345 )
1348 )
1346 coreconfigitem('web', 'guessmime',
1349 coreconfigitem('web', 'guessmime',
1347 default=False,
1350 default=False,
1348 )
1351 )
1349 coreconfigitem('web', 'hidden',
1352 coreconfigitem('web', 'hidden',
1350 default=False,
1353 default=False,
1351 )
1354 )
1352 coreconfigitem('web', 'labels',
1355 coreconfigitem('web', 'labels',
1353 default=list,
1356 default=list,
1354 )
1357 )
1355 coreconfigitem('web', 'logoimg',
1358 coreconfigitem('web', 'logoimg',
1356 default='hglogo.png',
1359 default='hglogo.png',
1357 )
1360 )
1358 coreconfigitem('web', 'logourl',
1361 coreconfigitem('web', 'logourl',
1359 default='https://mercurial-scm.org/',
1362 default='https://mercurial-scm.org/',
1360 )
1363 )
1361 coreconfigitem('web', 'accesslog',
1364 coreconfigitem('web', 'accesslog',
1362 default='-',
1365 default='-',
1363 )
1366 )
1364 coreconfigitem('web', 'address',
1367 coreconfigitem('web', 'address',
1365 default='',
1368 default='',
1366 )
1369 )
1367 coreconfigitem('web', 'allow-archive',
1370 coreconfigitem('web', 'allow-archive',
1368 alias=[('web', 'allow_archive')],
1371 alias=[('web', 'allow_archive')],
1369 default=list,
1372 default=list,
1370 )
1373 )
1371 coreconfigitem('web', 'allow_read',
1374 coreconfigitem('web', 'allow_read',
1372 default=list,
1375 default=list,
1373 )
1376 )
1374 coreconfigitem('web', 'baseurl',
1377 coreconfigitem('web', 'baseurl',
1375 default=None,
1378 default=None,
1376 )
1379 )
1377 coreconfigitem('web', 'cacerts',
1380 coreconfigitem('web', 'cacerts',
1378 default=None,
1381 default=None,
1379 )
1382 )
1380 coreconfigitem('web', 'certificate',
1383 coreconfigitem('web', 'certificate',
1381 default=None,
1384 default=None,
1382 )
1385 )
1383 coreconfigitem('web', 'collapse',
1386 coreconfigitem('web', 'collapse',
1384 default=False,
1387 default=False,
1385 )
1388 )
1386 coreconfigitem('web', 'csp',
1389 coreconfigitem('web', 'csp',
1387 default=None,
1390 default=None,
1388 )
1391 )
1389 coreconfigitem('web', 'deny_read',
1392 coreconfigitem('web', 'deny_read',
1390 default=list,
1393 default=list,
1391 )
1394 )
1392 coreconfigitem('web', 'descend',
1395 coreconfigitem('web', 'descend',
1393 default=True,
1396 default=True,
1394 )
1397 )
1395 coreconfigitem('web', 'description',
1398 coreconfigitem('web', 'description',
1396 default="",
1399 default="",
1397 )
1400 )
1398 coreconfigitem('web', 'encoding',
1401 coreconfigitem('web', 'encoding',
1399 default=lambda: encoding.encoding,
1402 default=lambda: encoding.encoding,
1400 )
1403 )
1401 coreconfigitem('web', 'errorlog',
1404 coreconfigitem('web', 'errorlog',
1402 default='-',
1405 default='-',
1403 )
1406 )
1404 coreconfigitem('web', 'ipv6',
1407 coreconfigitem('web', 'ipv6',
1405 default=False,
1408 default=False,
1406 )
1409 )
1407 coreconfigitem('web', 'maxchanges',
1410 coreconfigitem('web', 'maxchanges',
1408 default=10,
1411 default=10,
1409 )
1412 )
1410 coreconfigitem('web', 'maxfiles',
1413 coreconfigitem('web', 'maxfiles',
1411 default=10,
1414 default=10,
1412 )
1415 )
1413 coreconfigitem('web', 'maxshortchanges',
1416 coreconfigitem('web', 'maxshortchanges',
1414 default=60,
1417 default=60,
1415 )
1418 )
1416 coreconfigitem('web', 'motd',
1419 coreconfigitem('web', 'motd',
1417 default='',
1420 default='',
1418 )
1421 )
1419 coreconfigitem('web', 'name',
1422 coreconfigitem('web', 'name',
1420 default=dynamicdefault,
1423 default=dynamicdefault,
1421 )
1424 )
1422 coreconfigitem('web', 'port',
1425 coreconfigitem('web', 'port',
1423 default=8000,
1426 default=8000,
1424 )
1427 )
1425 coreconfigitem('web', 'prefix',
1428 coreconfigitem('web', 'prefix',
1426 default='',
1429 default='',
1427 )
1430 )
1428 coreconfigitem('web', 'push_ssl',
1431 coreconfigitem('web', 'push_ssl',
1429 default=True,
1432 default=True,
1430 )
1433 )
1431 coreconfigitem('web', 'refreshinterval',
1434 coreconfigitem('web', 'refreshinterval',
1432 default=20,
1435 default=20,
1433 )
1436 )
1434 coreconfigitem('web', 'server-header',
1437 coreconfigitem('web', 'server-header',
1435 default=None,
1438 default=None,
1436 )
1439 )
1437 coreconfigitem('web', 'static',
1440 coreconfigitem('web', 'static',
1438 default=None,
1441 default=None,
1439 )
1442 )
1440 coreconfigitem('web', 'staticurl',
1443 coreconfigitem('web', 'staticurl',
1441 default=None,
1444 default=None,
1442 )
1445 )
1443 coreconfigitem('web', 'stripes',
1446 coreconfigitem('web', 'stripes',
1444 default=1,
1447 default=1,
1445 )
1448 )
1446 coreconfigitem('web', 'style',
1449 coreconfigitem('web', 'style',
1447 default='paper',
1450 default='paper',
1448 )
1451 )
1449 coreconfigitem('web', 'templates',
1452 coreconfigitem('web', 'templates',
1450 default=None,
1453 default=None,
1451 )
1454 )
1452 coreconfigitem('web', 'view',
1455 coreconfigitem('web', 'view',
1453 default='served',
1456 default='served',
1454 )
1457 )
1455 coreconfigitem('worker', 'backgroundclose',
1458 coreconfigitem('worker', 'backgroundclose',
1456 default=dynamicdefault,
1459 default=dynamicdefault,
1457 )
1460 )
1458 # Windows defaults to a limit of 512 open files. A buffer of 128
1461 # Windows defaults to a limit of 512 open files. A buffer of 128
1459 # should give us enough headway.
1462 # should give us enough headway.
1460 coreconfigitem('worker', 'backgroundclosemaxqueue',
1463 coreconfigitem('worker', 'backgroundclosemaxqueue',
1461 default=384,
1464 default=384,
1462 )
1465 )
1463 coreconfigitem('worker', 'backgroundcloseminfilecount',
1466 coreconfigitem('worker', 'backgroundcloseminfilecount',
1464 default=2048,
1467 default=2048,
1465 )
1468 )
1466 coreconfigitem('worker', 'backgroundclosethreadcount',
1469 coreconfigitem('worker', 'backgroundclosethreadcount',
1467 default=4,
1470 default=4,
1468 )
1471 )
1469 coreconfigitem('worker', 'enabled',
1472 coreconfigitem('worker', 'enabled',
1470 default=True,
1473 default=True,
1471 )
1474 )
1472 coreconfigitem('worker', 'numcpus',
1475 coreconfigitem('worker', 'numcpus',
1473 default=None,
1476 default=None,
1474 )
1477 )
1475
1478
1476 # Rebase related configuration moved to core because other extension are doing
1479 # Rebase related configuration moved to core because other extension are doing
1477 # strange things. For example, shelve import the extensions to reuse some bit
1480 # strange things. For example, shelve import the extensions to reuse some bit
1478 # without formally loading it.
1481 # without formally loading it.
1479 coreconfigitem('commands', 'rebase.requiredest',
1482 coreconfigitem('commands', 'rebase.requiredest',
1480 default=False,
1483 default=False,
1481 )
1484 )
1482 coreconfigitem('experimental', 'rebaseskipobsolete',
1485 coreconfigitem('experimental', 'rebaseskipobsolete',
1483 default=True,
1486 default=True,
1484 )
1487 )
1485 coreconfigitem('rebase', 'singletransaction',
1488 coreconfigitem('rebase', 'singletransaction',
1486 default=False,
1489 default=False,
1487 )
1490 )
1488 coreconfigitem('rebase', 'experimental.inmemory',
1491 coreconfigitem('rebase', 'experimental.inmemory',
1489 default=False,
1492 default=False,
1490 )
1493 )
@@ -1,2847 +1,2856 b''
1 The Mercurial system uses a set of configuration files to control
1 The Mercurial system uses a set of configuration files to control
2 aspects of its behavior.
2 aspects of its behavior.
3
3
4 Troubleshooting
4 Troubleshooting
5 ===============
5 ===============
6
6
7 If you're having problems with your configuration,
7 If you're having problems with your configuration,
8 :hg:`config --debug` can help you understand what is introducing
8 :hg:`config --debug` can help you understand what is introducing
9 a setting into your environment.
9 a setting into your environment.
10
10
11 See :hg:`help config.syntax` and :hg:`help config.files`
11 See :hg:`help config.syntax` and :hg:`help config.files`
12 for information about how and where to override things.
12 for information about how and where to override things.
13
13
14 Structure
14 Structure
15 =========
15 =========
16
16
17 The configuration files use a simple ini-file format. A configuration
17 The configuration files use a simple ini-file format. A configuration
18 file consists of sections, led by a ``[section]`` header and followed
18 file consists of sections, led by a ``[section]`` header and followed
19 by ``name = value`` entries::
19 by ``name = value`` entries::
20
20
21 [ui]
21 [ui]
22 username = Firstname Lastname <firstname.lastname@example.net>
22 username = Firstname Lastname <firstname.lastname@example.net>
23 verbose = True
23 verbose = True
24
24
25 The above entries will be referred to as ``ui.username`` and
25 The above entries will be referred to as ``ui.username`` and
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
26 ``ui.verbose``, respectively. See :hg:`help config.syntax`.
27
27
28 Files
28 Files
29 =====
29 =====
30
30
31 Mercurial reads configuration data from several files, if they exist.
31 Mercurial reads configuration data from several files, if they exist.
32 These files do not exist by default and you will have to create the
32 These files do not exist by default and you will have to create the
33 appropriate configuration files yourself:
33 appropriate configuration files yourself:
34
34
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
35 Local configuration is put into the per-repository ``<repo>/.hg/hgrc`` file.
36
36
37 Global configuration like the username setting is typically put into:
37 Global configuration like the username setting is typically put into:
38
38
39 .. container:: windows
39 .. container:: windows
40
40
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
41 - ``%USERPROFILE%\mercurial.ini`` (on Windows)
42
42
43 .. container:: unix.plan9
43 .. container:: unix.plan9
44
44
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
45 - ``$HOME/.hgrc`` (on Unix, Plan9)
46
46
47 The names of these files depend on the system on which Mercurial is
47 The names of these files depend on the system on which Mercurial is
48 installed. ``*.rc`` files from a single directory are read in
48 installed. ``*.rc`` files from a single directory are read in
49 alphabetical order, later ones overriding earlier ones. Where multiple
49 alphabetical order, later ones overriding earlier ones. Where multiple
50 paths are given below, settings from earlier paths override later
50 paths are given below, settings from earlier paths override later
51 ones.
51 ones.
52
52
53 .. container:: verbose.unix
53 .. container:: verbose.unix
54
54
55 On Unix, the following files are consulted:
55 On Unix, the following files are consulted:
56
56
57 - ``<repo>/.hg/hgrc`` (per-repository)
57 - ``<repo>/.hg/hgrc`` (per-repository)
58 - ``$HOME/.hgrc`` (per-user)
58 - ``$HOME/.hgrc`` (per-user)
59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
59 - ``${XDG_CONFIG_HOME:-$HOME/.config}/hg/hgrc`` (per-user)
60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
60 - ``<install-root>/etc/mercurial/hgrc`` (per-installation)
61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
61 - ``<install-root>/etc/mercurial/hgrc.d/*.rc`` (per-installation)
62 - ``/etc/mercurial/hgrc`` (per-system)
62 - ``/etc/mercurial/hgrc`` (per-system)
63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
63 - ``/etc/mercurial/hgrc.d/*.rc`` (per-system)
64 - ``<internal>/default.d/*.rc`` (defaults)
64 - ``<internal>/default.d/*.rc`` (defaults)
65
65
66 .. container:: verbose.windows
66 .. container:: verbose.windows
67
67
68 On Windows, the following files are consulted:
68 On Windows, the following files are consulted:
69
69
70 - ``<repo>/.hg/hgrc`` (per-repository)
70 - ``<repo>/.hg/hgrc`` (per-repository)
71 - ``%USERPROFILE%\.hgrc`` (per-user)
71 - ``%USERPROFILE%\.hgrc`` (per-user)
72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
72 - ``%USERPROFILE%\Mercurial.ini`` (per-user)
73 - ``%HOME%\.hgrc`` (per-user)
73 - ``%HOME%\.hgrc`` (per-user)
74 - ``%HOME%\Mercurial.ini`` (per-user)
74 - ``%HOME%\Mercurial.ini`` (per-user)
75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
75 - ``HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial`` (per-installation)
76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
76 - ``<install-dir>\hgrc.d\*.rc`` (per-installation)
77 - ``<install-dir>\Mercurial.ini`` (per-installation)
77 - ``<install-dir>\Mercurial.ini`` (per-installation)
78 - ``<internal>/default.d/*.rc`` (defaults)
78 - ``<internal>/default.d/*.rc`` (defaults)
79
79
80 .. note::
80 .. note::
81
81
82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
82 The registry key ``HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Mercurial``
83 is used when running 32-bit Python on 64-bit Windows.
83 is used when running 32-bit Python on 64-bit Windows.
84
84
85 .. container:: windows
85 .. container:: windows
86
86
87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
87 On Windows 9x, ``%HOME%`` is replaced by ``%APPDATA%``.
88
88
89 .. container:: verbose.plan9
89 .. container:: verbose.plan9
90
90
91 On Plan9, the following files are consulted:
91 On Plan9, the following files are consulted:
92
92
93 - ``<repo>/.hg/hgrc`` (per-repository)
93 - ``<repo>/.hg/hgrc`` (per-repository)
94 - ``$home/lib/hgrc`` (per-user)
94 - ``$home/lib/hgrc`` (per-user)
95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
95 - ``<install-root>/lib/mercurial/hgrc`` (per-installation)
96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
96 - ``<install-root>/lib/mercurial/hgrc.d/*.rc`` (per-installation)
97 - ``/lib/mercurial/hgrc`` (per-system)
97 - ``/lib/mercurial/hgrc`` (per-system)
98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
98 - ``/lib/mercurial/hgrc.d/*.rc`` (per-system)
99 - ``<internal>/default.d/*.rc`` (defaults)
99 - ``<internal>/default.d/*.rc`` (defaults)
100
100
101 Per-repository configuration options only apply in a
101 Per-repository configuration options only apply in a
102 particular repository. This file is not version-controlled, and
102 particular repository. This file is not version-controlled, and
103 will not get transferred during a "clone" operation. Options in
103 will not get transferred during a "clone" operation. Options in
104 this file override options in all other configuration files.
104 this file override options in all other configuration files.
105
105
106 .. container:: unix.plan9
106 .. container:: unix.plan9
107
107
108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
108 On Plan 9 and Unix, most of this file will be ignored if it doesn't
109 belong to a trusted user or to a trusted group. See
109 belong to a trusted user or to a trusted group. See
110 :hg:`help config.trusted` for more details.
110 :hg:`help config.trusted` for more details.
111
111
112 Per-user configuration file(s) are for the user running Mercurial. Options
112 Per-user configuration file(s) are for the user running Mercurial. Options
113 in these files apply to all Mercurial commands executed by this user in any
113 in these files apply to all Mercurial commands executed by this user in any
114 directory. Options in these files override per-system and per-installation
114 directory. Options in these files override per-system and per-installation
115 options.
115 options.
116
116
117 Per-installation configuration files are searched for in the
117 Per-installation configuration files are searched for in the
118 directory where Mercurial is installed. ``<install-root>`` is the
118 directory where Mercurial is installed. ``<install-root>`` is the
119 parent directory of the **hg** executable (or symlink) being run.
119 parent directory of the **hg** executable (or symlink) being run.
120
120
121 .. container:: unix.plan9
121 .. container:: unix.plan9
122
122
123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
123 For example, if installed in ``/shared/tools/bin/hg``, Mercurial
124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
124 will look in ``/shared/tools/etc/mercurial/hgrc``. Options in these
125 files apply to all Mercurial commands executed by any user in any
125 files apply to all Mercurial commands executed by any user in any
126 directory.
126 directory.
127
127
128 Per-installation configuration files are for the system on
128 Per-installation configuration files are for the system on
129 which Mercurial is running. Options in these files apply to all
129 which Mercurial is running. Options in these files apply to all
130 Mercurial commands executed by any user in any directory. Registry
130 Mercurial commands executed by any user in any directory. Registry
131 keys contain PATH-like strings, every part of which must reference
131 keys contain PATH-like strings, every part of which must reference
132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
132 a ``Mercurial.ini`` file or be a directory where ``*.rc`` files will
133 be read. Mercurial checks each of these locations in the specified
133 be read. Mercurial checks each of these locations in the specified
134 order until one or more configuration files are detected.
134 order until one or more configuration files are detected.
135
135
136 Per-system configuration files are for the system on which Mercurial
136 Per-system configuration files are for the system on which Mercurial
137 is running. Options in these files apply to all Mercurial commands
137 is running. Options in these files apply to all Mercurial commands
138 executed by any user in any directory. Options in these files
138 executed by any user in any directory. Options in these files
139 override per-installation options.
139 override per-installation options.
140
140
141 Mercurial comes with some default configuration. The default configuration
141 Mercurial comes with some default configuration. The default configuration
142 files are installed with Mercurial and will be overwritten on upgrades. Default
142 files are installed with Mercurial and will be overwritten on upgrades. Default
143 configuration files should never be edited by users or administrators but can
143 configuration files should never be edited by users or administrators but can
144 be overridden in other configuration files. So far the directory only contains
144 be overridden in other configuration files. So far the directory only contains
145 merge tool configuration but packagers can also put other default configuration
145 merge tool configuration but packagers can also put other default configuration
146 there.
146 there.
147
147
148 Syntax
148 Syntax
149 ======
149 ======
150
150
151 A configuration file consists of sections, led by a ``[section]`` header
151 A configuration file consists of sections, led by a ``[section]`` header
152 and followed by ``name = value`` entries (sometimes called
152 and followed by ``name = value`` entries (sometimes called
153 ``configuration keys``)::
153 ``configuration keys``)::
154
154
155 [spam]
155 [spam]
156 eggs=ham
156 eggs=ham
157 green=
157 green=
158 eggs
158 eggs
159
159
160 Each line contains one entry. If the lines that follow are indented,
160 Each line contains one entry. If the lines that follow are indented,
161 they are treated as continuations of that entry. Leading whitespace is
161 they are treated as continuations of that entry. Leading whitespace is
162 removed from values. Empty lines are skipped. Lines beginning with
162 removed from values. Empty lines are skipped. Lines beginning with
163 ``#`` or ``;`` are ignored and may be used to provide comments.
163 ``#`` or ``;`` are ignored and may be used to provide comments.
164
164
165 Configuration keys can be set multiple times, in which case Mercurial
165 Configuration keys can be set multiple times, in which case Mercurial
166 will use the value that was configured last. As an example::
166 will use the value that was configured last. As an example::
167
167
168 [spam]
168 [spam]
169 eggs=large
169 eggs=large
170 ham=serrano
170 ham=serrano
171 eggs=small
171 eggs=small
172
172
173 This would set the configuration key named ``eggs`` to ``small``.
173 This would set the configuration key named ``eggs`` to ``small``.
174
174
175 It is also possible to define a section multiple times. A section can
175 It is also possible to define a section multiple times. A section can
176 be redefined on the same and/or on different configuration files. For
176 be redefined on the same and/or on different configuration files. For
177 example::
177 example::
178
178
179 [foo]
179 [foo]
180 eggs=large
180 eggs=large
181 ham=serrano
181 ham=serrano
182 eggs=small
182 eggs=small
183
183
184 [bar]
184 [bar]
185 eggs=ham
185 eggs=ham
186 green=
186 green=
187 eggs
187 eggs
188
188
189 [foo]
189 [foo]
190 ham=prosciutto
190 ham=prosciutto
191 eggs=medium
191 eggs=medium
192 bread=toasted
192 bread=toasted
193
193
194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
194 This would set the ``eggs``, ``ham``, and ``bread`` configuration keys
195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
195 of the ``foo`` section to ``medium``, ``prosciutto``, and ``toasted``,
196 respectively. As you can see there only thing that matters is the last
196 respectively. As you can see there only thing that matters is the last
197 value that was set for each of the configuration keys.
197 value that was set for each of the configuration keys.
198
198
199 If a configuration key is set multiple times in different
199 If a configuration key is set multiple times in different
200 configuration files the final value will depend on the order in which
200 configuration files the final value will depend on the order in which
201 the different configuration files are read, with settings from earlier
201 the different configuration files are read, with settings from earlier
202 paths overriding later ones as described on the ``Files`` section
202 paths overriding later ones as described on the ``Files`` section
203 above.
203 above.
204
204
205 A line of the form ``%include file`` will include ``file`` into the
205 A line of the form ``%include file`` will include ``file`` into the
206 current configuration file. The inclusion is recursive, which means
206 current configuration file. The inclusion is recursive, which means
207 that included files can include other files. Filenames are relative to
207 that included files can include other files. Filenames are relative to
208 the configuration file in which the ``%include`` directive is found.
208 the configuration file in which the ``%include`` directive is found.
209 Environment variables and ``~user`` constructs are expanded in
209 Environment variables and ``~user`` constructs are expanded in
210 ``file``. This lets you do something like::
210 ``file``. This lets you do something like::
211
211
212 %include ~/.hgrc.d/$HOST.rc
212 %include ~/.hgrc.d/$HOST.rc
213
213
214 to include a different configuration file on each computer you use.
214 to include a different configuration file on each computer you use.
215
215
216 A line with ``%unset name`` will remove ``name`` from the current
216 A line with ``%unset name`` will remove ``name`` from the current
217 section, if it has been set previously.
217 section, if it has been set previously.
218
218
219 The values are either free-form text strings, lists of text strings,
219 The values are either free-form text strings, lists of text strings,
220 or Boolean values. Boolean values can be set to true using any of "1",
220 or Boolean values. Boolean values can be set to true using any of "1",
221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
221 "yes", "true", or "on" and to false using "0", "no", "false", or "off"
222 (all case insensitive).
222 (all case insensitive).
223
223
224 List values are separated by whitespace or comma, except when values are
224 List values are separated by whitespace or comma, except when values are
225 placed in double quotation marks::
225 placed in double quotation marks::
226
226
227 allow_read = "John Doe, PhD", brian, betty
227 allow_read = "John Doe, PhD", brian, betty
228
228
229 Quotation marks can be escaped by prefixing them with a backslash. Only
229 Quotation marks can be escaped by prefixing them with a backslash. Only
230 quotation marks at the beginning of a word is counted as a quotation
230 quotation marks at the beginning of a word is counted as a quotation
231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
231 (e.g., ``foo"bar baz`` is the list of ``foo"bar`` and ``baz``).
232
232
233 Sections
233 Sections
234 ========
234 ========
235
235
236 This section describes the different sections that may appear in a
236 This section describes the different sections that may appear in a
237 Mercurial configuration file, the purpose of each section, its possible
237 Mercurial configuration file, the purpose of each section, its possible
238 keys, and their possible values.
238 keys, and their possible values.
239
239
240 ``alias``
240 ``alias``
241 ---------
241 ---------
242
242
243 Defines command aliases.
243 Defines command aliases.
244
244
245 Aliases allow you to define your own commands in terms of other
245 Aliases allow you to define your own commands in terms of other
246 commands (or aliases), optionally including arguments. Positional
246 commands (or aliases), optionally including arguments. Positional
247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
247 arguments in the form of ``$1``, ``$2``, etc. in the alias definition
248 are expanded by Mercurial before execution. Positional arguments not
248 are expanded by Mercurial before execution. Positional arguments not
249 already used by ``$N`` in the definition are put at the end of the
249 already used by ``$N`` in the definition are put at the end of the
250 command to be executed.
250 command to be executed.
251
251
252 Alias definitions consist of lines of the form::
252 Alias definitions consist of lines of the form::
253
253
254 <alias> = <command> [<argument>]...
254 <alias> = <command> [<argument>]...
255
255
256 For example, this definition::
256 For example, this definition::
257
257
258 latest = log --limit 5
258 latest = log --limit 5
259
259
260 creates a new command ``latest`` that shows only the five most recent
260 creates a new command ``latest`` that shows only the five most recent
261 changesets. You can define subsequent aliases using earlier ones::
261 changesets. You can define subsequent aliases using earlier ones::
262
262
263 stable5 = latest -b stable
263 stable5 = latest -b stable
264
264
265 .. note::
265 .. note::
266
266
267 It is possible to create aliases with the same names as
267 It is possible to create aliases with the same names as
268 existing commands, which will then override the original
268 existing commands, which will then override the original
269 definitions. This is almost always a bad idea!
269 definitions. This is almost always a bad idea!
270
270
271 An alias can start with an exclamation point (``!``) to make it a
271 An alias can start with an exclamation point (``!``) to make it a
272 shell alias. A shell alias is executed with the shell and will let you
272 shell alias. A shell alias is executed with the shell and will let you
273 run arbitrary commands. As an example, ::
273 run arbitrary commands. As an example, ::
274
274
275 echo = !echo $@
275 echo = !echo $@
276
276
277 will let you do ``hg echo foo`` to have ``foo`` printed in your
277 will let you do ``hg echo foo`` to have ``foo`` printed in your
278 terminal. A better example might be::
278 terminal. A better example might be::
279
279
280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
280 purge = !$HG status --no-status --unknown -0 re: | xargs -0 rm -f
281
281
282 which will make ``hg purge`` delete all unknown files in the
282 which will make ``hg purge`` delete all unknown files in the
283 repository in the same manner as the purge extension.
283 repository in the same manner as the purge extension.
284
284
285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
285 Positional arguments like ``$1``, ``$2``, etc. in the alias definition
286 expand to the command arguments. Unmatched arguments are
286 expand to the command arguments. Unmatched arguments are
287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
287 removed. ``$0`` expands to the alias name and ``$@`` expands to all
288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
288 arguments separated by a space. ``"$@"`` (with quotes) expands to all
289 arguments quoted individually and separated by a space. These expansions
289 arguments quoted individually and separated by a space. These expansions
290 happen before the command is passed to the shell.
290 happen before the command is passed to the shell.
291
291
292 Shell aliases are executed in an environment where ``$HG`` expands to
292 Shell aliases are executed in an environment where ``$HG`` expands to
293 the path of the Mercurial that was used to execute the alias. This is
293 the path of the Mercurial that was used to execute the alias. This is
294 useful when you want to call further Mercurial commands in a shell
294 useful when you want to call further Mercurial commands in a shell
295 alias, as was done above for the purge alias. In addition,
295 alias, as was done above for the purge alias. In addition,
296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
296 ``$HG_ARGS`` expands to the arguments given to Mercurial. In the ``hg
297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
297 echo foo`` call above, ``$HG_ARGS`` would expand to ``echo foo``.
298
298
299 .. note::
299 .. note::
300
300
301 Some global configuration options such as ``-R`` are
301 Some global configuration options such as ``-R`` are
302 processed before shell aliases and will thus not be passed to
302 processed before shell aliases and will thus not be passed to
303 aliases.
303 aliases.
304
304
305
305
306 ``annotate``
306 ``annotate``
307 ------------
307 ------------
308
308
309 Settings used when displaying file annotations. All values are
309 Settings used when displaying file annotations. All values are
310 Booleans and default to False. See :hg:`help config.diff` for
310 Booleans and default to False. See :hg:`help config.diff` for
311 related options for the diff command.
311 related options for the diff command.
312
312
313 ``ignorews``
313 ``ignorews``
314 Ignore white space when comparing lines.
314 Ignore white space when comparing lines.
315
315
316 ``ignorewseol``
316 ``ignorewseol``
317 Ignore white space at the end of a line when comparing lines.
317 Ignore white space at the end of a line when comparing lines.
318
318
319 ``ignorewsamount``
319 ``ignorewsamount``
320 Ignore changes in the amount of white space.
320 Ignore changes in the amount of white space.
321
321
322 ``ignoreblanklines``
322 ``ignoreblanklines``
323 Ignore changes whose lines are all blank.
323 Ignore changes whose lines are all blank.
324
324
325
325
326 ``auth``
326 ``auth``
327 --------
327 --------
328
328
329 Authentication credentials and other authentication-like configuration
329 Authentication credentials and other authentication-like configuration
330 for HTTP connections. This section allows you to store usernames and
330 for HTTP connections. This section allows you to store usernames and
331 passwords for use when logging *into* HTTP servers. See
331 passwords for use when logging *into* HTTP servers. See
332 :hg:`help config.web` if you want to configure *who* can login to
332 :hg:`help config.web` if you want to configure *who* can login to
333 your HTTP server.
333 your HTTP server.
334
334
335 The following options apply to all hosts.
335 The following options apply to all hosts.
336
336
337 ``cookiefile``
337 ``cookiefile``
338 Path to a file containing HTTP cookie lines. Cookies matching a
338 Path to a file containing HTTP cookie lines. Cookies matching a
339 host will be sent automatically.
339 host will be sent automatically.
340
340
341 The file format uses the Mozilla cookies.txt format, which defines cookies
341 The file format uses the Mozilla cookies.txt format, which defines cookies
342 on their own lines. Each line contains 7 fields delimited by the tab
342 on their own lines. Each line contains 7 fields delimited by the tab
343 character (domain, is_domain_cookie, path, is_secure, expires, name,
343 character (domain, is_domain_cookie, path, is_secure, expires, name,
344 value). For more info, do an Internet search for "Netscape cookies.txt
344 value). For more info, do an Internet search for "Netscape cookies.txt
345 format."
345 format."
346
346
347 Note: the cookies parser does not handle port numbers on domains. You
347 Note: the cookies parser does not handle port numbers on domains. You
348 will need to remove ports from the domain for the cookie to be recognized.
348 will need to remove ports from the domain for the cookie to be recognized.
349 This could result in a cookie being disclosed to an unwanted server.
349 This could result in a cookie being disclosed to an unwanted server.
350
350
351 The cookies file is read-only.
351 The cookies file is read-only.
352
352
353 Other options in this section are grouped by name and have the following
353 Other options in this section are grouped by name and have the following
354 format::
354 format::
355
355
356 <name>.<argument> = <value>
356 <name>.<argument> = <value>
357
357
358 where ``<name>`` is used to group arguments into authentication
358 where ``<name>`` is used to group arguments into authentication
359 entries. Example::
359 entries. Example::
360
360
361 foo.prefix = hg.intevation.de/mercurial
361 foo.prefix = hg.intevation.de/mercurial
362 foo.username = foo
362 foo.username = foo
363 foo.password = bar
363 foo.password = bar
364 foo.schemes = http https
364 foo.schemes = http https
365
365
366 bar.prefix = secure.example.org
366 bar.prefix = secure.example.org
367 bar.key = path/to/file.key
367 bar.key = path/to/file.key
368 bar.cert = path/to/file.cert
368 bar.cert = path/to/file.cert
369 bar.schemes = https
369 bar.schemes = https
370
370
371 Supported arguments:
371 Supported arguments:
372
372
373 ``prefix``
373 ``prefix``
374 Either ``*`` or a URI prefix with or without the scheme part.
374 Either ``*`` or a URI prefix with or without the scheme part.
375 The authentication entry with the longest matching prefix is used
375 The authentication entry with the longest matching prefix is used
376 (where ``*`` matches everything and counts as a match of length
376 (where ``*`` matches everything and counts as a match of length
377 1). If the prefix doesn't include a scheme, the match is performed
377 1). If the prefix doesn't include a scheme, the match is performed
378 against the URI with its scheme stripped as well, and the schemes
378 against the URI with its scheme stripped as well, and the schemes
379 argument, q.v., is then subsequently consulted.
379 argument, q.v., is then subsequently consulted.
380
380
381 ``username``
381 ``username``
382 Optional. Username to authenticate with. If not given, and the
382 Optional. Username to authenticate with. If not given, and the
383 remote site requires basic or digest authentication, the user will
383 remote site requires basic or digest authentication, the user will
384 be prompted for it. Environment variables are expanded in the
384 be prompted for it. Environment variables are expanded in the
385 username letting you do ``foo.username = $USER``. If the URI
385 username letting you do ``foo.username = $USER``. If the URI
386 includes a username, only ``[auth]`` entries with a matching
386 includes a username, only ``[auth]`` entries with a matching
387 username or without a username will be considered.
387 username or without a username will be considered.
388
388
389 ``password``
389 ``password``
390 Optional. Password to authenticate with. If not given, and the
390 Optional. Password to authenticate with. If not given, and the
391 remote site requires basic or digest authentication, the user
391 remote site requires basic or digest authentication, the user
392 will be prompted for it.
392 will be prompted for it.
393
393
394 ``key``
394 ``key``
395 Optional. PEM encoded client certificate key file. Environment
395 Optional. PEM encoded client certificate key file. Environment
396 variables are expanded in the filename.
396 variables are expanded in the filename.
397
397
398 ``cert``
398 ``cert``
399 Optional. PEM encoded client certificate chain file. Environment
399 Optional. PEM encoded client certificate chain file. Environment
400 variables are expanded in the filename.
400 variables are expanded in the filename.
401
401
402 ``schemes``
402 ``schemes``
403 Optional. Space separated list of URI schemes to use this
403 Optional. Space separated list of URI schemes to use this
404 authentication entry with. Only used if the prefix doesn't include
404 authentication entry with. Only used if the prefix doesn't include
405 a scheme. Supported schemes are http and https. They will match
405 a scheme. Supported schemes are http and https. They will match
406 static-http and static-https respectively, as well.
406 static-http and static-https respectively, as well.
407 (default: https)
407 (default: https)
408
408
409 If no suitable authentication entry is found, the user is prompted
409 If no suitable authentication entry is found, the user is prompted
410 for credentials as usual if required by the remote.
410 for credentials as usual if required by the remote.
411
411
412 ``color``
412 ``color``
413 ---------
413 ---------
414
414
415 Configure the Mercurial color mode. For details about how to define your custom
415 Configure the Mercurial color mode. For details about how to define your custom
416 effect and style see :hg:`help color`.
416 effect and style see :hg:`help color`.
417
417
418 ``mode``
418 ``mode``
419 String: control the method used to output color. One of ``auto``, ``ansi``,
419 String: control the method used to output color. One of ``auto``, ``ansi``,
420 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
420 ``win32``, ``terminfo`` or ``debug``. In auto mode, Mercurial will
421 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
421 use ANSI mode by default (or win32 mode prior to Windows 10) if it detects a
422 terminal. Any invalid value will disable color.
422 terminal. Any invalid value will disable color.
423
423
424 ``pagermode``
424 ``pagermode``
425 String: optional override of ``color.mode`` used with pager.
425 String: optional override of ``color.mode`` used with pager.
426
426
427 On some systems, terminfo mode may cause problems when using
427 On some systems, terminfo mode may cause problems when using
428 color with ``less -R`` as a pager program. less with the -R option
428 color with ``less -R`` as a pager program. less with the -R option
429 will only display ECMA-48 color codes, and terminfo mode may sometimes
429 will only display ECMA-48 color codes, and terminfo mode may sometimes
430 emit codes that less doesn't understand. You can work around this by
430 emit codes that less doesn't understand. You can work around this by
431 either using ansi mode (or auto mode), or by using less -r (which will
431 either using ansi mode (or auto mode), or by using less -r (which will
432 pass through all terminal control codes, not just color control
432 pass through all terminal control codes, not just color control
433 codes).
433 codes).
434
434
435 On some systems (such as MSYS in Windows), the terminal may support
435 On some systems (such as MSYS in Windows), the terminal may support
436 a different color mode than the pager program.
436 a different color mode than the pager program.
437
437
438 ``commands``
438 ``commands``
439 ------------
439 ------------
440
440
441 ``commit.post-status``
441 ``commit.post-status``
442 Show status of files in the working directory after successful commit.
442 Show status of files in the working directory after successful commit.
443 (default: False)
443 (default: False)
444
444
445 ``resolve.confirm``
445 ``resolve.confirm``
446 Confirm before performing action if no filename is passed.
446 Confirm before performing action if no filename is passed.
447 (default: False)
447 (default: False)
448
448
449 ``resolve.explicit-re-merge``
449 ``resolve.explicit-re-merge``
450 Require uses of ``hg resolve`` to specify which action it should perform,
450 Require uses of ``hg resolve`` to specify which action it should perform,
451 instead of re-merging files by default.
451 instead of re-merging files by default.
452 (default: False)
452 (default: False)
453
453
454 ``resolve.mark-check``
454 ``resolve.mark-check``
455 Determines what level of checking :hg:`resolve --mark` will perform before
455 Determines what level of checking :hg:`resolve --mark` will perform before
456 marking files as resolved. Valid values are ``none`, ``warn``, and
456 marking files as resolved. Valid values are ``none`, ``warn``, and
457 ``abort``. ``warn`` will output a warning listing the file(s) that still
457 ``abort``. ``warn`` will output a warning listing the file(s) that still
458 have conflict markers in them, but will still mark everything resolved.
458 have conflict markers in them, but will still mark everything resolved.
459 ``abort`` will output the same warning but will not mark things as resolved.
459 ``abort`` will output the same warning but will not mark things as resolved.
460 If --all is passed and this is set to ``abort``, only a warning will be
460 If --all is passed and this is set to ``abort``, only a warning will be
461 shown (an error will not be raised).
461 shown (an error will not be raised).
462 (default: ``none``)
462 (default: ``none``)
463
463
464 ``status.relative``
464 ``status.relative``
465 Make paths in :hg:`status` output relative to the current directory.
465 Make paths in :hg:`status` output relative to the current directory.
466 (default: False)
466 (default: False)
467
467
468 ``status.terse``
468 ``status.terse``
469 Default value for the --terse flag, which condenses status output.
469 Default value for the --terse flag, which condenses status output.
470 (default: empty)
470 (default: empty)
471
471
472 ``update.check``
472 ``update.check``
473 Determines what level of checking :hg:`update` will perform before moving
473 Determines what level of checking :hg:`update` will perform before moving
474 to a destination revision. Valid values are ``abort``, ``none``,
474 to a destination revision. Valid values are ``abort``, ``none``,
475 ``linear``, and ``noconflict``. ``abort`` always fails if the working
475 ``linear``, and ``noconflict``. ``abort`` always fails if the working
476 directory has uncommitted changes. ``none`` performs no checking, and may
476 directory has uncommitted changes. ``none`` performs no checking, and may
477 result in a merge with uncommitted changes. ``linear`` allows any update
477 result in a merge with uncommitted changes. ``linear`` allows any update
478 as long as it follows a straight line in the revision history, and may
478 as long as it follows a straight line in the revision history, and may
479 trigger a merge with uncommitted changes. ``noconflict`` will allow any
479 trigger a merge with uncommitted changes. ``noconflict`` will allow any
480 update which would not trigger a merge with uncommitted changes, if any
480 update which would not trigger a merge with uncommitted changes, if any
481 are present.
481 are present.
482 (default: ``linear``)
482 (default: ``linear``)
483
483
484 ``update.requiredest``
484 ``update.requiredest``
485 Require that the user pass a destination when running :hg:`update`.
485 Require that the user pass a destination when running :hg:`update`.
486 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
486 For example, :hg:`update .::` will be allowed, but a plain :hg:`update`
487 will be disallowed.
487 will be disallowed.
488 (default: False)
488 (default: False)
489
489
490 ``committemplate``
490 ``committemplate``
491 ------------------
491 ------------------
492
492
493 ``changeset``
493 ``changeset``
494 String: configuration in this section is used as the template to
494 String: configuration in this section is used as the template to
495 customize the text shown in the editor when committing.
495 customize the text shown in the editor when committing.
496
496
497 In addition to pre-defined template keywords, commit log specific one
497 In addition to pre-defined template keywords, commit log specific one
498 below can be used for customization:
498 below can be used for customization:
499
499
500 ``extramsg``
500 ``extramsg``
501 String: Extra message (typically 'Leave message empty to abort
501 String: Extra message (typically 'Leave message empty to abort
502 commit.'). This may be changed by some commands or extensions.
502 commit.'). This may be changed by some commands or extensions.
503
503
504 For example, the template configuration below shows as same text as
504 For example, the template configuration below shows as same text as
505 one shown by default::
505 one shown by default::
506
506
507 [committemplate]
507 [committemplate]
508 changeset = {desc}\n\n
508 changeset = {desc}\n\n
509 HG: Enter commit message. Lines beginning with 'HG:' are removed.
509 HG: Enter commit message. Lines beginning with 'HG:' are removed.
510 HG: {extramsg}
510 HG: {extramsg}
511 HG: --
511 HG: --
512 HG: user: {author}\n{ifeq(p2rev, "-1", "",
512 HG: user: {author}\n{ifeq(p2rev, "-1", "",
513 "HG: branch merge\n")
513 "HG: branch merge\n")
514 }HG: branch '{branch}'\n{if(activebookmark,
514 }HG: branch '{branch}'\n{if(activebookmark,
515 "HG: bookmark '{activebookmark}'\n") }{subrepos %
515 "HG: bookmark '{activebookmark}'\n") }{subrepos %
516 "HG: subrepo {subrepo}\n" }{file_adds %
516 "HG: subrepo {subrepo}\n" }{file_adds %
517 "HG: added {file}\n" }{file_mods %
517 "HG: added {file}\n" }{file_mods %
518 "HG: changed {file}\n" }{file_dels %
518 "HG: changed {file}\n" }{file_dels %
519 "HG: removed {file}\n" }{if(files, "",
519 "HG: removed {file}\n" }{if(files, "",
520 "HG: no files changed\n")}
520 "HG: no files changed\n")}
521
521
522 ``diff()``
522 ``diff()``
523 String: show the diff (see :hg:`help templates` for detail)
523 String: show the diff (see :hg:`help templates` for detail)
524
524
525 Sometimes it is helpful to show the diff of the changeset in the editor without
525 Sometimes it is helpful to show the diff of the changeset in the editor without
526 having to prefix 'HG: ' to each line so that highlighting works correctly. For
526 having to prefix 'HG: ' to each line so that highlighting works correctly. For
527 this, Mercurial provides a special string which will ignore everything below
527 this, Mercurial provides a special string which will ignore everything below
528 it::
528 it::
529
529
530 HG: ------------------------ >8 ------------------------
530 HG: ------------------------ >8 ------------------------
531
531
532 For example, the template configuration below will show the diff below the
532 For example, the template configuration below will show the diff below the
533 extra message::
533 extra message::
534
534
535 [committemplate]
535 [committemplate]
536 changeset = {desc}\n\n
536 changeset = {desc}\n\n
537 HG: Enter commit message. Lines beginning with 'HG:' are removed.
537 HG: Enter commit message. Lines beginning with 'HG:' are removed.
538 HG: {extramsg}
538 HG: {extramsg}
539 HG: ------------------------ >8 ------------------------
539 HG: ------------------------ >8 ------------------------
540 HG: Do not touch the line above.
540 HG: Do not touch the line above.
541 HG: Everything below will be removed.
541 HG: Everything below will be removed.
542 {diff()}
542 {diff()}
543
543
544 .. note::
544 .. note::
545
545
546 For some problematic encodings (see :hg:`help win32mbcs` for
546 For some problematic encodings (see :hg:`help win32mbcs` for
547 detail), this customization should be configured carefully, to
547 detail), this customization should be configured carefully, to
548 avoid showing broken characters.
548 avoid showing broken characters.
549
549
550 For example, if a multibyte character ending with backslash (0x5c) is
550 For example, if a multibyte character ending with backslash (0x5c) is
551 followed by the ASCII character 'n' in the customized template,
551 followed by the ASCII character 'n' in the customized template,
552 the sequence of backslash and 'n' is treated as line-feed unexpectedly
552 the sequence of backslash and 'n' is treated as line-feed unexpectedly
553 (and the multibyte character is broken, too).
553 (and the multibyte character is broken, too).
554
554
555 Customized template is used for commands below (``--edit`` may be
555 Customized template is used for commands below (``--edit`` may be
556 required):
556 required):
557
557
558 - :hg:`backout`
558 - :hg:`backout`
559 - :hg:`commit`
559 - :hg:`commit`
560 - :hg:`fetch` (for merge commit only)
560 - :hg:`fetch` (for merge commit only)
561 - :hg:`graft`
561 - :hg:`graft`
562 - :hg:`histedit`
562 - :hg:`histedit`
563 - :hg:`import`
563 - :hg:`import`
564 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
564 - :hg:`qfold`, :hg:`qnew` and :hg:`qrefresh`
565 - :hg:`rebase`
565 - :hg:`rebase`
566 - :hg:`shelve`
566 - :hg:`shelve`
567 - :hg:`sign`
567 - :hg:`sign`
568 - :hg:`tag`
568 - :hg:`tag`
569 - :hg:`transplant`
569 - :hg:`transplant`
570
570
571 Configuring items below instead of ``changeset`` allows showing
571 Configuring items below instead of ``changeset`` allows showing
572 customized message only for specific actions, or showing different
572 customized message only for specific actions, or showing different
573 messages for each action.
573 messages for each action.
574
574
575 - ``changeset.backout`` for :hg:`backout`
575 - ``changeset.backout`` for :hg:`backout`
576 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
576 - ``changeset.commit.amend.merge`` for :hg:`commit --amend` on merges
577 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
577 - ``changeset.commit.amend.normal`` for :hg:`commit --amend` on other
578 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
578 - ``changeset.commit.normal.merge`` for :hg:`commit` on merges
579 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
579 - ``changeset.commit.normal.normal`` for :hg:`commit` on other
580 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
580 - ``changeset.fetch`` for :hg:`fetch` (impling merge commit)
581 - ``changeset.gpg.sign`` for :hg:`sign`
581 - ``changeset.gpg.sign`` for :hg:`sign`
582 - ``changeset.graft`` for :hg:`graft`
582 - ``changeset.graft`` for :hg:`graft`
583 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
583 - ``changeset.histedit.edit`` for ``edit`` of :hg:`histedit`
584 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
584 - ``changeset.histedit.fold`` for ``fold`` of :hg:`histedit`
585 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
585 - ``changeset.histedit.mess`` for ``mess`` of :hg:`histedit`
586 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
586 - ``changeset.histedit.pick`` for ``pick`` of :hg:`histedit`
587 - ``changeset.import.bypass`` for :hg:`import --bypass`
587 - ``changeset.import.bypass`` for :hg:`import --bypass`
588 - ``changeset.import.normal.merge`` for :hg:`import` on merges
588 - ``changeset.import.normal.merge`` for :hg:`import` on merges
589 - ``changeset.import.normal.normal`` for :hg:`import` on other
589 - ``changeset.import.normal.normal`` for :hg:`import` on other
590 - ``changeset.mq.qnew`` for :hg:`qnew`
590 - ``changeset.mq.qnew`` for :hg:`qnew`
591 - ``changeset.mq.qfold`` for :hg:`qfold`
591 - ``changeset.mq.qfold`` for :hg:`qfold`
592 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
592 - ``changeset.mq.qrefresh`` for :hg:`qrefresh`
593 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
593 - ``changeset.rebase.collapse`` for :hg:`rebase --collapse`
594 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
594 - ``changeset.rebase.merge`` for :hg:`rebase` on merges
595 - ``changeset.rebase.normal`` for :hg:`rebase` on other
595 - ``changeset.rebase.normal`` for :hg:`rebase` on other
596 - ``changeset.shelve.shelve`` for :hg:`shelve`
596 - ``changeset.shelve.shelve`` for :hg:`shelve`
597 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
597 - ``changeset.tag.add`` for :hg:`tag` without ``--remove``
598 - ``changeset.tag.remove`` for :hg:`tag --remove`
598 - ``changeset.tag.remove`` for :hg:`tag --remove`
599 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
599 - ``changeset.transplant.merge`` for :hg:`transplant` on merges
600 - ``changeset.transplant.normal`` for :hg:`transplant` on other
600 - ``changeset.transplant.normal`` for :hg:`transplant` on other
601
601
602 These dot-separated lists of names are treated as hierarchical ones.
602 These dot-separated lists of names are treated as hierarchical ones.
603 For example, ``changeset.tag.remove`` customizes the commit message
603 For example, ``changeset.tag.remove`` customizes the commit message
604 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
604 only for :hg:`tag --remove`, but ``changeset.tag`` customizes the
605 commit message for :hg:`tag` regardless of ``--remove`` option.
605 commit message for :hg:`tag` regardless of ``--remove`` option.
606
606
607 When the external editor is invoked for a commit, the corresponding
607 When the external editor is invoked for a commit, the corresponding
608 dot-separated list of names without the ``changeset.`` prefix
608 dot-separated list of names without the ``changeset.`` prefix
609 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
609 (e.g. ``commit.normal.normal``) is in the ``HGEDITFORM`` environment
610 variable.
610 variable.
611
611
612 In this section, items other than ``changeset`` can be referred from
612 In this section, items other than ``changeset`` can be referred from
613 others. For example, the configuration to list committed files up
613 others. For example, the configuration to list committed files up
614 below can be referred as ``{listupfiles}``::
614 below can be referred as ``{listupfiles}``::
615
615
616 [committemplate]
616 [committemplate]
617 listupfiles = {file_adds %
617 listupfiles = {file_adds %
618 "HG: added {file}\n" }{file_mods %
618 "HG: added {file}\n" }{file_mods %
619 "HG: changed {file}\n" }{file_dels %
619 "HG: changed {file}\n" }{file_dels %
620 "HG: removed {file}\n" }{if(files, "",
620 "HG: removed {file}\n" }{if(files, "",
621 "HG: no files changed\n")}
621 "HG: no files changed\n")}
622
622
623 ``decode/encode``
623 ``decode/encode``
624 -----------------
624 -----------------
625
625
626 Filters for transforming files on checkout/checkin. This would
626 Filters for transforming files on checkout/checkin. This would
627 typically be used for newline processing or other
627 typically be used for newline processing or other
628 localization/canonicalization of files.
628 localization/canonicalization of files.
629
629
630 Filters consist of a filter pattern followed by a filter command.
630 Filters consist of a filter pattern followed by a filter command.
631 Filter patterns are globs by default, rooted at the repository root.
631 Filter patterns are globs by default, rooted at the repository root.
632 For example, to match any file ending in ``.txt`` in the root
632 For example, to match any file ending in ``.txt`` in the root
633 directory only, use the pattern ``*.txt``. To match any file ending
633 directory only, use the pattern ``*.txt``. To match any file ending
634 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
634 in ``.c`` anywhere in the repository, use the pattern ``**.c``.
635 For each file only the first matching filter applies.
635 For each file only the first matching filter applies.
636
636
637 The filter command can start with a specifier, either ``pipe:`` or
637 The filter command can start with a specifier, either ``pipe:`` or
638 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
638 ``tempfile:``. If no specifier is given, ``pipe:`` is used by default.
639
639
640 A ``pipe:`` command must accept data on stdin and return the transformed
640 A ``pipe:`` command must accept data on stdin and return the transformed
641 data on stdout.
641 data on stdout.
642
642
643 Pipe example::
643 Pipe example::
644
644
645 [encode]
645 [encode]
646 # uncompress gzip files on checkin to improve delta compression
646 # uncompress gzip files on checkin to improve delta compression
647 # note: not necessarily a good idea, just an example
647 # note: not necessarily a good idea, just an example
648 *.gz = pipe: gunzip
648 *.gz = pipe: gunzip
649
649
650 [decode]
650 [decode]
651 # recompress gzip files when writing them to the working dir (we
651 # recompress gzip files when writing them to the working dir (we
652 # can safely omit "pipe:", because it's the default)
652 # can safely omit "pipe:", because it's the default)
653 *.gz = gzip
653 *.gz = gzip
654
654
655 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
655 A ``tempfile:`` command is a template. The string ``INFILE`` is replaced
656 with the name of a temporary file that contains the data to be
656 with the name of a temporary file that contains the data to be
657 filtered by the command. The string ``OUTFILE`` is replaced with the name
657 filtered by the command. The string ``OUTFILE`` is replaced with the name
658 of an empty temporary file, where the filtered data must be written by
658 of an empty temporary file, where the filtered data must be written by
659 the command.
659 the command.
660
660
661 .. container:: windows
661 .. container:: windows
662
662
663 .. note::
663 .. note::
664
664
665 The tempfile mechanism is recommended for Windows systems,
665 The tempfile mechanism is recommended for Windows systems,
666 where the standard shell I/O redirection operators often have
666 where the standard shell I/O redirection operators often have
667 strange effects and may corrupt the contents of your files.
667 strange effects and may corrupt the contents of your files.
668
668
669 This filter mechanism is used internally by the ``eol`` extension to
669 This filter mechanism is used internally by the ``eol`` extension to
670 translate line ending characters between Windows (CRLF) and Unix (LF)
670 translate line ending characters between Windows (CRLF) and Unix (LF)
671 format. We suggest you use the ``eol`` extension for convenience.
671 format. We suggest you use the ``eol`` extension for convenience.
672
672
673
673
674 ``defaults``
674 ``defaults``
675 ------------
675 ------------
676
676
677 (defaults are deprecated. Don't use them. Use aliases instead.)
677 (defaults are deprecated. Don't use them. Use aliases instead.)
678
678
679 Use the ``[defaults]`` section to define command defaults, i.e. the
679 Use the ``[defaults]`` section to define command defaults, i.e. the
680 default options/arguments to pass to the specified commands.
680 default options/arguments to pass to the specified commands.
681
681
682 The following example makes :hg:`log` run in verbose mode, and
682 The following example makes :hg:`log` run in verbose mode, and
683 :hg:`status` show only the modified files, by default::
683 :hg:`status` show only the modified files, by default::
684
684
685 [defaults]
685 [defaults]
686 log = -v
686 log = -v
687 status = -m
687 status = -m
688
688
689 The actual commands, instead of their aliases, must be used when
689 The actual commands, instead of their aliases, must be used when
690 defining command defaults. The command defaults will also be applied
690 defining command defaults. The command defaults will also be applied
691 to the aliases of the commands defined.
691 to the aliases of the commands defined.
692
692
693
693
694 ``diff``
694 ``diff``
695 --------
695 --------
696
696
697 Settings used when displaying diffs. Everything except for ``unified``
697 Settings used when displaying diffs. Everything except for ``unified``
698 is a Boolean and defaults to False. See :hg:`help config.annotate`
698 is a Boolean and defaults to False. See :hg:`help config.annotate`
699 for related options for the annotate command.
699 for related options for the annotate command.
700
700
701 ``git``
701 ``git``
702 Use git extended diff format.
702 Use git extended diff format.
703
703
704 ``nobinary``
704 ``nobinary``
705 Omit git binary patches.
705 Omit git binary patches.
706
706
707 ``nodates``
707 ``nodates``
708 Don't include dates in diff headers.
708 Don't include dates in diff headers.
709
709
710 ``noprefix``
710 ``noprefix``
711 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
711 Omit 'a/' and 'b/' prefixes from filenames. Ignored in plain mode.
712
712
713 ``showfunc``
713 ``showfunc``
714 Show which function each change is in.
714 Show which function each change is in.
715
715
716 ``ignorews``
716 ``ignorews``
717 Ignore white space when comparing lines.
717 Ignore white space when comparing lines.
718
718
719 ``ignorewsamount``
719 ``ignorewsamount``
720 Ignore changes in the amount of white space.
720 Ignore changes in the amount of white space.
721
721
722 ``ignoreblanklines``
722 ``ignoreblanklines``
723 Ignore changes whose lines are all blank.
723 Ignore changes whose lines are all blank.
724
724
725 ``unified``
725 ``unified``
726 Number of lines of context to show.
726 Number of lines of context to show.
727
727
728 ``word-diff``
728 ``word-diff``
729 Highlight changed words.
729 Highlight changed words.
730
730
731 ``email``
731 ``email``
732 ---------
732 ---------
733
733
734 Settings for extensions that send email messages.
734 Settings for extensions that send email messages.
735
735
736 ``from``
736 ``from``
737 Optional. Email address to use in "From" header and SMTP envelope
737 Optional. Email address to use in "From" header and SMTP envelope
738 of outgoing messages.
738 of outgoing messages.
739
739
740 ``to``
740 ``to``
741 Optional. Comma-separated list of recipients' email addresses.
741 Optional. Comma-separated list of recipients' email addresses.
742
742
743 ``cc``
743 ``cc``
744 Optional. Comma-separated list of carbon copy recipients'
744 Optional. Comma-separated list of carbon copy recipients'
745 email addresses.
745 email addresses.
746
746
747 ``bcc``
747 ``bcc``
748 Optional. Comma-separated list of blind carbon copy recipients'
748 Optional. Comma-separated list of blind carbon copy recipients'
749 email addresses.
749 email addresses.
750
750
751 ``method``
751 ``method``
752 Optional. Method to use to send email messages. If value is ``smtp``
752 Optional. Method to use to send email messages. If value is ``smtp``
753 (default), use SMTP (see the ``[smtp]`` section for configuration).
753 (default), use SMTP (see the ``[smtp]`` section for configuration).
754 Otherwise, use as name of program to run that acts like sendmail
754 Otherwise, use as name of program to run that acts like sendmail
755 (takes ``-f`` option for sender, list of recipients on command line,
755 (takes ``-f`` option for sender, list of recipients on command line,
756 message on stdin). Normally, setting this to ``sendmail`` or
756 message on stdin). Normally, setting this to ``sendmail`` or
757 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
757 ``/usr/sbin/sendmail`` is enough to use sendmail to send messages.
758
758
759 ``charsets``
759 ``charsets``
760 Optional. Comma-separated list of character sets considered
760 Optional. Comma-separated list of character sets considered
761 convenient for recipients. Addresses, headers, and parts not
761 convenient for recipients. Addresses, headers, and parts not
762 containing patches of outgoing messages will be encoded in the
762 containing patches of outgoing messages will be encoded in the
763 first character set to which conversion from local encoding
763 first character set to which conversion from local encoding
764 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
764 (``$HGENCODING``, ``ui.fallbackencoding``) succeeds. If correct
765 conversion fails, the text in question is sent as is.
765 conversion fails, the text in question is sent as is.
766 (default: '')
766 (default: '')
767
767
768 Order of outgoing email character sets:
768 Order of outgoing email character sets:
769
769
770 1. ``us-ascii``: always first, regardless of settings
770 1. ``us-ascii``: always first, regardless of settings
771 2. ``email.charsets``: in order given by user
771 2. ``email.charsets``: in order given by user
772 3. ``ui.fallbackencoding``: if not in email.charsets
772 3. ``ui.fallbackencoding``: if not in email.charsets
773 4. ``$HGENCODING``: if not in email.charsets
773 4. ``$HGENCODING``: if not in email.charsets
774 5. ``utf-8``: always last, regardless of settings
774 5. ``utf-8``: always last, regardless of settings
775
775
776 Email example::
776 Email example::
777
777
778 [email]
778 [email]
779 from = Joseph User <joe.user@example.com>
779 from = Joseph User <joe.user@example.com>
780 method = /usr/sbin/sendmail
780 method = /usr/sbin/sendmail
781 # charsets for western Europeans
781 # charsets for western Europeans
782 # us-ascii, utf-8 omitted, as they are tried first and last
782 # us-ascii, utf-8 omitted, as they are tried first and last
783 charsets = iso-8859-1, iso-8859-15, windows-1252
783 charsets = iso-8859-1, iso-8859-15, windows-1252
784
784
785
785
786 ``extensions``
786 ``extensions``
787 --------------
787 --------------
788
788
789 Mercurial has an extension mechanism for adding new features. To
789 Mercurial has an extension mechanism for adding new features. To
790 enable an extension, create an entry for it in this section.
790 enable an extension, create an entry for it in this section.
791
791
792 If you know that the extension is already in Python's search path,
792 If you know that the extension is already in Python's search path,
793 you can give the name of the module, followed by ``=``, with nothing
793 you can give the name of the module, followed by ``=``, with nothing
794 after the ``=``.
794 after the ``=``.
795
795
796 Otherwise, give a name that you choose, followed by ``=``, followed by
796 Otherwise, give a name that you choose, followed by ``=``, followed by
797 the path to the ``.py`` file (including the file name extension) that
797 the path to the ``.py`` file (including the file name extension) that
798 defines the extension.
798 defines the extension.
799
799
800 To explicitly disable an extension that is enabled in an hgrc of
800 To explicitly disable an extension that is enabled in an hgrc of
801 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
801 broader scope, prepend its path with ``!``, as in ``foo = !/ext/path``
802 or ``foo = !`` when path is not supplied.
802 or ``foo = !`` when path is not supplied.
803
803
804 Example for ``~/.hgrc``::
804 Example for ``~/.hgrc``::
805
805
806 [extensions]
806 [extensions]
807 # (the churn extension will get loaded from Mercurial's path)
807 # (the churn extension will get loaded from Mercurial's path)
808 churn =
808 churn =
809 # (this extension will get loaded from the file specified)
809 # (this extension will get loaded from the file specified)
810 myfeature = ~/.hgext/myfeature.py
810 myfeature = ~/.hgext/myfeature.py
811
811
812
812
813 ``format``
813 ``format``
814 ----------
814 ----------
815
815
816 Configuration that controls the repository format. Newer format options are more
816 Configuration that controls the repository format. Newer format options are more
817 powerful but incompatible with some older versions of Mercurial. Format options
817 powerful but incompatible with some older versions of Mercurial. Format options
818 are considered at repository initialization only. You need to make a new clone
818 are considered at repository initialization only. You need to make a new clone
819 for config change to be taken into account.
819 for config change to be taken into account.
820
820
821 For more details about repository format and version compatibility, see
821 For more details about repository format and version compatibility, see
822 https://www.mercurial-scm.org/wiki/MissingRequirement
822 https://www.mercurial-scm.org/wiki/MissingRequirement
823
823
824 ``usegeneraldelta``
824 ``usegeneraldelta``
825 Enable or disable the "generaldelta" repository format which improves
825 Enable or disable the "generaldelta" repository format which improves
826 repository compression by allowing "revlog" to store delta against arbitrary
826 repository compression by allowing "revlog" to store delta against arbitrary
827 revision instead of the previous stored one. This provides significant
827 revision instead of the previous stored one. This provides significant
828 improvement for repositories with branches.
828 improvement for repositories with branches.
829
829
830 Repositories with this on-disk format require Mercurial version 1.9.
830 Repositories with this on-disk format require Mercurial version 1.9.
831
831
832 Enabled by default.
832 Enabled by default.
833
833
834 ``dotencode``
834 ``dotencode``
835 Enable or disable the "dotencode" repository format which enhances
835 Enable or disable the "dotencode" repository format which enhances
836 the "fncache" repository format (which has to be enabled to use
836 the "fncache" repository format (which has to be enabled to use
837 dotencode) to avoid issues with filenames starting with ._ on
837 dotencode) to avoid issues with filenames starting with ._ on
838 Mac OS X and spaces on Windows.
838 Mac OS X and spaces on Windows.
839
839
840 Repositories with this on-disk format require Mercurial version 1.7.
840 Repositories with this on-disk format require Mercurial version 1.7.
841
841
842 Enabled by default.
842 Enabled by default.
843
843
844 ``usefncache``
844 ``usefncache``
845 Enable or disable the "fncache" repository format which enhances
845 Enable or disable the "fncache" repository format which enhances
846 the "store" repository format (which has to be enabled to use
846 the "store" repository format (which has to be enabled to use
847 fncache) to allow longer filenames and avoids using Windows
847 fncache) to allow longer filenames and avoids using Windows
848 reserved names, e.g. "nul".
848 reserved names, e.g. "nul".
849
849
850 Repositories with this on-disk format require Mercurial version 1.1.
850 Repositories with this on-disk format require Mercurial version 1.1.
851
851
852 Enabled by default.
852 Enabled by default.
853
853
854 ``usestore``
854 ``usestore``
855 Enable or disable the "store" repository format which improves
855 Enable or disable the "store" repository format which improves
856 compatibility with systems that fold case or otherwise mangle
856 compatibility with systems that fold case or otherwise mangle
857 filenames. Disabling this option will allow you to store longer filenames
857 filenames. Disabling this option will allow you to store longer filenames
858 in some situations at the expense of compatibility.
858 in some situations at the expense of compatibility.
859
859
860 Repositories with this on-disk format require Mercurial version 0.9.4.
860 Repositories with this on-disk format require Mercurial version 0.9.4.
861
861
862 Enabled by default.
862 Enabled by default.
863
863
864 ``sparse-revlog``
864 ``sparse-revlog``
865 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
865 Enable or disable the ``sparse-revlog`` delta strategy. This format improves
866 delta re-use inside revlog. For very branchy repositories, it results in a
866 delta re-use inside revlog. For very branchy repositories, it results in a
867 smaller store. For repositories with many revisions, it also helps
867 smaller store. For repositories with many revisions, it also helps
868 performance (by using shortened delta chains.)
868 performance (by using shortened delta chains.)
869
869
870 Repositories with this on-disk format require Mercurial version 4.7
870 Repositories with this on-disk format require Mercurial version 4.7
871
871
872 Enabled by default.
872 Enabled by default.
873
873
874 ``revlog-compression``
874 ``revlog-compression``
875 Compression algorithm used by revlog. Supported value are `zlib` and `zstd`.
875 Compression algorithm used by revlog. Supported value are `zlib` and `zstd`.
876 The `zlib` engine is the historical default of Mercurial. `zstd` is a newer
876 The `zlib` engine is the historical default of Mercurial. `zstd` is a newer
877 format that is usually a net win over `zlib` operating faster at better
877 format that is usually a net win over `zlib` operating faster at better
878 compression rate. Use `zstd` to reduce CPU usage.
878 compression rate. Use `zstd` to reduce CPU usage.
879
879
880 On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`.
880 On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`.
881
881
882 ``bookmarks-in-store``
883 Store bookmarks in .hg/store/. This means that bookmarks are shared when
884 using `hg share` regardless of the `-B` option.
885
886 Repositories with this on-disk format require Mercurial version 5.1.
887
888 Disabled by default.
889
890
882 ``graph``
891 ``graph``
883 ---------
892 ---------
884
893
885 Web graph view configuration. This section let you change graph
894 Web graph view configuration. This section let you change graph
886 elements display properties by branches, for instance to make the
895 elements display properties by branches, for instance to make the
887 ``default`` branch stand out.
896 ``default`` branch stand out.
888
897
889 Each line has the following format::
898 Each line has the following format::
890
899
891 <branch>.<argument> = <value>
900 <branch>.<argument> = <value>
892
901
893 where ``<branch>`` is the name of the branch being
902 where ``<branch>`` is the name of the branch being
894 customized. Example::
903 customized. Example::
895
904
896 [graph]
905 [graph]
897 # 2px width
906 # 2px width
898 default.width = 2
907 default.width = 2
899 # red color
908 # red color
900 default.color = FF0000
909 default.color = FF0000
901
910
902 Supported arguments:
911 Supported arguments:
903
912
904 ``width``
913 ``width``
905 Set branch edges width in pixels.
914 Set branch edges width in pixels.
906
915
907 ``color``
916 ``color``
908 Set branch edges color in hexadecimal RGB notation.
917 Set branch edges color in hexadecimal RGB notation.
909
918
910 ``hooks``
919 ``hooks``
911 ---------
920 ---------
912
921
913 Commands or Python functions that get automatically executed by
922 Commands or Python functions that get automatically executed by
914 various actions such as starting or finishing a commit. Multiple
923 various actions such as starting or finishing a commit. Multiple
915 hooks can be run for the same action by appending a suffix to the
924 hooks can be run for the same action by appending a suffix to the
916 action. Overriding a site-wide hook can be done by changing its
925 action. Overriding a site-wide hook can be done by changing its
917 value or setting it to an empty string. Hooks can be prioritized
926 value or setting it to an empty string. Hooks can be prioritized
918 by adding a prefix of ``priority.`` to the hook name on a new line
927 by adding a prefix of ``priority.`` to the hook name on a new line
919 and setting the priority. The default priority is 0.
928 and setting the priority. The default priority is 0.
920
929
921 Example ``.hg/hgrc``::
930 Example ``.hg/hgrc``::
922
931
923 [hooks]
932 [hooks]
924 # update working directory after adding changesets
933 # update working directory after adding changesets
925 changegroup.update = hg update
934 changegroup.update = hg update
926 # do not use the site-wide hook
935 # do not use the site-wide hook
927 incoming =
936 incoming =
928 incoming.email = /my/email/hook
937 incoming.email = /my/email/hook
929 incoming.autobuild = /my/build/hook
938 incoming.autobuild = /my/build/hook
930 # force autobuild hook to run before other incoming hooks
939 # force autobuild hook to run before other incoming hooks
931 priority.incoming.autobuild = 1
940 priority.incoming.autobuild = 1
932
941
933 Most hooks are run with environment variables set that give useful
942 Most hooks are run with environment variables set that give useful
934 additional information. For each hook below, the environment variables
943 additional information. For each hook below, the environment variables
935 it is passed are listed with names in the form ``$HG_foo``. The
944 it is passed are listed with names in the form ``$HG_foo``. The
936 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
945 ``$HG_HOOKTYPE`` and ``$HG_HOOKNAME`` variables are set for all hooks.
937 They contain the type of hook which triggered the run and the full name
946 They contain the type of hook which triggered the run and the full name
938 of the hook in the config, respectively. In the example above, this will
947 of the hook in the config, respectively. In the example above, this will
939 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
948 be ``$HG_HOOKTYPE=incoming`` and ``$HG_HOOKNAME=incoming.email``.
940
949
941 .. container:: windows
950 .. container:: windows
942
951
943 Some basic Unix syntax can be enabled for portability, including ``$VAR``
952 Some basic Unix syntax can be enabled for portability, including ``$VAR``
944 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
953 and ``${VAR}`` style variables. A ``~`` followed by ``\`` or ``/`` will
945 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
954 be expanded to ``%USERPROFILE%`` to simulate a subset of tilde expansion
946 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
955 on Unix. To use a literal ``$`` or ``~``, it must be escaped with a back
947 slash or inside of a strong quote. Strong quotes will be replaced by
956 slash or inside of a strong quote. Strong quotes will be replaced by
948 double quotes after processing.
957 double quotes after processing.
949
958
950 This feature is enabled by adding a prefix of ``tonative.`` to the hook
959 This feature is enabled by adding a prefix of ``tonative.`` to the hook
951 name on a new line, and setting it to ``True``. For example::
960 name on a new line, and setting it to ``True``. For example::
952
961
953 [hooks]
962 [hooks]
954 incoming.autobuild = /my/build/hook
963 incoming.autobuild = /my/build/hook
955 # enable translation to cmd.exe syntax for autobuild hook
964 # enable translation to cmd.exe syntax for autobuild hook
956 tonative.incoming.autobuild = True
965 tonative.incoming.autobuild = True
957
966
958 ``changegroup``
967 ``changegroup``
959 Run after a changegroup has been added via push, pull or unbundle. The ID of
968 Run after a changegroup has been added via push, pull or unbundle. The ID of
960 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
969 the first new changeset is in ``$HG_NODE`` and last is in ``$HG_NODE_LAST``.
961 The URL from which changes came is in ``$HG_URL``.
970 The URL from which changes came is in ``$HG_URL``.
962
971
963 ``commit``
972 ``commit``
964 Run after a changeset has been created in the local repository. The ID
973 Run after a changeset has been created in the local repository. The ID
965 of the newly created changeset is in ``$HG_NODE``. Parent changeset
974 of the newly created changeset is in ``$HG_NODE``. Parent changeset
966 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
975 IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
967
976
968 ``incoming``
977 ``incoming``
969 Run after a changeset has been pulled, pushed, or unbundled into
978 Run after a changeset has been pulled, pushed, or unbundled into
970 the local repository. The ID of the newly arrived changeset is in
979 the local repository. The ID of the newly arrived changeset is in
971 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
980 ``$HG_NODE``. The URL that was source of the changes is in ``$HG_URL``.
972
981
973 ``outgoing``
982 ``outgoing``
974 Run after sending changes from the local repository to another. The ID of
983 Run after sending changes from the local repository to another. The ID of
975 first changeset sent is in ``$HG_NODE``. The source of operation is in
984 first changeset sent is in ``$HG_NODE``. The source of operation is in
976 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
985 ``$HG_SOURCE``. Also see :hg:`help config.hooks.preoutgoing`.
977
986
978 ``post-<command>``
987 ``post-<command>``
979 Run after successful invocations of the associated command. The
988 Run after successful invocations of the associated command. The
980 contents of the command line are passed as ``$HG_ARGS`` and the result
989 contents of the command line are passed as ``$HG_ARGS`` and the result
981 code in ``$HG_RESULT``. Parsed command line arguments are passed as
990 code in ``$HG_RESULT``. Parsed command line arguments are passed as
982 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
991 ``$HG_PATS`` and ``$HG_OPTS``. These contain string representations of
983 the python data internally passed to <command>. ``$HG_OPTS`` is a
992 the python data internally passed to <command>. ``$HG_OPTS`` is a
984 dictionary of options (with unspecified options set to their defaults).
993 dictionary of options (with unspecified options set to their defaults).
985 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
994 ``$HG_PATS`` is a list of arguments. Hook failure is ignored.
986
995
987 ``fail-<command>``
996 ``fail-<command>``
988 Run after a failed invocation of an associated command. The contents
997 Run after a failed invocation of an associated command. The contents
989 of the command line are passed as ``$HG_ARGS``. Parsed command line
998 of the command line are passed as ``$HG_ARGS``. Parsed command line
990 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
999 arguments are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain
991 string representations of the python data internally passed to
1000 string representations of the python data internally passed to
992 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
1001 <command>. ``$HG_OPTS`` is a dictionary of options (with unspecified
993 options set to their defaults). ``$HG_PATS`` is a list of arguments.
1002 options set to their defaults). ``$HG_PATS`` is a list of arguments.
994 Hook failure is ignored.
1003 Hook failure is ignored.
995
1004
996 ``pre-<command>``
1005 ``pre-<command>``
997 Run before executing the associated command. The contents of the
1006 Run before executing the associated command. The contents of the
998 command line are passed as ``$HG_ARGS``. Parsed command line arguments
1007 command line are passed as ``$HG_ARGS``. Parsed command line arguments
999 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1008 are passed as ``$HG_PATS`` and ``$HG_OPTS``. These contain string
1000 representations of the data internally passed to <command>. ``$HG_OPTS``
1009 representations of the data internally passed to <command>. ``$HG_OPTS``
1001 is a dictionary of options (with unspecified options set to their
1010 is a dictionary of options (with unspecified options set to their
1002 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
1011 defaults). ``$HG_PATS`` is a list of arguments. If the hook returns
1003 failure, the command doesn't execute and Mercurial returns the failure
1012 failure, the command doesn't execute and Mercurial returns the failure
1004 code.
1013 code.
1005
1014
1006 ``prechangegroup``
1015 ``prechangegroup``
1007 Run before a changegroup is added via push, pull or unbundle. Exit
1016 Run before a changegroup is added via push, pull or unbundle. Exit
1008 status 0 allows the changegroup to proceed. A non-zero status will
1017 status 0 allows the changegroup to proceed. A non-zero status will
1009 cause the push, pull or unbundle to fail. The URL from which changes
1018 cause the push, pull or unbundle to fail. The URL from which changes
1010 will come is in ``$HG_URL``.
1019 will come is in ``$HG_URL``.
1011
1020
1012 ``precommit``
1021 ``precommit``
1013 Run before starting a local commit. Exit status 0 allows the
1022 Run before starting a local commit. Exit status 0 allows the
1014 commit to proceed. A non-zero status will cause the commit to fail.
1023 commit to proceed. A non-zero status will cause the commit to fail.
1015 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1024 Parent changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1016
1025
1017 ``prelistkeys``
1026 ``prelistkeys``
1018 Run before listing pushkeys (like bookmarks) in the
1027 Run before listing pushkeys (like bookmarks) in the
1019 repository. A non-zero status will cause failure. The key namespace is
1028 repository. A non-zero status will cause failure. The key namespace is
1020 in ``$HG_NAMESPACE``.
1029 in ``$HG_NAMESPACE``.
1021
1030
1022 ``preoutgoing``
1031 ``preoutgoing``
1023 Run before collecting changes to send from the local repository to
1032 Run before collecting changes to send from the local repository to
1024 another. A non-zero status will cause failure. This lets you prevent
1033 another. A non-zero status will cause failure. This lets you prevent
1025 pull over HTTP or SSH. It can also prevent propagating commits (via
1034 pull over HTTP or SSH. It can also prevent propagating commits (via
1026 local pull, push (outbound) or bundle commands), but not completely,
1035 local pull, push (outbound) or bundle commands), but not completely,
1027 since you can just copy files instead. The source of operation is in
1036 since you can just copy files instead. The source of operation is in
1028 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1037 ``$HG_SOURCE``. If "serve", the operation is happening on behalf of a remote
1029 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1038 SSH or HTTP repository. If "push", "pull" or "bundle", the operation
1030 is happening on behalf of a repository on same system.
1039 is happening on behalf of a repository on same system.
1031
1040
1032 ``prepushkey``
1041 ``prepushkey``
1033 Run before a pushkey (like a bookmark) is added to the
1042 Run before a pushkey (like a bookmark) is added to the
1034 repository. A non-zero status will cause the key to be rejected. The
1043 repository. A non-zero status will cause the key to be rejected. The
1035 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1044 key namespace is in ``$HG_NAMESPACE``, the key is in ``$HG_KEY``,
1036 the old value (if any) is in ``$HG_OLD``, and the new value is in
1045 the old value (if any) is in ``$HG_OLD``, and the new value is in
1037 ``$HG_NEW``.
1046 ``$HG_NEW``.
1038
1047
1039 ``pretag``
1048 ``pretag``
1040 Run before creating a tag. Exit status 0 allows the tag to be
1049 Run before creating a tag. Exit status 0 allows the tag to be
1041 created. A non-zero status will cause the tag to fail. The ID of the
1050 created. A non-zero status will cause the tag to fail. The ID of the
1042 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1051 changeset to tag is in ``$HG_NODE``. The name of tag is in ``$HG_TAG``. The
1043 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1052 tag is local if ``$HG_LOCAL=1``, or in the repository if ``$HG_LOCAL=0``.
1044
1053
1045 ``pretxnopen``
1054 ``pretxnopen``
1046 Run before any new repository transaction is open. The reason for the
1055 Run before any new repository transaction is open. The reason for the
1047 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1056 transaction will be in ``$HG_TXNNAME``, and a unique identifier for the
1048 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1057 transaction will be in ``HG_TXNID``. A non-zero status will prevent the
1049 transaction from being opened.
1058 transaction from being opened.
1050
1059
1051 ``pretxnclose``
1060 ``pretxnclose``
1052 Run right before the transaction is actually finalized. Any repository change
1061 Run right before the transaction is actually finalized. Any repository change
1053 will be visible to the hook program. This lets you validate the transaction
1062 will be visible to the hook program. This lets you validate the transaction
1054 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1063 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1055 status will cause the transaction to be rolled back. The reason for the
1064 status will cause the transaction to be rolled back. The reason for the
1056 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1065 transaction opening will be in ``$HG_TXNNAME``, and a unique identifier for
1057 the transaction will be in ``HG_TXNID``. The rest of the available data will
1066 the transaction will be in ``HG_TXNID``. The rest of the available data will
1058 vary according the transaction type. New changesets will add ``$HG_NODE``
1067 vary according the transaction type. New changesets will add ``$HG_NODE``
1059 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1068 (the ID of the first added changeset), ``$HG_NODE_LAST`` (the ID of the last
1060 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1069 added changeset), ``$HG_URL`` and ``$HG_SOURCE`` variables. Bookmark and
1061 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1070 phase changes will set ``HG_BOOKMARK_MOVED`` and ``HG_PHASES_MOVED`` to ``1``
1062 respectively, etc.
1071 respectively, etc.
1063
1072
1064 ``pretxnclose-bookmark``
1073 ``pretxnclose-bookmark``
1065 Run right before a bookmark change is actually finalized. Any repository
1074 Run right before a bookmark change is actually finalized. Any repository
1066 change will be visible to the hook program. This lets you validate the
1075 change will be visible to the hook program. This lets you validate the
1067 transaction content or change it. Exit status 0 allows the commit to
1076 transaction content or change it. Exit status 0 allows the commit to
1068 proceed. A non-zero status will cause the transaction to be rolled back.
1077 proceed. A non-zero status will cause the transaction to be rolled back.
1069 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1078 The name of the bookmark will be available in ``$HG_BOOKMARK``, the new
1070 bookmark location will be available in ``$HG_NODE`` while the previous
1079 bookmark location will be available in ``$HG_NODE`` while the previous
1071 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1080 location will be available in ``$HG_OLDNODE``. In case of a bookmark
1072 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1081 creation ``$HG_OLDNODE`` will be empty. In case of deletion ``$HG_NODE``
1073 will be empty.
1082 will be empty.
1074 In addition, the reason for the transaction opening will be in
1083 In addition, the reason for the transaction opening will be in
1075 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1084 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1076 ``HG_TXNID``.
1085 ``HG_TXNID``.
1077
1086
1078 ``pretxnclose-phase``
1087 ``pretxnclose-phase``
1079 Run right before a phase change is actually finalized. Any repository change
1088 Run right before a phase change is actually finalized. Any repository change
1080 will be visible to the hook program. This lets you validate the transaction
1089 will be visible to the hook program. This lets you validate the transaction
1081 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1090 content or change it. Exit status 0 allows the commit to proceed. A non-zero
1082 status will cause the transaction to be rolled back. The hook is called
1091 status will cause the transaction to be rolled back. The hook is called
1083 multiple times, once for each revision affected by a phase change.
1092 multiple times, once for each revision affected by a phase change.
1084 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1093 The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``
1085 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1094 while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``
1086 will be empty. In addition, the reason for the transaction opening will be in
1095 will be empty. In addition, the reason for the transaction opening will be in
1087 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1096 ``$HG_TXNNAME``, and a unique identifier for the transaction will be in
1088 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1097 ``HG_TXNID``. The hook is also run for newly added revisions. In this case
1089 the ``$HG_OLDPHASE`` entry will be empty.
1098 the ``$HG_OLDPHASE`` entry will be empty.
1090
1099
1091 ``txnclose``
1100 ``txnclose``
1092 Run after any repository transaction has been committed. At this
1101 Run after any repository transaction has been committed. At this
1093 point, the transaction can no longer be rolled back. The hook will run
1102 point, the transaction can no longer be rolled back. The hook will run
1094 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1103 after the lock is released. See :hg:`help config.hooks.pretxnclose` for
1095 details about available variables.
1104 details about available variables.
1096
1105
1097 ``txnclose-bookmark``
1106 ``txnclose-bookmark``
1098 Run after any bookmark change has been committed. At this point, the
1107 Run after any bookmark change has been committed. At this point, the
1099 transaction can no longer be rolled back. The hook will run after the lock
1108 transaction can no longer be rolled back. The hook will run after the lock
1100 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1109 is released. See :hg:`help config.hooks.pretxnclose-bookmark` for details
1101 about available variables.
1110 about available variables.
1102
1111
1103 ``txnclose-phase``
1112 ``txnclose-phase``
1104 Run after any phase change has been committed. At this point, the
1113 Run after any phase change has been committed. At this point, the
1105 transaction can no longer be rolled back. The hook will run after the lock
1114 transaction can no longer be rolled back. The hook will run after the lock
1106 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1115 is released. See :hg:`help config.hooks.pretxnclose-phase` for details about
1107 available variables.
1116 available variables.
1108
1117
1109 ``txnabort``
1118 ``txnabort``
1110 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1119 Run when a transaction is aborted. See :hg:`help config.hooks.pretxnclose`
1111 for details about available variables.
1120 for details about available variables.
1112
1121
1113 ``pretxnchangegroup``
1122 ``pretxnchangegroup``
1114 Run after a changegroup has been added via push, pull or unbundle, but before
1123 Run after a changegroup has been added via push, pull or unbundle, but before
1115 the transaction has been committed. The changegroup is visible to the hook
1124 the transaction has been committed. The changegroup is visible to the hook
1116 program. This allows validation of incoming changes before accepting them.
1125 program. This allows validation of incoming changes before accepting them.
1117 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1126 The ID of the first new changeset is in ``$HG_NODE`` and last is in
1118 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1127 ``$HG_NODE_LAST``. Exit status 0 allows the transaction to commit. A non-zero
1119 status will cause the transaction to be rolled back, and the push, pull or
1128 status will cause the transaction to be rolled back, and the push, pull or
1120 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1129 unbundle will fail. The URL that was the source of changes is in ``$HG_URL``.
1121
1130
1122 ``pretxncommit``
1131 ``pretxncommit``
1123 Run after a changeset has been created, but before the transaction is
1132 Run after a changeset has been created, but before the transaction is
1124 committed. The changeset is visible to the hook program. This allows
1133 committed. The changeset is visible to the hook program. This allows
1125 validation of the commit message and changes. Exit status 0 allows the
1134 validation of the commit message and changes. Exit status 0 allows the
1126 commit to proceed. A non-zero status will cause the transaction to
1135 commit to proceed. A non-zero status will cause the transaction to
1127 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1136 be rolled back. The ID of the new changeset is in ``$HG_NODE``. The parent
1128 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1137 changeset IDs are in ``$HG_PARENT1`` and ``$HG_PARENT2``.
1129
1138
1130 ``preupdate``
1139 ``preupdate``
1131 Run before updating the working directory. Exit status 0 allows
1140 Run before updating the working directory. Exit status 0 allows
1132 the update to proceed. A non-zero status will prevent the update.
1141 the update to proceed. A non-zero status will prevent the update.
1133 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1142 The changeset ID of first new parent is in ``$HG_PARENT1``. If updating to a
1134 merge, the ID of second new parent is in ``$HG_PARENT2``.
1143 merge, the ID of second new parent is in ``$HG_PARENT2``.
1135
1144
1136 ``listkeys``
1145 ``listkeys``
1137 Run after listing pushkeys (like bookmarks) in the repository. The
1146 Run after listing pushkeys (like bookmarks) in the repository. The
1138 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1147 key namespace is in ``$HG_NAMESPACE``. ``$HG_VALUES`` is a
1139 dictionary containing the keys and values.
1148 dictionary containing the keys and values.
1140
1149
1141 ``pushkey``
1150 ``pushkey``
1142 Run after a pushkey (like a bookmark) is added to the
1151 Run after a pushkey (like a bookmark) is added to the
1143 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1152 repository. The key namespace is in ``$HG_NAMESPACE``, the key is in
1144 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1153 ``$HG_KEY``, the old value (if any) is in ``$HG_OLD``, and the new
1145 value is in ``$HG_NEW``.
1154 value is in ``$HG_NEW``.
1146
1155
1147 ``tag``
1156 ``tag``
1148 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1157 Run after a tag is created. The ID of the tagged changeset is in ``$HG_NODE``.
1149 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1158 The name of tag is in ``$HG_TAG``. The tag is local if ``$HG_LOCAL=1``, or in
1150 the repository if ``$HG_LOCAL=0``.
1159 the repository if ``$HG_LOCAL=0``.
1151
1160
1152 ``update``
1161 ``update``
1153 Run after updating the working directory. The changeset ID of first
1162 Run after updating the working directory. The changeset ID of first
1154 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1163 new parent is in ``$HG_PARENT1``. If updating to a merge, the ID of second new
1155 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1164 parent is in ``$HG_PARENT2``. If the update succeeded, ``$HG_ERROR=0``. If the
1156 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1165 update failed (e.g. because conflicts were not resolved), ``$HG_ERROR=1``.
1157
1166
1158 .. note::
1167 .. note::
1159
1168
1160 It is generally better to use standard hooks rather than the
1169 It is generally better to use standard hooks rather than the
1161 generic pre- and post- command hooks, as they are guaranteed to be
1170 generic pre- and post- command hooks, as they are guaranteed to be
1162 called in the appropriate contexts for influencing transactions.
1171 called in the appropriate contexts for influencing transactions.
1163 Also, hooks like "commit" will be called in all contexts that
1172 Also, hooks like "commit" will be called in all contexts that
1164 generate a commit (e.g. tag) and not just the commit command.
1173 generate a commit (e.g. tag) and not just the commit command.
1165
1174
1166 .. note::
1175 .. note::
1167
1176
1168 Environment variables with empty values may not be passed to
1177 Environment variables with empty values may not be passed to
1169 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1178 hooks on platforms such as Windows. As an example, ``$HG_PARENT2``
1170 will have an empty value under Unix-like platforms for non-merge
1179 will have an empty value under Unix-like platforms for non-merge
1171 changesets, while it will not be available at all under Windows.
1180 changesets, while it will not be available at all under Windows.
1172
1181
1173 The syntax for Python hooks is as follows::
1182 The syntax for Python hooks is as follows::
1174
1183
1175 hookname = python:modulename.submodule.callable
1184 hookname = python:modulename.submodule.callable
1176 hookname = python:/path/to/python/module.py:callable
1185 hookname = python:/path/to/python/module.py:callable
1177
1186
1178 Python hooks are run within the Mercurial process. Each hook is
1187 Python hooks are run within the Mercurial process. Each hook is
1179 called with at least three keyword arguments: a ui object (keyword
1188 called with at least three keyword arguments: a ui object (keyword
1180 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1189 ``ui``), a repository object (keyword ``repo``), and a ``hooktype``
1181 keyword that tells what kind of hook is used. Arguments listed as
1190 keyword that tells what kind of hook is used. Arguments listed as
1182 environment variables above are passed as keyword arguments, with no
1191 environment variables above are passed as keyword arguments, with no
1183 ``HG_`` prefix, and names in lower case.
1192 ``HG_`` prefix, and names in lower case.
1184
1193
1185 If a Python hook returns a "true" value or raises an exception, this
1194 If a Python hook returns a "true" value or raises an exception, this
1186 is treated as a failure.
1195 is treated as a failure.
1187
1196
1188
1197
1189 ``hostfingerprints``
1198 ``hostfingerprints``
1190 --------------------
1199 --------------------
1191
1200
1192 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1201 (Deprecated. Use ``[hostsecurity]``'s ``fingerprints`` options instead.)
1193
1202
1194 Fingerprints of the certificates of known HTTPS servers.
1203 Fingerprints of the certificates of known HTTPS servers.
1195
1204
1196 A HTTPS connection to a server with a fingerprint configured here will
1205 A HTTPS connection to a server with a fingerprint configured here will
1197 only succeed if the servers certificate matches the fingerprint.
1206 only succeed if the servers certificate matches the fingerprint.
1198 This is very similar to how ssh known hosts works.
1207 This is very similar to how ssh known hosts works.
1199
1208
1200 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1209 The fingerprint is the SHA-1 hash value of the DER encoded certificate.
1201 Multiple values can be specified (separated by spaces or commas). This can
1210 Multiple values can be specified (separated by spaces or commas). This can
1202 be used to define both old and new fingerprints while a host transitions
1211 be used to define both old and new fingerprints while a host transitions
1203 to a new certificate.
1212 to a new certificate.
1204
1213
1205 The CA chain and web.cacerts is not used for servers with a fingerprint.
1214 The CA chain and web.cacerts is not used for servers with a fingerprint.
1206
1215
1207 For example::
1216 For example::
1208
1217
1209 [hostfingerprints]
1218 [hostfingerprints]
1210 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1219 hg.intevation.de = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1211 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1220 hg.intevation.org = fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1212
1221
1213 ``hostsecurity``
1222 ``hostsecurity``
1214 ----------------
1223 ----------------
1215
1224
1216 Used to specify global and per-host security settings for connecting to
1225 Used to specify global and per-host security settings for connecting to
1217 other machines.
1226 other machines.
1218
1227
1219 The following options control default behavior for all hosts.
1228 The following options control default behavior for all hosts.
1220
1229
1221 ``ciphers``
1230 ``ciphers``
1222 Defines the cryptographic ciphers to use for connections.
1231 Defines the cryptographic ciphers to use for connections.
1223
1232
1224 Value must be a valid OpenSSL Cipher List Format as documented at
1233 Value must be a valid OpenSSL Cipher List Format as documented at
1225 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1234 https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-LIST-FORMAT.
1226
1235
1227 This setting is for advanced users only. Setting to incorrect values
1236 This setting is for advanced users only. Setting to incorrect values
1228 can significantly lower connection security or decrease performance.
1237 can significantly lower connection security or decrease performance.
1229 You have been warned.
1238 You have been warned.
1230
1239
1231 This option requires Python 2.7.
1240 This option requires Python 2.7.
1232
1241
1233 ``minimumprotocol``
1242 ``minimumprotocol``
1234 Defines the minimum channel encryption protocol to use.
1243 Defines the minimum channel encryption protocol to use.
1235
1244
1236 By default, the highest version of TLS supported by both client and server
1245 By default, the highest version of TLS supported by both client and server
1237 is used.
1246 is used.
1238
1247
1239 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1248 Allowed values are: ``tls1.0``, ``tls1.1``, ``tls1.2``.
1240
1249
1241 When running on an old Python version, only ``tls1.0`` is allowed since
1250 When running on an old Python version, only ``tls1.0`` is allowed since
1242 old versions of Python only support up to TLS 1.0.
1251 old versions of Python only support up to TLS 1.0.
1243
1252
1244 When running a Python that supports modern TLS versions, the default is
1253 When running a Python that supports modern TLS versions, the default is
1245 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1254 ``tls1.1``. ``tls1.0`` can still be used to allow TLS 1.0. However, this
1246 weakens security and should only be used as a feature of last resort if
1255 weakens security and should only be used as a feature of last resort if
1247 a server does not support TLS 1.1+.
1256 a server does not support TLS 1.1+.
1248
1257
1249 Options in the ``[hostsecurity]`` section can have the form
1258 Options in the ``[hostsecurity]`` section can have the form
1250 ``hostname``:``setting``. This allows multiple settings to be defined on a
1259 ``hostname``:``setting``. This allows multiple settings to be defined on a
1251 per-host basis.
1260 per-host basis.
1252
1261
1253 The following per-host settings can be defined.
1262 The following per-host settings can be defined.
1254
1263
1255 ``ciphers``
1264 ``ciphers``
1256 This behaves like ``ciphers`` as described above except it only applies
1265 This behaves like ``ciphers`` as described above except it only applies
1257 to the host on which it is defined.
1266 to the host on which it is defined.
1258
1267
1259 ``fingerprints``
1268 ``fingerprints``
1260 A list of hashes of the DER encoded peer/remote certificate. Values have
1269 A list of hashes of the DER encoded peer/remote certificate. Values have
1261 the form ``algorithm``:``fingerprint``. e.g.
1270 the form ``algorithm``:``fingerprint``. e.g.
1262 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1271 ``sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2``.
1263 In addition, colons (``:``) can appear in the fingerprint part.
1272 In addition, colons (``:``) can appear in the fingerprint part.
1264
1273
1265 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1274 The following algorithms/prefixes are supported: ``sha1``, ``sha256``,
1266 ``sha512``.
1275 ``sha512``.
1267
1276
1268 Use of ``sha256`` or ``sha512`` is preferred.
1277 Use of ``sha256`` or ``sha512`` is preferred.
1269
1278
1270 If a fingerprint is specified, the CA chain is not validated for this
1279 If a fingerprint is specified, the CA chain is not validated for this
1271 host and Mercurial will require the remote certificate to match one
1280 host and Mercurial will require the remote certificate to match one
1272 of the fingerprints specified. This means if the server updates its
1281 of the fingerprints specified. This means if the server updates its
1273 certificate, Mercurial will abort until a new fingerprint is defined.
1282 certificate, Mercurial will abort until a new fingerprint is defined.
1274 This can provide stronger security than traditional CA-based validation
1283 This can provide stronger security than traditional CA-based validation
1275 at the expense of convenience.
1284 at the expense of convenience.
1276
1285
1277 This option takes precedence over ``verifycertsfile``.
1286 This option takes precedence over ``verifycertsfile``.
1278
1287
1279 ``minimumprotocol``
1288 ``minimumprotocol``
1280 This behaves like ``minimumprotocol`` as described above except it
1289 This behaves like ``minimumprotocol`` as described above except it
1281 only applies to the host on which it is defined.
1290 only applies to the host on which it is defined.
1282
1291
1283 ``verifycertsfile``
1292 ``verifycertsfile``
1284 Path to file a containing a list of PEM encoded certificates used to
1293 Path to file a containing a list of PEM encoded certificates used to
1285 verify the server certificate. Environment variables and ``~user``
1294 verify the server certificate. Environment variables and ``~user``
1286 constructs are expanded in the filename.
1295 constructs are expanded in the filename.
1287
1296
1288 The server certificate or the certificate's certificate authority (CA)
1297 The server certificate or the certificate's certificate authority (CA)
1289 must match a certificate from this file or certificate verification
1298 must match a certificate from this file or certificate verification
1290 will fail and connections to the server will be refused.
1299 will fail and connections to the server will be refused.
1291
1300
1292 If defined, only certificates provided by this file will be used:
1301 If defined, only certificates provided by this file will be used:
1293 ``web.cacerts`` and any system/default certificates will not be
1302 ``web.cacerts`` and any system/default certificates will not be
1294 used.
1303 used.
1295
1304
1296 This option has no effect if the per-host ``fingerprints`` option
1305 This option has no effect if the per-host ``fingerprints`` option
1297 is set.
1306 is set.
1298
1307
1299 The format of the file is as follows::
1308 The format of the file is as follows::
1300
1309
1301 -----BEGIN CERTIFICATE-----
1310 -----BEGIN CERTIFICATE-----
1302 ... (certificate in base64 PEM encoding) ...
1311 ... (certificate in base64 PEM encoding) ...
1303 -----END CERTIFICATE-----
1312 -----END CERTIFICATE-----
1304 -----BEGIN CERTIFICATE-----
1313 -----BEGIN CERTIFICATE-----
1305 ... (certificate in base64 PEM encoding) ...
1314 ... (certificate in base64 PEM encoding) ...
1306 -----END CERTIFICATE-----
1315 -----END CERTIFICATE-----
1307
1316
1308 For example::
1317 For example::
1309
1318
1310 [hostsecurity]
1319 [hostsecurity]
1311 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1320 hg.example.com:fingerprints = sha256:c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2
1312 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1321 hg2.example.com:fingerprints = sha1:914f1aff87249c09b6859b88b1906d30756491ca, sha1:fc:e2:8d:d9:51:cd:cb:c1:4d:18:6b:b7:44:8d:49:72:57:e6:cd:33
1313 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1322 hg3.example.com:fingerprints = sha256:9a:b0:dc:e2:75:ad:8a:b7:84:58:e5:1f:07:32:f1:87:e6:bd:24:22:af:b7:ce:8e:9c:b4:10:cf:b9:f4:0e:d2
1314 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1323 foo.example.com:verifycertsfile = /etc/ssl/trusted-ca-certs.pem
1315
1324
1316 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1325 To change the default minimum protocol version to TLS 1.2 but to allow TLS 1.1
1317 when connecting to ``hg.example.com``::
1326 when connecting to ``hg.example.com``::
1318
1327
1319 [hostsecurity]
1328 [hostsecurity]
1320 minimumprotocol = tls1.2
1329 minimumprotocol = tls1.2
1321 hg.example.com:minimumprotocol = tls1.1
1330 hg.example.com:minimumprotocol = tls1.1
1322
1331
1323 ``http_proxy``
1332 ``http_proxy``
1324 --------------
1333 --------------
1325
1334
1326 Used to access web-based Mercurial repositories through a HTTP
1335 Used to access web-based Mercurial repositories through a HTTP
1327 proxy.
1336 proxy.
1328
1337
1329 ``host``
1338 ``host``
1330 Host name and (optional) port of the proxy server, for example
1339 Host name and (optional) port of the proxy server, for example
1331 "myproxy:8000".
1340 "myproxy:8000".
1332
1341
1333 ``no``
1342 ``no``
1334 Optional. Comma-separated list of host names that should bypass
1343 Optional. Comma-separated list of host names that should bypass
1335 the proxy.
1344 the proxy.
1336
1345
1337 ``passwd``
1346 ``passwd``
1338 Optional. Password to authenticate with at the proxy server.
1347 Optional. Password to authenticate with at the proxy server.
1339
1348
1340 ``user``
1349 ``user``
1341 Optional. User name to authenticate with at the proxy server.
1350 Optional. User name to authenticate with at the proxy server.
1342
1351
1343 ``always``
1352 ``always``
1344 Optional. Always use the proxy, even for localhost and any entries
1353 Optional. Always use the proxy, even for localhost and any entries
1345 in ``http_proxy.no``. (default: False)
1354 in ``http_proxy.no``. (default: False)
1346
1355
1347 ``http``
1356 ``http``
1348 ----------
1357 ----------
1349
1358
1350 Used to configure access to Mercurial repositories via HTTP.
1359 Used to configure access to Mercurial repositories via HTTP.
1351
1360
1352 ``timeout``
1361 ``timeout``
1353 If set, blocking operations will timeout after that many seconds.
1362 If set, blocking operations will timeout after that many seconds.
1354 (default: None)
1363 (default: None)
1355
1364
1356 ``merge``
1365 ``merge``
1357 ---------
1366 ---------
1358
1367
1359 This section specifies behavior during merges and updates.
1368 This section specifies behavior during merges and updates.
1360
1369
1361 ``checkignored``
1370 ``checkignored``
1362 Controls behavior when an ignored file on disk has the same name as a tracked
1371 Controls behavior when an ignored file on disk has the same name as a tracked
1363 file in the changeset being merged or updated to, and has different
1372 file in the changeset being merged or updated to, and has different
1364 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1373 contents. Options are ``abort``, ``warn`` and ``ignore``. With ``abort``,
1365 abort on such files. With ``warn``, warn on such files and back them up as
1374 abort on such files. With ``warn``, warn on such files and back them up as
1366 ``.orig``. With ``ignore``, don't print a warning and back them up as
1375 ``.orig``. With ``ignore``, don't print a warning and back them up as
1367 ``.orig``. (default: ``abort``)
1376 ``.orig``. (default: ``abort``)
1368
1377
1369 ``checkunknown``
1378 ``checkunknown``
1370 Controls behavior when an unknown file that isn't ignored has the same name
1379 Controls behavior when an unknown file that isn't ignored has the same name
1371 as a tracked file in the changeset being merged or updated to, and has
1380 as a tracked file in the changeset being merged or updated to, and has
1372 different contents. Similar to ``merge.checkignored``, except for files that
1381 different contents. Similar to ``merge.checkignored``, except for files that
1373 are not ignored. (default: ``abort``)
1382 are not ignored. (default: ``abort``)
1374
1383
1375 ``on-failure``
1384 ``on-failure``
1376 When set to ``continue`` (the default), the merge process attempts to
1385 When set to ``continue`` (the default), the merge process attempts to
1377 merge all unresolved files using the merge chosen tool, regardless of
1386 merge all unresolved files using the merge chosen tool, regardless of
1378 whether previous file merge attempts during the process succeeded or not.
1387 whether previous file merge attempts during the process succeeded or not.
1379 Setting this to ``prompt`` will prompt after any merge failure continue
1388 Setting this to ``prompt`` will prompt after any merge failure continue
1380 or halt the merge process. Setting this to ``halt`` will automatically
1389 or halt the merge process. Setting this to ``halt`` will automatically
1381 halt the merge process on any merge tool failure. The merge process
1390 halt the merge process on any merge tool failure. The merge process
1382 can be restarted by using the ``resolve`` command. When a merge is
1391 can be restarted by using the ``resolve`` command. When a merge is
1383 halted, the repository is left in a normal ``unresolved`` merge state.
1392 halted, the repository is left in a normal ``unresolved`` merge state.
1384 (default: ``continue``)
1393 (default: ``continue``)
1385
1394
1386 ``strict-capability-check``
1395 ``strict-capability-check``
1387 Whether capabilities of internal merge tools are checked strictly
1396 Whether capabilities of internal merge tools are checked strictly
1388 or not, while examining rules to decide merge tool to be used.
1397 or not, while examining rules to decide merge tool to be used.
1389 (default: False)
1398 (default: False)
1390
1399
1391 ``merge-patterns``
1400 ``merge-patterns``
1392 ------------------
1401 ------------------
1393
1402
1394 This section specifies merge tools to associate with particular file
1403 This section specifies merge tools to associate with particular file
1395 patterns. Tools matched here will take precedence over the default
1404 patterns. Tools matched here will take precedence over the default
1396 merge tool. Patterns are globs by default, rooted at the repository
1405 merge tool. Patterns are globs by default, rooted at the repository
1397 root.
1406 root.
1398
1407
1399 Example::
1408 Example::
1400
1409
1401 [merge-patterns]
1410 [merge-patterns]
1402 **.c = kdiff3
1411 **.c = kdiff3
1403 **.jpg = myimgmerge
1412 **.jpg = myimgmerge
1404
1413
1405 ``merge-tools``
1414 ``merge-tools``
1406 ---------------
1415 ---------------
1407
1416
1408 This section configures external merge tools to use for file-level
1417 This section configures external merge tools to use for file-level
1409 merges. This section has likely been preconfigured at install time.
1418 merges. This section has likely been preconfigured at install time.
1410 Use :hg:`config merge-tools` to check the existing configuration.
1419 Use :hg:`config merge-tools` to check the existing configuration.
1411 Also see :hg:`help merge-tools` for more details.
1420 Also see :hg:`help merge-tools` for more details.
1412
1421
1413 Example ``~/.hgrc``::
1422 Example ``~/.hgrc``::
1414
1423
1415 [merge-tools]
1424 [merge-tools]
1416 # Override stock tool location
1425 # Override stock tool location
1417 kdiff3.executable = ~/bin/kdiff3
1426 kdiff3.executable = ~/bin/kdiff3
1418 # Specify command line
1427 # Specify command line
1419 kdiff3.args = $base $local $other -o $output
1428 kdiff3.args = $base $local $other -o $output
1420 # Give higher priority
1429 # Give higher priority
1421 kdiff3.priority = 1
1430 kdiff3.priority = 1
1422
1431
1423 # Changing the priority of preconfigured tool
1432 # Changing the priority of preconfigured tool
1424 meld.priority = 0
1433 meld.priority = 0
1425
1434
1426 # Disable a preconfigured tool
1435 # Disable a preconfigured tool
1427 vimdiff.disabled = yes
1436 vimdiff.disabled = yes
1428
1437
1429 # Define new tool
1438 # Define new tool
1430 myHtmlTool.args = -m $local $other $base $output
1439 myHtmlTool.args = -m $local $other $base $output
1431 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1440 myHtmlTool.regkey = Software\FooSoftware\HtmlMerge
1432 myHtmlTool.priority = 1
1441 myHtmlTool.priority = 1
1433
1442
1434 Supported arguments:
1443 Supported arguments:
1435
1444
1436 ``priority``
1445 ``priority``
1437 The priority in which to evaluate this tool.
1446 The priority in which to evaluate this tool.
1438 (default: 0)
1447 (default: 0)
1439
1448
1440 ``executable``
1449 ``executable``
1441 Either just the name of the executable or its pathname.
1450 Either just the name of the executable or its pathname.
1442
1451
1443 .. container:: windows
1452 .. container:: windows
1444
1453
1445 On Windows, the path can use environment variables with ${ProgramFiles}
1454 On Windows, the path can use environment variables with ${ProgramFiles}
1446 syntax.
1455 syntax.
1447
1456
1448 (default: the tool name)
1457 (default: the tool name)
1449
1458
1450 ``args``
1459 ``args``
1451 The arguments to pass to the tool executable. You can refer to the
1460 The arguments to pass to the tool executable. You can refer to the
1452 files being merged as well as the output file through these
1461 files being merged as well as the output file through these
1453 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1462 variables: ``$base``, ``$local``, ``$other``, ``$output``.
1454
1463
1455 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1464 The meaning of ``$local`` and ``$other`` can vary depending on which action is
1456 being performed. During an update or merge, ``$local`` represents the original
1465 being performed. During an update or merge, ``$local`` represents the original
1457 state of the file, while ``$other`` represents the commit you are updating to or
1466 state of the file, while ``$other`` represents the commit you are updating to or
1458 the commit you are merging with. During a rebase, ``$local`` represents the
1467 the commit you are merging with. During a rebase, ``$local`` represents the
1459 destination of the rebase, and ``$other`` represents the commit being rebased.
1468 destination of the rebase, and ``$other`` represents the commit being rebased.
1460
1469
1461 Some operations define custom labels to assist with identifying the revisions,
1470 Some operations define custom labels to assist with identifying the revisions,
1462 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1471 accessible via ``$labellocal``, ``$labelother``, and ``$labelbase``. If custom
1463 labels are not available, these will be ``local``, ``other``, and ``base``,
1472 labels are not available, these will be ``local``, ``other``, and ``base``,
1464 respectively.
1473 respectively.
1465 (default: ``$local $base $other``)
1474 (default: ``$local $base $other``)
1466
1475
1467 ``premerge``
1476 ``premerge``
1468 Attempt to run internal non-interactive 3-way merge tool before
1477 Attempt to run internal non-interactive 3-way merge tool before
1469 launching external tool. Options are ``true``, ``false``, ``keep`` or
1478 launching external tool. Options are ``true``, ``false``, ``keep`` or
1470 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1479 ``keep-merge3``. The ``keep`` option will leave markers in the file if the
1471 premerge fails. The ``keep-merge3`` will do the same but include information
1480 premerge fails. The ``keep-merge3`` will do the same but include information
1472 about the base of the merge in the marker (see internal :merge3 in
1481 about the base of the merge in the marker (see internal :merge3 in
1473 :hg:`help merge-tools`).
1482 :hg:`help merge-tools`).
1474 (default: True)
1483 (default: True)
1475
1484
1476 ``binary``
1485 ``binary``
1477 This tool can merge binary files. (default: False, unless tool
1486 This tool can merge binary files. (default: False, unless tool
1478 was selected by file pattern match)
1487 was selected by file pattern match)
1479
1488
1480 ``symlink``
1489 ``symlink``
1481 This tool can merge symlinks. (default: False)
1490 This tool can merge symlinks. (default: False)
1482
1491
1483 ``check``
1492 ``check``
1484 A list of merge success-checking options:
1493 A list of merge success-checking options:
1485
1494
1486 ``changed``
1495 ``changed``
1487 Ask whether merge was successful when the merged file shows no changes.
1496 Ask whether merge was successful when the merged file shows no changes.
1488 ``conflicts``
1497 ``conflicts``
1489 Check whether there are conflicts even though the tool reported success.
1498 Check whether there are conflicts even though the tool reported success.
1490 ``prompt``
1499 ``prompt``
1491 Always prompt for merge success, regardless of success reported by tool.
1500 Always prompt for merge success, regardless of success reported by tool.
1492
1501
1493 ``fixeol``
1502 ``fixeol``
1494 Attempt to fix up EOL changes caused by the merge tool.
1503 Attempt to fix up EOL changes caused by the merge tool.
1495 (default: False)
1504 (default: False)
1496
1505
1497 ``gui``
1506 ``gui``
1498 This tool requires a graphical interface to run. (default: False)
1507 This tool requires a graphical interface to run. (default: False)
1499
1508
1500 ``mergemarkers``
1509 ``mergemarkers``
1501 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1510 Controls whether the labels passed via ``$labellocal``, ``$labelother``, and
1502 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1511 ``$labelbase`` are ``detailed`` (respecting ``mergemarkertemplate``) or
1503 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1512 ``basic``. If ``premerge`` is ``keep`` or ``keep-merge3``, the conflict
1504 markers generated during premerge will be ``detailed`` if either this option or
1513 markers generated during premerge will be ``detailed`` if either this option or
1505 the corresponding option in the ``[ui]`` section is ``detailed``.
1514 the corresponding option in the ``[ui]`` section is ``detailed``.
1506 (default: ``basic``)
1515 (default: ``basic``)
1507
1516
1508 ``mergemarkertemplate``
1517 ``mergemarkertemplate``
1509 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1518 This setting can be used to override ``mergemarkertemplate`` from the ``[ui]``
1510 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1519 section on a per-tool basis; this applies to the ``$label``-prefixed variables
1511 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1520 and to the conflict markers that are generated if ``premerge`` is ``keep` or
1512 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1521 ``keep-merge3``. See the corresponding variable in ``[ui]`` for more
1513 information.
1522 information.
1514
1523
1515 .. container:: windows
1524 .. container:: windows
1516
1525
1517 ``regkey``
1526 ``regkey``
1518 Windows registry key which describes install location of this
1527 Windows registry key which describes install location of this
1519 tool. Mercurial will search for this key first under
1528 tool. Mercurial will search for this key first under
1520 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1529 ``HKEY_CURRENT_USER`` and then under ``HKEY_LOCAL_MACHINE``.
1521 (default: None)
1530 (default: None)
1522
1531
1523 ``regkeyalt``
1532 ``regkeyalt``
1524 An alternate Windows registry key to try if the first key is not
1533 An alternate Windows registry key to try if the first key is not
1525 found. The alternate key uses the same ``regname`` and ``regappend``
1534 found. The alternate key uses the same ``regname`` and ``regappend``
1526 semantics of the primary key. The most common use for this key
1535 semantics of the primary key. The most common use for this key
1527 is to search for 32bit applications on 64bit operating systems.
1536 is to search for 32bit applications on 64bit operating systems.
1528 (default: None)
1537 (default: None)
1529
1538
1530 ``regname``
1539 ``regname``
1531 Name of value to read from specified registry key.
1540 Name of value to read from specified registry key.
1532 (default: the unnamed (default) value)
1541 (default: the unnamed (default) value)
1533
1542
1534 ``regappend``
1543 ``regappend``
1535 String to append to the value read from the registry, typically
1544 String to append to the value read from the registry, typically
1536 the executable name of the tool.
1545 the executable name of the tool.
1537 (default: None)
1546 (default: None)
1538
1547
1539 ``pager``
1548 ``pager``
1540 ---------
1549 ---------
1541
1550
1542 Setting used to control when to paginate and with what external tool. See
1551 Setting used to control when to paginate and with what external tool. See
1543 :hg:`help pager` for details.
1552 :hg:`help pager` for details.
1544
1553
1545 ``pager``
1554 ``pager``
1546 Define the external tool used as pager.
1555 Define the external tool used as pager.
1547
1556
1548 If no pager is set, Mercurial uses the environment variable $PAGER.
1557 If no pager is set, Mercurial uses the environment variable $PAGER.
1549 If neither pager.pager, nor $PAGER is set, a default pager will be
1558 If neither pager.pager, nor $PAGER is set, a default pager will be
1550 used, typically `less` on Unix and `more` on Windows. Example::
1559 used, typically `less` on Unix and `more` on Windows. Example::
1551
1560
1552 [pager]
1561 [pager]
1553 pager = less -FRX
1562 pager = less -FRX
1554
1563
1555 ``ignore``
1564 ``ignore``
1556 List of commands to disable the pager for. Example::
1565 List of commands to disable the pager for. Example::
1557
1566
1558 [pager]
1567 [pager]
1559 ignore = version, help, update
1568 ignore = version, help, update
1560
1569
1561 ``patch``
1570 ``patch``
1562 ---------
1571 ---------
1563
1572
1564 Settings used when applying patches, for instance through the 'import'
1573 Settings used when applying patches, for instance through the 'import'
1565 command or with Mercurial Queues extension.
1574 command or with Mercurial Queues extension.
1566
1575
1567 ``eol``
1576 ``eol``
1568 When set to 'strict' patch content and patched files end of lines
1577 When set to 'strict' patch content and patched files end of lines
1569 are preserved. When set to ``lf`` or ``crlf``, both files end of
1578 are preserved. When set to ``lf`` or ``crlf``, both files end of
1570 lines are ignored when patching and the result line endings are
1579 lines are ignored when patching and the result line endings are
1571 normalized to either LF (Unix) or CRLF (Windows). When set to
1580 normalized to either LF (Unix) or CRLF (Windows). When set to
1572 ``auto``, end of lines are again ignored while patching but line
1581 ``auto``, end of lines are again ignored while patching but line
1573 endings in patched files are normalized to their original setting
1582 endings in patched files are normalized to their original setting
1574 on a per-file basis. If target file does not exist or has no end
1583 on a per-file basis. If target file does not exist or has no end
1575 of line, patch line endings are preserved.
1584 of line, patch line endings are preserved.
1576 (default: strict)
1585 (default: strict)
1577
1586
1578 ``fuzz``
1587 ``fuzz``
1579 The number of lines of 'fuzz' to allow when applying patches. This
1588 The number of lines of 'fuzz' to allow when applying patches. This
1580 controls how much context the patcher is allowed to ignore when
1589 controls how much context the patcher is allowed to ignore when
1581 trying to apply a patch.
1590 trying to apply a patch.
1582 (default: 2)
1591 (default: 2)
1583
1592
1584 ``paths``
1593 ``paths``
1585 ---------
1594 ---------
1586
1595
1587 Assigns symbolic names and behavior to repositories.
1596 Assigns symbolic names and behavior to repositories.
1588
1597
1589 Options are symbolic names defining the URL or directory that is the
1598 Options are symbolic names defining the URL or directory that is the
1590 location of the repository. Example::
1599 location of the repository. Example::
1591
1600
1592 [paths]
1601 [paths]
1593 my_server = https://example.com/my_repo
1602 my_server = https://example.com/my_repo
1594 local_path = /home/me/repo
1603 local_path = /home/me/repo
1595
1604
1596 These symbolic names can be used from the command line. To pull
1605 These symbolic names can be used from the command line. To pull
1597 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1606 from ``my_server``: :hg:`pull my_server`. To push to ``local_path``:
1598 :hg:`push local_path`.
1607 :hg:`push local_path`.
1599
1608
1600 Options containing colons (``:``) denote sub-options that can influence
1609 Options containing colons (``:``) denote sub-options that can influence
1601 behavior for that specific path. Example::
1610 behavior for that specific path. Example::
1602
1611
1603 [paths]
1612 [paths]
1604 my_server = https://example.com/my_path
1613 my_server = https://example.com/my_path
1605 my_server:pushurl = ssh://example.com/my_path
1614 my_server:pushurl = ssh://example.com/my_path
1606
1615
1607 The following sub-options can be defined:
1616 The following sub-options can be defined:
1608
1617
1609 ``pushurl``
1618 ``pushurl``
1610 The URL to use for push operations. If not defined, the location
1619 The URL to use for push operations. If not defined, the location
1611 defined by the path's main entry is used.
1620 defined by the path's main entry is used.
1612
1621
1613 ``pushrev``
1622 ``pushrev``
1614 A revset defining which revisions to push by default.
1623 A revset defining which revisions to push by default.
1615
1624
1616 When :hg:`push` is executed without a ``-r`` argument, the revset
1625 When :hg:`push` is executed without a ``-r`` argument, the revset
1617 defined by this sub-option is evaluated to determine what to push.
1626 defined by this sub-option is evaluated to determine what to push.
1618
1627
1619 For example, a value of ``.`` will push the working directory's
1628 For example, a value of ``.`` will push the working directory's
1620 revision by default.
1629 revision by default.
1621
1630
1622 Revsets specifying bookmarks will not result in the bookmark being
1631 Revsets specifying bookmarks will not result in the bookmark being
1623 pushed.
1632 pushed.
1624
1633
1625 The following special named paths exist:
1634 The following special named paths exist:
1626
1635
1627 ``default``
1636 ``default``
1628 The URL or directory to use when no source or remote is specified.
1637 The URL or directory to use when no source or remote is specified.
1629
1638
1630 :hg:`clone` will automatically define this path to the location the
1639 :hg:`clone` will automatically define this path to the location the
1631 repository was cloned from.
1640 repository was cloned from.
1632
1641
1633 ``default-push``
1642 ``default-push``
1634 (deprecated) The URL or directory for the default :hg:`push` location.
1643 (deprecated) The URL or directory for the default :hg:`push` location.
1635 ``default:pushurl`` should be used instead.
1644 ``default:pushurl`` should be used instead.
1636
1645
1637 ``phases``
1646 ``phases``
1638 ----------
1647 ----------
1639
1648
1640 Specifies default handling of phases. See :hg:`help phases` for more
1649 Specifies default handling of phases. See :hg:`help phases` for more
1641 information about working with phases.
1650 information about working with phases.
1642
1651
1643 ``publish``
1652 ``publish``
1644 Controls draft phase behavior when working as a server. When true,
1653 Controls draft phase behavior when working as a server. When true,
1645 pushed changesets are set to public in both client and server and
1654 pushed changesets are set to public in both client and server and
1646 pulled or cloned changesets are set to public in the client.
1655 pulled or cloned changesets are set to public in the client.
1647 (default: True)
1656 (default: True)
1648
1657
1649 ``new-commit``
1658 ``new-commit``
1650 Phase of newly-created commits.
1659 Phase of newly-created commits.
1651 (default: draft)
1660 (default: draft)
1652
1661
1653 ``checksubrepos``
1662 ``checksubrepos``
1654 Check the phase of the current revision of each subrepository. Allowed
1663 Check the phase of the current revision of each subrepository. Allowed
1655 values are "ignore", "follow" and "abort". For settings other than
1664 values are "ignore", "follow" and "abort". For settings other than
1656 "ignore", the phase of the current revision of each subrepository is
1665 "ignore", the phase of the current revision of each subrepository is
1657 checked before committing the parent repository. If any of those phases is
1666 checked before committing the parent repository. If any of those phases is
1658 greater than the phase of the parent repository (e.g. if a subrepo is in a
1667 greater than the phase of the parent repository (e.g. if a subrepo is in a
1659 "secret" phase while the parent repo is in "draft" phase), the commit is
1668 "secret" phase while the parent repo is in "draft" phase), the commit is
1660 either aborted (if checksubrepos is set to "abort") or the higher phase is
1669 either aborted (if checksubrepos is set to "abort") or the higher phase is
1661 used for the parent repository commit (if set to "follow").
1670 used for the parent repository commit (if set to "follow").
1662 (default: follow)
1671 (default: follow)
1663
1672
1664
1673
1665 ``profiling``
1674 ``profiling``
1666 -------------
1675 -------------
1667
1676
1668 Specifies profiling type, format, and file output. Two profilers are
1677 Specifies profiling type, format, and file output. Two profilers are
1669 supported: an instrumenting profiler (named ``ls``), and a sampling
1678 supported: an instrumenting profiler (named ``ls``), and a sampling
1670 profiler (named ``stat``).
1679 profiler (named ``stat``).
1671
1680
1672 In this section description, 'profiling data' stands for the raw data
1681 In this section description, 'profiling data' stands for the raw data
1673 collected during profiling, while 'profiling report' stands for a
1682 collected during profiling, while 'profiling report' stands for a
1674 statistical text report generated from the profiling data.
1683 statistical text report generated from the profiling data.
1675
1684
1676 ``enabled``
1685 ``enabled``
1677 Enable the profiler.
1686 Enable the profiler.
1678 (default: false)
1687 (default: false)
1679
1688
1680 This is equivalent to passing ``--profile`` on the command line.
1689 This is equivalent to passing ``--profile`` on the command line.
1681
1690
1682 ``type``
1691 ``type``
1683 The type of profiler to use.
1692 The type of profiler to use.
1684 (default: stat)
1693 (default: stat)
1685
1694
1686 ``ls``
1695 ``ls``
1687 Use Python's built-in instrumenting profiler. This profiler
1696 Use Python's built-in instrumenting profiler. This profiler
1688 works on all platforms, but each line number it reports is the
1697 works on all platforms, but each line number it reports is the
1689 first line of a function. This restriction makes it difficult to
1698 first line of a function. This restriction makes it difficult to
1690 identify the expensive parts of a non-trivial function.
1699 identify the expensive parts of a non-trivial function.
1691 ``stat``
1700 ``stat``
1692 Use a statistical profiler, statprof. This profiler is most
1701 Use a statistical profiler, statprof. This profiler is most
1693 useful for profiling commands that run for longer than about 0.1
1702 useful for profiling commands that run for longer than about 0.1
1694 seconds.
1703 seconds.
1695
1704
1696 ``format``
1705 ``format``
1697 Profiling format. Specific to the ``ls`` instrumenting profiler.
1706 Profiling format. Specific to the ``ls`` instrumenting profiler.
1698 (default: text)
1707 (default: text)
1699
1708
1700 ``text``
1709 ``text``
1701 Generate a profiling report. When saving to a file, it should be
1710 Generate a profiling report. When saving to a file, it should be
1702 noted that only the report is saved, and the profiling data is
1711 noted that only the report is saved, and the profiling data is
1703 not kept.
1712 not kept.
1704 ``kcachegrind``
1713 ``kcachegrind``
1705 Format profiling data for kcachegrind use: when saving to a
1714 Format profiling data for kcachegrind use: when saving to a
1706 file, the generated file can directly be loaded into
1715 file, the generated file can directly be loaded into
1707 kcachegrind.
1716 kcachegrind.
1708
1717
1709 ``statformat``
1718 ``statformat``
1710 Profiling format for the ``stat`` profiler.
1719 Profiling format for the ``stat`` profiler.
1711 (default: hotpath)
1720 (default: hotpath)
1712
1721
1713 ``hotpath``
1722 ``hotpath``
1714 Show a tree-based display containing the hot path of execution (where
1723 Show a tree-based display containing the hot path of execution (where
1715 most time was spent).
1724 most time was spent).
1716 ``bymethod``
1725 ``bymethod``
1717 Show a table of methods ordered by how frequently they are active.
1726 Show a table of methods ordered by how frequently they are active.
1718 ``byline``
1727 ``byline``
1719 Show a table of lines in files ordered by how frequently they are active.
1728 Show a table of lines in files ordered by how frequently they are active.
1720 ``json``
1729 ``json``
1721 Render profiling data as JSON.
1730 Render profiling data as JSON.
1722
1731
1723 ``frequency``
1732 ``frequency``
1724 Sampling frequency. Specific to the ``stat`` sampling profiler.
1733 Sampling frequency. Specific to the ``stat`` sampling profiler.
1725 (default: 1000)
1734 (default: 1000)
1726
1735
1727 ``output``
1736 ``output``
1728 File path where profiling data or report should be saved. If the
1737 File path where profiling data or report should be saved. If the
1729 file exists, it is replaced. (default: None, data is printed on
1738 file exists, it is replaced. (default: None, data is printed on
1730 stderr)
1739 stderr)
1731
1740
1732 ``sort``
1741 ``sort``
1733 Sort field. Specific to the ``ls`` instrumenting profiler.
1742 Sort field. Specific to the ``ls`` instrumenting profiler.
1734 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1743 One of ``callcount``, ``reccallcount``, ``totaltime`` and
1735 ``inlinetime``.
1744 ``inlinetime``.
1736 (default: inlinetime)
1745 (default: inlinetime)
1737
1746
1738 ``time-track``
1747 ``time-track``
1739 Control if the stat profiler track ``cpu`` or ``real`` time.
1748 Control if the stat profiler track ``cpu`` or ``real`` time.
1740 (default: ``cpu`` on Windows, otherwise ``real``)
1749 (default: ``cpu`` on Windows, otherwise ``real``)
1741
1750
1742 ``limit``
1751 ``limit``
1743 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1752 Number of lines to show. Specific to the ``ls`` instrumenting profiler.
1744 (default: 30)
1753 (default: 30)
1745
1754
1746 ``nested``
1755 ``nested``
1747 Show at most this number of lines of drill-down info after each main entry.
1756 Show at most this number of lines of drill-down info after each main entry.
1748 This can help explain the difference between Total and Inline.
1757 This can help explain the difference between Total and Inline.
1749 Specific to the ``ls`` instrumenting profiler.
1758 Specific to the ``ls`` instrumenting profiler.
1750 (default: 0)
1759 (default: 0)
1751
1760
1752 ``showmin``
1761 ``showmin``
1753 Minimum fraction of samples an entry must have for it to be displayed.
1762 Minimum fraction of samples an entry must have for it to be displayed.
1754 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1763 Can be specified as a float between ``0.0`` and ``1.0`` or can have a
1755 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1764 ``%`` afterwards to allow values up to ``100``. e.g. ``5%``.
1756
1765
1757 Only used by the ``stat`` profiler.
1766 Only used by the ``stat`` profiler.
1758
1767
1759 For the ``hotpath`` format, default is ``0.05``.
1768 For the ``hotpath`` format, default is ``0.05``.
1760 For the ``chrome`` format, default is ``0.005``.
1769 For the ``chrome`` format, default is ``0.005``.
1761
1770
1762 The option is unused on other formats.
1771 The option is unused on other formats.
1763
1772
1764 ``showmax``
1773 ``showmax``
1765 Maximum fraction of samples an entry can have before it is ignored in
1774 Maximum fraction of samples an entry can have before it is ignored in
1766 display. Values format is the same as ``showmin``.
1775 display. Values format is the same as ``showmin``.
1767
1776
1768 Only used by the ``stat`` profiler.
1777 Only used by the ``stat`` profiler.
1769
1778
1770 For the ``chrome`` format, default is ``0.999``.
1779 For the ``chrome`` format, default is ``0.999``.
1771
1780
1772 The option is unused on other formats.
1781 The option is unused on other formats.
1773
1782
1774 ``progress``
1783 ``progress``
1775 ------------
1784 ------------
1776
1785
1777 Mercurial commands can draw progress bars that are as informative as
1786 Mercurial commands can draw progress bars that are as informative as
1778 possible. Some progress bars only offer indeterminate information, while others
1787 possible. Some progress bars only offer indeterminate information, while others
1779 have a definite end point.
1788 have a definite end point.
1780
1789
1781 ``debug``
1790 ``debug``
1782 Whether to print debug info when updating the progress bar. (default: False)
1791 Whether to print debug info when updating the progress bar. (default: False)
1783
1792
1784 ``delay``
1793 ``delay``
1785 Number of seconds (float) before showing the progress bar. (default: 3)
1794 Number of seconds (float) before showing the progress bar. (default: 3)
1786
1795
1787 ``changedelay``
1796 ``changedelay``
1788 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1797 Minimum delay before showing a new topic. When set to less than 3 * refresh,
1789 that value will be used instead. (default: 1)
1798 that value will be used instead. (default: 1)
1790
1799
1791 ``estimateinterval``
1800 ``estimateinterval``
1792 Maximum sampling interval in seconds for speed and estimated time
1801 Maximum sampling interval in seconds for speed and estimated time
1793 calculation. (default: 60)
1802 calculation. (default: 60)
1794
1803
1795 ``refresh``
1804 ``refresh``
1796 Time in seconds between refreshes of the progress bar. (default: 0.1)
1805 Time in seconds between refreshes of the progress bar. (default: 0.1)
1797
1806
1798 ``format``
1807 ``format``
1799 Format of the progress bar.
1808 Format of the progress bar.
1800
1809
1801 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1810 Valid entries for the format field are ``topic``, ``bar``, ``number``,
1802 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1811 ``unit``, ``estimate``, ``speed``, and ``item``. ``item`` defaults to the
1803 last 20 characters of the item, but this can be changed by adding either
1812 last 20 characters of the item, but this can be changed by adding either
1804 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1813 ``-<num>`` which would take the last num characters, or ``+<num>`` for the
1805 first num characters.
1814 first num characters.
1806
1815
1807 (default: topic bar number estimate)
1816 (default: topic bar number estimate)
1808
1817
1809 ``width``
1818 ``width``
1810 If set, the maximum width of the progress information (that is, min(width,
1819 If set, the maximum width of the progress information (that is, min(width,
1811 term width) will be used).
1820 term width) will be used).
1812
1821
1813 ``clear-complete``
1822 ``clear-complete``
1814 Clear the progress bar after it's done. (default: True)
1823 Clear the progress bar after it's done. (default: True)
1815
1824
1816 ``disable``
1825 ``disable``
1817 If true, don't show a progress bar.
1826 If true, don't show a progress bar.
1818
1827
1819 ``assume-tty``
1828 ``assume-tty``
1820 If true, ALWAYS show a progress bar, unless disable is given.
1829 If true, ALWAYS show a progress bar, unless disable is given.
1821
1830
1822 ``rebase``
1831 ``rebase``
1823 ----------
1832 ----------
1824
1833
1825 ``evolution.allowdivergence``
1834 ``evolution.allowdivergence``
1826 Default to False, when True allow creating divergence when performing
1835 Default to False, when True allow creating divergence when performing
1827 rebase of obsolete changesets.
1836 rebase of obsolete changesets.
1828
1837
1829 ``revsetalias``
1838 ``revsetalias``
1830 ---------------
1839 ---------------
1831
1840
1832 Alias definitions for revsets. See :hg:`help revsets` for details.
1841 Alias definitions for revsets. See :hg:`help revsets` for details.
1833
1842
1834 ``rewrite``
1843 ``rewrite``
1835 -----------
1844 -----------
1836
1845
1837 ``backup-bundle``
1846 ``backup-bundle``
1838 Whether to save stripped changesets to a bundle file. (default: True)
1847 Whether to save stripped changesets to a bundle file. (default: True)
1839
1848
1840 ``update-timestamp``
1849 ``update-timestamp``
1841 If true, updates the date and time of the changeset to current. It is only
1850 If true, updates the date and time of the changeset to current. It is only
1842 applicable for hg amend in current version.
1851 applicable for hg amend in current version.
1843
1852
1844 ``storage``
1853 ``storage``
1845 -----------
1854 -----------
1846
1855
1847 Control the strategy Mercurial uses internally to store history. Options in this
1856 Control the strategy Mercurial uses internally to store history. Options in this
1848 category impact performance and repository size.
1857 category impact performance and repository size.
1849
1858
1850 ``revlog.optimize-delta-parent-choice``
1859 ``revlog.optimize-delta-parent-choice``
1851 When storing a merge revision, both parents will be equally considered as
1860 When storing a merge revision, both parents will be equally considered as
1852 a possible delta base. This results in better delta selection and improved
1861 a possible delta base. This results in better delta selection and improved
1853 revlog compression. This option is enabled by default.
1862 revlog compression. This option is enabled by default.
1854
1863
1855 Turning this option off can result in large increase of repository size for
1864 Turning this option off can result in large increase of repository size for
1856 repository with many merges.
1865 repository with many merges.
1857
1866
1858 ``revlog.reuse-external-delta-parent``
1867 ``revlog.reuse-external-delta-parent``
1859 Control the order in which delta parents are considered when adding new
1868 Control the order in which delta parents are considered when adding new
1860 revisions from an external source.
1869 revisions from an external source.
1861 (typically: apply bundle from `hg pull` or `hg push`).
1870 (typically: apply bundle from `hg pull` or `hg push`).
1862
1871
1863 New revisions are usually provided as a delta against other revisions. By
1872 New revisions are usually provided as a delta against other revisions. By
1864 default, Mercurial will try to reuse this delta first, therefore using the
1873 default, Mercurial will try to reuse this delta first, therefore using the
1865 same "delta parent" as the source. Directly using delta's from the source
1874 same "delta parent" as the source. Directly using delta's from the source
1866 reduces CPU usage and usually speeds up operation. However, in some case,
1875 reduces CPU usage and usually speeds up operation. However, in some case,
1867 the source might have sub-optimal delta bases and forcing their reevaluation
1876 the source might have sub-optimal delta bases and forcing their reevaluation
1868 is useful. For example, pushes from an old client could have sub-optimal
1877 is useful. For example, pushes from an old client could have sub-optimal
1869 delta's parent that the server want to optimize. (lack of general delta, bad
1878 delta's parent that the server want to optimize. (lack of general delta, bad
1870 parents, choice, lack of sparse-revlog, etc).
1879 parents, choice, lack of sparse-revlog, etc).
1871
1880
1872 This option is enabled by default. Turning it off will ensure bad delta
1881 This option is enabled by default. Turning it off will ensure bad delta
1873 parent choices from older client do not propagate to this repository, at
1882 parent choices from older client do not propagate to this repository, at
1874 the cost of a small increase in CPU consumption.
1883 the cost of a small increase in CPU consumption.
1875
1884
1876 Note: this option only control the order in which delta parents are
1885 Note: this option only control the order in which delta parents are
1877 considered. Even when disabled, the existing delta from the source will be
1886 considered. Even when disabled, the existing delta from the source will be
1878 reused if the same delta parent is selected.
1887 reused if the same delta parent is selected.
1879
1888
1880 ``revlog.reuse-external-delta``
1889 ``revlog.reuse-external-delta``
1881 Control the reuse of delta from external source.
1890 Control the reuse of delta from external source.
1882 (typically: apply bundle from `hg pull` or `hg push`).
1891 (typically: apply bundle from `hg pull` or `hg push`).
1883
1892
1884 New revisions are usually provided as a delta against another revision. By
1893 New revisions are usually provided as a delta against another revision. By
1885 default, Mercurial will not recompute the same delta again, trusting
1894 default, Mercurial will not recompute the same delta again, trusting
1886 externally provided deltas. There have been rare cases of small adjustment
1895 externally provided deltas. There have been rare cases of small adjustment
1887 to the diffing algorithm in the past. So in some rare case, recomputing
1896 to the diffing algorithm in the past. So in some rare case, recomputing
1888 delta provided by ancient clients can provides better results. Disabling
1897 delta provided by ancient clients can provides better results. Disabling
1889 this option means going through a full delta recomputation for all incoming
1898 this option means going through a full delta recomputation for all incoming
1890 revisions. It means a large increase in CPU usage and will slow operations
1899 revisions. It means a large increase in CPU usage and will slow operations
1891 down.
1900 down.
1892
1901
1893 This option is enabled by default. When disabled, it also disables the
1902 This option is enabled by default. When disabled, it also disables the
1894 related ``storage.revlog.reuse-external-delta-parent`` option.
1903 related ``storage.revlog.reuse-external-delta-parent`` option.
1895
1904
1896 ``revlog.zlib.level``
1905 ``revlog.zlib.level``
1897 Zlib compression level used when storing data into the repository. Accepted
1906 Zlib compression level used when storing data into the repository. Accepted
1898 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
1907 Value range from 1 (lowest compression) to 9 (highest compression). Zlib
1899 default value is 6.
1908 default value is 6.
1900
1909
1901
1910
1902 ``revlog.zstd.level``
1911 ``revlog.zstd.level``
1903 zstd compression level used when storing data into the repository. Accepted
1912 zstd compression level used when storing data into the repository. Accepted
1904 Value range from 1 (lowest compression) to 22 (highest compression).
1913 Value range from 1 (lowest compression) to 22 (highest compression).
1905 (default 3)
1914 (default 3)
1906
1915
1907 ``server``
1916 ``server``
1908 ----------
1917 ----------
1909
1918
1910 Controls generic server settings.
1919 Controls generic server settings.
1911
1920
1912 ``bookmarks-pushkey-compat``
1921 ``bookmarks-pushkey-compat``
1913 Trigger pushkey hook when being pushed bookmark updates. This config exist
1922 Trigger pushkey hook when being pushed bookmark updates. This config exist
1914 for compatibility purpose (default to True)
1923 for compatibility purpose (default to True)
1915
1924
1916 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1925 If you use ``pushkey`` and ``pre-pushkey`` hooks to control bookmark
1917 movement we recommend you migrate them to ``txnclose-bookmark`` and
1926 movement we recommend you migrate them to ``txnclose-bookmark`` and
1918 ``pretxnclose-bookmark``.
1927 ``pretxnclose-bookmark``.
1919
1928
1920 ``compressionengines``
1929 ``compressionengines``
1921 List of compression engines and their relative priority to advertise
1930 List of compression engines and their relative priority to advertise
1922 to clients.
1931 to clients.
1923
1932
1924 The order of compression engines determines their priority, the first
1933 The order of compression engines determines their priority, the first
1925 having the highest priority. If a compression engine is not listed
1934 having the highest priority. If a compression engine is not listed
1926 here, it won't be advertised to clients.
1935 here, it won't be advertised to clients.
1927
1936
1928 If not set (the default), built-in defaults are used. Run
1937 If not set (the default), built-in defaults are used. Run
1929 :hg:`debuginstall` to list available compression engines and their
1938 :hg:`debuginstall` to list available compression engines and their
1930 default wire protocol priority.
1939 default wire protocol priority.
1931
1940
1932 Older Mercurial clients only support zlib compression and this setting
1941 Older Mercurial clients only support zlib compression and this setting
1933 has no effect for legacy clients.
1942 has no effect for legacy clients.
1934
1943
1935 ``uncompressed``
1944 ``uncompressed``
1936 Whether to allow clients to clone a repository using the
1945 Whether to allow clients to clone a repository using the
1937 uncompressed streaming protocol. This transfers about 40% more
1946 uncompressed streaming protocol. This transfers about 40% more
1938 data than a regular clone, but uses less memory and CPU on both
1947 data than a regular clone, but uses less memory and CPU on both
1939 server and client. Over a LAN (100 Mbps or better) or a very fast
1948 server and client. Over a LAN (100 Mbps or better) or a very fast
1940 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1949 WAN, an uncompressed streaming clone is a lot faster (~10x) than a
1941 regular clone. Over most WAN connections (anything slower than
1950 regular clone. Over most WAN connections (anything slower than
1942 about 6 Mbps), uncompressed streaming is slower, because of the
1951 about 6 Mbps), uncompressed streaming is slower, because of the
1943 extra data transfer overhead. This mode will also temporarily hold
1952 extra data transfer overhead. This mode will also temporarily hold
1944 the write lock while determining what data to transfer.
1953 the write lock while determining what data to transfer.
1945 (default: True)
1954 (default: True)
1946
1955
1947 ``uncompressedallowsecret``
1956 ``uncompressedallowsecret``
1948 Whether to allow stream clones when the repository contains secret
1957 Whether to allow stream clones when the repository contains secret
1949 changesets. (default: False)
1958 changesets. (default: False)
1950
1959
1951 ``preferuncompressed``
1960 ``preferuncompressed``
1952 When set, clients will try to use the uncompressed streaming
1961 When set, clients will try to use the uncompressed streaming
1953 protocol. (default: False)
1962 protocol. (default: False)
1954
1963
1955 ``disablefullbundle``
1964 ``disablefullbundle``
1956 When set, servers will refuse attempts to do pull-based clones.
1965 When set, servers will refuse attempts to do pull-based clones.
1957 If this option is set, ``preferuncompressed`` and/or clone bundles
1966 If this option is set, ``preferuncompressed`` and/or clone bundles
1958 are highly recommended. Partial clones will still be allowed.
1967 are highly recommended. Partial clones will still be allowed.
1959 (default: False)
1968 (default: False)
1960
1969
1961 ``streamunbundle``
1970 ``streamunbundle``
1962 When set, servers will apply data sent from the client directly,
1971 When set, servers will apply data sent from the client directly,
1963 otherwise it will be written to a temporary file first. This option
1972 otherwise it will be written to a temporary file first. This option
1964 effectively prevents concurrent pushes.
1973 effectively prevents concurrent pushes.
1965
1974
1966 ``pullbundle``
1975 ``pullbundle``
1967 When set, the server will check pullbundle.manifest for bundles
1976 When set, the server will check pullbundle.manifest for bundles
1968 covering the requested heads and common nodes. The first matching
1977 covering the requested heads and common nodes. The first matching
1969 entry will be streamed to the client.
1978 entry will be streamed to the client.
1970
1979
1971 For HTTP transport, the stream will still use zlib compression
1980 For HTTP transport, the stream will still use zlib compression
1972 for older clients.
1981 for older clients.
1973
1982
1974 ``concurrent-push-mode``
1983 ``concurrent-push-mode``
1975 Level of allowed race condition between two pushing clients.
1984 Level of allowed race condition between two pushing clients.
1976
1985
1977 - 'strict': push is abort if another client touched the repository
1986 - 'strict': push is abort if another client touched the repository
1978 while the push was preparing. (default)
1987 while the push was preparing. (default)
1979 - 'check-related': push is only aborted if it affects head that got also
1988 - 'check-related': push is only aborted if it affects head that got also
1980 affected while the push was preparing.
1989 affected while the push was preparing.
1981
1990
1982 This requires compatible client (version 4.3 and later). Old client will
1991 This requires compatible client (version 4.3 and later). Old client will
1983 use 'strict'.
1992 use 'strict'.
1984
1993
1985 ``validate``
1994 ``validate``
1986 Whether to validate the completeness of pushed changesets by
1995 Whether to validate the completeness of pushed changesets by
1987 checking that all new file revisions specified in manifests are
1996 checking that all new file revisions specified in manifests are
1988 present. (default: False)
1997 present. (default: False)
1989
1998
1990 ``maxhttpheaderlen``
1999 ``maxhttpheaderlen``
1991 Instruct HTTP clients not to send request headers longer than this
2000 Instruct HTTP clients not to send request headers longer than this
1992 many bytes. (default: 1024)
2001 many bytes. (default: 1024)
1993
2002
1994 ``bundle1``
2003 ``bundle1``
1995 Whether to allow clients to push and pull using the legacy bundle1
2004 Whether to allow clients to push and pull using the legacy bundle1
1996 exchange format. (default: True)
2005 exchange format. (default: True)
1997
2006
1998 ``bundle1gd``
2007 ``bundle1gd``
1999 Like ``bundle1`` but only used if the repository is using the
2008 Like ``bundle1`` but only used if the repository is using the
2000 *generaldelta* storage format. (default: True)
2009 *generaldelta* storage format. (default: True)
2001
2010
2002 ``bundle1.push``
2011 ``bundle1.push``
2003 Whether to allow clients to push using the legacy bundle1 exchange
2012 Whether to allow clients to push using the legacy bundle1 exchange
2004 format. (default: True)
2013 format. (default: True)
2005
2014
2006 ``bundle1gd.push``
2015 ``bundle1gd.push``
2007 Like ``bundle1.push`` but only used if the repository is using the
2016 Like ``bundle1.push`` but only used if the repository is using the
2008 *generaldelta* storage format. (default: True)
2017 *generaldelta* storage format. (default: True)
2009
2018
2010 ``bundle1.pull``
2019 ``bundle1.pull``
2011 Whether to allow clients to pull using the legacy bundle1 exchange
2020 Whether to allow clients to pull using the legacy bundle1 exchange
2012 format. (default: True)
2021 format. (default: True)
2013
2022
2014 ``bundle1gd.pull``
2023 ``bundle1gd.pull``
2015 Like ``bundle1.pull`` but only used if the repository is using the
2024 Like ``bundle1.pull`` but only used if the repository is using the
2016 *generaldelta* storage format. (default: True)
2025 *generaldelta* storage format. (default: True)
2017
2026
2018 Large repositories using the *generaldelta* storage format should
2027 Large repositories using the *generaldelta* storage format should
2019 consider setting this option because converting *generaldelta*
2028 consider setting this option because converting *generaldelta*
2020 repositories to the exchange format required by the bundle1 data
2029 repositories to the exchange format required by the bundle1 data
2021 format can consume a lot of CPU.
2030 format can consume a lot of CPU.
2022
2031
2023 ``bundle2.stream``
2032 ``bundle2.stream``
2024 Whether to allow clients to pull using the bundle2 streaming protocol.
2033 Whether to allow clients to pull using the bundle2 streaming protocol.
2025 (default: True)
2034 (default: True)
2026
2035
2027 ``zliblevel``
2036 ``zliblevel``
2028 Integer between ``-1`` and ``9`` that controls the zlib compression level
2037 Integer between ``-1`` and ``9`` that controls the zlib compression level
2029 for wire protocol commands that send zlib compressed output (notably the
2038 for wire protocol commands that send zlib compressed output (notably the
2030 commands that send repository history data).
2039 commands that send repository history data).
2031
2040
2032 The default (``-1``) uses the default zlib compression level, which is
2041 The default (``-1``) uses the default zlib compression level, which is
2033 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2042 likely equivalent to ``6``. ``0`` means no compression. ``9`` means
2034 maximum compression.
2043 maximum compression.
2035
2044
2036 Setting this option allows server operators to make trade-offs between
2045 Setting this option allows server operators to make trade-offs between
2037 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2046 bandwidth and CPU used. Lowering the compression lowers CPU utilization
2038 but sends more bytes to clients.
2047 but sends more bytes to clients.
2039
2048
2040 This option only impacts the HTTP server.
2049 This option only impacts the HTTP server.
2041
2050
2042 ``zstdlevel``
2051 ``zstdlevel``
2043 Integer between ``1`` and ``22`` that controls the zstd compression level
2052 Integer between ``1`` and ``22`` that controls the zstd compression level
2044 for wire protocol commands. ``1`` is the minimal amount of compression and
2053 for wire protocol commands. ``1`` is the minimal amount of compression and
2045 ``22`` is the highest amount of compression.
2054 ``22`` is the highest amount of compression.
2046
2055
2047 The default (``3``) should be significantly faster than zlib while likely
2056 The default (``3``) should be significantly faster than zlib while likely
2048 delivering better compression ratios.
2057 delivering better compression ratios.
2049
2058
2050 This option only impacts the HTTP server.
2059 This option only impacts the HTTP server.
2051
2060
2052 See also ``server.zliblevel``.
2061 See also ``server.zliblevel``.
2053
2062
2054 ``view``
2063 ``view``
2055 Repository filter used when exchanging revisions with the peer.
2064 Repository filter used when exchanging revisions with the peer.
2056
2065
2057 The default view (``served``) excludes secret and hidden changesets.
2066 The default view (``served``) excludes secret and hidden changesets.
2058 Another useful value is ``immutable`` (no draft, secret or hidden
2067 Another useful value is ``immutable`` (no draft, secret or hidden
2059 changesets). (EXPERIMENTAL)
2068 changesets). (EXPERIMENTAL)
2060
2069
2061 ``smtp``
2070 ``smtp``
2062 --------
2071 --------
2063
2072
2064 Configuration for extensions that need to send email messages.
2073 Configuration for extensions that need to send email messages.
2065
2074
2066 ``host``
2075 ``host``
2067 Host name of mail server, e.g. "mail.example.com".
2076 Host name of mail server, e.g. "mail.example.com".
2068
2077
2069 ``port``
2078 ``port``
2070 Optional. Port to connect to on mail server. (default: 465 if
2079 Optional. Port to connect to on mail server. (default: 465 if
2071 ``tls`` is smtps; 25 otherwise)
2080 ``tls`` is smtps; 25 otherwise)
2072
2081
2073 ``tls``
2082 ``tls``
2074 Optional. Method to enable TLS when connecting to mail server: starttls,
2083 Optional. Method to enable TLS when connecting to mail server: starttls,
2075 smtps or none. (default: none)
2084 smtps or none. (default: none)
2076
2085
2077 ``username``
2086 ``username``
2078 Optional. User name for authenticating with the SMTP server.
2087 Optional. User name for authenticating with the SMTP server.
2079 (default: None)
2088 (default: None)
2080
2089
2081 ``password``
2090 ``password``
2082 Optional. Password for authenticating with the SMTP server. If not
2091 Optional. Password for authenticating with the SMTP server. If not
2083 specified, interactive sessions will prompt the user for a
2092 specified, interactive sessions will prompt the user for a
2084 password; non-interactive sessions will fail. (default: None)
2093 password; non-interactive sessions will fail. (default: None)
2085
2094
2086 ``local_hostname``
2095 ``local_hostname``
2087 Optional. The hostname that the sender can use to identify
2096 Optional. The hostname that the sender can use to identify
2088 itself to the MTA.
2097 itself to the MTA.
2089
2098
2090
2099
2091 ``subpaths``
2100 ``subpaths``
2092 ------------
2101 ------------
2093
2102
2094 Subrepository source URLs can go stale if a remote server changes name
2103 Subrepository source URLs can go stale if a remote server changes name
2095 or becomes temporarily unavailable. This section lets you define
2104 or becomes temporarily unavailable. This section lets you define
2096 rewrite rules of the form::
2105 rewrite rules of the form::
2097
2106
2098 <pattern> = <replacement>
2107 <pattern> = <replacement>
2099
2108
2100 where ``pattern`` is a regular expression matching a subrepository
2109 where ``pattern`` is a regular expression matching a subrepository
2101 source URL and ``replacement`` is the replacement string used to
2110 source URL and ``replacement`` is the replacement string used to
2102 rewrite it. Groups can be matched in ``pattern`` and referenced in
2111 rewrite it. Groups can be matched in ``pattern`` and referenced in
2103 ``replacements``. For instance::
2112 ``replacements``. For instance::
2104
2113
2105 http://server/(.*)-hg/ = http://hg.server/\1/
2114 http://server/(.*)-hg/ = http://hg.server/\1/
2106
2115
2107 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2116 rewrites ``http://server/foo-hg/`` into ``http://hg.server/foo/``.
2108
2117
2109 Relative subrepository paths are first made absolute, and the
2118 Relative subrepository paths are first made absolute, and the
2110 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2119 rewrite rules are then applied on the full (absolute) path. If ``pattern``
2111 doesn't match the full path, an attempt is made to apply it on the
2120 doesn't match the full path, an attempt is made to apply it on the
2112 relative path alone. The rules are applied in definition order.
2121 relative path alone. The rules are applied in definition order.
2113
2122
2114 ``subrepos``
2123 ``subrepos``
2115 ------------
2124 ------------
2116
2125
2117 This section contains options that control the behavior of the
2126 This section contains options that control the behavior of the
2118 subrepositories feature. See also :hg:`help subrepos`.
2127 subrepositories feature. See also :hg:`help subrepos`.
2119
2128
2120 Security note: auditing in Mercurial is known to be insufficient to
2129 Security note: auditing in Mercurial is known to be insufficient to
2121 prevent clone-time code execution with carefully constructed Git
2130 prevent clone-time code execution with carefully constructed Git
2122 subrepos. It is unknown if a similar detect is present in Subversion
2131 subrepos. It is unknown if a similar detect is present in Subversion
2123 subrepos. Both Git and Subversion subrepos are disabled by default
2132 subrepos. Both Git and Subversion subrepos are disabled by default
2124 out of security concerns. These subrepo types can be enabled using
2133 out of security concerns. These subrepo types can be enabled using
2125 the respective options below.
2134 the respective options below.
2126
2135
2127 ``allowed``
2136 ``allowed``
2128 Whether subrepositories are allowed in the working directory.
2137 Whether subrepositories are allowed in the working directory.
2129
2138
2130 When false, commands involving subrepositories (like :hg:`update`)
2139 When false, commands involving subrepositories (like :hg:`update`)
2131 will fail for all subrepository types.
2140 will fail for all subrepository types.
2132 (default: true)
2141 (default: true)
2133
2142
2134 ``hg:allowed``
2143 ``hg:allowed``
2135 Whether Mercurial subrepositories are allowed in the working
2144 Whether Mercurial subrepositories are allowed in the working
2136 directory. This option only has an effect if ``subrepos.allowed``
2145 directory. This option only has an effect if ``subrepos.allowed``
2137 is true.
2146 is true.
2138 (default: true)
2147 (default: true)
2139
2148
2140 ``git:allowed``
2149 ``git:allowed``
2141 Whether Git subrepositories are allowed in the working directory.
2150 Whether Git subrepositories are allowed in the working directory.
2142 This option only has an effect if ``subrepos.allowed`` is true.
2151 This option only has an effect if ``subrepos.allowed`` is true.
2143
2152
2144 See the security note above before enabling Git subrepos.
2153 See the security note above before enabling Git subrepos.
2145 (default: false)
2154 (default: false)
2146
2155
2147 ``svn:allowed``
2156 ``svn:allowed``
2148 Whether Subversion subrepositories are allowed in the working
2157 Whether Subversion subrepositories are allowed in the working
2149 directory. This option only has an effect if ``subrepos.allowed``
2158 directory. This option only has an effect if ``subrepos.allowed``
2150 is true.
2159 is true.
2151
2160
2152 See the security note above before enabling Subversion subrepos.
2161 See the security note above before enabling Subversion subrepos.
2153 (default: false)
2162 (default: false)
2154
2163
2155 ``templatealias``
2164 ``templatealias``
2156 -----------------
2165 -----------------
2157
2166
2158 Alias definitions for templates. See :hg:`help templates` for details.
2167 Alias definitions for templates. See :hg:`help templates` for details.
2159
2168
2160 ``templates``
2169 ``templates``
2161 -------------
2170 -------------
2162
2171
2163 Use the ``[templates]`` section to define template strings.
2172 Use the ``[templates]`` section to define template strings.
2164 See :hg:`help templates` for details.
2173 See :hg:`help templates` for details.
2165
2174
2166 ``trusted``
2175 ``trusted``
2167 -----------
2176 -----------
2168
2177
2169 Mercurial will not use the settings in the
2178 Mercurial will not use the settings in the
2170 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2179 ``.hg/hgrc`` file from a repository if it doesn't belong to a trusted
2171 user or to a trusted group, as various hgrc features allow arbitrary
2180 user or to a trusted group, as various hgrc features allow arbitrary
2172 commands to be run. This issue is often encountered when configuring
2181 commands to be run. This issue is often encountered when configuring
2173 hooks or extensions for shared repositories or servers. However,
2182 hooks or extensions for shared repositories or servers. However,
2174 the web interface will use some safe settings from the ``[web]``
2183 the web interface will use some safe settings from the ``[web]``
2175 section.
2184 section.
2176
2185
2177 This section specifies what users and groups are trusted. The
2186 This section specifies what users and groups are trusted. The
2178 current user is always trusted. To trust everybody, list a user or a
2187 current user is always trusted. To trust everybody, list a user or a
2179 group with name ``*``. These settings must be placed in an
2188 group with name ``*``. These settings must be placed in an
2180 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2189 *already-trusted file* to take effect, such as ``$HOME/.hgrc`` of the
2181 user or service running Mercurial.
2190 user or service running Mercurial.
2182
2191
2183 ``users``
2192 ``users``
2184 Comma-separated list of trusted users.
2193 Comma-separated list of trusted users.
2185
2194
2186 ``groups``
2195 ``groups``
2187 Comma-separated list of trusted groups.
2196 Comma-separated list of trusted groups.
2188
2197
2189
2198
2190 ``ui``
2199 ``ui``
2191 ------
2200 ------
2192
2201
2193 User interface controls.
2202 User interface controls.
2194
2203
2195 ``archivemeta``
2204 ``archivemeta``
2196 Whether to include the .hg_archival.txt file containing meta data
2205 Whether to include the .hg_archival.txt file containing meta data
2197 (hashes for the repository base and for tip) in archives created
2206 (hashes for the repository base and for tip) in archives created
2198 by the :hg:`archive` command or downloaded via hgweb.
2207 by the :hg:`archive` command or downloaded via hgweb.
2199 (default: True)
2208 (default: True)
2200
2209
2201 ``askusername``
2210 ``askusername``
2202 Whether to prompt for a username when committing. If True, and
2211 Whether to prompt for a username when committing. If True, and
2203 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2212 neither ``$HGUSER`` nor ``$EMAIL`` has been specified, then the user will
2204 be prompted to enter a username. If no username is entered, the
2213 be prompted to enter a username. If no username is entered, the
2205 default ``USER@HOST`` is used instead.
2214 default ``USER@HOST`` is used instead.
2206 (default: False)
2215 (default: False)
2207
2216
2208 ``clonebundles``
2217 ``clonebundles``
2209 Whether the "clone bundles" feature is enabled.
2218 Whether the "clone bundles" feature is enabled.
2210
2219
2211 When enabled, :hg:`clone` may download and apply a server-advertised
2220 When enabled, :hg:`clone` may download and apply a server-advertised
2212 bundle file from a URL instead of using the normal exchange mechanism.
2221 bundle file from a URL instead of using the normal exchange mechanism.
2213
2222
2214 This can likely result in faster and more reliable clones.
2223 This can likely result in faster and more reliable clones.
2215
2224
2216 (default: True)
2225 (default: True)
2217
2226
2218 ``clonebundlefallback``
2227 ``clonebundlefallback``
2219 Whether failure to apply an advertised "clone bundle" from a server
2228 Whether failure to apply an advertised "clone bundle" from a server
2220 should result in fallback to a regular clone.
2229 should result in fallback to a regular clone.
2221
2230
2222 This is disabled by default because servers advertising "clone
2231 This is disabled by default because servers advertising "clone
2223 bundles" often do so to reduce server load. If advertised bundles
2232 bundles" often do so to reduce server load. If advertised bundles
2224 start mass failing and clients automatically fall back to a regular
2233 start mass failing and clients automatically fall back to a regular
2225 clone, this would add significant and unexpected load to the server
2234 clone, this would add significant and unexpected load to the server
2226 since the server is expecting clone operations to be offloaded to
2235 since the server is expecting clone operations to be offloaded to
2227 pre-generated bundles. Failing fast (the default behavior) ensures
2236 pre-generated bundles. Failing fast (the default behavior) ensures
2228 clients don't overwhelm the server when "clone bundle" application
2237 clients don't overwhelm the server when "clone bundle" application
2229 fails.
2238 fails.
2230
2239
2231 (default: False)
2240 (default: False)
2232
2241
2233 ``clonebundleprefers``
2242 ``clonebundleprefers``
2234 Defines preferences for which "clone bundles" to use.
2243 Defines preferences for which "clone bundles" to use.
2235
2244
2236 Servers advertising "clone bundles" may advertise multiple available
2245 Servers advertising "clone bundles" may advertise multiple available
2237 bundles. Each bundle may have different attributes, such as the bundle
2246 bundles. Each bundle may have different attributes, such as the bundle
2238 type and compression format. This option is used to prefer a particular
2247 type and compression format. This option is used to prefer a particular
2239 bundle over another.
2248 bundle over another.
2240
2249
2241 The following keys are defined by Mercurial:
2250 The following keys are defined by Mercurial:
2242
2251
2243 BUNDLESPEC
2252 BUNDLESPEC
2244 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2253 A bundle type specifier. These are strings passed to :hg:`bundle -t`.
2245 e.g. ``gzip-v2`` or ``bzip2-v1``.
2254 e.g. ``gzip-v2`` or ``bzip2-v1``.
2246
2255
2247 COMPRESSION
2256 COMPRESSION
2248 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2257 The compression format of the bundle. e.g. ``gzip`` and ``bzip2``.
2249
2258
2250 Server operators may define custom keys.
2259 Server operators may define custom keys.
2251
2260
2252 Example values: ``COMPRESSION=bzip2``,
2261 Example values: ``COMPRESSION=bzip2``,
2253 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2262 ``BUNDLESPEC=gzip-v2, COMPRESSION=gzip``.
2254
2263
2255 By default, the first bundle advertised by the server is used.
2264 By default, the first bundle advertised by the server is used.
2256
2265
2257 ``color``
2266 ``color``
2258 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2267 When to colorize output. Possible value are Boolean ("yes" or "no"), or
2259 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2268 "debug", or "always". (default: "yes"). "yes" will use color whenever it
2260 seems possible. See :hg:`help color` for details.
2269 seems possible. See :hg:`help color` for details.
2261
2270
2262 ``commitsubrepos``
2271 ``commitsubrepos``
2263 Whether to commit modified subrepositories when committing the
2272 Whether to commit modified subrepositories when committing the
2264 parent repository. If False and one subrepository has uncommitted
2273 parent repository. If False and one subrepository has uncommitted
2265 changes, abort the commit.
2274 changes, abort the commit.
2266 (default: False)
2275 (default: False)
2267
2276
2268 ``debug``
2277 ``debug``
2269 Print debugging information. (default: False)
2278 Print debugging information. (default: False)
2270
2279
2271 ``editor``
2280 ``editor``
2272 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2281 The editor to use during a commit. (default: ``$EDITOR`` or ``vi``)
2273
2282
2274 ``fallbackencoding``
2283 ``fallbackencoding``
2275 Encoding to try if it's not possible to decode the changelog using
2284 Encoding to try if it's not possible to decode the changelog using
2276 UTF-8. (default: ISO-8859-1)
2285 UTF-8. (default: ISO-8859-1)
2277
2286
2278 ``graphnodetemplate``
2287 ``graphnodetemplate``
2279 The template used to print changeset nodes in an ASCII revision graph.
2288 The template used to print changeset nodes in an ASCII revision graph.
2280 (default: ``{graphnode}``)
2289 (default: ``{graphnode}``)
2281
2290
2282 ``ignore``
2291 ``ignore``
2283 A file to read per-user ignore patterns from. This file should be
2292 A file to read per-user ignore patterns from. This file should be
2284 in the same format as a repository-wide .hgignore file. Filenames
2293 in the same format as a repository-wide .hgignore file. Filenames
2285 are relative to the repository root. This option supports hook syntax,
2294 are relative to the repository root. This option supports hook syntax,
2286 so if you want to specify multiple ignore files, you can do so by
2295 so if you want to specify multiple ignore files, you can do so by
2287 setting something like ``ignore.other = ~/.hgignore2``. For details
2296 setting something like ``ignore.other = ~/.hgignore2``. For details
2288 of the ignore file format, see the ``hgignore(5)`` man page.
2297 of the ignore file format, see the ``hgignore(5)`` man page.
2289
2298
2290 ``interactive``
2299 ``interactive``
2291 Allow to prompt the user. (default: True)
2300 Allow to prompt the user. (default: True)
2292
2301
2293 ``interface``
2302 ``interface``
2294 Select the default interface for interactive features (default: text).
2303 Select the default interface for interactive features (default: text).
2295 Possible values are 'text' and 'curses'.
2304 Possible values are 'text' and 'curses'.
2296
2305
2297 ``interface.chunkselector``
2306 ``interface.chunkselector``
2298 Select the interface for change recording (e.g. :hg:`commit -i`).
2307 Select the interface for change recording (e.g. :hg:`commit -i`).
2299 Possible values are 'text' and 'curses'.
2308 Possible values are 'text' and 'curses'.
2300 This config overrides the interface specified by ui.interface.
2309 This config overrides the interface specified by ui.interface.
2301
2310
2302 ``large-file-limit``
2311 ``large-file-limit``
2303 Largest file size that gives no memory use warning.
2312 Largest file size that gives no memory use warning.
2304 Possible values are integers or 0 to disable the check.
2313 Possible values are integers or 0 to disable the check.
2305 (default: 10000000)
2314 (default: 10000000)
2306
2315
2307 ``logtemplate``
2316 ``logtemplate``
2308 Template string for commands that print changesets.
2317 Template string for commands that print changesets.
2309
2318
2310 ``merge``
2319 ``merge``
2311 The conflict resolution program to use during a manual merge.
2320 The conflict resolution program to use during a manual merge.
2312 For more information on merge tools see :hg:`help merge-tools`.
2321 For more information on merge tools see :hg:`help merge-tools`.
2313 For configuring merge tools see the ``[merge-tools]`` section.
2322 For configuring merge tools see the ``[merge-tools]`` section.
2314
2323
2315 ``mergemarkers``
2324 ``mergemarkers``
2316 Sets the merge conflict marker label styling. The ``detailed``
2325 Sets the merge conflict marker label styling. The ``detailed``
2317 style uses the ``mergemarkertemplate`` setting to style the labels.
2326 style uses the ``mergemarkertemplate`` setting to style the labels.
2318 The ``basic`` style just uses 'local' and 'other' as the marker label.
2327 The ``basic`` style just uses 'local' and 'other' as the marker label.
2319 One of ``basic`` or ``detailed``.
2328 One of ``basic`` or ``detailed``.
2320 (default: ``basic``)
2329 (default: ``basic``)
2321
2330
2322 ``mergemarkertemplate``
2331 ``mergemarkertemplate``
2323 The template used to print the commit description next to each conflict
2332 The template used to print the commit description next to each conflict
2324 marker during merge conflicts. See :hg:`help templates` for the template
2333 marker during merge conflicts. See :hg:`help templates` for the template
2325 format.
2334 format.
2326
2335
2327 Defaults to showing the hash, tags, branches, bookmarks, author, and
2336 Defaults to showing the hash, tags, branches, bookmarks, author, and
2328 the first line of the commit description.
2337 the first line of the commit description.
2329
2338
2330 If you use non-ASCII characters in names for tags, branches, bookmarks,
2339 If you use non-ASCII characters in names for tags, branches, bookmarks,
2331 authors, and/or commit descriptions, you must pay attention to encodings of
2340 authors, and/or commit descriptions, you must pay attention to encodings of
2332 managed files. At template expansion, non-ASCII characters use the encoding
2341 managed files. At template expansion, non-ASCII characters use the encoding
2333 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2342 specified by the ``--encoding`` global option, ``HGENCODING`` or other
2334 environment variables that govern your locale. If the encoding of the merge
2343 environment variables that govern your locale. If the encoding of the merge
2335 markers is different from the encoding of the merged files,
2344 markers is different from the encoding of the merged files,
2336 serious problems may occur.
2345 serious problems may occur.
2337
2346
2338 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2347 Can be overridden per-merge-tool, see the ``[merge-tools]`` section.
2339
2348
2340 ``message-output``
2349 ``message-output``
2341 Where to write status and error messages. (default: ``stdio``)
2350 Where to write status and error messages. (default: ``stdio``)
2342
2351
2343 ``stderr``
2352 ``stderr``
2344 Everything to stderr.
2353 Everything to stderr.
2345 ``stdio``
2354 ``stdio``
2346 Status to stdout, and error to stderr.
2355 Status to stdout, and error to stderr.
2347
2356
2348 ``origbackuppath``
2357 ``origbackuppath``
2349 The path to a directory used to store generated .orig files. If the path is
2358 The path to a directory used to store generated .orig files. If the path is
2350 not a directory, one will be created. If set, files stored in this
2359 not a directory, one will be created. If set, files stored in this
2351 directory have the same name as the original file and do not have a .orig
2360 directory have the same name as the original file and do not have a .orig
2352 suffix.
2361 suffix.
2353
2362
2354 ``paginate``
2363 ``paginate``
2355 Control the pagination of command output (default: True). See :hg:`help pager`
2364 Control the pagination of command output (default: True). See :hg:`help pager`
2356 for details.
2365 for details.
2357
2366
2358 ``patch``
2367 ``patch``
2359 An optional external tool that ``hg import`` and some extensions
2368 An optional external tool that ``hg import`` and some extensions
2360 will use for applying patches. By default Mercurial uses an
2369 will use for applying patches. By default Mercurial uses an
2361 internal patch utility. The external tool must work as the common
2370 internal patch utility. The external tool must work as the common
2362 Unix ``patch`` program. In particular, it must accept a ``-p``
2371 Unix ``patch`` program. In particular, it must accept a ``-p``
2363 argument to strip patch headers, a ``-d`` argument to specify the
2372 argument to strip patch headers, a ``-d`` argument to specify the
2364 current directory, a file name to patch, and a patch file to take
2373 current directory, a file name to patch, and a patch file to take
2365 from stdin.
2374 from stdin.
2366
2375
2367 It is possible to specify a patch tool together with extra
2376 It is possible to specify a patch tool together with extra
2368 arguments. For example, setting this option to ``patch --merge``
2377 arguments. For example, setting this option to ``patch --merge``
2369 will use the ``patch`` program with its 2-way merge option.
2378 will use the ``patch`` program with its 2-way merge option.
2370
2379
2371 ``portablefilenames``
2380 ``portablefilenames``
2372 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2381 Check for portable filenames. Can be ``warn``, ``ignore`` or ``abort``.
2373 (default: ``warn``)
2382 (default: ``warn``)
2374
2383
2375 ``warn``
2384 ``warn``
2376 Print a warning message on POSIX platforms, if a file with a non-portable
2385 Print a warning message on POSIX platforms, if a file with a non-portable
2377 filename is added (e.g. a file with a name that can't be created on
2386 filename is added (e.g. a file with a name that can't be created on
2378 Windows because it contains reserved parts like ``AUX``, reserved
2387 Windows because it contains reserved parts like ``AUX``, reserved
2379 characters like ``:``, or would cause a case collision with an existing
2388 characters like ``:``, or would cause a case collision with an existing
2380 file).
2389 file).
2381
2390
2382 ``ignore``
2391 ``ignore``
2383 Don't print a warning.
2392 Don't print a warning.
2384
2393
2385 ``abort``
2394 ``abort``
2386 The command is aborted.
2395 The command is aborted.
2387
2396
2388 ``true``
2397 ``true``
2389 Alias for ``warn``.
2398 Alias for ``warn``.
2390
2399
2391 ``false``
2400 ``false``
2392 Alias for ``ignore``.
2401 Alias for ``ignore``.
2393
2402
2394 .. container:: windows
2403 .. container:: windows
2395
2404
2396 On Windows, this configuration option is ignored and the command aborted.
2405 On Windows, this configuration option is ignored and the command aborted.
2397
2406
2398 ``pre-merge-tool-output-template``
2407 ``pre-merge-tool-output-template``
2399 A template that is printed before executing an external merge tool. This can
2408 A template that is printed before executing an external merge tool. This can
2400 be used to print out additional context that might be useful to have during
2409 be used to print out additional context that might be useful to have during
2401 the conflict resolution, such as the description of the various commits
2410 the conflict resolution, such as the description of the various commits
2402 involved or bookmarks/tags.
2411 involved or bookmarks/tags.
2403
2412
2404 Additional information is available in the ``local`, ``base``, and ``other``
2413 Additional information is available in the ``local`, ``base``, and ``other``
2405 dicts. For example: ``{local.label}``, ``{base.name}``, or
2414 dicts. For example: ``{local.label}``, ``{base.name}``, or
2406 ``{other.islink}``.
2415 ``{other.islink}``.
2407
2416
2408 ``quiet``
2417 ``quiet``
2409 Reduce the amount of output printed.
2418 Reduce the amount of output printed.
2410 (default: False)
2419 (default: False)
2411
2420
2412 ``relative-paths``
2421 ``relative-paths``
2413 Prefer relative paths in the UI.
2422 Prefer relative paths in the UI.
2414
2423
2415 ``remotecmd``
2424 ``remotecmd``
2416 Remote command to use for clone/push/pull operations.
2425 Remote command to use for clone/push/pull operations.
2417 (default: ``hg``)
2426 (default: ``hg``)
2418
2427
2419 ``report_untrusted``
2428 ``report_untrusted``
2420 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2429 Warn if a ``.hg/hgrc`` file is ignored due to not being owned by a
2421 trusted user or group.
2430 trusted user or group.
2422 (default: True)
2431 (default: True)
2423
2432
2424 ``slash``
2433 ``slash``
2425 (Deprecated. Use ``slashpath`` template filter instead.)
2434 (Deprecated. Use ``slashpath`` template filter instead.)
2426
2435
2427 Display paths using a slash (``/``) as the path separator. This
2436 Display paths using a slash (``/``) as the path separator. This
2428 only makes a difference on systems where the default path
2437 only makes a difference on systems where the default path
2429 separator is not the slash character (e.g. Windows uses the
2438 separator is not the slash character (e.g. Windows uses the
2430 backslash character (``\``)).
2439 backslash character (``\``)).
2431 (default: False)
2440 (default: False)
2432
2441
2433 ``statuscopies``
2442 ``statuscopies``
2434 Display copies in the status command.
2443 Display copies in the status command.
2435
2444
2436 ``ssh``
2445 ``ssh``
2437 Command to use for SSH connections. (default: ``ssh``)
2446 Command to use for SSH connections. (default: ``ssh``)
2438
2447
2439 ``ssherrorhint``
2448 ``ssherrorhint``
2440 A hint shown to the user in the case of SSH error (e.g.
2449 A hint shown to the user in the case of SSH error (e.g.
2441 ``Please see http://company/internalwiki/ssh.html``)
2450 ``Please see http://company/internalwiki/ssh.html``)
2442
2451
2443 ``strict``
2452 ``strict``
2444 Require exact command names, instead of allowing unambiguous
2453 Require exact command names, instead of allowing unambiguous
2445 abbreviations. (default: False)
2454 abbreviations. (default: False)
2446
2455
2447 ``style``
2456 ``style``
2448 Name of style to use for command output.
2457 Name of style to use for command output.
2449
2458
2450 ``supportcontact``
2459 ``supportcontact``
2451 A URL where users should report a Mercurial traceback. Use this if you are a
2460 A URL where users should report a Mercurial traceback. Use this if you are a
2452 large organisation with its own Mercurial deployment process and crash
2461 large organisation with its own Mercurial deployment process and crash
2453 reports should be addressed to your internal support.
2462 reports should be addressed to your internal support.
2454
2463
2455 ``textwidth``
2464 ``textwidth``
2456 Maximum width of help text. A longer line generated by ``hg help`` or
2465 Maximum width of help text. A longer line generated by ``hg help`` or
2457 ``hg subcommand --help`` will be broken after white space to get this
2466 ``hg subcommand --help`` will be broken after white space to get this
2458 width or the terminal width, whichever comes first.
2467 width or the terminal width, whichever comes first.
2459 A non-positive value will disable this and the terminal width will be
2468 A non-positive value will disable this and the terminal width will be
2460 used. (default: 78)
2469 used. (default: 78)
2461
2470
2462 ``timeout``
2471 ``timeout``
2463 The timeout used when a lock is held (in seconds), a negative value
2472 The timeout used when a lock is held (in seconds), a negative value
2464 means no timeout. (default: 600)
2473 means no timeout. (default: 600)
2465
2474
2466 ``timeout.warn``
2475 ``timeout.warn``
2467 Time (in seconds) before a warning is printed about held lock. A negative
2476 Time (in seconds) before a warning is printed about held lock. A negative
2468 value means no warning. (default: 0)
2477 value means no warning. (default: 0)
2469
2478
2470 ``traceback``
2479 ``traceback``
2471 Mercurial always prints a traceback when an unknown exception
2480 Mercurial always prints a traceback when an unknown exception
2472 occurs. Setting this to True will make Mercurial print a traceback
2481 occurs. Setting this to True will make Mercurial print a traceback
2473 on all exceptions, even those recognized by Mercurial (such as
2482 on all exceptions, even those recognized by Mercurial (such as
2474 IOError or MemoryError). (default: False)
2483 IOError or MemoryError). (default: False)
2475
2484
2476 ``tweakdefaults``
2485 ``tweakdefaults``
2477
2486
2478 By default Mercurial's behavior changes very little from release
2487 By default Mercurial's behavior changes very little from release
2479 to release, but over time the recommended config settings
2488 to release, but over time the recommended config settings
2480 shift. Enable this config to opt in to get automatic tweaks to
2489 shift. Enable this config to opt in to get automatic tweaks to
2481 Mercurial's behavior over time. This config setting will have no
2490 Mercurial's behavior over time. This config setting will have no
2482 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2491 effect if ``HGPLAIN`` is set or ``HGPLAINEXCEPT`` is set and does
2483 not include ``tweakdefaults``. (default: False)
2492 not include ``tweakdefaults``. (default: False)
2484
2493
2485 It currently means::
2494 It currently means::
2486
2495
2487 .. tweakdefaultsmarker
2496 .. tweakdefaultsmarker
2488
2497
2489 ``username``
2498 ``username``
2490 The committer of a changeset created when running "commit".
2499 The committer of a changeset created when running "commit".
2491 Typically a person's name and email address, e.g. ``Fred Widget
2500 Typically a person's name and email address, e.g. ``Fred Widget
2492 <fred@example.com>``. Environment variables in the
2501 <fred@example.com>``. Environment variables in the
2493 username are expanded.
2502 username are expanded.
2494
2503
2495 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2504 (default: ``$EMAIL`` or ``username@hostname``. If the username in
2496 hgrc is empty, e.g. if the system admin set ``username =`` in the
2505 hgrc is empty, e.g. if the system admin set ``username =`` in the
2497 system hgrc, it has to be specified manually or in a different
2506 system hgrc, it has to be specified manually or in a different
2498 hgrc file)
2507 hgrc file)
2499
2508
2500 ``verbose``
2509 ``verbose``
2501 Increase the amount of output printed. (default: False)
2510 Increase the amount of output printed. (default: False)
2502
2511
2503
2512
2504 ``web``
2513 ``web``
2505 -------
2514 -------
2506
2515
2507 Web interface configuration. The settings in this section apply to
2516 Web interface configuration. The settings in this section apply to
2508 both the builtin webserver (started by :hg:`serve`) and the script you
2517 both the builtin webserver (started by :hg:`serve`) and the script you
2509 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2518 run through a webserver (``hgweb.cgi`` and the derivatives for FastCGI
2510 and WSGI).
2519 and WSGI).
2511
2520
2512 The Mercurial webserver does no authentication (it does not prompt for
2521 The Mercurial webserver does no authentication (it does not prompt for
2513 usernames and passwords to validate *who* users are), but it does do
2522 usernames and passwords to validate *who* users are), but it does do
2514 authorization (it grants or denies access for *authenticated users*
2523 authorization (it grants or denies access for *authenticated users*
2515 based on settings in this section). You must either configure your
2524 based on settings in this section). You must either configure your
2516 webserver to do authentication for you, or disable the authorization
2525 webserver to do authentication for you, or disable the authorization
2517 checks.
2526 checks.
2518
2527
2519 For a quick setup in a trusted environment, e.g., a private LAN, where
2528 For a quick setup in a trusted environment, e.g., a private LAN, where
2520 you want it to accept pushes from anybody, you can use the following
2529 you want it to accept pushes from anybody, you can use the following
2521 command line::
2530 command line::
2522
2531
2523 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2532 $ hg --config web.allow-push=* --config web.push_ssl=False serve
2524
2533
2525 Note that this will allow anybody to push anything to the server and
2534 Note that this will allow anybody to push anything to the server and
2526 that this should not be used for public servers.
2535 that this should not be used for public servers.
2527
2536
2528 The full set of options is:
2537 The full set of options is:
2529
2538
2530 ``accesslog``
2539 ``accesslog``
2531 Where to output the access log. (default: stdout)
2540 Where to output the access log. (default: stdout)
2532
2541
2533 ``address``
2542 ``address``
2534 Interface address to bind to. (default: all)
2543 Interface address to bind to. (default: all)
2535
2544
2536 ``allow-archive``
2545 ``allow-archive``
2537 List of archive format (bz2, gz, zip) allowed for downloading.
2546 List of archive format (bz2, gz, zip) allowed for downloading.
2538 (default: empty)
2547 (default: empty)
2539
2548
2540 ``allowbz2``
2549 ``allowbz2``
2541 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2550 (DEPRECATED) Whether to allow .tar.bz2 downloading of repository
2542 revisions.
2551 revisions.
2543 (default: False)
2552 (default: False)
2544
2553
2545 ``allowgz``
2554 ``allowgz``
2546 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2555 (DEPRECATED) Whether to allow .tar.gz downloading of repository
2547 revisions.
2556 revisions.
2548 (default: False)
2557 (default: False)
2549
2558
2550 ``allow-pull``
2559 ``allow-pull``
2551 Whether to allow pulling from the repository. (default: True)
2560 Whether to allow pulling from the repository. (default: True)
2552
2561
2553 ``allow-push``
2562 ``allow-push``
2554 Whether to allow pushing to the repository. If empty or not set,
2563 Whether to allow pushing to the repository. If empty or not set,
2555 pushing is not allowed. If the special value ``*``, any remote
2564 pushing is not allowed. If the special value ``*``, any remote
2556 user can push, including unauthenticated users. Otherwise, the
2565 user can push, including unauthenticated users. Otherwise, the
2557 remote user must have been authenticated, and the authenticated
2566 remote user must have been authenticated, and the authenticated
2558 user name must be present in this list. The contents of the
2567 user name must be present in this list. The contents of the
2559 allow-push list are examined after the deny_push list.
2568 allow-push list are examined after the deny_push list.
2560
2569
2561 ``allow_read``
2570 ``allow_read``
2562 If the user has not already been denied repository access due to
2571 If the user has not already been denied repository access due to
2563 the contents of deny_read, this list determines whether to grant
2572 the contents of deny_read, this list determines whether to grant
2564 repository access to the user. If this list is not empty, and the
2573 repository access to the user. If this list is not empty, and the
2565 user is unauthenticated or not present in the list, then access is
2574 user is unauthenticated or not present in the list, then access is
2566 denied for the user. If the list is empty or not set, then access
2575 denied for the user. If the list is empty or not set, then access
2567 is permitted to all users by default. Setting allow_read to the
2576 is permitted to all users by default. Setting allow_read to the
2568 special value ``*`` is equivalent to it not being set (i.e. access
2577 special value ``*`` is equivalent to it not being set (i.e. access
2569 is permitted to all users). The contents of the allow_read list are
2578 is permitted to all users). The contents of the allow_read list are
2570 examined after the deny_read list.
2579 examined after the deny_read list.
2571
2580
2572 ``allowzip``
2581 ``allowzip``
2573 (DEPRECATED) Whether to allow .zip downloading of repository
2582 (DEPRECATED) Whether to allow .zip downloading of repository
2574 revisions. This feature creates temporary files.
2583 revisions. This feature creates temporary files.
2575 (default: False)
2584 (default: False)
2576
2585
2577 ``archivesubrepos``
2586 ``archivesubrepos``
2578 Whether to recurse into subrepositories when archiving.
2587 Whether to recurse into subrepositories when archiving.
2579 (default: False)
2588 (default: False)
2580
2589
2581 ``baseurl``
2590 ``baseurl``
2582 Base URL to use when publishing URLs in other locations, so
2591 Base URL to use when publishing URLs in other locations, so
2583 third-party tools like email notification hooks can construct
2592 third-party tools like email notification hooks can construct
2584 URLs. Example: ``http://hgserver/repos/``.
2593 URLs. Example: ``http://hgserver/repos/``.
2585
2594
2586 ``cacerts``
2595 ``cacerts``
2587 Path to file containing a list of PEM encoded certificate
2596 Path to file containing a list of PEM encoded certificate
2588 authority certificates. Environment variables and ``~user``
2597 authority certificates. Environment variables and ``~user``
2589 constructs are expanded in the filename. If specified on the
2598 constructs are expanded in the filename. If specified on the
2590 client, then it will verify the identity of remote HTTPS servers
2599 client, then it will verify the identity of remote HTTPS servers
2591 with these certificates.
2600 with these certificates.
2592
2601
2593 To disable SSL verification temporarily, specify ``--insecure`` from
2602 To disable SSL verification temporarily, specify ``--insecure`` from
2594 command line.
2603 command line.
2595
2604
2596 You can use OpenSSL's CA certificate file if your platform has
2605 You can use OpenSSL's CA certificate file if your platform has
2597 one. On most Linux systems this will be
2606 one. On most Linux systems this will be
2598 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2607 ``/etc/ssl/certs/ca-certificates.crt``. Otherwise you will have to
2599 generate this file manually. The form must be as follows::
2608 generate this file manually. The form must be as follows::
2600
2609
2601 -----BEGIN CERTIFICATE-----
2610 -----BEGIN CERTIFICATE-----
2602 ... (certificate in base64 PEM encoding) ...
2611 ... (certificate in base64 PEM encoding) ...
2603 -----END CERTIFICATE-----
2612 -----END CERTIFICATE-----
2604 -----BEGIN CERTIFICATE-----
2613 -----BEGIN CERTIFICATE-----
2605 ... (certificate in base64 PEM encoding) ...
2614 ... (certificate in base64 PEM encoding) ...
2606 -----END CERTIFICATE-----
2615 -----END CERTIFICATE-----
2607
2616
2608 ``cache``
2617 ``cache``
2609 Whether to support caching in hgweb. (default: True)
2618 Whether to support caching in hgweb. (default: True)
2610
2619
2611 ``certificate``
2620 ``certificate``
2612 Certificate to use when running :hg:`serve`.
2621 Certificate to use when running :hg:`serve`.
2613
2622
2614 ``collapse``
2623 ``collapse``
2615 With ``descend`` enabled, repositories in subdirectories are shown at
2624 With ``descend`` enabled, repositories in subdirectories are shown at
2616 a single level alongside repositories in the current path. With
2625 a single level alongside repositories in the current path. With
2617 ``collapse`` also enabled, repositories residing at a deeper level than
2626 ``collapse`` also enabled, repositories residing at a deeper level than
2618 the current path are grouped behind navigable directory entries that
2627 the current path are grouped behind navigable directory entries that
2619 lead to the locations of these repositories. In effect, this setting
2628 lead to the locations of these repositories. In effect, this setting
2620 collapses each collection of repositories found within a subdirectory
2629 collapses each collection of repositories found within a subdirectory
2621 into a single entry for that subdirectory. (default: False)
2630 into a single entry for that subdirectory. (default: False)
2622
2631
2623 ``comparisoncontext``
2632 ``comparisoncontext``
2624 Number of lines of context to show in side-by-side file comparison. If
2633 Number of lines of context to show in side-by-side file comparison. If
2625 negative or the value ``full``, whole files are shown. (default: 5)
2634 negative or the value ``full``, whole files are shown. (default: 5)
2626
2635
2627 This setting can be overridden by a ``context`` request parameter to the
2636 This setting can be overridden by a ``context`` request parameter to the
2628 ``comparison`` command, taking the same values.
2637 ``comparison`` command, taking the same values.
2629
2638
2630 ``contact``
2639 ``contact``
2631 Name or email address of the person in charge of the repository.
2640 Name or email address of the person in charge of the repository.
2632 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2641 (default: ui.username or ``$EMAIL`` or "unknown" if unset or empty)
2633
2642
2634 ``csp``
2643 ``csp``
2635 Send a ``Content-Security-Policy`` HTTP header with this value.
2644 Send a ``Content-Security-Policy`` HTTP header with this value.
2636
2645
2637 The value may contain a special string ``%nonce%``, which will be replaced
2646 The value may contain a special string ``%nonce%``, which will be replaced
2638 by a randomly-generated one-time use value. If the value contains
2647 by a randomly-generated one-time use value. If the value contains
2639 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2648 ``%nonce%``, ``web.cache`` will be disabled, as caching undermines the
2640 one-time property of the nonce. This nonce will also be inserted into
2649 one-time property of the nonce. This nonce will also be inserted into
2641 ``<script>`` elements containing inline JavaScript.
2650 ``<script>`` elements containing inline JavaScript.
2642
2651
2643 Note: lots of HTML content sent by the server is derived from repository
2652 Note: lots of HTML content sent by the server is derived from repository
2644 data. Please consider the potential for malicious repository data to
2653 data. Please consider the potential for malicious repository data to
2645 "inject" itself into generated HTML content as part of your security
2654 "inject" itself into generated HTML content as part of your security
2646 threat model.
2655 threat model.
2647
2656
2648 ``deny_push``
2657 ``deny_push``
2649 Whether to deny pushing to the repository. If empty or not set,
2658 Whether to deny pushing to the repository. If empty or not set,
2650 push is not denied. If the special value ``*``, all remote users are
2659 push is not denied. If the special value ``*``, all remote users are
2651 denied push. Otherwise, unauthenticated users are all denied, and
2660 denied push. Otherwise, unauthenticated users are all denied, and
2652 any authenticated user name present in this list is also denied. The
2661 any authenticated user name present in this list is also denied. The
2653 contents of the deny_push list are examined before the allow-push list.
2662 contents of the deny_push list are examined before the allow-push list.
2654
2663
2655 ``deny_read``
2664 ``deny_read``
2656 Whether to deny reading/viewing of the repository. If this list is
2665 Whether to deny reading/viewing of the repository. If this list is
2657 not empty, unauthenticated users are all denied, and any
2666 not empty, unauthenticated users are all denied, and any
2658 authenticated user name present in this list is also denied access to
2667 authenticated user name present in this list is also denied access to
2659 the repository. If set to the special value ``*``, all remote users
2668 the repository. If set to the special value ``*``, all remote users
2660 are denied access (rarely needed ;). If deny_read is empty or not set,
2669 are denied access (rarely needed ;). If deny_read is empty or not set,
2661 the determination of repository access depends on the presence and
2670 the determination of repository access depends on the presence and
2662 content of the allow_read list (see description). If both
2671 content of the allow_read list (see description). If both
2663 deny_read and allow_read are empty or not set, then access is
2672 deny_read and allow_read are empty or not set, then access is
2664 permitted to all users by default. If the repository is being
2673 permitted to all users by default. If the repository is being
2665 served via hgwebdir, denied users will not be able to see it in
2674 served via hgwebdir, denied users will not be able to see it in
2666 the list of repositories. The contents of the deny_read list have
2675 the list of repositories. The contents of the deny_read list have
2667 priority over (are examined before) the contents of the allow_read
2676 priority over (are examined before) the contents of the allow_read
2668 list.
2677 list.
2669
2678
2670 ``descend``
2679 ``descend``
2671 hgwebdir indexes will not descend into subdirectories. Only repositories
2680 hgwebdir indexes will not descend into subdirectories. Only repositories
2672 directly in the current path will be shown (other repositories are still
2681 directly in the current path will be shown (other repositories are still
2673 available from the index corresponding to their containing path).
2682 available from the index corresponding to their containing path).
2674
2683
2675 ``description``
2684 ``description``
2676 Textual description of the repository's purpose or contents.
2685 Textual description of the repository's purpose or contents.
2677 (default: "unknown")
2686 (default: "unknown")
2678
2687
2679 ``encoding``
2688 ``encoding``
2680 Character encoding name. (default: the current locale charset)
2689 Character encoding name. (default: the current locale charset)
2681 Example: "UTF-8".
2690 Example: "UTF-8".
2682
2691
2683 ``errorlog``
2692 ``errorlog``
2684 Where to output the error log. (default: stderr)
2693 Where to output the error log. (default: stderr)
2685
2694
2686 ``guessmime``
2695 ``guessmime``
2687 Control MIME types for raw download of file content.
2696 Control MIME types for raw download of file content.
2688 Set to True to let hgweb guess the content type from the file
2697 Set to True to let hgweb guess the content type from the file
2689 extension. This will serve HTML files as ``text/html`` and might
2698 extension. This will serve HTML files as ``text/html`` and might
2690 allow cross-site scripting attacks when serving untrusted
2699 allow cross-site scripting attacks when serving untrusted
2691 repositories. (default: False)
2700 repositories. (default: False)
2692
2701
2693 ``hidden``
2702 ``hidden``
2694 Whether to hide the repository in the hgwebdir index.
2703 Whether to hide the repository in the hgwebdir index.
2695 (default: False)
2704 (default: False)
2696
2705
2697 ``ipv6``
2706 ``ipv6``
2698 Whether to use IPv6. (default: False)
2707 Whether to use IPv6. (default: False)
2699
2708
2700 ``labels``
2709 ``labels``
2701 List of string *labels* associated with the repository.
2710 List of string *labels* associated with the repository.
2702
2711
2703 Labels are exposed as a template keyword and can be used to customize
2712 Labels are exposed as a template keyword and can be used to customize
2704 output. e.g. the ``index`` template can group or filter repositories
2713 output. e.g. the ``index`` template can group or filter repositories
2705 by labels and the ``summary`` template can display additional content
2714 by labels and the ``summary`` template can display additional content
2706 if a specific label is present.
2715 if a specific label is present.
2707
2716
2708 ``logoimg``
2717 ``logoimg``
2709 File name of the logo image that some templates display on each page.
2718 File name of the logo image that some templates display on each page.
2710 The file name is relative to ``staticurl``. That is, the full path to
2719 The file name is relative to ``staticurl``. That is, the full path to
2711 the logo image is "staticurl/logoimg".
2720 the logo image is "staticurl/logoimg".
2712 If unset, ``hglogo.png`` will be used.
2721 If unset, ``hglogo.png`` will be used.
2713
2722
2714 ``logourl``
2723 ``logourl``
2715 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2724 Base URL to use for logos. If unset, ``https://mercurial-scm.org/``
2716 will be used.
2725 will be used.
2717
2726
2718 ``maxchanges``
2727 ``maxchanges``
2719 Maximum number of changes to list on the changelog. (default: 10)
2728 Maximum number of changes to list on the changelog. (default: 10)
2720
2729
2721 ``maxfiles``
2730 ``maxfiles``
2722 Maximum number of files to list per changeset. (default: 10)
2731 Maximum number of files to list per changeset. (default: 10)
2723
2732
2724 ``maxshortchanges``
2733 ``maxshortchanges``
2725 Maximum number of changes to list on the shortlog, graph or filelog
2734 Maximum number of changes to list on the shortlog, graph or filelog
2726 pages. (default: 60)
2735 pages. (default: 60)
2727
2736
2728 ``name``
2737 ``name``
2729 Repository name to use in the web interface.
2738 Repository name to use in the web interface.
2730 (default: current working directory)
2739 (default: current working directory)
2731
2740
2732 ``port``
2741 ``port``
2733 Port to listen on. (default: 8000)
2742 Port to listen on. (default: 8000)
2734
2743
2735 ``prefix``
2744 ``prefix``
2736 Prefix path to serve from. (default: '' (server root))
2745 Prefix path to serve from. (default: '' (server root))
2737
2746
2738 ``push_ssl``
2747 ``push_ssl``
2739 Whether to require that inbound pushes be transported over SSL to
2748 Whether to require that inbound pushes be transported over SSL to
2740 prevent password sniffing. (default: True)
2749 prevent password sniffing. (default: True)
2741
2750
2742 ``refreshinterval``
2751 ``refreshinterval``
2743 How frequently directory listings re-scan the filesystem for new
2752 How frequently directory listings re-scan the filesystem for new
2744 repositories, in seconds. This is relevant when wildcards are used
2753 repositories, in seconds. This is relevant when wildcards are used
2745 to define paths. Depending on how much filesystem traversal is
2754 to define paths. Depending on how much filesystem traversal is
2746 required, refreshing may negatively impact performance.
2755 required, refreshing may negatively impact performance.
2747
2756
2748 Values less than or equal to 0 always refresh.
2757 Values less than or equal to 0 always refresh.
2749 (default: 20)
2758 (default: 20)
2750
2759
2751 ``server-header``
2760 ``server-header``
2752 Value for HTTP ``Server`` response header.
2761 Value for HTTP ``Server`` response header.
2753
2762
2754 ``static``
2763 ``static``
2755 Directory where static files are served from.
2764 Directory where static files are served from.
2756
2765
2757 ``staticurl``
2766 ``staticurl``
2758 Base URL to use for static files. If unset, static files (e.g. the
2767 Base URL to use for static files. If unset, static files (e.g. the
2759 hgicon.png favicon) will be served by the CGI script itself. Use
2768 hgicon.png favicon) will be served by the CGI script itself. Use
2760 this setting to serve them directly with the HTTP server.
2769 this setting to serve them directly with the HTTP server.
2761 Example: ``http://hgserver/static/``.
2770 Example: ``http://hgserver/static/``.
2762
2771
2763 ``stripes``
2772 ``stripes``
2764 How many lines a "zebra stripe" should span in multi-line output.
2773 How many lines a "zebra stripe" should span in multi-line output.
2765 Set to 0 to disable. (default: 1)
2774 Set to 0 to disable. (default: 1)
2766
2775
2767 ``style``
2776 ``style``
2768 Which template map style to use. The available options are the names of
2777 Which template map style to use. The available options are the names of
2769 subdirectories in the HTML templates path. (default: ``paper``)
2778 subdirectories in the HTML templates path. (default: ``paper``)
2770 Example: ``monoblue``.
2779 Example: ``monoblue``.
2771
2780
2772 ``templates``
2781 ``templates``
2773 Where to find the HTML templates. The default path to the HTML templates
2782 Where to find the HTML templates. The default path to the HTML templates
2774 can be obtained from ``hg debuginstall``.
2783 can be obtained from ``hg debuginstall``.
2775
2784
2776 ``websub``
2785 ``websub``
2777 ----------
2786 ----------
2778
2787
2779 Web substitution filter definition. You can use this section to
2788 Web substitution filter definition. You can use this section to
2780 define a set of regular expression substitution patterns which
2789 define a set of regular expression substitution patterns which
2781 let you automatically modify the hgweb server output.
2790 let you automatically modify the hgweb server output.
2782
2791
2783 The default hgweb templates only apply these substitution patterns
2792 The default hgweb templates only apply these substitution patterns
2784 on the revision description fields. You can apply them anywhere
2793 on the revision description fields. You can apply them anywhere
2785 you want when you create your own templates by adding calls to the
2794 you want when you create your own templates by adding calls to the
2786 "websub" filter (usually after calling the "escape" filter).
2795 "websub" filter (usually after calling the "escape" filter).
2787
2796
2788 This can be used, for example, to convert issue references to links
2797 This can be used, for example, to convert issue references to links
2789 to your issue tracker, or to convert "markdown-like" syntax into
2798 to your issue tracker, or to convert "markdown-like" syntax into
2790 HTML (see the examples below).
2799 HTML (see the examples below).
2791
2800
2792 Each entry in this section names a substitution filter.
2801 Each entry in this section names a substitution filter.
2793 The value of each entry defines the substitution expression itself.
2802 The value of each entry defines the substitution expression itself.
2794 The websub expressions follow the old interhg extension syntax,
2803 The websub expressions follow the old interhg extension syntax,
2795 which in turn imitates the Unix sed replacement syntax::
2804 which in turn imitates the Unix sed replacement syntax::
2796
2805
2797 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2806 patternname = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
2798
2807
2799 You can use any separator other than "/". The final "i" is optional
2808 You can use any separator other than "/". The final "i" is optional
2800 and indicates that the search must be case insensitive.
2809 and indicates that the search must be case insensitive.
2801
2810
2802 Examples::
2811 Examples::
2803
2812
2804 [websub]
2813 [websub]
2805 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2814 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
2806 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2815 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
2807 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2816 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
2808
2817
2809 ``worker``
2818 ``worker``
2810 ----------
2819 ----------
2811
2820
2812 Parallel master/worker configuration. We currently perform working
2821 Parallel master/worker configuration. We currently perform working
2813 directory updates in parallel on Unix-like systems, which greatly
2822 directory updates in parallel on Unix-like systems, which greatly
2814 helps performance.
2823 helps performance.
2815
2824
2816 ``enabled``
2825 ``enabled``
2817 Whether to enable workers code to be used.
2826 Whether to enable workers code to be used.
2818 (default: true)
2827 (default: true)
2819
2828
2820 ``numcpus``
2829 ``numcpus``
2821 Number of CPUs to use for parallel operations. A zero or
2830 Number of CPUs to use for parallel operations. A zero or
2822 negative value is treated as ``use the default``.
2831 negative value is treated as ``use the default``.
2823 (default: 4 or the number of CPUs on the system, whichever is larger)
2832 (default: 4 or the number of CPUs on the system, whichever is larger)
2824
2833
2825 ``backgroundclose``
2834 ``backgroundclose``
2826 Whether to enable closing file handles on background threads during certain
2835 Whether to enable closing file handles on background threads during certain
2827 operations. Some platforms aren't very efficient at closing file
2836 operations. Some platforms aren't very efficient at closing file
2828 handles that have been written or appended to. By performing file closing
2837 handles that have been written or appended to. By performing file closing
2829 on background threads, file write rate can increase substantially.
2838 on background threads, file write rate can increase substantially.
2830 (default: true on Windows, false elsewhere)
2839 (default: true on Windows, false elsewhere)
2831
2840
2832 ``backgroundcloseminfilecount``
2841 ``backgroundcloseminfilecount``
2833 Minimum number of files required to trigger background file closing.
2842 Minimum number of files required to trigger background file closing.
2834 Operations not writing this many files won't start background close
2843 Operations not writing this many files won't start background close
2835 threads.
2844 threads.
2836 (default: 2048)
2845 (default: 2048)
2837
2846
2838 ``backgroundclosemaxqueue``
2847 ``backgroundclosemaxqueue``
2839 The maximum number of opened file handles waiting to be closed in the
2848 The maximum number of opened file handles waiting to be closed in the
2840 background. This option only has an effect if ``backgroundclose`` is
2849 background. This option only has an effect if ``backgroundclose`` is
2841 enabled.
2850 enabled.
2842 (default: 384)
2851 (default: 384)
2843
2852
2844 ``backgroundclosethreadcount``
2853 ``backgroundclosethreadcount``
2845 Number of threads to process background file closes. Only relevant if
2854 Number of threads to process background file closes. Only relevant if
2846 ``backgroundclose`` is enabled.
2855 ``backgroundclose`` is enabled.
2847 (default: 4)
2856 (default: 4)
@@ -1,3151 +1,3177 b''
1 # localrepo.py - read/write repository class for mercurial
1 # localrepo.py - read/write repository class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import hashlib
11 import hashlib
12 import os
12 import os
13 import random
13 import random
14 import sys
14 import sys
15 import time
15 import time
16 import weakref
16 import weakref
17
17
18 from .i18n import _
18 from .i18n import _
19 from .node import (
19 from .node import (
20 bin,
20 bin,
21 hex,
21 hex,
22 nullid,
22 nullid,
23 nullrev,
23 nullrev,
24 short,
24 short,
25 )
25 )
26 from . import (
26 from . import (
27 bookmarks,
27 bookmarks,
28 branchmap,
28 branchmap,
29 bundle2,
29 bundle2,
30 changegroup,
30 changegroup,
31 changelog,
31 changelog,
32 color,
32 color,
33 context,
33 context,
34 dirstate,
34 dirstate,
35 dirstateguard,
35 dirstateguard,
36 discovery,
36 discovery,
37 encoding,
37 encoding,
38 error,
38 error,
39 exchange,
39 exchange,
40 extensions,
40 extensions,
41 filelog,
41 filelog,
42 hook,
42 hook,
43 lock as lockmod,
43 lock as lockmod,
44 manifest,
44 manifest,
45 match as matchmod,
45 match as matchmod,
46 merge as mergemod,
46 merge as mergemod,
47 mergeutil,
47 mergeutil,
48 namespaces,
48 namespaces,
49 narrowspec,
49 narrowspec,
50 obsolete,
50 obsolete,
51 pathutil,
51 pathutil,
52 phases,
52 phases,
53 pushkey,
53 pushkey,
54 pycompat,
54 pycompat,
55 repository,
55 repository,
56 repoview,
56 repoview,
57 revset,
57 revset,
58 revsetlang,
58 revsetlang,
59 scmutil,
59 scmutil,
60 sparse,
60 sparse,
61 store as storemod,
61 store as storemod,
62 subrepoutil,
62 subrepoutil,
63 tags as tagsmod,
63 tags as tagsmod,
64 transaction,
64 transaction,
65 txnutil,
65 txnutil,
66 util,
66 util,
67 vfs as vfsmod,
67 vfs as vfsmod,
68 )
68 )
69 from .utils import (
69 from .utils import (
70 interfaceutil,
70 interfaceutil,
71 procutil,
71 procutil,
72 stringutil,
72 stringutil,
73 )
73 )
74
74
75 from .revlogutils import (
75 from .revlogutils import (
76 constants as revlogconst,
76 constants as revlogconst,
77 )
77 )
78
78
79 release = lockmod.release
79 release = lockmod.release
80 urlerr = util.urlerr
80 urlerr = util.urlerr
81 urlreq = util.urlreq
81 urlreq = util.urlreq
82
82
83 # set of (path, vfs-location) tuples. vfs-location is:
83 # set of (path, vfs-location) tuples. vfs-location is:
84 # - 'plain for vfs relative paths
84 # - 'plain for vfs relative paths
85 # - '' for svfs relative paths
85 # - '' for svfs relative paths
86 _cachedfiles = set()
86 _cachedfiles = set()
87
87
88 class _basefilecache(scmutil.filecache):
88 class _basefilecache(scmutil.filecache):
89 """All filecache usage on repo are done for logic that should be unfiltered
89 """All filecache usage on repo are done for logic that should be unfiltered
90 """
90 """
91 def __get__(self, repo, type=None):
91 def __get__(self, repo, type=None):
92 if repo is None:
92 if repo is None:
93 return self
93 return self
94 # proxy to unfiltered __dict__ since filtered repo has no entry
94 # proxy to unfiltered __dict__ since filtered repo has no entry
95 unfi = repo.unfiltered()
95 unfi = repo.unfiltered()
96 try:
96 try:
97 return unfi.__dict__[self.sname]
97 return unfi.__dict__[self.sname]
98 except KeyError:
98 except KeyError:
99 pass
99 pass
100 return super(_basefilecache, self).__get__(unfi, type)
100 return super(_basefilecache, self).__get__(unfi, type)
101
101
102 def set(self, repo, value):
102 def set(self, repo, value):
103 return super(_basefilecache, self).set(repo.unfiltered(), value)
103 return super(_basefilecache, self).set(repo.unfiltered(), value)
104
104
105 class repofilecache(_basefilecache):
105 class repofilecache(_basefilecache):
106 """filecache for files in .hg but outside of .hg/store"""
106 """filecache for files in .hg but outside of .hg/store"""
107 def __init__(self, *paths):
107 def __init__(self, *paths):
108 super(repofilecache, self).__init__(*paths)
108 super(repofilecache, self).__init__(*paths)
109 for path in paths:
109 for path in paths:
110 _cachedfiles.add((path, 'plain'))
110 _cachedfiles.add((path, 'plain'))
111
111
112 def join(self, obj, fname):
112 def join(self, obj, fname):
113 return obj.vfs.join(fname)
113 return obj.vfs.join(fname)
114
114
115 class storecache(_basefilecache):
115 class storecache(_basefilecache):
116 """filecache for files in the store"""
116 """filecache for files in the store"""
117 def __init__(self, *paths):
117 def __init__(self, *paths):
118 super(storecache, self).__init__(*paths)
118 super(storecache, self).__init__(*paths)
119 for path in paths:
119 for path in paths:
120 _cachedfiles.add((path, ''))
120 _cachedfiles.add((path, ''))
121
121
122 def join(self, obj, fname):
122 def join(self, obj, fname):
123 return obj.sjoin(fname)
123 return obj.sjoin(fname)
124
124
125 class mixedrepostorecache(_basefilecache):
126 """filecache for a mix files in .hg/store and outside"""
127 def __init__(self, *pathsandlocations):
128 # scmutil.filecache only uses the path for passing back into our
129 # join(), so we can safely pass a list of paths and locations
130 super(mixedrepostorecache, self).__init__(*pathsandlocations)
131 for path, location in pathsandlocations:
132 _cachedfiles.update(pathsandlocations)
133
134 def join(self, obj, fnameandlocation):
135 fname, location = fnameandlocation
136 if location == '':
137 return obj.vfs.join(fname)
138 else:
139 if location != 'store':
140 raise error.ProgrammingError('unexpected location: %s' %
141 location)
142 return obj.sjoin(fname)
143
125 def isfilecached(repo, name):
144 def isfilecached(repo, name):
126 """check if a repo has already cached "name" filecache-ed property
145 """check if a repo has already cached "name" filecache-ed property
127
146
128 This returns (cachedobj-or-None, iscached) tuple.
147 This returns (cachedobj-or-None, iscached) tuple.
129 """
148 """
130 cacheentry = repo.unfiltered()._filecache.get(name, None)
149 cacheentry = repo.unfiltered()._filecache.get(name, None)
131 if not cacheentry:
150 if not cacheentry:
132 return None, False
151 return None, False
133 return cacheentry.obj, True
152 return cacheentry.obj, True
134
153
135 class unfilteredpropertycache(util.propertycache):
154 class unfilteredpropertycache(util.propertycache):
136 """propertycache that apply to unfiltered repo only"""
155 """propertycache that apply to unfiltered repo only"""
137
156
138 def __get__(self, repo, type=None):
157 def __get__(self, repo, type=None):
139 unfi = repo.unfiltered()
158 unfi = repo.unfiltered()
140 if unfi is repo:
159 if unfi is repo:
141 return super(unfilteredpropertycache, self).__get__(unfi)
160 return super(unfilteredpropertycache, self).__get__(unfi)
142 return getattr(unfi, self.name)
161 return getattr(unfi, self.name)
143
162
144 class filteredpropertycache(util.propertycache):
163 class filteredpropertycache(util.propertycache):
145 """propertycache that must take filtering in account"""
164 """propertycache that must take filtering in account"""
146
165
147 def cachevalue(self, obj, value):
166 def cachevalue(self, obj, value):
148 object.__setattr__(obj, self.name, value)
167 object.__setattr__(obj, self.name, value)
149
168
150
169
151 def hasunfilteredcache(repo, name):
170 def hasunfilteredcache(repo, name):
152 """check if a repo has an unfilteredpropertycache value for <name>"""
171 """check if a repo has an unfilteredpropertycache value for <name>"""
153 return name in vars(repo.unfiltered())
172 return name in vars(repo.unfiltered())
154
173
155 def unfilteredmethod(orig):
174 def unfilteredmethod(orig):
156 """decorate method that always need to be run on unfiltered version"""
175 """decorate method that always need to be run on unfiltered version"""
157 def wrapper(repo, *args, **kwargs):
176 def wrapper(repo, *args, **kwargs):
158 return orig(repo.unfiltered(), *args, **kwargs)
177 return orig(repo.unfiltered(), *args, **kwargs)
159 return wrapper
178 return wrapper
160
179
161 moderncaps = {'lookup', 'branchmap', 'pushkey', 'known', 'getbundle',
180 moderncaps = {'lookup', 'branchmap', 'pushkey', 'known', 'getbundle',
162 'unbundle'}
181 'unbundle'}
163 legacycaps = moderncaps.union({'changegroupsubset'})
182 legacycaps = moderncaps.union({'changegroupsubset'})
164
183
165 @interfaceutil.implementer(repository.ipeercommandexecutor)
184 @interfaceutil.implementer(repository.ipeercommandexecutor)
166 class localcommandexecutor(object):
185 class localcommandexecutor(object):
167 def __init__(self, peer):
186 def __init__(self, peer):
168 self._peer = peer
187 self._peer = peer
169 self._sent = False
188 self._sent = False
170 self._closed = False
189 self._closed = False
171
190
172 def __enter__(self):
191 def __enter__(self):
173 return self
192 return self
174
193
175 def __exit__(self, exctype, excvalue, exctb):
194 def __exit__(self, exctype, excvalue, exctb):
176 self.close()
195 self.close()
177
196
178 def callcommand(self, command, args):
197 def callcommand(self, command, args):
179 if self._sent:
198 if self._sent:
180 raise error.ProgrammingError('callcommand() cannot be used after '
199 raise error.ProgrammingError('callcommand() cannot be used after '
181 'sendcommands()')
200 'sendcommands()')
182
201
183 if self._closed:
202 if self._closed:
184 raise error.ProgrammingError('callcommand() cannot be used after '
203 raise error.ProgrammingError('callcommand() cannot be used after '
185 'close()')
204 'close()')
186
205
187 # We don't need to support anything fancy. Just call the named
206 # We don't need to support anything fancy. Just call the named
188 # method on the peer and return a resolved future.
207 # method on the peer and return a resolved future.
189 fn = getattr(self._peer, pycompat.sysstr(command))
208 fn = getattr(self._peer, pycompat.sysstr(command))
190
209
191 f = pycompat.futures.Future()
210 f = pycompat.futures.Future()
192
211
193 try:
212 try:
194 result = fn(**pycompat.strkwargs(args))
213 result = fn(**pycompat.strkwargs(args))
195 except Exception:
214 except Exception:
196 pycompat.future_set_exception_info(f, sys.exc_info()[1:])
215 pycompat.future_set_exception_info(f, sys.exc_info()[1:])
197 else:
216 else:
198 f.set_result(result)
217 f.set_result(result)
199
218
200 return f
219 return f
201
220
202 def sendcommands(self):
221 def sendcommands(self):
203 self._sent = True
222 self._sent = True
204
223
205 def close(self):
224 def close(self):
206 self._closed = True
225 self._closed = True
207
226
208 @interfaceutil.implementer(repository.ipeercommands)
227 @interfaceutil.implementer(repository.ipeercommands)
209 class localpeer(repository.peer):
228 class localpeer(repository.peer):
210 '''peer for a local repo; reflects only the most recent API'''
229 '''peer for a local repo; reflects only the most recent API'''
211
230
212 def __init__(self, repo, caps=None):
231 def __init__(self, repo, caps=None):
213 super(localpeer, self).__init__()
232 super(localpeer, self).__init__()
214
233
215 if caps is None:
234 if caps is None:
216 caps = moderncaps.copy()
235 caps = moderncaps.copy()
217 self._repo = repo.filtered('served')
236 self._repo = repo.filtered('served')
218 self.ui = repo.ui
237 self.ui = repo.ui
219 self._caps = repo._restrictcapabilities(caps)
238 self._caps = repo._restrictcapabilities(caps)
220
239
221 # Begin of _basepeer interface.
240 # Begin of _basepeer interface.
222
241
223 def url(self):
242 def url(self):
224 return self._repo.url()
243 return self._repo.url()
225
244
226 def local(self):
245 def local(self):
227 return self._repo
246 return self._repo
228
247
229 def peer(self):
248 def peer(self):
230 return self
249 return self
231
250
232 def canpush(self):
251 def canpush(self):
233 return True
252 return True
234
253
235 def close(self):
254 def close(self):
236 self._repo.close()
255 self._repo.close()
237
256
238 # End of _basepeer interface.
257 # End of _basepeer interface.
239
258
240 # Begin of _basewirecommands interface.
259 # Begin of _basewirecommands interface.
241
260
242 def branchmap(self):
261 def branchmap(self):
243 return self._repo.branchmap()
262 return self._repo.branchmap()
244
263
245 def capabilities(self):
264 def capabilities(self):
246 return self._caps
265 return self._caps
247
266
248 def clonebundles(self):
267 def clonebundles(self):
249 return self._repo.tryread('clonebundles.manifest')
268 return self._repo.tryread('clonebundles.manifest')
250
269
251 def debugwireargs(self, one, two, three=None, four=None, five=None):
270 def debugwireargs(self, one, two, three=None, four=None, five=None):
252 """Used to test argument passing over the wire"""
271 """Used to test argument passing over the wire"""
253 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
272 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
254 pycompat.bytestr(four),
273 pycompat.bytestr(four),
255 pycompat.bytestr(five))
274 pycompat.bytestr(five))
256
275
257 def getbundle(self, source, heads=None, common=None, bundlecaps=None,
276 def getbundle(self, source, heads=None, common=None, bundlecaps=None,
258 **kwargs):
277 **kwargs):
259 chunks = exchange.getbundlechunks(self._repo, source, heads=heads,
278 chunks = exchange.getbundlechunks(self._repo, source, heads=heads,
260 common=common, bundlecaps=bundlecaps,
279 common=common, bundlecaps=bundlecaps,
261 **kwargs)[1]
280 **kwargs)[1]
262 cb = util.chunkbuffer(chunks)
281 cb = util.chunkbuffer(chunks)
263
282
264 if exchange.bundle2requested(bundlecaps):
283 if exchange.bundle2requested(bundlecaps):
265 # When requesting a bundle2, getbundle returns a stream to make the
284 # When requesting a bundle2, getbundle returns a stream to make the
266 # wire level function happier. We need to build a proper object
285 # wire level function happier. We need to build a proper object
267 # from it in local peer.
286 # from it in local peer.
268 return bundle2.getunbundler(self.ui, cb)
287 return bundle2.getunbundler(self.ui, cb)
269 else:
288 else:
270 return changegroup.getunbundler('01', cb, None)
289 return changegroup.getunbundler('01', cb, None)
271
290
272 def heads(self):
291 def heads(self):
273 return self._repo.heads()
292 return self._repo.heads()
274
293
275 def known(self, nodes):
294 def known(self, nodes):
276 return self._repo.known(nodes)
295 return self._repo.known(nodes)
277
296
278 def listkeys(self, namespace):
297 def listkeys(self, namespace):
279 return self._repo.listkeys(namespace)
298 return self._repo.listkeys(namespace)
280
299
281 def lookup(self, key):
300 def lookup(self, key):
282 return self._repo.lookup(key)
301 return self._repo.lookup(key)
283
302
284 def pushkey(self, namespace, key, old, new):
303 def pushkey(self, namespace, key, old, new):
285 return self._repo.pushkey(namespace, key, old, new)
304 return self._repo.pushkey(namespace, key, old, new)
286
305
287 def stream_out(self):
306 def stream_out(self):
288 raise error.Abort(_('cannot perform stream clone against local '
307 raise error.Abort(_('cannot perform stream clone against local '
289 'peer'))
308 'peer'))
290
309
291 def unbundle(self, bundle, heads, url):
310 def unbundle(self, bundle, heads, url):
292 """apply a bundle on a repo
311 """apply a bundle on a repo
293
312
294 This function handles the repo locking itself."""
313 This function handles the repo locking itself."""
295 try:
314 try:
296 try:
315 try:
297 bundle = exchange.readbundle(self.ui, bundle, None)
316 bundle = exchange.readbundle(self.ui, bundle, None)
298 ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
317 ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
299 if util.safehasattr(ret, 'getchunks'):
318 if util.safehasattr(ret, 'getchunks'):
300 # This is a bundle20 object, turn it into an unbundler.
319 # This is a bundle20 object, turn it into an unbundler.
301 # This little dance should be dropped eventually when the
320 # This little dance should be dropped eventually when the
302 # API is finally improved.
321 # API is finally improved.
303 stream = util.chunkbuffer(ret.getchunks())
322 stream = util.chunkbuffer(ret.getchunks())
304 ret = bundle2.getunbundler(self.ui, stream)
323 ret = bundle2.getunbundler(self.ui, stream)
305 return ret
324 return ret
306 except Exception as exc:
325 except Exception as exc:
307 # If the exception contains output salvaged from a bundle2
326 # If the exception contains output salvaged from a bundle2
308 # reply, we need to make sure it is printed before continuing
327 # reply, we need to make sure it is printed before continuing
309 # to fail. So we build a bundle2 with such output and consume
328 # to fail. So we build a bundle2 with such output and consume
310 # it directly.
329 # it directly.
311 #
330 #
312 # This is not very elegant but allows a "simple" solution for
331 # This is not very elegant but allows a "simple" solution for
313 # issue4594
332 # issue4594
314 output = getattr(exc, '_bundle2salvagedoutput', ())
333 output = getattr(exc, '_bundle2salvagedoutput', ())
315 if output:
334 if output:
316 bundler = bundle2.bundle20(self._repo.ui)
335 bundler = bundle2.bundle20(self._repo.ui)
317 for out in output:
336 for out in output:
318 bundler.addpart(out)
337 bundler.addpart(out)
319 stream = util.chunkbuffer(bundler.getchunks())
338 stream = util.chunkbuffer(bundler.getchunks())
320 b = bundle2.getunbundler(self.ui, stream)
339 b = bundle2.getunbundler(self.ui, stream)
321 bundle2.processbundle(self._repo, b)
340 bundle2.processbundle(self._repo, b)
322 raise
341 raise
323 except error.PushRaced as exc:
342 except error.PushRaced as exc:
324 raise error.ResponseError(_('push failed:'),
343 raise error.ResponseError(_('push failed:'),
325 stringutil.forcebytestr(exc))
344 stringutil.forcebytestr(exc))
326
345
327 # End of _basewirecommands interface.
346 # End of _basewirecommands interface.
328
347
329 # Begin of peer interface.
348 # Begin of peer interface.
330
349
331 def commandexecutor(self):
350 def commandexecutor(self):
332 return localcommandexecutor(self)
351 return localcommandexecutor(self)
333
352
334 # End of peer interface.
353 # End of peer interface.
335
354
336 @interfaceutil.implementer(repository.ipeerlegacycommands)
355 @interfaceutil.implementer(repository.ipeerlegacycommands)
337 class locallegacypeer(localpeer):
356 class locallegacypeer(localpeer):
338 '''peer extension which implements legacy methods too; used for tests with
357 '''peer extension which implements legacy methods too; used for tests with
339 restricted capabilities'''
358 restricted capabilities'''
340
359
341 def __init__(self, repo):
360 def __init__(self, repo):
342 super(locallegacypeer, self).__init__(repo, caps=legacycaps)
361 super(locallegacypeer, self).__init__(repo, caps=legacycaps)
343
362
344 # Begin of baselegacywirecommands interface.
363 # Begin of baselegacywirecommands interface.
345
364
346 def between(self, pairs):
365 def between(self, pairs):
347 return self._repo.between(pairs)
366 return self._repo.between(pairs)
348
367
349 def branches(self, nodes):
368 def branches(self, nodes):
350 return self._repo.branches(nodes)
369 return self._repo.branches(nodes)
351
370
352 def changegroup(self, nodes, source):
371 def changegroup(self, nodes, source):
353 outgoing = discovery.outgoing(self._repo, missingroots=nodes,
372 outgoing = discovery.outgoing(self._repo, missingroots=nodes,
354 missingheads=self._repo.heads())
373 missingheads=self._repo.heads())
355 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
374 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
356
375
357 def changegroupsubset(self, bases, heads, source):
376 def changegroupsubset(self, bases, heads, source):
358 outgoing = discovery.outgoing(self._repo, missingroots=bases,
377 outgoing = discovery.outgoing(self._repo, missingroots=bases,
359 missingheads=heads)
378 missingheads=heads)
360 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
379 return changegroup.makechangegroup(self._repo, outgoing, '01', source)
361
380
362 # End of baselegacywirecommands interface.
381 # End of baselegacywirecommands interface.
363
382
364 # Increment the sub-version when the revlog v2 format changes to lock out old
383 # Increment the sub-version when the revlog v2 format changes to lock out old
365 # clients.
384 # clients.
366 REVLOGV2_REQUIREMENT = 'exp-revlogv2.1'
385 REVLOGV2_REQUIREMENT = 'exp-revlogv2.1'
367
386
368 # A repository with the sparserevlog feature will have delta chains that
387 # A repository with the sparserevlog feature will have delta chains that
369 # can spread over a larger span. Sparse reading cuts these large spans into
388 # can spread over a larger span. Sparse reading cuts these large spans into
370 # pieces, so that each piece isn't too big.
389 # pieces, so that each piece isn't too big.
371 # Without the sparserevlog capability, reading from the repository could use
390 # Without the sparserevlog capability, reading from the repository could use
372 # huge amounts of memory, because the whole span would be read at once,
391 # huge amounts of memory, because the whole span would be read at once,
373 # including all the intermediate revisions that aren't pertinent for the chain.
392 # including all the intermediate revisions that aren't pertinent for the chain.
374 # This is why once a repository has enabled sparse-read, it becomes required.
393 # This is why once a repository has enabled sparse-read, it becomes required.
375 SPARSEREVLOG_REQUIREMENT = 'sparserevlog'
394 SPARSEREVLOG_REQUIREMENT = 'sparserevlog'
376
395
377 # Functions receiving (ui, features) that extensions can register to impact
396 # Functions receiving (ui, features) that extensions can register to impact
378 # the ability to load repositories with custom requirements. Only
397 # the ability to load repositories with custom requirements. Only
379 # functions defined in loaded extensions are called.
398 # functions defined in loaded extensions are called.
380 #
399 #
381 # The function receives a set of requirement strings that the repository
400 # The function receives a set of requirement strings that the repository
382 # is capable of opening. Functions will typically add elements to the
401 # is capable of opening. Functions will typically add elements to the
383 # set to reflect that the extension knows how to handle that requirements.
402 # set to reflect that the extension knows how to handle that requirements.
384 featuresetupfuncs = set()
403 featuresetupfuncs = set()
385
404
386 def makelocalrepository(baseui, path, intents=None):
405 def makelocalrepository(baseui, path, intents=None):
387 """Create a local repository object.
406 """Create a local repository object.
388
407
389 Given arguments needed to construct a local repository, this function
408 Given arguments needed to construct a local repository, this function
390 performs various early repository loading functionality (such as
409 performs various early repository loading functionality (such as
391 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
410 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
392 the repository can be opened, derives a type suitable for representing
411 the repository can be opened, derives a type suitable for representing
393 that repository, and returns an instance of it.
412 that repository, and returns an instance of it.
394
413
395 The returned object conforms to the ``repository.completelocalrepository``
414 The returned object conforms to the ``repository.completelocalrepository``
396 interface.
415 interface.
397
416
398 The repository type is derived by calling a series of factory functions
417 The repository type is derived by calling a series of factory functions
399 for each aspect/interface of the final repository. These are defined by
418 for each aspect/interface of the final repository. These are defined by
400 ``REPO_INTERFACES``.
419 ``REPO_INTERFACES``.
401
420
402 Each factory function is called to produce a type implementing a specific
421 Each factory function is called to produce a type implementing a specific
403 interface. The cumulative list of returned types will be combined into a
422 interface. The cumulative list of returned types will be combined into a
404 new type and that type will be instantiated to represent the local
423 new type and that type will be instantiated to represent the local
405 repository.
424 repository.
406
425
407 The factory functions each receive various state that may be consulted
426 The factory functions each receive various state that may be consulted
408 as part of deriving a type.
427 as part of deriving a type.
409
428
410 Extensions should wrap these factory functions to customize repository type
429 Extensions should wrap these factory functions to customize repository type
411 creation. Note that an extension's wrapped function may be called even if
430 creation. Note that an extension's wrapped function may be called even if
412 that extension is not loaded for the repo being constructed. Extensions
431 that extension is not loaded for the repo being constructed. Extensions
413 should check if their ``__name__`` appears in the
432 should check if their ``__name__`` appears in the
414 ``extensionmodulenames`` set passed to the factory function and no-op if
433 ``extensionmodulenames`` set passed to the factory function and no-op if
415 not.
434 not.
416 """
435 """
417 ui = baseui.copy()
436 ui = baseui.copy()
418 # Prevent copying repo configuration.
437 # Prevent copying repo configuration.
419 ui.copy = baseui.copy
438 ui.copy = baseui.copy
420
439
421 # Working directory VFS rooted at repository root.
440 # Working directory VFS rooted at repository root.
422 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
441 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
423
442
424 # Main VFS for .hg/ directory.
443 # Main VFS for .hg/ directory.
425 hgpath = wdirvfs.join(b'.hg')
444 hgpath = wdirvfs.join(b'.hg')
426 hgvfs = vfsmod.vfs(hgpath, cacheaudited=True)
445 hgvfs = vfsmod.vfs(hgpath, cacheaudited=True)
427
446
428 # The .hg/ path should exist and should be a directory. All other
447 # The .hg/ path should exist and should be a directory. All other
429 # cases are errors.
448 # cases are errors.
430 if not hgvfs.isdir():
449 if not hgvfs.isdir():
431 try:
450 try:
432 hgvfs.stat()
451 hgvfs.stat()
433 except OSError as e:
452 except OSError as e:
434 if e.errno != errno.ENOENT:
453 if e.errno != errno.ENOENT:
435 raise
454 raise
436
455
437 raise error.RepoError(_(b'repository %s not found') % path)
456 raise error.RepoError(_(b'repository %s not found') % path)
438
457
439 # .hg/requires file contains a newline-delimited list of
458 # .hg/requires file contains a newline-delimited list of
440 # features/capabilities the opener (us) must have in order to use
459 # features/capabilities the opener (us) must have in order to use
441 # the repository. This file was introduced in Mercurial 0.9.2,
460 # the repository. This file was introduced in Mercurial 0.9.2,
442 # which means very old repositories may not have one. We assume
461 # which means very old repositories may not have one. We assume
443 # a missing file translates to no requirements.
462 # a missing file translates to no requirements.
444 try:
463 try:
445 requirements = set(hgvfs.read(b'requires').splitlines())
464 requirements = set(hgvfs.read(b'requires').splitlines())
446 except IOError as e:
465 except IOError as e:
447 if e.errno != errno.ENOENT:
466 if e.errno != errno.ENOENT:
448 raise
467 raise
449 requirements = set()
468 requirements = set()
450
469
451 # The .hg/hgrc file may load extensions or contain config options
470 # The .hg/hgrc file may load extensions or contain config options
452 # that influence repository construction. Attempt to load it and
471 # that influence repository construction. Attempt to load it and
453 # process any new extensions that it may have pulled in.
472 # process any new extensions that it may have pulled in.
454 if loadhgrc(ui, wdirvfs, hgvfs, requirements):
473 if loadhgrc(ui, wdirvfs, hgvfs, requirements):
455 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
474 afterhgrcload(ui, wdirvfs, hgvfs, requirements)
456 extensions.loadall(ui)
475 extensions.loadall(ui)
457 extensions.populateui(ui)
476 extensions.populateui(ui)
458
477
459 # Set of module names of extensions loaded for this repository.
478 # Set of module names of extensions loaded for this repository.
460 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
479 extensionmodulenames = {m.__name__ for n, m in extensions.extensions(ui)}
461
480
462 supportedrequirements = gathersupportedrequirements(ui)
481 supportedrequirements = gathersupportedrequirements(ui)
463
482
464 # We first validate the requirements are known.
483 # We first validate the requirements are known.
465 ensurerequirementsrecognized(requirements, supportedrequirements)
484 ensurerequirementsrecognized(requirements, supportedrequirements)
466
485
467 # Then we validate that the known set is reasonable to use together.
486 # Then we validate that the known set is reasonable to use together.
468 ensurerequirementscompatible(ui, requirements)
487 ensurerequirementscompatible(ui, requirements)
469
488
470 # TODO there are unhandled edge cases related to opening repositories with
489 # TODO there are unhandled edge cases related to opening repositories with
471 # shared storage. If storage is shared, we should also test for requirements
490 # shared storage. If storage is shared, we should also test for requirements
472 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
491 # compatibility in the pointed-to repo. This entails loading the .hg/hgrc in
473 # that repo, as that repo may load extensions needed to open it. This is a
492 # that repo, as that repo may load extensions needed to open it. This is a
474 # bit complicated because we don't want the other hgrc to overwrite settings
493 # bit complicated because we don't want the other hgrc to overwrite settings
475 # in this hgrc.
494 # in this hgrc.
476 #
495 #
477 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
496 # This bug is somewhat mitigated by the fact that we copy the .hg/requires
478 # file when sharing repos. But if a requirement is added after the share is
497 # file when sharing repos. But if a requirement is added after the share is
479 # performed, thereby introducing a new requirement for the opener, we may
498 # performed, thereby introducing a new requirement for the opener, we may
480 # will not see that and could encounter a run-time error interacting with
499 # will not see that and could encounter a run-time error interacting with
481 # that shared store since it has an unknown-to-us requirement.
500 # that shared store since it has an unknown-to-us requirement.
482
501
483 # At this point, we know we should be capable of opening the repository.
502 # At this point, we know we should be capable of opening the repository.
484 # Now get on with doing that.
503 # Now get on with doing that.
485
504
486 features = set()
505 features = set()
487
506
488 # The "store" part of the repository holds versioned data. How it is
507 # The "store" part of the repository holds versioned data. How it is
489 # accessed is determined by various requirements. The ``shared`` or
508 # accessed is determined by various requirements. The ``shared`` or
490 # ``relshared`` requirements indicate the store lives in the path contained
509 # ``relshared`` requirements indicate the store lives in the path contained
491 # in the ``.hg/sharedpath`` file. This is an absolute path for
510 # in the ``.hg/sharedpath`` file. This is an absolute path for
492 # ``shared`` and relative to ``.hg/`` for ``relshared``.
511 # ``shared`` and relative to ``.hg/`` for ``relshared``.
493 if b'shared' in requirements or b'relshared' in requirements:
512 if b'shared' in requirements or b'relshared' in requirements:
494 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n')
513 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n')
495 if b'relshared' in requirements:
514 if b'relshared' in requirements:
496 sharedpath = hgvfs.join(sharedpath)
515 sharedpath = hgvfs.join(sharedpath)
497
516
498 sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
517 sharedvfs = vfsmod.vfs(sharedpath, realpath=True)
499
518
500 if not sharedvfs.exists():
519 if not sharedvfs.exists():
501 raise error.RepoError(_(b'.hg/sharedpath points to nonexistent '
520 raise error.RepoError(_(b'.hg/sharedpath points to nonexistent '
502 b'directory %s') % sharedvfs.base)
521 b'directory %s') % sharedvfs.base)
503
522
504 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
523 features.add(repository.REPO_FEATURE_SHARED_STORAGE)
505
524
506 storebasepath = sharedvfs.base
525 storebasepath = sharedvfs.base
507 cachepath = sharedvfs.join(b'cache')
526 cachepath = sharedvfs.join(b'cache')
508 else:
527 else:
509 storebasepath = hgvfs.base
528 storebasepath = hgvfs.base
510 cachepath = hgvfs.join(b'cache')
529 cachepath = hgvfs.join(b'cache')
511 wcachepath = hgvfs.join(b'wcache')
530 wcachepath = hgvfs.join(b'wcache')
512
531
513
532
514 # The store has changed over time and the exact layout is dictated by
533 # The store has changed over time and the exact layout is dictated by
515 # requirements. The store interface abstracts differences across all
534 # requirements. The store interface abstracts differences across all
516 # of them.
535 # of them.
517 store = makestore(requirements, storebasepath,
536 store = makestore(requirements, storebasepath,
518 lambda base: vfsmod.vfs(base, cacheaudited=True))
537 lambda base: vfsmod.vfs(base, cacheaudited=True))
519 hgvfs.createmode = store.createmode
538 hgvfs.createmode = store.createmode
520
539
521 storevfs = store.vfs
540 storevfs = store.vfs
522 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
541 storevfs.options = resolvestorevfsoptions(ui, requirements, features)
523
542
524 # The cache vfs is used to manage cache files.
543 # The cache vfs is used to manage cache files.
525 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
544 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True)
526 cachevfs.createmode = store.createmode
545 cachevfs.createmode = store.createmode
527 # The cache vfs is used to manage cache files related to the working copy
546 # The cache vfs is used to manage cache files related to the working copy
528 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
547 wcachevfs = vfsmod.vfs(wcachepath, cacheaudited=True)
529 wcachevfs.createmode = store.createmode
548 wcachevfs.createmode = store.createmode
530
549
531 # Now resolve the type for the repository object. We do this by repeatedly
550 # Now resolve the type for the repository object. We do this by repeatedly
532 # calling a factory function to produces types for specific aspects of the
551 # calling a factory function to produces types for specific aspects of the
533 # repo's operation. The aggregate returned types are used as base classes
552 # repo's operation. The aggregate returned types are used as base classes
534 # for a dynamically-derived type, which will represent our new repository.
553 # for a dynamically-derived type, which will represent our new repository.
535
554
536 bases = []
555 bases = []
537 extrastate = {}
556 extrastate = {}
538
557
539 for iface, fn in REPO_INTERFACES:
558 for iface, fn in REPO_INTERFACES:
540 # We pass all potentially useful state to give extensions tons of
559 # We pass all potentially useful state to give extensions tons of
541 # flexibility.
560 # flexibility.
542 typ = fn()(ui=ui,
561 typ = fn()(ui=ui,
543 intents=intents,
562 intents=intents,
544 requirements=requirements,
563 requirements=requirements,
545 features=features,
564 features=features,
546 wdirvfs=wdirvfs,
565 wdirvfs=wdirvfs,
547 hgvfs=hgvfs,
566 hgvfs=hgvfs,
548 store=store,
567 store=store,
549 storevfs=storevfs,
568 storevfs=storevfs,
550 storeoptions=storevfs.options,
569 storeoptions=storevfs.options,
551 cachevfs=cachevfs,
570 cachevfs=cachevfs,
552 wcachevfs=wcachevfs,
571 wcachevfs=wcachevfs,
553 extensionmodulenames=extensionmodulenames,
572 extensionmodulenames=extensionmodulenames,
554 extrastate=extrastate,
573 extrastate=extrastate,
555 baseclasses=bases)
574 baseclasses=bases)
556
575
557 if not isinstance(typ, type):
576 if not isinstance(typ, type):
558 raise error.ProgrammingError('unable to construct type for %s' %
577 raise error.ProgrammingError('unable to construct type for %s' %
559 iface)
578 iface)
560
579
561 bases.append(typ)
580 bases.append(typ)
562
581
563 # type() allows you to use characters in type names that wouldn't be
582 # type() allows you to use characters in type names that wouldn't be
564 # recognized as Python symbols in source code. We abuse that to add
583 # recognized as Python symbols in source code. We abuse that to add
565 # rich information about our constructed repo.
584 # rich information about our constructed repo.
566 name = pycompat.sysstr(b'derivedrepo:%s<%s>' % (
585 name = pycompat.sysstr(b'derivedrepo:%s<%s>' % (
567 wdirvfs.base,
586 wdirvfs.base,
568 b','.join(sorted(requirements))))
587 b','.join(sorted(requirements))))
569
588
570 cls = type(name, tuple(bases), {})
589 cls = type(name, tuple(bases), {})
571
590
572 return cls(
591 return cls(
573 baseui=baseui,
592 baseui=baseui,
574 ui=ui,
593 ui=ui,
575 origroot=path,
594 origroot=path,
576 wdirvfs=wdirvfs,
595 wdirvfs=wdirvfs,
577 hgvfs=hgvfs,
596 hgvfs=hgvfs,
578 requirements=requirements,
597 requirements=requirements,
579 supportedrequirements=supportedrequirements,
598 supportedrequirements=supportedrequirements,
580 sharedpath=storebasepath,
599 sharedpath=storebasepath,
581 store=store,
600 store=store,
582 cachevfs=cachevfs,
601 cachevfs=cachevfs,
583 wcachevfs=wcachevfs,
602 wcachevfs=wcachevfs,
584 features=features,
603 features=features,
585 intents=intents)
604 intents=intents)
586
605
587 def loadhgrc(ui, wdirvfs, hgvfs, requirements):
606 def loadhgrc(ui, wdirvfs, hgvfs, requirements):
588 """Load hgrc files/content into a ui instance.
607 """Load hgrc files/content into a ui instance.
589
608
590 This is called during repository opening to load any additional
609 This is called during repository opening to load any additional
591 config files or settings relevant to the current repository.
610 config files or settings relevant to the current repository.
592
611
593 Returns a bool indicating whether any additional configs were loaded.
612 Returns a bool indicating whether any additional configs were loaded.
594
613
595 Extensions should monkeypatch this function to modify how per-repo
614 Extensions should monkeypatch this function to modify how per-repo
596 configs are loaded. For example, an extension may wish to pull in
615 configs are loaded. For example, an extension may wish to pull in
597 configs from alternate files or sources.
616 configs from alternate files or sources.
598 """
617 """
599 try:
618 try:
600 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
619 ui.readconfig(hgvfs.join(b'hgrc'), root=wdirvfs.base)
601 return True
620 return True
602 except IOError:
621 except IOError:
603 return False
622 return False
604
623
605 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
624 def afterhgrcload(ui, wdirvfs, hgvfs, requirements):
606 """Perform additional actions after .hg/hgrc is loaded.
625 """Perform additional actions after .hg/hgrc is loaded.
607
626
608 This function is called during repository loading immediately after
627 This function is called during repository loading immediately after
609 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
628 the .hg/hgrc file is loaded and before per-repo extensions are loaded.
610
629
611 The function can be used to validate configs, automatically add
630 The function can be used to validate configs, automatically add
612 options (including extensions) based on requirements, etc.
631 options (including extensions) based on requirements, etc.
613 """
632 """
614
633
615 # Map of requirements to list of extensions to load automatically when
634 # Map of requirements to list of extensions to load automatically when
616 # requirement is present.
635 # requirement is present.
617 autoextensions = {
636 autoextensions = {
618 b'largefiles': [b'largefiles'],
637 b'largefiles': [b'largefiles'],
619 b'lfs': [b'lfs'],
638 b'lfs': [b'lfs'],
620 }
639 }
621
640
622 for requirement, names in sorted(autoextensions.items()):
641 for requirement, names in sorted(autoextensions.items()):
623 if requirement not in requirements:
642 if requirement not in requirements:
624 continue
643 continue
625
644
626 for name in names:
645 for name in names:
627 if not ui.hasconfig(b'extensions', name):
646 if not ui.hasconfig(b'extensions', name):
628 ui.setconfig(b'extensions', name, b'', source='autoload')
647 ui.setconfig(b'extensions', name, b'', source='autoload')
629
648
630 def gathersupportedrequirements(ui):
649 def gathersupportedrequirements(ui):
631 """Determine the complete set of recognized requirements."""
650 """Determine the complete set of recognized requirements."""
632 # Start with all requirements supported by this file.
651 # Start with all requirements supported by this file.
633 supported = set(localrepository._basesupported)
652 supported = set(localrepository._basesupported)
634
653
635 # Execute ``featuresetupfuncs`` entries if they belong to an extension
654 # Execute ``featuresetupfuncs`` entries if they belong to an extension
636 # relevant to this ui instance.
655 # relevant to this ui instance.
637 modules = {m.__name__ for n, m in extensions.extensions(ui)}
656 modules = {m.__name__ for n, m in extensions.extensions(ui)}
638
657
639 for fn in featuresetupfuncs:
658 for fn in featuresetupfuncs:
640 if fn.__module__ in modules:
659 if fn.__module__ in modules:
641 fn(ui, supported)
660 fn(ui, supported)
642
661
643 # Add derived requirements from registered compression engines.
662 # Add derived requirements from registered compression engines.
644 for name in util.compengines:
663 for name in util.compengines:
645 engine = util.compengines[name]
664 engine = util.compengines[name]
646 if engine.available() and engine.revlogheader():
665 if engine.available() and engine.revlogheader():
647 supported.add(b'exp-compression-%s' % name)
666 supported.add(b'exp-compression-%s' % name)
648 if engine.name() == 'zstd':
667 if engine.name() == 'zstd':
649 supported.add(b'revlog-compression-zstd')
668 supported.add(b'revlog-compression-zstd')
650
669
651 return supported
670 return supported
652
671
653 def ensurerequirementsrecognized(requirements, supported):
672 def ensurerequirementsrecognized(requirements, supported):
654 """Validate that a set of local requirements is recognized.
673 """Validate that a set of local requirements is recognized.
655
674
656 Receives a set of requirements. Raises an ``error.RepoError`` if there
675 Receives a set of requirements. Raises an ``error.RepoError`` if there
657 exists any requirement in that set that currently loaded code doesn't
676 exists any requirement in that set that currently loaded code doesn't
658 recognize.
677 recognize.
659
678
660 Returns a set of supported requirements.
679 Returns a set of supported requirements.
661 """
680 """
662 missing = set()
681 missing = set()
663
682
664 for requirement in requirements:
683 for requirement in requirements:
665 if requirement in supported:
684 if requirement in supported:
666 continue
685 continue
667
686
668 if not requirement or not requirement[0:1].isalnum():
687 if not requirement or not requirement[0:1].isalnum():
669 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
688 raise error.RequirementError(_(b'.hg/requires file is corrupt'))
670
689
671 missing.add(requirement)
690 missing.add(requirement)
672
691
673 if missing:
692 if missing:
674 raise error.RequirementError(
693 raise error.RequirementError(
675 _(b'repository requires features unknown to this Mercurial: %s') %
694 _(b'repository requires features unknown to this Mercurial: %s') %
676 b' '.join(sorted(missing)),
695 b' '.join(sorted(missing)),
677 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement '
696 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement '
678 b'for more information'))
697 b'for more information'))
679
698
680 def ensurerequirementscompatible(ui, requirements):
699 def ensurerequirementscompatible(ui, requirements):
681 """Validates that a set of recognized requirements is mutually compatible.
700 """Validates that a set of recognized requirements is mutually compatible.
682
701
683 Some requirements may not be compatible with others or require
702 Some requirements may not be compatible with others or require
684 config options that aren't enabled. This function is called during
703 config options that aren't enabled. This function is called during
685 repository opening to ensure that the set of requirements needed
704 repository opening to ensure that the set of requirements needed
686 to open a repository is sane and compatible with config options.
705 to open a repository is sane and compatible with config options.
687
706
688 Extensions can monkeypatch this function to perform additional
707 Extensions can monkeypatch this function to perform additional
689 checking.
708 checking.
690
709
691 ``error.RepoError`` should be raised on failure.
710 ``error.RepoError`` should be raised on failure.
692 """
711 """
693 if b'exp-sparse' in requirements and not sparse.enabled:
712 if b'exp-sparse' in requirements and not sparse.enabled:
694 raise error.RepoError(_(b'repository is using sparse feature but '
713 raise error.RepoError(_(b'repository is using sparse feature but '
695 b'sparse is not enabled; enable the '
714 b'sparse is not enabled; enable the '
696 b'"sparse" extensions to access'))
715 b'"sparse" extensions to access'))
697
716
698 def makestore(requirements, path, vfstype):
717 def makestore(requirements, path, vfstype):
699 """Construct a storage object for a repository."""
718 """Construct a storage object for a repository."""
700 if b'store' in requirements:
719 if b'store' in requirements:
701 if b'fncache' in requirements:
720 if b'fncache' in requirements:
702 return storemod.fncachestore(path, vfstype,
721 return storemod.fncachestore(path, vfstype,
703 b'dotencode' in requirements)
722 b'dotencode' in requirements)
704
723
705 return storemod.encodedstore(path, vfstype)
724 return storemod.encodedstore(path, vfstype)
706
725
707 return storemod.basicstore(path, vfstype)
726 return storemod.basicstore(path, vfstype)
708
727
709 def resolvestorevfsoptions(ui, requirements, features):
728 def resolvestorevfsoptions(ui, requirements, features):
710 """Resolve the options to pass to the store vfs opener.
729 """Resolve the options to pass to the store vfs opener.
711
730
712 The returned dict is used to influence behavior of the storage layer.
731 The returned dict is used to influence behavior of the storage layer.
713 """
732 """
714 options = {}
733 options = {}
715
734
716 if b'treemanifest' in requirements:
735 if b'treemanifest' in requirements:
717 options[b'treemanifest'] = True
736 options[b'treemanifest'] = True
718
737
719 # experimental config: format.manifestcachesize
738 # experimental config: format.manifestcachesize
720 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
739 manifestcachesize = ui.configint(b'format', b'manifestcachesize')
721 if manifestcachesize is not None:
740 if manifestcachesize is not None:
722 options[b'manifestcachesize'] = manifestcachesize
741 options[b'manifestcachesize'] = manifestcachesize
723
742
724 # In the absence of another requirement superseding a revlog-related
743 # In the absence of another requirement superseding a revlog-related
725 # requirement, we have to assume the repo is using revlog version 0.
744 # requirement, we have to assume the repo is using revlog version 0.
726 # This revlog format is super old and we don't bother trying to parse
745 # This revlog format is super old and we don't bother trying to parse
727 # opener options for it because those options wouldn't do anything
746 # opener options for it because those options wouldn't do anything
728 # meaningful on such old repos.
747 # meaningful on such old repos.
729 if b'revlogv1' in requirements or REVLOGV2_REQUIREMENT in requirements:
748 if b'revlogv1' in requirements or REVLOGV2_REQUIREMENT in requirements:
730 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
749 options.update(resolverevlogstorevfsoptions(ui, requirements, features))
731
750
732 return options
751 return options
733
752
734 def resolverevlogstorevfsoptions(ui, requirements, features):
753 def resolverevlogstorevfsoptions(ui, requirements, features):
735 """Resolve opener options specific to revlogs."""
754 """Resolve opener options specific to revlogs."""
736
755
737 options = {}
756 options = {}
738 options[b'flagprocessors'] = {}
757 options[b'flagprocessors'] = {}
739
758
740 if b'revlogv1' in requirements:
759 if b'revlogv1' in requirements:
741 options[b'revlogv1'] = True
760 options[b'revlogv1'] = True
742 if REVLOGV2_REQUIREMENT in requirements:
761 if REVLOGV2_REQUIREMENT in requirements:
743 options[b'revlogv2'] = True
762 options[b'revlogv2'] = True
744
763
745 if b'generaldelta' in requirements:
764 if b'generaldelta' in requirements:
746 options[b'generaldelta'] = True
765 options[b'generaldelta'] = True
747
766
748 # experimental config: format.chunkcachesize
767 # experimental config: format.chunkcachesize
749 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
768 chunkcachesize = ui.configint(b'format', b'chunkcachesize')
750 if chunkcachesize is not None:
769 if chunkcachesize is not None:
751 options[b'chunkcachesize'] = chunkcachesize
770 options[b'chunkcachesize'] = chunkcachesize
752
771
753 deltabothparents = ui.configbool(b'storage',
772 deltabothparents = ui.configbool(b'storage',
754 b'revlog.optimize-delta-parent-choice')
773 b'revlog.optimize-delta-parent-choice')
755 options[b'deltabothparents'] = deltabothparents
774 options[b'deltabothparents'] = deltabothparents
756
775
757 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
776 lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta')
758 lazydeltabase = False
777 lazydeltabase = False
759 if lazydelta:
778 if lazydelta:
760 lazydeltabase = ui.configbool(b'storage',
779 lazydeltabase = ui.configbool(b'storage',
761 b'revlog.reuse-external-delta-parent')
780 b'revlog.reuse-external-delta-parent')
762 if lazydeltabase is None:
781 if lazydeltabase is None:
763 lazydeltabase = not scmutil.gddeltaconfig(ui)
782 lazydeltabase = not scmutil.gddeltaconfig(ui)
764 options[b'lazydelta'] = lazydelta
783 options[b'lazydelta'] = lazydelta
765 options[b'lazydeltabase'] = lazydeltabase
784 options[b'lazydeltabase'] = lazydeltabase
766
785
767 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
786 chainspan = ui.configbytes(b'experimental', b'maxdeltachainspan')
768 if 0 <= chainspan:
787 if 0 <= chainspan:
769 options[b'maxdeltachainspan'] = chainspan
788 options[b'maxdeltachainspan'] = chainspan
770
789
771 mmapindexthreshold = ui.configbytes(b'experimental',
790 mmapindexthreshold = ui.configbytes(b'experimental',
772 b'mmapindexthreshold')
791 b'mmapindexthreshold')
773 if mmapindexthreshold is not None:
792 if mmapindexthreshold is not None:
774 options[b'mmapindexthreshold'] = mmapindexthreshold
793 options[b'mmapindexthreshold'] = mmapindexthreshold
775
794
776 withsparseread = ui.configbool(b'experimental', b'sparse-read')
795 withsparseread = ui.configbool(b'experimental', b'sparse-read')
777 srdensitythres = float(ui.config(b'experimental',
796 srdensitythres = float(ui.config(b'experimental',
778 b'sparse-read.density-threshold'))
797 b'sparse-read.density-threshold'))
779 srmingapsize = ui.configbytes(b'experimental',
798 srmingapsize = ui.configbytes(b'experimental',
780 b'sparse-read.min-gap-size')
799 b'sparse-read.min-gap-size')
781 options[b'with-sparse-read'] = withsparseread
800 options[b'with-sparse-read'] = withsparseread
782 options[b'sparse-read-density-threshold'] = srdensitythres
801 options[b'sparse-read-density-threshold'] = srdensitythres
783 options[b'sparse-read-min-gap-size'] = srmingapsize
802 options[b'sparse-read-min-gap-size'] = srmingapsize
784
803
785 sparserevlog = SPARSEREVLOG_REQUIREMENT in requirements
804 sparserevlog = SPARSEREVLOG_REQUIREMENT in requirements
786 options[b'sparse-revlog'] = sparserevlog
805 options[b'sparse-revlog'] = sparserevlog
787 if sparserevlog:
806 if sparserevlog:
788 options[b'generaldelta'] = True
807 options[b'generaldelta'] = True
789
808
790 maxchainlen = None
809 maxchainlen = None
791 if sparserevlog:
810 if sparserevlog:
792 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
811 maxchainlen = revlogconst.SPARSE_REVLOG_MAX_CHAIN_LENGTH
793 # experimental config: format.maxchainlen
812 # experimental config: format.maxchainlen
794 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
813 maxchainlen = ui.configint(b'format', b'maxchainlen', maxchainlen)
795 if maxchainlen is not None:
814 if maxchainlen is not None:
796 options[b'maxchainlen'] = maxchainlen
815 options[b'maxchainlen'] = maxchainlen
797
816
798 for r in requirements:
817 for r in requirements:
799 # we allow multiple compression engine requirement to co-exist because
818 # we allow multiple compression engine requirement to co-exist because
800 # strickly speaking, revlog seems to support mixed compression style.
819 # strickly speaking, revlog seems to support mixed compression style.
801 #
820 #
802 # The compression used for new entries will be "the last one"
821 # The compression used for new entries will be "the last one"
803 prefix = r.startswith
822 prefix = r.startswith
804 if prefix('revlog-compression-') or prefix('exp-compression-'):
823 if prefix('revlog-compression-') or prefix('exp-compression-'):
805 options[b'compengine'] = r.split('-', 2)[2]
824 options[b'compengine'] = r.split('-', 2)[2]
806
825
807 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
826 options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
808 if options[b'zlib.level'] is not None:
827 if options[b'zlib.level'] is not None:
809 if not (0 <= options[b'zlib.level'] <= 9):
828 if not (0 <= options[b'zlib.level'] <= 9):
810 msg = _('invalid value for `storage.revlog.zlib.level` config: %d')
829 msg = _('invalid value for `storage.revlog.zlib.level` config: %d')
811 raise error.Abort(msg % options[b'zlib.level'])
830 raise error.Abort(msg % options[b'zlib.level'])
812 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
831 options[b'zstd.level'] = ui.configint(b'storage', b'revlog.zstd.level')
813 if options[b'zstd.level'] is not None:
832 if options[b'zstd.level'] is not None:
814 if not (0 <= options[b'zstd.level'] <= 22):
833 if not (0 <= options[b'zstd.level'] <= 22):
815 msg = _('invalid value for `storage.revlog.zstd.level` config: %d')
834 msg = _('invalid value for `storage.revlog.zstd.level` config: %d')
816 raise error.Abort(msg % options[b'zstd.level'])
835 raise error.Abort(msg % options[b'zstd.level'])
817
836
818 if repository.NARROW_REQUIREMENT in requirements:
837 if repository.NARROW_REQUIREMENT in requirements:
819 options[b'enableellipsis'] = True
838 options[b'enableellipsis'] = True
820
839
821 return options
840 return options
822
841
823 def makemain(**kwargs):
842 def makemain(**kwargs):
824 """Produce a type conforming to ``ilocalrepositorymain``."""
843 """Produce a type conforming to ``ilocalrepositorymain``."""
825 return localrepository
844 return localrepository
826
845
827 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
846 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
828 class revlogfilestorage(object):
847 class revlogfilestorage(object):
829 """File storage when using revlogs."""
848 """File storage when using revlogs."""
830
849
831 def file(self, path):
850 def file(self, path):
832 if path[0] == b'/':
851 if path[0] == b'/':
833 path = path[1:]
852 path = path[1:]
834
853
835 return filelog.filelog(self.svfs, path)
854 return filelog.filelog(self.svfs, path)
836
855
837 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
856 @interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
838 class revlognarrowfilestorage(object):
857 class revlognarrowfilestorage(object):
839 """File storage when using revlogs and narrow files."""
858 """File storage when using revlogs and narrow files."""
840
859
841 def file(self, path):
860 def file(self, path):
842 if path[0] == b'/':
861 if path[0] == b'/':
843 path = path[1:]
862 path = path[1:]
844
863
845 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
864 return filelog.narrowfilelog(self.svfs, path, self._storenarrowmatch)
846
865
847 def makefilestorage(requirements, features, **kwargs):
866 def makefilestorage(requirements, features, **kwargs):
848 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
867 """Produce a type conforming to ``ilocalrepositoryfilestorage``."""
849 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
868 features.add(repository.REPO_FEATURE_REVLOG_FILE_STORAGE)
850 features.add(repository.REPO_FEATURE_STREAM_CLONE)
869 features.add(repository.REPO_FEATURE_STREAM_CLONE)
851
870
852 if repository.NARROW_REQUIREMENT in requirements:
871 if repository.NARROW_REQUIREMENT in requirements:
853 return revlognarrowfilestorage
872 return revlognarrowfilestorage
854 else:
873 else:
855 return revlogfilestorage
874 return revlogfilestorage
856
875
857 # List of repository interfaces and factory functions for them. Each
876 # List of repository interfaces and factory functions for them. Each
858 # will be called in order during ``makelocalrepository()`` to iteratively
877 # will be called in order during ``makelocalrepository()`` to iteratively
859 # derive the final type for a local repository instance. We capture the
878 # derive the final type for a local repository instance. We capture the
860 # function as a lambda so we don't hold a reference and the module-level
879 # function as a lambda so we don't hold a reference and the module-level
861 # functions can be wrapped.
880 # functions can be wrapped.
862 REPO_INTERFACES = [
881 REPO_INTERFACES = [
863 (repository.ilocalrepositorymain, lambda: makemain),
882 (repository.ilocalrepositorymain, lambda: makemain),
864 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
883 (repository.ilocalrepositoryfilestorage, lambda: makefilestorage),
865 ]
884 ]
866
885
867 @interfaceutil.implementer(repository.ilocalrepositorymain)
886 @interfaceutil.implementer(repository.ilocalrepositorymain)
868 class localrepository(object):
887 class localrepository(object):
869 """Main class for representing local repositories.
888 """Main class for representing local repositories.
870
889
871 All local repositories are instances of this class.
890 All local repositories are instances of this class.
872
891
873 Constructed on its own, instances of this class are not usable as
892 Constructed on its own, instances of this class are not usable as
874 repository objects. To obtain a usable repository object, call
893 repository objects. To obtain a usable repository object, call
875 ``hg.repository()``, ``localrepo.instance()``, or
894 ``hg.repository()``, ``localrepo.instance()``, or
876 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
895 ``localrepo.makelocalrepository()``. The latter is the lowest-level.
877 ``instance()`` adds support for creating new repositories.
896 ``instance()`` adds support for creating new repositories.
878 ``hg.repository()`` adds more extension integration, including calling
897 ``hg.repository()`` adds more extension integration, including calling
879 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
898 ``reposetup()``. Generally speaking, ``hg.repository()`` should be
880 used.
899 used.
881 """
900 """
882
901
883 # obsolete experimental requirements:
902 # obsolete experimental requirements:
884 # - manifestv2: An experimental new manifest format that allowed
903 # - manifestv2: An experimental new manifest format that allowed
885 # for stem compression of long paths. Experiment ended up not
904 # for stem compression of long paths. Experiment ended up not
886 # being successful (repository sizes went up due to worse delta
905 # being successful (repository sizes went up due to worse delta
887 # chains), and the code was deleted in 4.6.
906 # chains), and the code was deleted in 4.6.
888 supportedformats = {
907 supportedformats = {
889 'revlogv1',
908 'revlogv1',
890 'generaldelta',
909 'generaldelta',
891 'treemanifest',
910 'treemanifest',
892 REVLOGV2_REQUIREMENT,
911 REVLOGV2_REQUIREMENT,
893 SPARSEREVLOG_REQUIREMENT,
912 SPARSEREVLOG_REQUIREMENT,
913 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
894 }
914 }
895 _basesupported = supportedformats | {
915 _basesupported = supportedformats | {
896 'store',
916 'store',
897 'fncache',
917 'fncache',
898 'shared',
918 'shared',
899 'relshared',
919 'relshared',
900 'dotencode',
920 'dotencode',
901 'exp-sparse',
921 'exp-sparse',
902 'internal-phase'
922 'internal-phase'
903 }
923 }
904
924
905 # list of prefix for file which can be written without 'wlock'
925 # list of prefix for file which can be written without 'wlock'
906 # Extensions should extend this list when needed
926 # Extensions should extend this list when needed
907 _wlockfreeprefix = {
927 _wlockfreeprefix = {
908 # We migh consider requiring 'wlock' for the next
928 # We migh consider requiring 'wlock' for the next
909 # two, but pretty much all the existing code assume
929 # two, but pretty much all the existing code assume
910 # wlock is not needed so we keep them excluded for
930 # wlock is not needed so we keep them excluded for
911 # now.
931 # now.
912 'hgrc',
932 'hgrc',
913 'requires',
933 'requires',
914 # XXX cache is a complicatged business someone
934 # XXX cache is a complicatged business someone
915 # should investigate this in depth at some point
935 # should investigate this in depth at some point
916 'cache/',
936 'cache/',
917 # XXX shouldn't be dirstate covered by the wlock?
937 # XXX shouldn't be dirstate covered by the wlock?
918 'dirstate',
938 'dirstate',
919 # XXX bisect was still a bit too messy at the time
939 # XXX bisect was still a bit too messy at the time
920 # this changeset was introduced. Someone should fix
940 # this changeset was introduced. Someone should fix
921 # the remainig bit and drop this line
941 # the remainig bit and drop this line
922 'bisect.state',
942 'bisect.state',
923 }
943 }
924
944
925 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements,
945 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements,
926 supportedrequirements, sharedpath, store, cachevfs, wcachevfs,
946 supportedrequirements, sharedpath, store, cachevfs, wcachevfs,
927 features, intents=None):
947 features, intents=None):
928 """Create a new local repository instance.
948 """Create a new local repository instance.
929
949
930 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
950 Most callers should use ``hg.repository()``, ``localrepo.instance()``,
931 or ``localrepo.makelocalrepository()`` for obtaining a new repository
951 or ``localrepo.makelocalrepository()`` for obtaining a new repository
932 object.
952 object.
933
953
934 Arguments:
954 Arguments:
935
955
936 baseui
956 baseui
937 ``ui.ui`` instance that ``ui`` argument was based off of.
957 ``ui.ui`` instance that ``ui`` argument was based off of.
938
958
939 ui
959 ui
940 ``ui.ui`` instance for use by the repository.
960 ``ui.ui`` instance for use by the repository.
941
961
942 origroot
962 origroot
943 ``bytes`` path to working directory root of this repository.
963 ``bytes`` path to working directory root of this repository.
944
964
945 wdirvfs
965 wdirvfs
946 ``vfs.vfs`` rooted at the working directory.
966 ``vfs.vfs`` rooted at the working directory.
947
967
948 hgvfs
968 hgvfs
949 ``vfs.vfs`` rooted at .hg/
969 ``vfs.vfs`` rooted at .hg/
950
970
951 requirements
971 requirements
952 ``set`` of bytestrings representing repository opening requirements.
972 ``set`` of bytestrings representing repository opening requirements.
953
973
954 supportedrequirements
974 supportedrequirements
955 ``set`` of bytestrings representing repository requirements that we
975 ``set`` of bytestrings representing repository requirements that we
956 know how to open. May be a supetset of ``requirements``.
976 know how to open. May be a supetset of ``requirements``.
957
977
958 sharedpath
978 sharedpath
959 ``bytes`` Defining path to storage base directory. Points to a
979 ``bytes`` Defining path to storage base directory. Points to a
960 ``.hg/`` directory somewhere.
980 ``.hg/`` directory somewhere.
961
981
962 store
982 store
963 ``store.basicstore`` (or derived) instance providing access to
983 ``store.basicstore`` (or derived) instance providing access to
964 versioned storage.
984 versioned storage.
965
985
966 cachevfs
986 cachevfs
967 ``vfs.vfs`` used for cache files.
987 ``vfs.vfs`` used for cache files.
968
988
969 wcachevfs
989 wcachevfs
970 ``vfs.vfs`` used for cache files related to the working copy.
990 ``vfs.vfs`` used for cache files related to the working copy.
971
991
972 features
992 features
973 ``set`` of bytestrings defining features/capabilities of this
993 ``set`` of bytestrings defining features/capabilities of this
974 instance.
994 instance.
975
995
976 intents
996 intents
977 ``set`` of system strings indicating what this repo will be used
997 ``set`` of system strings indicating what this repo will be used
978 for.
998 for.
979 """
999 """
980 self.baseui = baseui
1000 self.baseui = baseui
981 self.ui = ui
1001 self.ui = ui
982 self.origroot = origroot
1002 self.origroot = origroot
983 # vfs rooted at working directory.
1003 # vfs rooted at working directory.
984 self.wvfs = wdirvfs
1004 self.wvfs = wdirvfs
985 self.root = wdirvfs.base
1005 self.root = wdirvfs.base
986 # vfs rooted at .hg/. Used to access most non-store paths.
1006 # vfs rooted at .hg/. Used to access most non-store paths.
987 self.vfs = hgvfs
1007 self.vfs = hgvfs
988 self.path = hgvfs.base
1008 self.path = hgvfs.base
989 self.requirements = requirements
1009 self.requirements = requirements
990 self.supported = supportedrequirements
1010 self.supported = supportedrequirements
991 self.sharedpath = sharedpath
1011 self.sharedpath = sharedpath
992 self.store = store
1012 self.store = store
993 self.cachevfs = cachevfs
1013 self.cachevfs = cachevfs
994 self.wcachevfs = wcachevfs
1014 self.wcachevfs = wcachevfs
995 self.features = features
1015 self.features = features
996
1016
997 self.filtername = None
1017 self.filtername = None
998
1018
999 if (self.ui.configbool('devel', 'all-warnings') or
1019 if (self.ui.configbool('devel', 'all-warnings') or
1000 self.ui.configbool('devel', 'check-locks')):
1020 self.ui.configbool('devel', 'check-locks')):
1001 self.vfs.audit = self._getvfsward(self.vfs.audit)
1021 self.vfs.audit = self._getvfsward(self.vfs.audit)
1002 # A list of callback to shape the phase if no data were found.
1022 # A list of callback to shape the phase if no data were found.
1003 # Callback are in the form: func(repo, roots) --> processed root.
1023 # Callback are in the form: func(repo, roots) --> processed root.
1004 # This list it to be filled by extension during repo setup
1024 # This list it to be filled by extension during repo setup
1005 self._phasedefaults = []
1025 self._phasedefaults = []
1006
1026
1007 color.setup(self.ui)
1027 color.setup(self.ui)
1008
1028
1009 self.spath = self.store.path
1029 self.spath = self.store.path
1010 self.svfs = self.store.vfs
1030 self.svfs = self.store.vfs
1011 self.sjoin = self.store.join
1031 self.sjoin = self.store.join
1012 if (self.ui.configbool('devel', 'all-warnings') or
1032 if (self.ui.configbool('devel', 'all-warnings') or
1013 self.ui.configbool('devel', 'check-locks')):
1033 self.ui.configbool('devel', 'check-locks')):
1014 if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
1034 if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs
1015 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1035 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit)
1016 else: # standard vfs
1036 else: # standard vfs
1017 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1037 self.svfs.audit = self._getsvfsward(self.svfs.audit)
1018
1038
1019 self._dirstatevalidatewarned = False
1039 self._dirstatevalidatewarned = False
1020
1040
1021 self._branchcaches = branchmap.BranchMapCache()
1041 self._branchcaches = branchmap.BranchMapCache()
1022 self._revbranchcache = None
1042 self._revbranchcache = None
1023 self._filterpats = {}
1043 self._filterpats = {}
1024 self._datafilters = {}
1044 self._datafilters = {}
1025 self._transref = self._lockref = self._wlockref = None
1045 self._transref = self._lockref = self._wlockref = None
1026
1046
1027 # A cache for various files under .hg/ that tracks file changes,
1047 # A cache for various files under .hg/ that tracks file changes,
1028 # (used by the filecache decorator)
1048 # (used by the filecache decorator)
1029 #
1049 #
1030 # Maps a property name to its util.filecacheentry
1050 # Maps a property name to its util.filecacheentry
1031 self._filecache = {}
1051 self._filecache = {}
1032
1052
1033 # hold sets of revision to be filtered
1053 # hold sets of revision to be filtered
1034 # should be cleared when something might have changed the filter value:
1054 # should be cleared when something might have changed the filter value:
1035 # - new changesets,
1055 # - new changesets,
1036 # - phase change,
1056 # - phase change,
1037 # - new obsolescence marker,
1057 # - new obsolescence marker,
1038 # - working directory parent change,
1058 # - working directory parent change,
1039 # - bookmark changes
1059 # - bookmark changes
1040 self.filteredrevcache = {}
1060 self.filteredrevcache = {}
1041
1061
1042 # post-dirstate-status hooks
1062 # post-dirstate-status hooks
1043 self._postdsstatus = []
1063 self._postdsstatus = []
1044
1064
1045 # generic mapping between names and nodes
1065 # generic mapping between names and nodes
1046 self.names = namespaces.namespaces()
1066 self.names = namespaces.namespaces()
1047
1067
1048 # Key to signature value.
1068 # Key to signature value.
1049 self._sparsesignaturecache = {}
1069 self._sparsesignaturecache = {}
1050 # Signature to cached matcher instance.
1070 # Signature to cached matcher instance.
1051 self._sparsematchercache = {}
1071 self._sparsematchercache = {}
1052
1072
1053 self._extrafilterid = repoview.extrafilter(ui)
1073 self._extrafilterid = repoview.extrafilter(ui)
1054
1074
1055 def _getvfsward(self, origfunc):
1075 def _getvfsward(self, origfunc):
1056 """build a ward for self.vfs"""
1076 """build a ward for self.vfs"""
1057 rref = weakref.ref(self)
1077 rref = weakref.ref(self)
1058 def checkvfs(path, mode=None):
1078 def checkvfs(path, mode=None):
1059 ret = origfunc(path, mode=mode)
1079 ret = origfunc(path, mode=mode)
1060 repo = rref()
1080 repo = rref()
1061 if (repo is None
1081 if (repo is None
1062 or not util.safehasattr(repo, '_wlockref')
1082 or not util.safehasattr(repo, '_wlockref')
1063 or not util.safehasattr(repo, '_lockref')):
1083 or not util.safehasattr(repo, '_lockref')):
1064 return
1084 return
1065 if mode in (None, 'r', 'rb'):
1085 if mode in (None, 'r', 'rb'):
1066 return
1086 return
1067 if path.startswith(repo.path):
1087 if path.startswith(repo.path):
1068 # truncate name relative to the repository (.hg)
1088 # truncate name relative to the repository (.hg)
1069 path = path[len(repo.path) + 1:]
1089 path = path[len(repo.path) + 1:]
1070 if path.startswith('cache/'):
1090 if path.startswith('cache/'):
1071 msg = 'accessing cache with vfs instead of cachevfs: "%s"'
1091 msg = 'accessing cache with vfs instead of cachevfs: "%s"'
1072 repo.ui.develwarn(msg % path, stacklevel=3, config="cache-vfs")
1092 repo.ui.develwarn(msg % path, stacklevel=3, config="cache-vfs")
1073 if path.startswith('journal.') or path.startswith('undo.'):
1093 if path.startswith('journal.') or path.startswith('undo.'):
1074 # journal is covered by 'lock'
1094 # journal is covered by 'lock'
1075 if repo._currentlock(repo._lockref) is None:
1095 if repo._currentlock(repo._lockref) is None:
1076 repo.ui.develwarn('write with no lock: "%s"' % path,
1096 repo.ui.develwarn('write with no lock: "%s"' % path,
1077 stacklevel=3, config='check-locks')
1097 stacklevel=3, config='check-locks')
1078 elif repo._currentlock(repo._wlockref) is None:
1098 elif repo._currentlock(repo._wlockref) is None:
1079 # rest of vfs files are covered by 'wlock'
1099 # rest of vfs files are covered by 'wlock'
1080 #
1100 #
1081 # exclude special files
1101 # exclude special files
1082 for prefix in self._wlockfreeprefix:
1102 for prefix in self._wlockfreeprefix:
1083 if path.startswith(prefix):
1103 if path.startswith(prefix):
1084 return
1104 return
1085 repo.ui.develwarn('write with no wlock: "%s"' % path,
1105 repo.ui.develwarn('write with no wlock: "%s"' % path,
1086 stacklevel=3, config='check-locks')
1106 stacklevel=3, config='check-locks')
1087 return ret
1107 return ret
1088 return checkvfs
1108 return checkvfs
1089
1109
1090 def _getsvfsward(self, origfunc):
1110 def _getsvfsward(self, origfunc):
1091 """build a ward for self.svfs"""
1111 """build a ward for self.svfs"""
1092 rref = weakref.ref(self)
1112 rref = weakref.ref(self)
1093 def checksvfs(path, mode=None):
1113 def checksvfs(path, mode=None):
1094 ret = origfunc(path, mode=mode)
1114 ret = origfunc(path, mode=mode)
1095 repo = rref()
1115 repo = rref()
1096 if repo is None or not util.safehasattr(repo, '_lockref'):
1116 if repo is None or not util.safehasattr(repo, '_lockref'):
1097 return
1117 return
1098 if mode in (None, 'r', 'rb'):
1118 if mode in (None, 'r', 'rb'):
1099 return
1119 return
1100 if path.startswith(repo.sharedpath):
1120 if path.startswith(repo.sharedpath):
1101 # truncate name relative to the repository (.hg)
1121 # truncate name relative to the repository (.hg)
1102 path = path[len(repo.sharedpath) + 1:]
1122 path = path[len(repo.sharedpath) + 1:]
1103 if repo._currentlock(repo._lockref) is None:
1123 if repo._currentlock(repo._lockref) is None:
1104 repo.ui.develwarn('write with no lock: "%s"' % path,
1124 repo.ui.develwarn('write with no lock: "%s"' % path,
1105 stacklevel=4)
1125 stacklevel=4)
1106 return ret
1126 return ret
1107 return checksvfs
1127 return checksvfs
1108
1128
1109 def close(self):
1129 def close(self):
1110 self._writecaches()
1130 self._writecaches()
1111
1131
1112 def _writecaches(self):
1132 def _writecaches(self):
1113 if self._revbranchcache:
1133 if self._revbranchcache:
1114 self._revbranchcache.write()
1134 self._revbranchcache.write()
1115
1135
1116 def _restrictcapabilities(self, caps):
1136 def _restrictcapabilities(self, caps):
1117 if self.ui.configbool('experimental', 'bundle2-advertise'):
1137 if self.ui.configbool('experimental', 'bundle2-advertise'):
1118 caps = set(caps)
1138 caps = set(caps)
1119 capsblob = bundle2.encodecaps(bundle2.getrepocaps(self,
1139 capsblob = bundle2.encodecaps(bundle2.getrepocaps(self,
1120 role='client'))
1140 role='client'))
1121 caps.add('bundle2=' + urlreq.quote(capsblob))
1141 caps.add('bundle2=' + urlreq.quote(capsblob))
1122 return caps
1142 return caps
1123
1143
1124 def _writerequirements(self):
1144 def _writerequirements(self):
1125 scmutil.writerequires(self.vfs, self.requirements)
1145 scmutil.writerequires(self.vfs, self.requirements)
1126
1146
1127 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1147 # Don't cache auditor/nofsauditor, or you'll end up with reference cycle:
1128 # self -> auditor -> self._checknested -> self
1148 # self -> auditor -> self._checknested -> self
1129
1149
1130 @property
1150 @property
1131 def auditor(self):
1151 def auditor(self):
1132 # This is only used by context.workingctx.match in order to
1152 # This is only used by context.workingctx.match in order to
1133 # detect files in subrepos.
1153 # detect files in subrepos.
1134 return pathutil.pathauditor(self.root, callback=self._checknested)
1154 return pathutil.pathauditor(self.root, callback=self._checknested)
1135
1155
1136 @property
1156 @property
1137 def nofsauditor(self):
1157 def nofsauditor(self):
1138 # This is only used by context.basectx.match in order to detect
1158 # This is only used by context.basectx.match in order to detect
1139 # files in subrepos.
1159 # files in subrepos.
1140 return pathutil.pathauditor(self.root, callback=self._checknested,
1160 return pathutil.pathauditor(self.root, callback=self._checknested,
1141 realfs=False, cached=True)
1161 realfs=False, cached=True)
1142
1162
1143 def _checknested(self, path):
1163 def _checknested(self, path):
1144 """Determine if path is a legal nested repository."""
1164 """Determine if path is a legal nested repository."""
1145 if not path.startswith(self.root):
1165 if not path.startswith(self.root):
1146 return False
1166 return False
1147 subpath = path[len(self.root) + 1:]
1167 subpath = path[len(self.root) + 1:]
1148 normsubpath = util.pconvert(subpath)
1168 normsubpath = util.pconvert(subpath)
1149
1169
1150 # XXX: Checking against the current working copy is wrong in
1170 # XXX: Checking against the current working copy is wrong in
1151 # the sense that it can reject things like
1171 # the sense that it can reject things like
1152 #
1172 #
1153 # $ hg cat -r 10 sub/x.txt
1173 # $ hg cat -r 10 sub/x.txt
1154 #
1174 #
1155 # if sub/ is no longer a subrepository in the working copy
1175 # if sub/ is no longer a subrepository in the working copy
1156 # parent revision.
1176 # parent revision.
1157 #
1177 #
1158 # However, it can of course also allow things that would have
1178 # However, it can of course also allow things that would have
1159 # been rejected before, such as the above cat command if sub/
1179 # been rejected before, such as the above cat command if sub/
1160 # is a subrepository now, but was a normal directory before.
1180 # is a subrepository now, but was a normal directory before.
1161 # The old path auditor would have rejected by mistake since it
1181 # The old path auditor would have rejected by mistake since it
1162 # panics when it sees sub/.hg/.
1182 # panics when it sees sub/.hg/.
1163 #
1183 #
1164 # All in all, checking against the working copy seems sensible
1184 # All in all, checking against the working copy seems sensible
1165 # since we want to prevent access to nested repositories on
1185 # since we want to prevent access to nested repositories on
1166 # the filesystem *now*.
1186 # the filesystem *now*.
1167 ctx = self[None]
1187 ctx = self[None]
1168 parts = util.splitpath(subpath)
1188 parts = util.splitpath(subpath)
1169 while parts:
1189 while parts:
1170 prefix = '/'.join(parts)
1190 prefix = '/'.join(parts)
1171 if prefix in ctx.substate:
1191 if prefix in ctx.substate:
1172 if prefix == normsubpath:
1192 if prefix == normsubpath:
1173 return True
1193 return True
1174 else:
1194 else:
1175 sub = ctx.sub(prefix)
1195 sub = ctx.sub(prefix)
1176 return sub.checknested(subpath[len(prefix) + 1:])
1196 return sub.checknested(subpath[len(prefix) + 1:])
1177 else:
1197 else:
1178 parts.pop()
1198 parts.pop()
1179 return False
1199 return False
1180
1200
1181 def peer(self):
1201 def peer(self):
1182 return localpeer(self) # not cached to avoid reference cycle
1202 return localpeer(self) # not cached to avoid reference cycle
1183
1203
1184 def unfiltered(self):
1204 def unfiltered(self):
1185 """Return unfiltered version of the repository
1205 """Return unfiltered version of the repository
1186
1206
1187 Intended to be overwritten by filtered repo."""
1207 Intended to be overwritten by filtered repo."""
1188 return self
1208 return self
1189
1209
1190 def filtered(self, name, visibilityexceptions=None):
1210 def filtered(self, name, visibilityexceptions=None):
1191 """Return a filtered version of a repository
1211 """Return a filtered version of a repository
1192
1212
1193 The `name` parameter is the identifier of the requested view. This
1213 The `name` parameter is the identifier of the requested view. This
1194 will return a repoview object set "exactly" to the specified view.
1214 will return a repoview object set "exactly" to the specified view.
1195
1215
1196 This function does not apply recursive filtering to a repository. For
1216 This function does not apply recursive filtering to a repository. For
1197 example calling `repo.filtered("served")` will return a repoview using
1217 example calling `repo.filtered("served")` will return a repoview using
1198 the "served" view, regardless of the initial view used by `repo`.
1218 the "served" view, regardless of the initial view used by `repo`.
1199
1219
1200 In other word, there is always only one level of `repoview` "filtering".
1220 In other word, there is always only one level of `repoview` "filtering".
1201 """
1221 """
1202 if self._extrafilterid is not None and '%' not in name:
1222 if self._extrafilterid is not None and '%' not in name:
1203 name = name + '%' + self._extrafilterid
1223 name = name + '%' + self._extrafilterid
1204
1224
1205 cls = repoview.newtype(self.unfiltered().__class__)
1225 cls = repoview.newtype(self.unfiltered().__class__)
1206 return cls(self, name, visibilityexceptions)
1226 return cls(self, name, visibilityexceptions)
1207
1227
1208 @repofilecache('bookmarks', 'bookmarks.current')
1228 @mixedrepostorecache(('bookmarks', ''), ('bookmarks.current', ''),
1229 ('bookmarks', 'store'))
1209 def _bookmarks(self):
1230 def _bookmarks(self):
1210 return bookmarks.bmstore(self)
1231 return bookmarks.bmstore(self)
1211
1232
1212 @property
1233 @property
1213 def _activebookmark(self):
1234 def _activebookmark(self):
1214 return self._bookmarks.active
1235 return self._bookmarks.active
1215
1236
1216 # _phasesets depend on changelog. what we need is to call
1237 # _phasesets depend on changelog. what we need is to call
1217 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1238 # _phasecache.invalidate() if '00changelog.i' was changed, but it
1218 # can't be easily expressed in filecache mechanism.
1239 # can't be easily expressed in filecache mechanism.
1219 @storecache('phaseroots', '00changelog.i')
1240 @storecache('phaseroots', '00changelog.i')
1220 def _phasecache(self):
1241 def _phasecache(self):
1221 return phases.phasecache(self, self._phasedefaults)
1242 return phases.phasecache(self, self._phasedefaults)
1222
1243
1223 @storecache('obsstore')
1244 @storecache('obsstore')
1224 def obsstore(self):
1245 def obsstore(self):
1225 return obsolete.makestore(self.ui, self)
1246 return obsolete.makestore(self.ui, self)
1226
1247
1227 @storecache('00changelog.i')
1248 @storecache('00changelog.i')
1228 def changelog(self):
1249 def changelog(self):
1229 return changelog.changelog(self.svfs,
1250 return changelog.changelog(self.svfs,
1230 trypending=txnutil.mayhavepending(self.root))
1251 trypending=txnutil.mayhavepending(self.root))
1231
1252
1232 @storecache('00manifest.i')
1253 @storecache('00manifest.i')
1233 def manifestlog(self):
1254 def manifestlog(self):
1234 rootstore = manifest.manifestrevlog(self.svfs)
1255 rootstore = manifest.manifestrevlog(self.svfs)
1235 return manifest.manifestlog(self.svfs, self, rootstore,
1256 return manifest.manifestlog(self.svfs, self, rootstore,
1236 self._storenarrowmatch)
1257 self._storenarrowmatch)
1237
1258
1238 @repofilecache('dirstate')
1259 @repofilecache('dirstate')
1239 def dirstate(self):
1260 def dirstate(self):
1240 return self._makedirstate()
1261 return self._makedirstate()
1241
1262
1242 def _makedirstate(self):
1263 def _makedirstate(self):
1243 """Extension point for wrapping the dirstate per-repo."""
1264 """Extension point for wrapping the dirstate per-repo."""
1244 sparsematchfn = lambda: sparse.matcher(self)
1265 sparsematchfn = lambda: sparse.matcher(self)
1245
1266
1246 return dirstate.dirstate(self.vfs, self.ui, self.root,
1267 return dirstate.dirstate(self.vfs, self.ui, self.root,
1247 self._dirstatevalidate, sparsematchfn)
1268 self._dirstatevalidate, sparsematchfn)
1248
1269
1249 def _dirstatevalidate(self, node):
1270 def _dirstatevalidate(self, node):
1250 try:
1271 try:
1251 self.changelog.rev(node)
1272 self.changelog.rev(node)
1252 return node
1273 return node
1253 except error.LookupError:
1274 except error.LookupError:
1254 if not self._dirstatevalidatewarned:
1275 if not self._dirstatevalidatewarned:
1255 self._dirstatevalidatewarned = True
1276 self._dirstatevalidatewarned = True
1256 self.ui.warn(_("warning: ignoring unknown"
1277 self.ui.warn(_("warning: ignoring unknown"
1257 " working parent %s!\n") % short(node))
1278 " working parent %s!\n") % short(node))
1258 return nullid
1279 return nullid
1259
1280
1260 @storecache(narrowspec.FILENAME)
1281 @storecache(narrowspec.FILENAME)
1261 def narrowpats(self):
1282 def narrowpats(self):
1262 """matcher patterns for this repository's narrowspec
1283 """matcher patterns for this repository's narrowspec
1263
1284
1264 A tuple of (includes, excludes).
1285 A tuple of (includes, excludes).
1265 """
1286 """
1266 return narrowspec.load(self)
1287 return narrowspec.load(self)
1267
1288
1268 @storecache(narrowspec.FILENAME)
1289 @storecache(narrowspec.FILENAME)
1269 def _storenarrowmatch(self):
1290 def _storenarrowmatch(self):
1270 if repository.NARROW_REQUIREMENT not in self.requirements:
1291 if repository.NARROW_REQUIREMENT not in self.requirements:
1271 return matchmod.always()
1292 return matchmod.always()
1272 include, exclude = self.narrowpats
1293 include, exclude = self.narrowpats
1273 return narrowspec.match(self.root, include=include, exclude=exclude)
1294 return narrowspec.match(self.root, include=include, exclude=exclude)
1274
1295
1275 @storecache(narrowspec.FILENAME)
1296 @storecache(narrowspec.FILENAME)
1276 def _narrowmatch(self):
1297 def _narrowmatch(self):
1277 if repository.NARROW_REQUIREMENT not in self.requirements:
1298 if repository.NARROW_REQUIREMENT not in self.requirements:
1278 return matchmod.always()
1299 return matchmod.always()
1279 narrowspec.checkworkingcopynarrowspec(self)
1300 narrowspec.checkworkingcopynarrowspec(self)
1280 include, exclude = self.narrowpats
1301 include, exclude = self.narrowpats
1281 return narrowspec.match(self.root, include=include, exclude=exclude)
1302 return narrowspec.match(self.root, include=include, exclude=exclude)
1282
1303
1283 def narrowmatch(self, match=None, includeexact=False):
1304 def narrowmatch(self, match=None, includeexact=False):
1284 """matcher corresponding the the repo's narrowspec
1305 """matcher corresponding the the repo's narrowspec
1285
1306
1286 If `match` is given, then that will be intersected with the narrow
1307 If `match` is given, then that will be intersected with the narrow
1287 matcher.
1308 matcher.
1288
1309
1289 If `includeexact` is True, then any exact matches from `match` will
1310 If `includeexact` is True, then any exact matches from `match` will
1290 be included even if they're outside the narrowspec.
1311 be included even if they're outside the narrowspec.
1291 """
1312 """
1292 if match:
1313 if match:
1293 if includeexact and not self._narrowmatch.always():
1314 if includeexact and not self._narrowmatch.always():
1294 # do not exclude explicitly-specified paths so that they can
1315 # do not exclude explicitly-specified paths so that they can
1295 # be warned later on
1316 # be warned later on
1296 em = matchmod.exact(match.files())
1317 em = matchmod.exact(match.files())
1297 nm = matchmod.unionmatcher([self._narrowmatch, em])
1318 nm = matchmod.unionmatcher([self._narrowmatch, em])
1298 return matchmod.intersectmatchers(match, nm)
1319 return matchmod.intersectmatchers(match, nm)
1299 return matchmod.intersectmatchers(match, self._narrowmatch)
1320 return matchmod.intersectmatchers(match, self._narrowmatch)
1300 return self._narrowmatch
1321 return self._narrowmatch
1301
1322
1302 def setnarrowpats(self, newincludes, newexcludes):
1323 def setnarrowpats(self, newincludes, newexcludes):
1303 narrowspec.save(self, newincludes, newexcludes)
1324 narrowspec.save(self, newincludes, newexcludes)
1304 self.invalidate(clearfilecache=True)
1325 self.invalidate(clearfilecache=True)
1305
1326
1306 def __getitem__(self, changeid):
1327 def __getitem__(self, changeid):
1307 if changeid is None:
1328 if changeid is None:
1308 return context.workingctx(self)
1329 return context.workingctx(self)
1309 if isinstance(changeid, context.basectx):
1330 if isinstance(changeid, context.basectx):
1310 return changeid
1331 return changeid
1311 if isinstance(changeid, slice):
1332 if isinstance(changeid, slice):
1312 # wdirrev isn't contiguous so the slice shouldn't include it
1333 # wdirrev isn't contiguous so the slice shouldn't include it
1313 return [self[i]
1334 return [self[i]
1314 for i in pycompat.xrange(*changeid.indices(len(self)))
1335 for i in pycompat.xrange(*changeid.indices(len(self)))
1315 if i not in self.changelog.filteredrevs]
1336 if i not in self.changelog.filteredrevs]
1316 try:
1337 try:
1317 if isinstance(changeid, int):
1338 if isinstance(changeid, int):
1318 node = self.changelog.node(changeid)
1339 node = self.changelog.node(changeid)
1319 rev = changeid
1340 rev = changeid
1320 elif changeid == 'null':
1341 elif changeid == 'null':
1321 node = nullid
1342 node = nullid
1322 rev = nullrev
1343 rev = nullrev
1323 elif changeid == 'tip':
1344 elif changeid == 'tip':
1324 node = self.changelog.tip()
1345 node = self.changelog.tip()
1325 rev = self.changelog.rev(node)
1346 rev = self.changelog.rev(node)
1326 elif changeid == '.':
1347 elif changeid == '.':
1327 # this is a hack to delay/avoid loading obsmarkers
1348 # this is a hack to delay/avoid loading obsmarkers
1328 # when we know that '.' won't be hidden
1349 # when we know that '.' won't be hidden
1329 node = self.dirstate.p1()
1350 node = self.dirstate.p1()
1330 rev = self.unfiltered().changelog.rev(node)
1351 rev = self.unfiltered().changelog.rev(node)
1331 elif len(changeid) == 20:
1352 elif len(changeid) == 20:
1332 try:
1353 try:
1333 node = changeid
1354 node = changeid
1334 rev = self.changelog.rev(changeid)
1355 rev = self.changelog.rev(changeid)
1335 except error.FilteredLookupError:
1356 except error.FilteredLookupError:
1336 changeid = hex(changeid) # for the error message
1357 changeid = hex(changeid) # for the error message
1337 raise
1358 raise
1338 except LookupError:
1359 except LookupError:
1339 # check if it might have come from damaged dirstate
1360 # check if it might have come from damaged dirstate
1340 #
1361 #
1341 # XXX we could avoid the unfiltered if we had a recognizable
1362 # XXX we could avoid the unfiltered if we had a recognizable
1342 # exception for filtered changeset access
1363 # exception for filtered changeset access
1343 if (self.local()
1364 if (self.local()
1344 and changeid in self.unfiltered().dirstate.parents()):
1365 and changeid in self.unfiltered().dirstate.parents()):
1345 msg = _("working directory has unknown parent '%s'!")
1366 msg = _("working directory has unknown parent '%s'!")
1346 raise error.Abort(msg % short(changeid))
1367 raise error.Abort(msg % short(changeid))
1347 changeid = hex(changeid) # for the error message
1368 changeid = hex(changeid) # for the error message
1348 raise
1369 raise
1349
1370
1350 elif len(changeid) == 40:
1371 elif len(changeid) == 40:
1351 node = bin(changeid)
1372 node = bin(changeid)
1352 rev = self.changelog.rev(node)
1373 rev = self.changelog.rev(node)
1353 else:
1374 else:
1354 raise error.ProgrammingError(
1375 raise error.ProgrammingError(
1355 "unsupported changeid '%s' of type %s" %
1376 "unsupported changeid '%s' of type %s" %
1356 (changeid, type(changeid)))
1377 (changeid, type(changeid)))
1357
1378
1358 return context.changectx(self, rev, node)
1379 return context.changectx(self, rev, node)
1359
1380
1360 except (error.FilteredIndexError, error.FilteredLookupError):
1381 except (error.FilteredIndexError, error.FilteredLookupError):
1361 raise error.FilteredRepoLookupError(_("filtered revision '%s'")
1382 raise error.FilteredRepoLookupError(_("filtered revision '%s'")
1362 % pycompat.bytestr(changeid))
1383 % pycompat.bytestr(changeid))
1363 except (IndexError, LookupError):
1384 except (IndexError, LookupError):
1364 raise error.RepoLookupError(
1385 raise error.RepoLookupError(
1365 _("unknown revision '%s'") % pycompat.bytestr(changeid))
1386 _("unknown revision '%s'") % pycompat.bytestr(changeid))
1366 except error.WdirUnsupported:
1387 except error.WdirUnsupported:
1367 return context.workingctx(self)
1388 return context.workingctx(self)
1368
1389
1369 def __contains__(self, changeid):
1390 def __contains__(self, changeid):
1370 """True if the given changeid exists
1391 """True if the given changeid exists
1371
1392
1372 error.AmbiguousPrefixLookupError is raised if an ambiguous node
1393 error.AmbiguousPrefixLookupError is raised if an ambiguous node
1373 specified.
1394 specified.
1374 """
1395 """
1375 try:
1396 try:
1376 self[changeid]
1397 self[changeid]
1377 return True
1398 return True
1378 except error.RepoLookupError:
1399 except error.RepoLookupError:
1379 return False
1400 return False
1380
1401
1381 def __nonzero__(self):
1402 def __nonzero__(self):
1382 return True
1403 return True
1383
1404
1384 __bool__ = __nonzero__
1405 __bool__ = __nonzero__
1385
1406
1386 def __len__(self):
1407 def __len__(self):
1387 # no need to pay the cost of repoview.changelog
1408 # no need to pay the cost of repoview.changelog
1388 unfi = self.unfiltered()
1409 unfi = self.unfiltered()
1389 return len(unfi.changelog)
1410 return len(unfi.changelog)
1390
1411
1391 def __iter__(self):
1412 def __iter__(self):
1392 return iter(self.changelog)
1413 return iter(self.changelog)
1393
1414
1394 def revs(self, expr, *args):
1415 def revs(self, expr, *args):
1395 '''Find revisions matching a revset.
1416 '''Find revisions matching a revset.
1396
1417
1397 The revset is specified as a string ``expr`` that may contain
1418 The revset is specified as a string ``expr`` that may contain
1398 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1419 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1399
1420
1400 Revset aliases from the configuration are not expanded. To expand
1421 Revset aliases from the configuration are not expanded. To expand
1401 user aliases, consider calling ``scmutil.revrange()`` or
1422 user aliases, consider calling ``scmutil.revrange()`` or
1402 ``repo.anyrevs([expr], user=True)``.
1423 ``repo.anyrevs([expr], user=True)``.
1403
1424
1404 Returns a revset.abstractsmartset, which is a list-like interface
1425 Returns a revset.abstractsmartset, which is a list-like interface
1405 that contains integer revisions.
1426 that contains integer revisions.
1406 '''
1427 '''
1407 tree = revsetlang.spectree(expr, *args)
1428 tree = revsetlang.spectree(expr, *args)
1408 return revset.makematcher(tree)(self)
1429 return revset.makematcher(tree)(self)
1409
1430
1410 def set(self, expr, *args):
1431 def set(self, expr, *args):
1411 '''Find revisions matching a revset and emit changectx instances.
1432 '''Find revisions matching a revset and emit changectx instances.
1412
1433
1413 This is a convenience wrapper around ``revs()`` that iterates the
1434 This is a convenience wrapper around ``revs()`` that iterates the
1414 result and is a generator of changectx instances.
1435 result and is a generator of changectx instances.
1415
1436
1416 Revset aliases from the configuration are not expanded. To expand
1437 Revset aliases from the configuration are not expanded. To expand
1417 user aliases, consider calling ``scmutil.revrange()``.
1438 user aliases, consider calling ``scmutil.revrange()``.
1418 '''
1439 '''
1419 for r in self.revs(expr, *args):
1440 for r in self.revs(expr, *args):
1420 yield self[r]
1441 yield self[r]
1421
1442
1422 def anyrevs(self, specs, user=False, localalias=None):
1443 def anyrevs(self, specs, user=False, localalias=None):
1423 '''Find revisions matching one of the given revsets.
1444 '''Find revisions matching one of the given revsets.
1424
1445
1425 Revset aliases from the configuration are not expanded by default. To
1446 Revset aliases from the configuration are not expanded by default. To
1426 expand user aliases, specify ``user=True``. To provide some local
1447 expand user aliases, specify ``user=True``. To provide some local
1427 definitions overriding user aliases, set ``localalias`` to
1448 definitions overriding user aliases, set ``localalias`` to
1428 ``{name: definitionstring}``.
1449 ``{name: definitionstring}``.
1429 '''
1450 '''
1430 if user:
1451 if user:
1431 m = revset.matchany(self.ui, specs,
1452 m = revset.matchany(self.ui, specs,
1432 lookup=revset.lookupfn(self),
1453 lookup=revset.lookupfn(self),
1433 localalias=localalias)
1454 localalias=localalias)
1434 else:
1455 else:
1435 m = revset.matchany(None, specs, localalias=localalias)
1456 m = revset.matchany(None, specs, localalias=localalias)
1436 return m(self)
1457 return m(self)
1437
1458
1438 def url(self):
1459 def url(self):
1439 return 'file:' + self.root
1460 return 'file:' + self.root
1440
1461
1441 def hook(self, name, throw=False, **args):
1462 def hook(self, name, throw=False, **args):
1442 """Call a hook, passing this repo instance.
1463 """Call a hook, passing this repo instance.
1443
1464
1444 This a convenience method to aid invoking hooks. Extensions likely
1465 This a convenience method to aid invoking hooks. Extensions likely
1445 won't call this unless they have registered a custom hook or are
1466 won't call this unless they have registered a custom hook or are
1446 replacing code that is expected to call a hook.
1467 replacing code that is expected to call a hook.
1447 """
1468 """
1448 return hook.hook(self.ui, self, name, throw, **args)
1469 return hook.hook(self.ui, self, name, throw, **args)
1449
1470
1450 @filteredpropertycache
1471 @filteredpropertycache
1451 def _tagscache(self):
1472 def _tagscache(self):
1452 '''Returns a tagscache object that contains various tags related
1473 '''Returns a tagscache object that contains various tags related
1453 caches.'''
1474 caches.'''
1454
1475
1455 # This simplifies its cache management by having one decorated
1476 # This simplifies its cache management by having one decorated
1456 # function (this one) and the rest simply fetch things from it.
1477 # function (this one) and the rest simply fetch things from it.
1457 class tagscache(object):
1478 class tagscache(object):
1458 def __init__(self):
1479 def __init__(self):
1459 # These two define the set of tags for this repository. tags
1480 # These two define the set of tags for this repository. tags
1460 # maps tag name to node; tagtypes maps tag name to 'global' or
1481 # maps tag name to node; tagtypes maps tag name to 'global' or
1461 # 'local'. (Global tags are defined by .hgtags across all
1482 # 'local'. (Global tags are defined by .hgtags across all
1462 # heads, and local tags are defined in .hg/localtags.)
1483 # heads, and local tags are defined in .hg/localtags.)
1463 # They constitute the in-memory cache of tags.
1484 # They constitute the in-memory cache of tags.
1464 self.tags = self.tagtypes = None
1485 self.tags = self.tagtypes = None
1465
1486
1466 self.nodetagscache = self.tagslist = None
1487 self.nodetagscache = self.tagslist = None
1467
1488
1468 cache = tagscache()
1489 cache = tagscache()
1469 cache.tags, cache.tagtypes = self._findtags()
1490 cache.tags, cache.tagtypes = self._findtags()
1470
1491
1471 return cache
1492 return cache
1472
1493
1473 def tags(self):
1494 def tags(self):
1474 '''return a mapping of tag to node'''
1495 '''return a mapping of tag to node'''
1475 t = {}
1496 t = {}
1476 if self.changelog.filteredrevs:
1497 if self.changelog.filteredrevs:
1477 tags, tt = self._findtags()
1498 tags, tt = self._findtags()
1478 else:
1499 else:
1479 tags = self._tagscache.tags
1500 tags = self._tagscache.tags
1480 rev = self.changelog.rev
1501 rev = self.changelog.rev
1481 for k, v in tags.iteritems():
1502 for k, v in tags.iteritems():
1482 try:
1503 try:
1483 # ignore tags to unknown nodes
1504 # ignore tags to unknown nodes
1484 rev(v)
1505 rev(v)
1485 t[k] = v
1506 t[k] = v
1486 except (error.LookupError, ValueError):
1507 except (error.LookupError, ValueError):
1487 pass
1508 pass
1488 return t
1509 return t
1489
1510
1490 def _findtags(self):
1511 def _findtags(self):
1491 '''Do the hard work of finding tags. Return a pair of dicts
1512 '''Do the hard work of finding tags. Return a pair of dicts
1492 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1513 (tags, tagtypes) where tags maps tag name to node, and tagtypes
1493 maps tag name to a string like \'global\' or \'local\'.
1514 maps tag name to a string like \'global\' or \'local\'.
1494 Subclasses or extensions are free to add their own tags, but
1515 Subclasses or extensions are free to add their own tags, but
1495 should be aware that the returned dicts will be retained for the
1516 should be aware that the returned dicts will be retained for the
1496 duration of the localrepo object.'''
1517 duration of the localrepo object.'''
1497
1518
1498 # XXX what tagtype should subclasses/extensions use? Currently
1519 # XXX what tagtype should subclasses/extensions use? Currently
1499 # mq and bookmarks add tags, but do not set the tagtype at all.
1520 # mq and bookmarks add tags, but do not set the tagtype at all.
1500 # Should each extension invent its own tag type? Should there
1521 # Should each extension invent its own tag type? Should there
1501 # be one tagtype for all such "virtual" tags? Or is the status
1522 # be one tagtype for all such "virtual" tags? Or is the status
1502 # quo fine?
1523 # quo fine?
1503
1524
1504
1525
1505 # map tag name to (node, hist)
1526 # map tag name to (node, hist)
1506 alltags = tagsmod.findglobaltags(self.ui, self)
1527 alltags = tagsmod.findglobaltags(self.ui, self)
1507 # map tag name to tag type
1528 # map tag name to tag type
1508 tagtypes = dict((tag, 'global') for tag in alltags)
1529 tagtypes = dict((tag, 'global') for tag in alltags)
1509
1530
1510 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1531 tagsmod.readlocaltags(self.ui, self, alltags, tagtypes)
1511
1532
1512 # Build the return dicts. Have to re-encode tag names because
1533 # Build the return dicts. Have to re-encode tag names because
1513 # the tags module always uses UTF-8 (in order not to lose info
1534 # the tags module always uses UTF-8 (in order not to lose info
1514 # writing to the cache), but the rest of Mercurial wants them in
1535 # writing to the cache), but the rest of Mercurial wants them in
1515 # local encoding.
1536 # local encoding.
1516 tags = {}
1537 tags = {}
1517 for (name, (node, hist)) in alltags.iteritems():
1538 for (name, (node, hist)) in alltags.iteritems():
1518 if node != nullid:
1539 if node != nullid:
1519 tags[encoding.tolocal(name)] = node
1540 tags[encoding.tolocal(name)] = node
1520 tags['tip'] = self.changelog.tip()
1541 tags['tip'] = self.changelog.tip()
1521 tagtypes = dict([(encoding.tolocal(name), value)
1542 tagtypes = dict([(encoding.tolocal(name), value)
1522 for (name, value) in tagtypes.iteritems()])
1543 for (name, value) in tagtypes.iteritems()])
1523 return (tags, tagtypes)
1544 return (tags, tagtypes)
1524
1545
1525 def tagtype(self, tagname):
1546 def tagtype(self, tagname):
1526 '''
1547 '''
1527 return the type of the given tag. result can be:
1548 return the type of the given tag. result can be:
1528
1549
1529 'local' : a local tag
1550 'local' : a local tag
1530 'global' : a global tag
1551 'global' : a global tag
1531 None : tag does not exist
1552 None : tag does not exist
1532 '''
1553 '''
1533
1554
1534 return self._tagscache.tagtypes.get(tagname)
1555 return self._tagscache.tagtypes.get(tagname)
1535
1556
1536 def tagslist(self):
1557 def tagslist(self):
1537 '''return a list of tags ordered by revision'''
1558 '''return a list of tags ordered by revision'''
1538 if not self._tagscache.tagslist:
1559 if not self._tagscache.tagslist:
1539 l = []
1560 l = []
1540 for t, n in self.tags().iteritems():
1561 for t, n in self.tags().iteritems():
1541 l.append((self.changelog.rev(n), t, n))
1562 l.append((self.changelog.rev(n), t, n))
1542 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
1563 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
1543
1564
1544 return self._tagscache.tagslist
1565 return self._tagscache.tagslist
1545
1566
1546 def nodetags(self, node):
1567 def nodetags(self, node):
1547 '''return the tags associated with a node'''
1568 '''return the tags associated with a node'''
1548 if not self._tagscache.nodetagscache:
1569 if not self._tagscache.nodetagscache:
1549 nodetagscache = {}
1570 nodetagscache = {}
1550 for t, n in self._tagscache.tags.iteritems():
1571 for t, n in self._tagscache.tags.iteritems():
1551 nodetagscache.setdefault(n, []).append(t)
1572 nodetagscache.setdefault(n, []).append(t)
1552 for tags in nodetagscache.itervalues():
1573 for tags in nodetagscache.itervalues():
1553 tags.sort()
1574 tags.sort()
1554 self._tagscache.nodetagscache = nodetagscache
1575 self._tagscache.nodetagscache = nodetagscache
1555 return self._tagscache.nodetagscache.get(node, [])
1576 return self._tagscache.nodetagscache.get(node, [])
1556
1577
1557 def nodebookmarks(self, node):
1578 def nodebookmarks(self, node):
1558 """return the list of bookmarks pointing to the specified node"""
1579 """return the list of bookmarks pointing to the specified node"""
1559 return self._bookmarks.names(node)
1580 return self._bookmarks.names(node)
1560
1581
1561 def branchmap(self):
1582 def branchmap(self):
1562 '''returns a dictionary {branch: [branchheads]} with branchheads
1583 '''returns a dictionary {branch: [branchheads]} with branchheads
1563 ordered by increasing revision number'''
1584 ordered by increasing revision number'''
1564 return self._branchcaches[self]
1585 return self._branchcaches[self]
1565
1586
1566 @unfilteredmethod
1587 @unfilteredmethod
1567 def revbranchcache(self):
1588 def revbranchcache(self):
1568 if not self._revbranchcache:
1589 if not self._revbranchcache:
1569 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
1590 self._revbranchcache = branchmap.revbranchcache(self.unfiltered())
1570 return self._revbranchcache
1591 return self._revbranchcache
1571
1592
1572 def branchtip(self, branch, ignoremissing=False):
1593 def branchtip(self, branch, ignoremissing=False):
1573 '''return the tip node for a given branch
1594 '''return the tip node for a given branch
1574
1595
1575 If ignoremissing is True, then this method will not raise an error.
1596 If ignoremissing is True, then this method will not raise an error.
1576 This is helpful for callers that only expect None for a missing branch
1597 This is helpful for callers that only expect None for a missing branch
1577 (e.g. namespace).
1598 (e.g. namespace).
1578
1599
1579 '''
1600 '''
1580 try:
1601 try:
1581 return self.branchmap().branchtip(branch)
1602 return self.branchmap().branchtip(branch)
1582 except KeyError:
1603 except KeyError:
1583 if not ignoremissing:
1604 if not ignoremissing:
1584 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
1605 raise error.RepoLookupError(_("unknown branch '%s'") % branch)
1585 else:
1606 else:
1586 pass
1607 pass
1587
1608
1588 def lookup(self, key):
1609 def lookup(self, key):
1589 node = scmutil.revsymbol(self, key).node()
1610 node = scmutil.revsymbol(self, key).node()
1590 if node is None:
1611 if node is None:
1591 raise error.RepoLookupError(_("unknown revision '%s'") % key)
1612 raise error.RepoLookupError(_("unknown revision '%s'") % key)
1592 return node
1613 return node
1593
1614
1594 def lookupbranch(self, key):
1615 def lookupbranch(self, key):
1595 if self.branchmap().hasbranch(key):
1616 if self.branchmap().hasbranch(key):
1596 return key
1617 return key
1597
1618
1598 return scmutil.revsymbol(self, key).branch()
1619 return scmutil.revsymbol(self, key).branch()
1599
1620
1600 def known(self, nodes):
1621 def known(self, nodes):
1601 cl = self.changelog
1622 cl = self.changelog
1602 nm = cl.nodemap
1623 nm = cl.nodemap
1603 filtered = cl.filteredrevs
1624 filtered = cl.filteredrevs
1604 result = []
1625 result = []
1605 for n in nodes:
1626 for n in nodes:
1606 r = nm.get(n)
1627 r = nm.get(n)
1607 resp = not (r is None or r in filtered)
1628 resp = not (r is None or r in filtered)
1608 result.append(resp)
1629 result.append(resp)
1609 return result
1630 return result
1610
1631
1611 def local(self):
1632 def local(self):
1612 return self
1633 return self
1613
1634
1614 def publishing(self):
1635 def publishing(self):
1615 # it's safe (and desirable) to trust the publish flag unconditionally
1636 # it's safe (and desirable) to trust the publish flag unconditionally
1616 # so that we don't finalize changes shared between users via ssh or nfs
1637 # so that we don't finalize changes shared between users via ssh or nfs
1617 return self.ui.configbool('phases', 'publish', untrusted=True)
1638 return self.ui.configbool('phases', 'publish', untrusted=True)
1618
1639
1619 def cancopy(self):
1640 def cancopy(self):
1620 # so statichttprepo's override of local() works
1641 # so statichttprepo's override of local() works
1621 if not self.local():
1642 if not self.local():
1622 return False
1643 return False
1623 if not self.publishing():
1644 if not self.publishing():
1624 return True
1645 return True
1625 # if publishing we can't copy if there is filtered content
1646 # if publishing we can't copy if there is filtered content
1626 return not self.filtered('visible').changelog.filteredrevs
1647 return not self.filtered('visible').changelog.filteredrevs
1627
1648
1628 def shared(self):
1649 def shared(self):
1629 '''the type of shared repository (None if not shared)'''
1650 '''the type of shared repository (None if not shared)'''
1630 if self.sharedpath != self.path:
1651 if self.sharedpath != self.path:
1631 return 'store'
1652 return 'store'
1632 return None
1653 return None
1633
1654
1634 def wjoin(self, f, *insidef):
1655 def wjoin(self, f, *insidef):
1635 return self.vfs.reljoin(self.root, f, *insidef)
1656 return self.vfs.reljoin(self.root, f, *insidef)
1636
1657
1637 def setparents(self, p1, p2=nullid):
1658 def setparents(self, p1, p2=nullid):
1638 with self.dirstate.parentchange():
1659 with self.dirstate.parentchange():
1639 copies = self.dirstate.setparents(p1, p2)
1660 copies = self.dirstate.setparents(p1, p2)
1640 pctx = self[p1]
1661 pctx = self[p1]
1641 if copies:
1662 if copies:
1642 # Adjust copy records, the dirstate cannot do it, it
1663 # Adjust copy records, the dirstate cannot do it, it
1643 # requires access to parents manifests. Preserve them
1664 # requires access to parents manifests. Preserve them
1644 # only for entries added to first parent.
1665 # only for entries added to first parent.
1645 for f in copies:
1666 for f in copies:
1646 if f not in pctx and copies[f] in pctx:
1667 if f not in pctx and copies[f] in pctx:
1647 self.dirstate.copy(copies[f], f)
1668 self.dirstate.copy(copies[f], f)
1648 if p2 == nullid:
1669 if p2 == nullid:
1649 for f, s in sorted(self.dirstate.copies().items()):
1670 for f, s in sorted(self.dirstate.copies().items()):
1650 if f not in pctx and s not in pctx:
1671 if f not in pctx and s not in pctx:
1651 self.dirstate.copy(None, f)
1672 self.dirstate.copy(None, f)
1652
1673
1653 def filectx(self, path, changeid=None, fileid=None, changectx=None):
1674 def filectx(self, path, changeid=None, fileid=None, changectx=None):
1654 """changeid must be a changeset revision, if specified.
1675 """changeid must be a changeset revision, if specified.
1655 fileid can be a file revision or node."""
1676 fileid can be a file revision or node."""
1656 return context.filectx(self, path, changeid, fileid,
1677 return context.filectx(self, path, changeid, fileid,
1657 changectx=changectx)
1678 changectx=changectx)
1658
1679
1659 def getcwd(self):
1680 def getcwd(self):
1660 return self.dirstate.getcwd()
1681 return self.dirstate.getcwd()
1661
1682
1662 def pathto(self, f, cwd=None):
1683 def pathto(self, f, cwd=None):
1663 return self.dirstate.pathto(f, cwd)
1684 return self.dirstate.pathto(f, cwd)
1664
1685
1665 def _loadfilter(self, filter):
1686 def _loadfilter(self, filter):
1666 if filter not in self._filterpats:
1687 if filter not in self._filterpats:
1667 l = []
1688 l = []
1668 for pat, cmd in self.ui.configitems(filter):
1689 for pat, cmd in self.ui.configitems(filter):
1669 if cmd == '!':
1690 if cmd == '!':
1670 continue
1691 continue
1671 mf = matchmod.match(self.root, '', [pat])
1692 mf = matchmod.match(self.root, '', [pat])
1672 fn = None
1693 fn = None
1673 params = cmd
1694 params = cmd
1674 for name, filterfn in self._datafilters.iteritems():
1695 for name, filterfn in self._datafilters.iteritems():
1675 if cmd.startswith(name):
1696 if cmd.startswith(name):
1676 fn = filterfn
1697 fn = filterfn
1677 params = cmd[len(name):].lstrip()
1698 params = cmd[len(name):].lstrip()
1678 break
1699 break
1679 if not fn:
1700 if not fn:
1680 fn = lambda s, c, **kwargs: procutil.filter(s, c)
1701 fn = lambda s, c, **kwargs: procutil.filter(s, c)
1681 # Wrap old filters not supporting keyword arguments
1702 # Wrap old filters not supporting keyword arguments
1682 if not pycompat.getargspec(fn)[2]:
1703 if not pycompat.getargspec(fn)[2]:
1683 oldfn = fn
1704 oldfn = fn
1684 fn = lambda s, c, **kwargs: oldfn(s, c)
1705 fn = lambda s, c, **kwargs: oldfn(s, c)
1685 l.append((mf, fn, params))
1706 l.append((mf, fn, params))
1686 self._filterpats[filter] = l
1707 self._filterpats[filter] = l
1687 return self._filterpats[filter]
1708 return self._filterpats[filter]
1688
1709
1689 def _filter(self, filterpats, filename, data):
1710 def _filter(self, filterpats, filename, data):
1690 for mf, fn, cmd in filterpats:
1711 for mf, fn, cmd in filterpats:
1691 if mf(filename):
1712 if mf(filename):
1692 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
1713 self.ui.debug("filtering %s through %s\n" % (filename, cmd))
1693 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
1714 data = fn(data, cmd, ui=self.ui, repo=self, filename=filename)
1694 break
1715 break
1695
1716
1696 return data
1717 return data
1697
1718
1698 @unfilteredpropertycache
1719 @unfilteredpropertycache
1699 def _encodefilterpats(self):
1720 def _encodefilterpats(self):
1700 return self._loadfilter('encode')
1721 return self._loadfilter('encode')
1701
1722
1702 @unfilteredpropertycache
1723 @unfilteredpropertycache
1703 def _decodefilterpats(self):
1724 def _decodefilterpats(self):
1704 return self._loadfilter('decode')
1725 return self._loadfilter('decode')
1705
1726
1706 def adddatafilter(self, name, filter):
1727 def adddatafilter(self, name, filter):
1707 self._datafilters[name] = filter
1728 self._datafilters[name] = filter
1708
1729
1709 def wread(self, filename):
1730 def wread(self, filename):
1710 if self.wvfs.islink(filename):
1731 if self.wvfs.islink(filename):
1711 data = self.wvfs.readlink(filename)
1732 data = self.wvfs.readlink(filename)
1712 else:
1733 else:
1713 data = self.wvfs.read(filename)
1734 data = self.wvfs.read(filename)
1714 return self._filter(self._encodefilterpats, filename, data)
1735 return self._filter(self._encodefilterpats, filename, data)
1715
1736
1716 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
1737 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
1717 """write ``data`` into ``filename`` in the working directory
1738 """write ``data`` into ``filename`` in the working directory
1718
1739
1719 This returns length of written (maybe decoded) data.
1740 This returns length of written (maybe decoded) data.
1720 """
1741 """
1721 data = self._filter(self._decodefilterpats, filename, data)
1742 data = self._filter(self._decodefilterpats, filename, data)
1722 if 'l' in flags:
1743 if 'l' in flags:
1723 self.wvfs.symlink(data, filename)
1744 self.wvfs.symlink(data, filename)
1724 else:
1745 else:
1725 self.wvfs.write(filename, data, backgroundclose=backgroundclose,
1746 self.wvfs.write(filename, data, backgroundclose=backgroundclose,
1726 **kwargs)
1747 **kwargs)
1727 if 'x' in flags:
1748 if 'x' in flags:
1728 self.wvfs.setflags(filename, False, True)
1749 self.wvfs.setflags(filename, False, True)
1729 else:
1750 else:
1730 self.wvfs.setflags(filename, False, False)
1751 self.wvfs.setflags(filename, False, False)
1731 return len(data)
1752 return len(data)
1732
1753
1733 def wwritedata(self, filename, data):
1754 def wwritedata(self, filename, data):
1734 return self._filter(self._decodefilterpats, filename, data)
1755 return self._filter(self._decodefilterpats, filename, data)
1735
1756
1736 def currenttransaction(self):
1757 def currenttransaction(self):
1737 """return the current transaction or None if non exists"""
1758 """return the current transaction or None if non exists"""
1738 if self._transref:
1759 if self._transref:
1739 tr = self._transref()
1760 tr = self._transref()
1740 else:
1761 else:
1741 tr = None
1762 tr = None
1742
1763
1743 if tr and tr.running():
1764 if tr and tr.running():
1744 return tr
1765 return tr
1745 return None
1766 return None
1746
1767
1747 def transaction(self, desc, report=None):
1768 def transaction(self, desc, report=None):
1748 if (self.ui.configbool('devel', 'all-warnings')
1769 if (self.ui.configbool('devel', 'all-warnings')
1749 or self.ui.configbool('devel', 'check-locks')):
1770 or self.ui.configbool('devel', 'check-locks')):
1750 if self._currentlock(self._lockref) is None:
1771 if self._currentlock(self._lockref) is None:
1751 raise error.ProgrammingError('transaction requires locking')
1772 raise error.ProgrammingError('transaction requires locking')
1752 tr = self.currenttransaction()
1773 tr = self.currenttransaction()
1753 if tr is not None:
1774 if tr is not None:
1754 return tr.nest(name=desc)
1775 return tr.nest(name=desc)
1755
1776
1756 # abort here if the journal already exists
1777 # abort here if the journal already exists
1757 if self.svfs.exists("journal"):
1778 if self.svfs.exists("journal"):
1758 raise error.RepoError(
1779 raise error.RepoError(
1759 _("abandoned transaction found"),
1780 _("abandoned transaction found"),
1760 hint=_("run 'hg recover' to clean up transaction"))
1781 hint=_("run 'hg recover' to clean up transaction"))
1761
1782
1762 idbase = "%.40f#%f" % (random.random(), time.time())
1783 idbase = "%.40f#%f" % (random.random(), time.time())
1763 ha = hex(hashlib.sha1(idbase).digest())
1784 ha = hex(hashlib.sha1(idbase).digest())
1764 txnid = 'TXN:' + ha
1785 txnid = 'TXN:' + ha
1765 self.hook('pretxnopen', throw=True, txnname=desc, txnid=txnid)
1786 self.hook('pretxnopen', throw=True, txnname=desc, txnid=txnid)
1766
1787
1767 self._writejournal(desc)
1788 self._writejournal(desc)
1768 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
1789 renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()]
1769 if report:
1790 if report:
1770 rp = report
1791 rp = report
1771 else:
1792 else:
1772 rp = self.ui.warn
1793 rp = self.ui.warn
1773 vfsmap = {'plain': self.vfs, 'store': self.svfs} # root of .hg/
1794 vfsmap = {'plain': self.vfs, 'store': self.svfs} # root of .hg/
1774 # we must avoid cyclic reference between repo and transaction.
1795 # we must avoid cyclic reference between repo and transaction.
1775 reporef = weakref.ref(self)
1796 reporef = weakref.ref(self)
1776 # Code to track tag movement
1797 # Code to track tag movement
1777 #
1798 #
1778 # Since tags are all handled as file content, it is actually quite hard
1799 # Since tags are all handled as file content, it is actually quite hard
1779 # to track these movement from a code perspective. So we fallback to a
1800 # to track these movement from a code perspective. So we fallback to a
1780 # tracking at the repository level. One could envision to track changes
1801 # tracking at the repository level. One could envision to track changes
1781 # to the '.hgtags' file through changegroup apply but that fails to
1802 # to the '.hgtags' file through changegroup apply but that fails to
1782 # cope with case where transaction expose new heads without changegroup
1803 # cope with case where transaction expose new heads without changegroup
1783 # being involved (eg: phase movement).
1804 # being involved (eg: phase movement).
1784 #
1805 #
1785 # For now, We gate the feature behind a flag since this likely comes
1806 # For now, We gate the feature behind a flag since this likely comes
1786 # with performance impacts. The current code run more often than needed
1807 # with performance impacts. The current code run more often than needed
1787 # and do not use caches as much as it could. The current focus is on
1808 # and do not use caches as much as it could. The current focus is on
1788 # the behavior of the feature so we disable it by default. The flag
1809 # the behavior of the feature so we disable it by default. The flag
1789 # will be removed when we are happy with the performance impact.
1810 # will be removed when we are happy with the performance impact.
1790 #
1811 #
1791 # Once this feature is no longer experimental move the following
1812 # Once this feature is no longer experimental move the following
1792 # documentation to the appropriate help section:
1813 # documentation to the appropriate help section:
1793 #
1814 #
1794 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
1815 # The ``HG_TAG_MOVED`` variable will be set if the transaction touched
1795 # tags (new or changed or deleted tags). In addition the details of
1816 # tags (new or changed or deleted tags). In addition the details of
1796 # these changes are made available in a file at:
1817 # these changes are made available in a file at:
1797 # ``REPOROOT/.hg/changes/tags.changes``.
1818 # ``REPOROOT/.hg/changes/tags.changes``.
1798 # Make sure you check for HG_TAG_MOVED before reading that file as it
1819 # Make sure you check for HG_TAG_MOVED before reading that file as it
1799 # might exist from a previous transaction even if no tag were touched
1820 # might exist from a previous transaction even if no tag were touched
1800 # in this one. Changes are recorded in a line base format::
1821 # in this one. Changes are recorded in a line base format::
1801 #
1822 #
1802 # <action> <hex-node> <tag-name>\n
1823 # <action> <hex-node> <tag-name>\n
1803 #
1824 #
1804 # Actions are defined as follow:
1825 # Actions are defined as follow:
1805 # "-R": tag is removed,
1826 # "-R": tag is removed,
1806 # "+A": tag is added,
1827 # "+A": tag is added,
1807 # "-M": tag is moved (old value),
1828 # "-M": tag is moved (old value),
1808 # "+M": tag is moved (new value),
1829 # "+M": tag is moved (new value),
1809 tracktags = lambda x: None
1830 tracktags = lambda x: None
1810 # experimental config: experimental.hook-track-tags
1831 # experimental config: experimental.hook-track-tags
1811 shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags')
1832 shouldtracktags = self.ui.configbool('experimental', 'hook-track-tags')
1812 if desc != 'strip' and shouldtracktags:
1833 if desc != 'strip' and shouldtracktags:
1813 oldheads = self.changelog.headrevs()
1834 oldheads = self.changelog.headrevs()
1814 def tracktags(tr2):
1835 def tracktags(tr2):
1815 repo = reporef()
1836 repo = reporef()
1816 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
1837 oldfnodes = tagsmod.fnoderevs(repo.ui, repo, oldheads)
1817 newheads = repo.changelog.headrevs()
1838 newheads = repo.changelog.headrevs()
1818 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
1839 newfnodes = tagsmod.fnoderevs(repo.ui, repo, newheads)
1819 # notes: we compare lists here.
1840 # notes: we compare lists here.
1820 # As we do it only once buiding set would not be cheaper
1841 # As we do it only once buiding set would not be cheaper
1821 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
1842 changes = tagsmod.difftags(repo.ui, repo, oldfnodes, newfnodes)
1822 if changes:
1843 if changes:
1823 tr2.hookargs['tag_moved'] = '1'
1844 tr2.hookargs['tag_moved'] = '1'
1824 with repo.vfs('changes/tags.changes', 'w',
1845 with repo.vfs('changes/tags.changes', 'w',
1825 atomictemp=True) as changesfile:
1846 atomictemp=True) as changesfile:
1826 # note: we do not register the file to the transaction
1847 # note: we do not register the file to the transaction
1827 # because we needs it to still exist on the transaction
1848 # because we needs it to still exist on the transaction
1828 # is close (for txnclose hooks)
1849 # is close (for txnclose hooks)
1829 tagsmod.writediff(changesfile, changes)
1850 tagsmod.writediff(changesfile, changes)
1830 def validate(tr2):
1851 def validate(tr2):
1831 """will run pre-closing hooks"""
1852 """will run pre-closing hooks"""
1832 # XXX the transaction API is a bit lacking here so we take a hacky
1853 # XXX the transaction API is a bit lacking here so we take a hacky
1833 # path for now
1854 # path for now
1834 #
1855 #
1835 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
1856 # We cannot add this as a "pending" hooks since the 'tr.hookargs'
1836 # dict is copied before these run. In addition we needs the data
1857 # dict is copied before these run. In addition we needs the data
1837 # available to in memory hooks too.
1858 # available to in memory hooks too.
1838 #
1859 #
1839 # Moreover, we also need to make sure this runs before txnclose
1860 # Moreover, we also need to make sure this runs before txnclose
1840 # hooks and there is no "pending" mechanism that would execute
1861 # hooks and there is no "pending" mechanism that would execute
1841 # logic only if hooks are about to run.
1862 # logic only if hooks are about to run.
1842 #
1863 #
1843 # Fixing this limitation of the transaction is also needed to track
1864 # Fixing this limitation of the transaction is also needed to track
1844 # other families of changes (bookmarks, phases, obsolescence).
1865 # other families of changes (bookmarks, phases, obsolescence).
1845 #
1866 #
1846 # This will have to be fixed before we remove the experimental
1867 # This will have to be fixed before we remove the experimental
1847 # gating.
1868 # gating.
1848 tracktags(tr2)
1869 tracktags(tr2)
1849 repo = reporef()
1870 repo = reporef()
1850 if repo.ui.configbool('experimental', 'single-head-per-branch'):
1871 if repo.ui.configbool('experimental', 'single-head-per-branch'):
1851 scmutil.enforcesinglehead(repo, tr2, desc)
1872 scmutil.enforcesinglehead(repo, tr2, desc)
1852 if hook.hashook(repo.ui, 'pretxnclose-bookmark'):
1873 if hook.hashook(repo.ui, 'pretxnclose-bookmark'):
1853 for name, (old, new) in sorted(tr.changes['bookmarks'].items()):
1874 for name, (old, new) in sorted(tr.changes['bookmarks'].items()):
1854 args = tr.hookargs.copy()
1875 args = tr.hookargs.copy()
1855 args.update(bookmarks.preparehookargs(name, old, new))
1876 args.update(bookmarks.preparehookargs(name, old, new))
1856 repo.hook('pretxnclose-bookmark', throw=True,
1877 repo.hook('pretxnclose-bookmark', throw=True,
1857 **pycompat.strkwargs(args))
1878 **pycompat.strkwargs(args))
1858 if hook.hashook(repo.ui, 'pretxnclose-phase'):
1879 if hook.hashook(repo.ui, 'pretxnclose-phase'):
1859 cl = repo.unfiltered().changelog
1880 cl = repo.unfiltered().changelog
1860 for rev, (old, new) in tr.changes['phases'].items():
1881 for rev, (old, new) in tr.changes['phases'].items():
1861 args = tr.hookargs.copy()
1882 args = tr.hookargs.copy()
1862 node = hex(cl.node(rev))
1883 node = hex(cl.node(rev))
1863 args.update(phases.preparehookargs(node, old, new))
1884 args.update(phases.preparehookargs(node, old, new))
1864 repo.hook('pretxnclose-phase', throw=True,
1885 repo.hook('pretxnclose-phase', throw=True,
1865 **pycompat.strkwargs(args))
1886 **pycompat.strkwargs(args))
1866
1887
1867 repo.hook('pretxnclose', throw=True,
1888 repo.hook('pretxnclose', throw=True,
1868 **pycompat.strkwargs(tr.hookargs))
1889 **pycompat.strkwargs(tr.hookargs))
1869 def releasefn(tr, success):
1890 def releasefn(tr, success):
1870 repo = reporef()
1891 repo = reporef()
1871 if success:
1892 if success:
1872 # this should be explicitly invoked here, because
1893 # this should be explicitly invoked here, because
1873 # in-memory changes aren't written out at closing
1894 # in-memory changes aren't written out at closing
1874 # transaction, if tr.addfilegenerator (via
1895 # transaction, if tr.addfilegenerator (via
1875 # dirstate.write or so) isn't invoked while
1896 # dirstate.write or so) isn't invoked while
1876 # transaction running
1897 # transaction running
1877 repo.dirstate.write(None)
1898 repo.dirstate.write(None)
1878 else:
1899 else:
1879 # discard all changes (including ones already written
1900 # discard all changes (including ones already written
1880 # out) in this transaction
1901 # out) in this transaction
1881 narrowspec.restorebackup(self, 'journal.narrowspec')
1902 narrowspec.restorebackup(self, 'journal.narrowspec')
1882 narrowspec.restorewcbackup(self, 'journal.narrowspec.dirstate')
1903 narrowspec.restorewcbackup(self, 'journal.narrowspec.dirstate')
1883 repo.dirstate.restorebackup(None, 'journal.dirstate')
1904 repo.dirstate.restorebackup(None, 'journal.dirstate')
1884
1905
1885 repo.invalidate(clearfilecache=True)
1906 repo.invalidate(clearfilecache=True)
1886
1907
1887 tr = transaction.transaction(rp, self.svfs, vfsmap,
1908 tr = transaction.transaction(rp, self.svfs, vfsmap,
1888 "journal",
1909 "journal",
1889 "undo",
1910 "undo",
1890 aftertrans(renames),
1911 aftertrans(renames),
1891 self.store.createmode,
1912 self.store.createmode,
1892 validator=validate,
1913 validator=validate,
1893 releasefn=releasefn,
1914 releasefn=releasefn,
1894 checkambigfiles=_cachedfiles,
1915 checkambigfiles=_cachedfiles,
1895 name=desc)
1916 name=desc)
1896 tr.changes['origrepolen'] = len(self)
1917 tr.changes['origrepolen'] = len(self)
1897 tr.changes['obsmarkers'] = set()
1918 tr.changes['obsmarkers'] = set()
1898 tr.changes['phases'] = {}
1919 tr.changes['phases'] = {}
1899 tr.changes['bookmarks'] = {}
1920 tr.changes['bookmarks'] = {}
1900
1921
1901 tr.hookargs['txnid'] = txnid
1922 tr.hookargs['txnid'] = txnid
1902 tr.hookargs['txnname'] = desc
1923 tr.hookargs['txnname'] = desc
1903 # note: writing the fncache only during finalize mean that the file is
1924 # note: writing the fncache only during finalize mean that the file is
1904 # outdated when running hooks. As fncache is used for streaming clone,
1925 # outdated when running hooks. As fncache is used for streaming clone,
1905 # this is not expected to break anything that happen during the hooks.
1926 # this is not expected to break anything that happen during the hooks.
1906 tr.addfinalize('flush-fncache', self.store.write)
1927 tr.addfinalize('flush-fncache', self.store.write)
1907 def txnclosehook(tr2):
1928 def txnclosehook(tr2):
1908 """To be run if transaction is successful, will schedule a hook run
1929 """To be run if transaction is successful, will schedule a hook run
1909 """
1930 """
1910 # Don't reference tr2 in hook() so we don't hold a reference.
1931 # Don't reference tr2 in hook() so we don't hold a reference.
1911 # This reduces memory consumption when there are multiple
1932 # This reduces memory consumption when there are multiple
1912 # transactions per lock. This can likely go away if issue5045
1933 # transactions per lock. This can likely go away if issue5045
1913 # fixes the function accumulation.
1934 # fixes the function accumulation.
1914 hookargs = tr2.hookargs
1935 hookargs = tr2.hookargs
1915
1936
1916 def hookfunc():
1937 def hookfunc():
1917 repo = reporef()
1938 repo = reporef()
1918 if hook.hashook(repo.ui, 'txnclose-bookmark'):
1939 if hook.hashook(repo.ui, 'txnclose-bookmark'):
1919 bmchanges = sorted(tr.changes['bookmarks'].items())
1940 bmchanges = sorted(tr.changes['bookmarks'].items())
1920 for name, (old, new) in bmchanges:
1941 for name, (old, new) in bmchanges:
1921 args = tr.hookargs.copy()
1942 args = tr.hookargs.copy()
1922 args.update(bookmarks.preparehookargs(name, old, new))
1943 args.update(bookmarks.preparehookargs(name, old, new))
1923 repo.hook('txnclose-bookmark', throw=False,
1944 repo.hook('txnclose-bookmark', throw=False,
1924 **pycompat.strkwargs(args))
1945 **pycompat.strkwargs(args))
1925
1946
1926 if hook.hashook(repo.ui, 'txnclose-phase'):
1947 if hook.hashook(repo.ui, 'txnclose-phase'):
1927 cl = repo.unfiltered().changelog
1948 cl = repo.unfiltered().changelog
1928 phasemv = sorted(tr.changes['phases'].items())
1949 phasemv = sorted(tr.changes['phases'].items())
1929 for rev, (old, new) in phasemv:
1950 for rev, (old, new) in phasemv:
1930 args = tr.hookargs.copy()
1951 args = tr.hookargs.copy()
1931 node = hex(cl.node(rev))
1952 node = hex(cl.node(rev))
1932 args.update(phases.preparehookargs(node, old, new))
1953 args.update(phases.preparehookargs(node, old, new))
1933 repo.hook('txnclose-phase', throw=False,
1954 repo.hook('txnclose-phase', throw=False,
1934 **pycompat.strkwargs(args))
1955 **pycompat.strkwargs(args))
1935
1956
1936 repo.hook('txnclose', throw=False,
1957 repo.hook('txnclose', throw=False,
1937 **pycompat.strkwargs(hookargs))
1958 **pycompat.strkwargs(hookargs))
1938 reporef()._afterlock(hookfunc)
1959 reporef()._afterlock(hookfunc)
1939 tr.addfinalize('txnclose-hook', txnclosehook)
1960 tr.addfinalize('txnclose-hook', txnclosehook)
1940 # Include a leading "-" to make it happen before the transaction summary
1961 # Include a leading "-" to make it happen before the transaction summary
1941 # reports registered via scmutil.registersummarycallback() whose names
1962 # reports registered via scmutil.registersummarycallback() whose names
1942 # are 00-txnreport etc. That way, the caches will be warm when the
1963 # are 00-txnreport etc. That way, the caches will be warm when the
1943 # callbacks run.
1964 # callbacks run.
1944 tr.addpostclose('-warm-cache', self._buildcacheupdater(tr))
1965 tr.addpostclose('-warm-cache', self._buildcacheupdater(tr))
1945 def txnaborthook(tr2):
1966 def txnaborthook(tr2):
1946 """To be run if transaction is aborted
1967 """To be run if transaction is aborted
1947 """
1968 """
1948 reporef().hook('txnabort', throw=False,
1969 reporef().hook('txnabort', throw=False,
1949 **pycompat.strkwargs(tr2.hookargs))
1970 **pycompat.strkwargs(tr2.hookargs))
1950 tr.addabort('txnabort-hook', txnaborthook)
1971 tr.addabort('txnabort-hook', txnaborthook)
1951 # avoid eager cache invalidation. in-memory data should be identical
1972 # avoid eager cache invalidation. in-memory data should be identical
1952 # to stored data if transaction has no error.
1973 # to stored data if transaction has no error.
1953 tr.addpostclose('refresh-filecachestats', self._refreshfilecachestats)
1974 tr.addpostclose('refresh-filecachestats', self._refreshfilecachestats)
1954 self._transref = weakref.ref(tr)
1975 self._transref = weakref.ref(tr)
1955 scmutil.registersummarycallback(self, tr, desc)
1976 scmutil.registersummarycallback(self, tr, desc)
1956 return tr
1977 return tr
1957
1978
1958 def _journalfiles(self):
1979 def _journalfiles(self):
1959 return ((self.svfs, 'journal'),
1980 return ((self.svfs, 'journal'),
1960 (self.svfs, 'journal.narrowspec'),
1981 (self.svfs, 'journal.narrowspec'),
1961 (self.vfs, 'journal.narrowspec.dirstate'),
1982 (self.vfs, 'journal.narrowspec.dirstate'),
1962 (self.vfs, 'journal.dirstate'),
1983 (self.vfs, 'journal.dirstate'),
1963 (self.vfs, 'journal.branch'),
1984 (self.vfs, 'journal.branch'),
1964 (self.vfs, 'journal.desc'),
1985 (self.vfs, 'journal.desc'),
1965 (self.vfs, 'journal.bookmarks'),
1986 (bookmarks.bookmarksvfs(self), 'journal.bookmarks'),
1966 (self.svfs, 'journal.phaseroots'))
1987 (self.svfs, 'journal.phaseroots'))
1967
1988
1968 def undofiles(self):
1989 def undofiles(self):
1969 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
1990 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
1970
1991
1971 @unfilteredmethod
1992 @unfilteredmethod
1972 def _writejournal(self, desc):
1993 def _writejournal(self, desc):
1973 self.dirstate.savebackup(None, 'journal.dirstate')
1994 self.dirstate.savebackup(None, 'journal.dirstate')
1974 narrowspec.savewcbackup(self, 'journal.narrowspec.dirstate')
1995 narrowspec.savewcbackup(self, 'journal.narrowspec.dirstate')
1975 narrowspec.savebackup(self, 'journal.narrowspec')
1996 narrowspec.savebackup(self, 'journal.narrowspec')
1976 self.vfs.write("journal.branch",
1997 self.vfs.write("journal.branch",
1977 encoding.fromlocal(self.dirstate.branch()))
1998 encoding.fromlocal(self.dirstate.branch()))
1978 self.vfs.write("journal.desc",
1999 self.vfs.write("journal.desc",
1979 "%d\n%s\n" % (len(self), desc))
2000 "%d\n%s\n" % (len(self), desc))
1980 self.vfs.write("journal.bookmarks",
2001 bookmarksvfs = bookmarks.bookmarksvfs(self)
1981 self.vfs.tryread("bookmarks"))
2002 bookmarksvfs.write("journal.bookmarks",
2003 bookmarksvfs.tryread("bookmarks"))
1982 self.svfs.write("journal.phaseroots",
2004 self.svfs.write("journal.phaseroots",
1983 self.svfs.tryread("phaseroots"))
2005 self.svfs.tryread("phaseroots"))
1984
2006
1985 def recover(self):
2007 def recover(self):
1986 with self.lock():
2008 with self.lock():
1987 if self.svfs.exists("journal"):
2009 if self.svfs.exists("journal"):
1988 self.ui.status(_("rolling back interrupted transaction\n"))
2010 self.ui.status(_("rolling back interrupted transaction\n"))
1989 vfsmap = {'': self.svfs,
2011 vfsmap = {'': self.svfs,
1990 'plain': self.vfs,}
2012 'plain': self.vfs,}
1991 transaction.rollback(self.svfs, vfsmap, "journal",
2013 transaction.rollback(self.svfs, vfsmap, "journal",
1992 self.ui.warn,
2014 self.ui.warn,
1993 checkambigfiles=_cachedfiles)
2015 checkambigfiles=_cachedfiles)
1994 self.invalidate()
2016 self.invalidate()
1995 return True
2017 return True
1996 else:
2018 else:
1997 self.ui.warn(_("no interrupted transaction available\n"))
2019 self.ui.warn(_("no interrupted transaction available\n"))
1998 return False
2020 return False
1999
2021
2000 def rollback(self, dryrun=False, force=False):
2022 def rollback(self, dryrun=False, force=False):
2001 wlock = lock = dsguard = None
2023 wlock = lock = dsguard = None
2002 try:
2024 try:
2003 wlock = self.wlock()
2025 wlock = self.wlock()
2004 lock = self.lock()
2026 lock = self.lock()
2005 if self.svfs.exists("undo"):
2027 if self.svfs.exists("undo"):
2006 dsguard = dirstateguard.dirstateguard(self, 'rollback')
2028 dsguard = dirstateguard.dirstateguard(self, 'rollback')
2007
2029
2008 return self._rollback(dryrun, force, dsguard)
2030 return self._rollback(dryrun, force, dsguard)
2009 else:
2031 else:
2010 self.ui.warn(_("no rollback information available\n"))
2032 self.ui.warn(_("no rollback information available\n"))
2011 return 1
2033 return 1
2012 finally:
2034 finally:
2013 release(dsguard, lock, wlock)
2035 release(dsguard, lock, wlock)
2014
2036
2015 @unfilteredmethod # Until we get smarter cache management
2037 @unfilteredmethod # Until we get smarter cache management
2016 def _rollback(self, dryrun, force, dsguard):
2038 def _rollback(self, dryrun, force, dsguard):
2017 ui = self.ui
2039 ui = self.ui
2018 try:
2040 try:
2019 args = self.vfs.read('undo.desc').splitlines()
2041 args = self.vfs.read('undo.desc').splitlines()
2020 (oldlen, desc, detail) = (int(args[0]), args[1], None)
2042 (oldlen, desc, detail) = (int(args[0]), args[1], None)
2021 if len(args) >= 3:
2043 if len(args) >= 3:
2022 detail = args[2]
2044 detail = args[2]
2023 oldtip = oldlen - 1
2045 oldtip = oldlen - 1
2024
2046
2025 if detail and ui.verbose:
2047 if detail and ui.verbose:
2026 msg = (_('repository tip rolled back to revision %d'
2048 msg = (_('repository tip rolled back to revision %d'
2027 ' (undo %s: %s)\n')
2049 ' (undo %s: %s)\n')
2028 % (oldtip, desc, detail))
2050 % (oldtip, desc, detail))
2029 else:
2051 else:
2030 msg = (_('repository tip rolled back to revision %d'
2052 msg = (_('repository tip rolled back to revision %d'
2031 ' (undo %s)\n')
2053 ' (undo %s)\n')
2032 % (oldtip, desc))
2054 % (oldtip, desc))
2033 except IOError:
2055 except IOError:
2034 msg = _('rolling back unknown transaction\n')
2056 msg = _('rolling back unknown transaction\n')
2035 desc = None
2057 desc = None
2036
2058
2037 if not force and self['.'] != self['tip'] and desc == 'commit':
2059 if not force and self['.'] != self['tip'] and desc == 'commit':
2038 raise error.Abort(
2060 raise error.Abort(
2039 _('rollback of last commit while not checked out '
2061 _('rollback of last commit while not checked out '
2040 'may lose data'), hint=_('use -f to force'))
2062 'may lose data'), hint=_('use -f to force'))
2041
2063
2042 ui.status(msg)
2064 ui.status(msg)
2043 if dryrun:
2065 if dryrun:
2044 return 0
2066 return 0
2045
2067
2046 parents = self.dirstate.parents()
2068 parents = self.dirstate.parents()
2047 self.destroying()
2069 self.destroying()
2048 vfsmap = {'plain': self.vfs, '': self.svfs}
2070 vfsmap = {'plain': self.vfs, '': self.svfs}
2049 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn,
2071 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn,
2050 checkambigfiles=_cachedfiles)
2072 checkambigfiles=_cachedfiles)
2051 if self.vfs.exists('undo.bookmarks'):
2073 bookmarksvfs = bookmarks.bookmarksvfs(self)
2052 self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True)
2074 if bookmarksvfs.exists('undo.bookmarks'):
2075 bookmarksvfs.rename('undo.bookmarks', 'bookmarks', checkambig=True)
2053 if self.svfs.exists('undo.phaseroots'):
2076 if self.svfs.exists('undo.phaseroots'):
2054 self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True)
2077 self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True)
2055 self.invalidate()
2078 self.invalidate()
2056
2079
2057 parentgone = any(p not in self.changelog.nodemap for p in parents)
2080 parentgone = any(p not in self.changelog.nodemap for p in parents)
2058 if parentgone:
2081 if parentgone:
2059 # prevent dirstateguard from overwriting already restored one
2082 # prevent dirstateguard from overwriting already restored one
2060 dsguard.close()
2083 dsguard.close()
2061
2084
2062 narrowspec.restorebackup(self, 'undo.narrowspec')
2085 narrowspec.restorebackup(self, 'undo.narrowspec')
2063 narrowspec.restorewcbackup(self, 'undo.narrowspec.dirstate')
2086 narrowspec.restorewcbackup(self, 'undo.narrowspec.dirstate')
2064 self.dirstate.restorebackup(None, 'undo.dirstate')
2087 self.dirstate.restorebackup(None, 'undo.dirstate')
2065 try:
2088 try:
2066 branch = self.vfs.read('undo.branch')
2089 branch = self.vfs.read('undo.branch')
2067 self.dirstate.setbranch(encoding.tolocal(branch))
2090 self.dirstate.setbranch(encoding.tolocal(branch))
2068 except IOError:
2091 except IOError:
2069 ui.warn(_('named branch could not be reset: '
2092 ui.warn(_('named branch could not be reset: '
2070 'current branch is still \'%s\'\n')
2093 'current branch is still \'%s\'\n')
2071 % self.dirstate.branch())
2094 % self.dirstate.branch())
2072
2095
2073 parents = tuple([p.rev() for p in self[None].parents()])
2096 parents = tuple([p.rev() for p in self[None].parents()])
2074 if len(parents) > 1:
2097 if len(parents) > 1:
2075 ui.status(_('working directory now based on '
2098 ui.status(_('working directory now based on '
2076 'revisions %d and %d\n') % parents)
2099 'revisions %d and %d\n') % parents)
2077 else:
2100 else:
2078 ui.status(_('working directory now based on '
2101 ui.status(_('working directory now based on '
2079 'revision %d\n') % parents)
2102 'revision %d\n') % parents)
2080 mergemod.mergestate.clean(self, self['.'].node())
2103 mergemod.mergestate.clean(self, self['.'].node())
2081
2104
2082 # TODO: if we know which new heads may result from this rollback, pass
2105 # TODO: if we know which new heads may result from this rollback, pass
2083 # them to destroy(), which will prevent the branchhead cache from being
2106 # them to destroy(), which will prevent the branchhead cache from being
2084 # invalidated.
2107 # invalidated.
2085 self.destroyed()
2108 self.destroyed()
2086 return 0
2109 return 0
2087
2110
2088 def _buildcacheupdater(self, newtransaction):
2111 def _buildcacheupdater(self, newtransaction):
2089 """called during transaction to build the callback updating cache
2112 """called during transaction to build the callback updating cache
2090
2113
2091 Lives on the repository to help extension who might want to augment
2114 Lives on the repository to help extension who might want to augment
2092 this logic. For this purpose, the created transaction is passed to the
2115 this logic. For this purpose, the created transaction is passed to the
2093 method.
2116 method.
2094 """
2117 """
2095 # we must avoid cyclic reference between repo and transaction.
2118 # we must avoid cyclic reference between repo and transaction.
2096 reporef = weakref.ref(self)
2119 reporef = weakref.ref(self)
2097 def updater(tr):
2120 def updater(tr):
2098 repo = reporef()
2121 repo = reporef()
2099 repo.updatecaches(tr)
2122 repo.updatecaches(tr)
2100 return updater
2123 return updater
2101
2124
2102 @unfilteredmethod
2125 @unfilteredmethod
2103 def updatecaches(self, tr=None, full=False):
2126 def updatecaches(self, tr=None, full=False):
2104 """warm appropriate caches
2127 """warm appropriate caches
2105
2128
2106 If this function is called after a transaction closed. The transaction
2129 If this function is called after a transaction closed. The transaction
2107 will be available in the 'tr' argument. This can be used to selectively
2130 will be available in the 'tr' argument. This can be used to selectively
2108 update caches relevant to the changes in that transaction.
2131 update caches relevant to the changes in that transaction.
2109
2132
2110 If 'full' is set, make sure all caches the function knows about have
2133 If 'full' is set, make sure all caches the function knows about have
2111 up-to-date data. Even the ones usually loaded more lazily.
2134 up-to-date data. Even the ones usually loaded more lazily.
2112 """
2135 """
2113 if tr is not None and tr.hookargs.get('source') == 'strip':
2136 if tr is not None and tr.hookargs.get('source') == 'strip':
2114 # During strip, many caches are invalid but
2137 # During strip, many caches are invalid but
2115 # later call to `destroyed` will refresh them.
2138 # later call to `destroyed` will refresh them.
2116 return
2139 return
2117
2140
2118 if tr is None or tr.changes['origrepolen'] < len(self):
2141 if tr is None or tr.changes['origrepolen'] < len(self):
2119 # accessing the 'ser ved' branchmap should refresh all the others,
2142 # accessing the 'ser ved' branchmap should refresh all the others,
2120 self.ui.debug('updating the branch cache\n')
2143 self.ui.debug('updating the branch cache\n')
2121 self.filtered('served').branchmap()
2144 self.filtered('served').branchmap()
2122 self.filtered('served.hidden').branchmap()
2145 self.filtered('served.hidden').branchmap()
2123
2146
2124 if full:
2147 if full:
2125 unfi = self.unfiltered()
2148 unfi = self.unfiltered()
2126 rbc = unfi.revbranchcache()
2149 rbc = unfi.revbranchcache()
2127 for r in unfi.changelog:
2150 for r in unfi.changelog:
2128 rbc.branchinfo(r)
2151 rbc.branchinfo(r)
2129 rbc.write()
2152 rbc.write()
2130
2153
2131 # ensure the working copy parents are in the manifestfulltextcache
2154 # ensure the working copy parents are in the manifestfulltextcache
2132 for ctx in self['.'].parents():
2155 for ctx in self['.'].parents():
2133 ctx.manifest() # accessing the manifest is enough
2156 ctx.manifest() # accessing the manifest is enough
2134
2157
2135 # accessing fnode cache warms the cache
2158 # accessing fnode cache warms the cache
2136 tagsmod.fnoderevs(self.ui, unfi, unfi.changelog.revs())
2159 tagsmod.fnoderevs(self.ui, unfi, unfi.changelog.revs())
2137 # accessing tags warm the cache
2160 # accessing tags warm the cache
2138 self.tags()
2161 self.tags()
2139 self.filtered('served').tags()
2162 self.filtered('served').tags()
2140
2163
2141 def invalidatecaches(self):
2164 def invalidatecaches(self):
2142
2165
2143 if r'_tagscache' in vars(self):
2166 if r'_tagscache' in vars(self):
2144 # can't use delattr on proxy
2167 # can't use delattr on proxy
2145 del self.__dict__[r'_tagscache']
2168 del self.__dict__[r'_tagscache']
2146
2169
2147 self._branchcaches.clear()
2170 self._branchcaches.clear()
2148 self.invalidatevolatilesets()
2171 self.invalidatevolatilesets()
2149 self._sparsesignaturecache.clear()
2172 self._sparsesignaturecache.clear()
2150
2173
2151 def invalidatevolatilesets(self):
2174 def invalidatevolatilesets(self):
2152 self.filteredrevcache.clear()
2175 self.filteredrevcache.clear()
2153 obsolete.clearobscaches(self)
2176 obsolete.clearobscaches(self)
2154
2177
2155 def invalidatedirstate(self):
2178 def invalidatedirstate(self):
2156 '''Invalidates the dirstate, causing the next call to dirstate
2179 '''Invalidates the dirstate, causing the next call to dirstate
2157 to check if it was modified since the last time it was read,
2180 to check if it was modified since the last time it was read,
2158 rereading it if it has.
2181 rereading it if it has.
2159
2182
2160 This is different to dirstate.invalidate() that it doesn't always
2183 This is different to dirstate.invalidate() that it doesn't always
2161 rereads the dirstate. Use dirstate.invalidate() if you want to
2184 rereads the dirstate. Use dirstate.invalidate() if you want to
2162 explicitly read the dirstate again (i.e. restoring it to a previous
2185 explicitly read the dirstate again (i.e. restoring it to a previous
2163 known good state).'''
2186 known good state).'''
2164 if hasunfilteredcache(self, r'dirstate'):
2187 if hasunfilteredcache(self, r'dirstate'):
2165 for k in self.dirstate._filecache:
2188 for k in self.dirstate._filecache:
2166 try:
2189 try:
2167 delattr(self.dirstate, k)
2190 delattr(self.dirstate, k)
2168 except AttributeError:
2191 except AttributeError:
2169 pass
2192 pass
2170 delattr(self.unfiltered(), r'dirstate')
2193 delattr(self.unfiltered(), r'dirstate')
2171
2194
2172 def invalidate(self, clearfilecache=False):
2195 def invalidate(self, clearfilecache=False):
2173 '''Invalidates both store and non-store parts other than dirstate
2196 '''Invalidates both store and non-store parts other than dirstate
2174
2197
2175 If a transaction is running, invalidation of store is omitted,
2198 If a transaction is running, invalidation of store is omitted,
2176 because discarding in-memory changes might cause inconsistency
2199 because discarding in-memory changes might cause inconsistency
2177 (e.g. incomplete fncache causes unintentional failure, but
2200 (e.g. incomplete fncache causes unintentional failure, but
2178 redundant one doesn't).
2201 redundant one doesn't).
2179 '''
2202 '''
2180 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2203 unfiltered = self.unfiltered() # all file caches are stored unfiltered
2181 for k in list(self._filecache.keys()):
2204 for k in list(self._filecache.keys()):
2182 # dirstate is invalidated separately in invalidatedirstate()
2205 # dirstate is invalidated separately in invalidatedirstate()
2183 if k == 'dirstate':
2206 if k == 'dirstate':
2184 continue
2207 continue
2185 if (k == 'changelog' and
2208 if (k == 'changelog' and
2186 self.currenttransaction() and
2209 self.currenttransaction() and
2187 self.changelog._delayed):
2210 self.changelog._delayed):
2188 # The changelog object may store unwritten revisions. We don't
2211 # The changelog object may store unwritten revisions. We don't
2189 # want to lose them.
2212 # want to lose them.
2190 # TODO: Solve the problem instead of working around it.
2213 # TODO: Solve the problem instead of working around it.
2191 continue
2214 continue
2192
2215
2193 if clearfilecache:
2216 if clearfilecache:
2194 del self._filecache[k]
2217 del self._filecache[k]
2195 try:
2218 try:
2196 delattr(unfiltered, k)
2219 delattr(unfiltered, k)
2197 except AttributeError:
2220 except AttributeError:
2198 pass
2221 pass
2199 self.invalidatecaches()
2222 self.invalidatecaches()
2200 if not self.currenttransaction():
2223 if not self.currenttransaction():
2201 # TODO: Changing contents of store outside transaction
2224 # TODO: Changing contents of store outside transaction
2202 # causes inconsistency. We should make in-memory store
2225 # causes inconsistency. We should make in-memory store
2203 # changes detectable, and abort if changed.
2226 # changes detectable, and abort if changed.
2204 self.store.invalidatecaches()
2227 self.store.invalidatecaches()
2205
2228
2206 def invalidateall(self):
2229 def invalidateall(self):
2207 '''Fully invalidates both store and non-store parts, causing the
2230 '''Fully invalidates both store and non-store parts, causing the
2208 subsequent operation to reread any outside changes.'''
2231 subsequent operation to reread any outside changes.'''
2209 # extension should hook this to invalidate its caches
2232 # extension should hook this to invalidate its caches
2210 self.invalidate()
2233 self.invalidate()
2211 self.invalidatedirstate()
2234 self.invalidatedirstate()
2212
2235
2213 @unfilteredmethod
2236 @unfilteredmethod
2214 def _refreshfilecachestats(self, tr):
2237 def _refreshfilecachestats(self, tr):
2215 """Reload stats of cached files so that they are flagged as valid"""
2238 """Reload stats of cached files so that they are flagged as valid"""
2216 for k, ce in self._filecache.items():
2239 for k, ce in self._filecache.items():
2217 k = pycompat.sysstr(k)
2240 k = pycompat.sysstr(k)
2218 if k == r'dirstate' or k not in self.__dict__:
2241 if k == r'dirstate' or k not in self.__dict__:
2219 continue
2242 continue
2220 ce.refresh()
2243 ce.refresh()
2221
2244
2222 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc,
2245 def _lock(self, vfs, lockname, wait, releasefn, acquirefn, desc,
2223 inheritchecker=None, parentenvvar=None):
2246 inheritchecker=None, parentenvvar=None):
2224 parentlock = None
2247 parentlock = None
2225 # the contents of parentenvvar are used by the underlying lock to
2248 # the contents of parentenvvar are used by the underlying lock to
2226 # determine whether it can be inherited
2249 # determine whether it can be inherited
2227 if parentenvvar is not None:
2250 if parentenvvar is not None:
2228 parentlock = encoding.environ.get(parentenvvar)
2251 parentlock = encoding.environ.get(parentenvvar)
2229
2252
2230 timeout = 0
2253 timeout = 0
2231 warntimeout = 0
2254 warntimeout = 0
2232 if wait:
2255 if wait:
2233 timeout = self.ui.configint("ui", "timeout")
2256 timeout = self.ui.configint("ui", "timeout")
2234 warntimeout = self.ui.configint("ui", "timeout.warn")
2257 warntimeout = self.ui.configint("ui", "timeout.warn")
2235 # internal config: ui.signal-safe-lock
2258 # internal config: ui.signal-safe-lock
2236 signalsafe = self.ui.configbool('ui', 'signal-safe-lock')
2259 signalsafe = self.ui.configbool('ui', 'signal-safe-lock')
2237
2260
2238 l = lockmod.trylock(self.ui, vfs, lockname, timeout, warntimeout,
2261 l = lockmod.trylock(self.ui, vfs, lockname, timeout, warntimeout,
2239 releasefn=releasefn,
2262 releasefn=releasefn,
2240 acquirefn=acquirefn, desc=desc,
2263 acquirefn=acquirefn, desc=desc,
2241 inheritchecker=inheritchecker,
2264 inheritchecker=inheritchecker,
2242 parentlock=parentlock,
2265 parentlock=parentlock,
2243 signalsafe=signalsafe)
2266 signalsafe=signalsafe)
2244 return l
2267 return l
2245
2268
2246 def _afterlock(self, callback):
2269 def _afterlock(self, callback):
2247 """add a callback to be run when the repository is fully unlocked
2270 """add a callback to be run when the repository is fully unlocked
2248
2271
2249 The callback will be executed when the outermost lock is released
2272 The callback will be executed when the outermost lock is released
2250 (with wlock being higher level than 'lock')."""
2273 (with wlock being higher level than 'lock')."""
2251 for ref in (self._wlockref, self._lockref):
2274 for ref in (self._wlockref, self._lockref):
2252 l = ref and ref()
2275 l = ref and ref()
2253 if l and l.held:
2276 if l and l.held:
2254 l.postrelease.append(callback)
2277 l.postrelease.append(callback)
2255 break
2278 break
2256 else: # no lock have been found.
2279 else: # no lock have been found.
2257 callback()
2280 callback()
2258
2281
2259 def lock(self, wait=True):
2282 def lock(self, wait=True):
2260 '''Lock the repository store (.hg/store) and return a weak reference
2283 '''Lock the repository store (.hg/store) and return a weak reference
2261 to the lock. Use this before modifying the store (e.g. committing or
2284 to the lock. Use this before modifying the store (e.g. committing or
2262 stripping). If you are opening a transaction, get a lock as well.)
2285 stripping). If you are opening a transaction, get a lock as well.)
2263
2286
2264 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2287 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2265 'wlock' first to avoid a dead-lock hazard.'''
2288 'wlock' first to avoid a dead-lock hazard.'''
2266 l = self._currentlock(self._lockref)
2289 l = self._currentlock(self._lockref)
2267 if l is not None:
2290 if l is not None:
2268 l.lock()
2291 l.lock()
2269 return l
2292 return l
2270
2293
2271 l = self._lock(vfs=self.svfs,
2294 l = self._lock(vfs=self.svfs,
2272 lockname="lock",
2295 lockname="lock",
2273 wait=wait,
2296 wait=wait,
2274 releasefn=None,
2297 releasefn=None,
2275 acquirefn=self.invalidate,
2298 acquirefn=self.invalidate,
2276 desc=_('repository %s') % self.origroot)
2299 desc=_('repository %s') % self.origroot)
2277 self._lockref = weakref.ref(l)
2300 self._lockref = weakref.ref(l)
2278 return l
2301 return l
2279
2302
2280 def _wlockchecktransaction(self):
2303 def _wlockchecktransaction(self):
2281 if self.currenttransaction() is not None:
2304 if self.currenttransaction() is not None:
2282 raise error.LockInheritanceContractViolation(
2305 raise error.LockInheritanceContractViolation(
2283 'wlock cannot be inherited in the middle of a transaction')
2306 'wlock cannot be inherited in the middle of a transaction')
2284
2307
2285 def wlock(self, wait=True):
2308 def wlock(self, wait=True):
2286 '''Lock the non-store parts of the repository (everything under
2309 '''Lock the non-store parts of the repository (everything under
2287 .hg except .hg/store) and return a weak reference to the lock.
2310 .hg except .hg/store) and return a weak reference to the lock.
2288
2311
2289 Use this before modifying files in .hg.
2312 Use this before modifying files in .hg.
2290
2313
2291 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2314 If both 'lock' and 'wlock' must be acquired, ensure you always acquires
2292 'wlock' first to avoid a dead-lock hazard.'''
2315 'wlock' first to avoid a dead-lock hazard.'''
2293 l = self._wlockref and self._wlockref()
2316 l = self._wlockref and self._wlockref()
2294 if l is not None and l.held:
2317 if l is not None and l.held:
2295 l.lock()
2318 l.lock()
2296 return l
2319 return l
2297
2320
2298 # We do not need to check for non-waiting lock acquisition. Such
2321 # We do not need to check for non-waiting lock acquisition. Such
2299 # acquisition would not cause dead-lock as they would just fail.
2322 # acquisition would not cause dead-lock as they would just fail.
2300 if wait and (self.ui.configbool('devel', 'all-warnings')
2323 if wait and (self.ui.configbool('devel', 'all-warnings')
2301 or self.ui.configbool('devel', 'check-locks')):
2324 or self.ui.configbool('devel', 'check-locks')):
2302 if self._currentlock(self._lockref) is not None:
2325 if self._currentlock(self._lockref) is not None:
2303 self.ui.develwarn('"wlock" acquired after "lock"')
2326 self.ui.develwarn('"wlock" acquired after "lock"')
2304
2327
2305 def unlock():
2328 def unlock():
2306 if self.dirstate.pendingparentchange():
2329 if self.dirstate.pendingparentchange():
2307 self.dirstate.invalidate()
2330 self.dirstate.invalidate()
2308 else:
2331 else:
2309 self.dirstate.write(None)
2332 self.dirstate.write(None)
2310
2333
2311 self._filecache['dirstate'].refresh()
2334 self._filecache['dirstate'].refresh()
2312
2335
2313 l = self._lock(self.vfs, "wlock", wait, unlock,
2336 l = self._lock(self.vfs, "wlock", wait, unlock,
2314 self.invalidatedirstate, _('working directory of %s') %
2337 self.invalidatedirstate, _('working directory of %s') %
2315 self.origroot,
2338 self.origroot,
2316 inheritchecker=self._wlockchecktransaction,
2339 inheritchecker=self._wlockchecktransaction,
2317 parentenvvar='HG_WLOCK_LOCKER')
2340 parentenvvar='HG_WLOCK_LOCKER')
2318 self._wlockref = weakref.ref(l)
2341 self._wlockref = weakref.ref(l)
2319 return l
2342 return l
2320
2343
2321 def _currentlock(self, lockref):
2344 def _currentlock(self, lockref):
2322 """Returns the lock if it's held, or None if it's not."""
2345 """Returns the lock if it's held, or None if it's not."""
2323 if lockref is None:
2346 if lockref is None:
2324 return None
2347 return None
2325 l = lockref()
2348 l = lockref()
2326 if l is None or not l.held:
2349 if l is None or not l.held:
2327 return None
2350 return None
2328 return l
2351 return l
2329
2352
2330 def currentwlock(self):
2353 def currentwlock(self):
2331 """Returns the wlock if it's held, or None if it's not."""
2354 """Returns the wlock if it's held, or None if it's not."""
2332 return self._currentlock(self._wlockref)
2355 return self._currentlock(self._wlockref)
2333
2356
2334 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist,
2357 def _filecommit(self, fctx, manifest1, manifest2, linkrev, tr, changelist,
2335 includecopymeta):
2358 includecopymeta):
2336 """
2359 """
2337 commit an individual file as part of a larger transaction
2360 commit an individual file as part of a larger transaction
2338 """
2361 """
2339
2362
2340 fname = fctx.path()
2363 fname = fctx.path()
2341 fparent1 = manifest1.get(fname, nullid)
2364 fparent1 = manifest1.get(fname, nullid)
2342 fparent2 = manifest2.get(fname, nullid)
2365 fparent2 = manifest2.get(fname, nullid)
2343 if isinstance(fctx, context.filectx):
2366 if isinstance(fctx, context.filectx):
2344 node = fctx.filenode()
2367 node = fctx.filenode()
2345 if node in [fparent1, fparent2]:
2368 if node in [fparent1, fparent2]:
2346 self.ui.debug('reusing %s filelog entry\n' % fname)
2369 self.ui.debug('reusing %s filelog entry\n' % fname)
2347 if manifest1.flags(fname) != fctx.flags():
2370 if manifest1.flags(fname) != fctx.flags():
2348 changelist.append(fname)
2371 changelist.append(fname)
2349 return node
2372 return node
2350
2373
2351 flog = self.file(fname)
2374 flog = self.file(fname)
2352 meta = {}
2375 meta = {}
2353 cfname = fctx.copysource()
2376 cfname = fctx.copysource()
2354 if cfname and cfname != fname:
2377 if cfname and cfname != fname:
2355 # Mark the new revision of this file as a copy of another
2378 # Mark the new revision of this file as a copy of another
2356 # file. This copy data will effectively act as a parent
2379 # file. This copy data will effectively act as a parent
2357 # of this new revision. If this is a merge, the first
2380 # of this new revision. If this is a merge, the first
2358 # parent will be the nullid (meaning "look up the copy data")
2381 # parent will be the nullid (meaning "look up the copy data")
2359 # and the second one will be the other parent. For example:
2382 # and the second one will be the other parent. For example:
2360 #
2383 #
2361 # 0 --- 1 --- 3 rev1 changes file foo
2384 # 0 --- 1 --- 3 rev1 changes file foo
2362 # \ / rev2 renames foo to bar and changes it
2385 # \ / rev2 renames foo to bar and changes it
2363 # \- 2 -/ rev3 should have bar with all changes and
2386 # \- 2 -/ rev3 should have bar with all changes and
2364 # should record that bar descends from
2387 # should record that bar descends from
2365 # bar in rev2 and foo in rev1
2388 # bar in rev2 and foo in rev1
2366 #
2389 #
2367 # this allows this merge to succeed:
2390 # this allows this merge to succeed:
2368 #
2391 #
2369 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
2392 # 0 --- 1 --- 3 rev4 reverts the content change from rev2
2370 # \ / merging rev3 and rev4 should use bar@rev2
2393 # \ / merging rev3 and rev4 should use bar@rev2
2371 # \- 2 --- 4 as the merge base
2394 # \- 2 --- 4 as the merge base
2372 #
2395 #
2373
2396
2374 cnode = manifest1.get(cfname)
2397 cnode = manifest1.get(cfname)
2375 newfparent = fparent2
2398 newfparent = fparent2
2376
2399
2377 if manifest2: # branch merge
2400 if manifest2: # branch merge
2378 if fparent2 == nullid or cnode is None: # copied on remote side
2401 if fparent2 == nullid or cnode is None: # copied on remote side
2379 if cfname in manifest2:
2402 if cfname in manifest2:
2380 cnode = manifest2[cfname]
2403 cnode = manifest2[cfname]
2381 newfparent = fparent1
2404 newfparent = fparent1
2382
2405
2383 # Here, we used to search backwards through history to try to find
2406 # Here, we used to search backwards through history to try to find
2384 # where the file copy came from if the source of a copy was not in
2407 # where the file copy came from if the source of a copy was not in
2385 # the parent directory. However, this doesn't actually make sense to
2408 # the parent directory. However, this doesn't actually make sense to
2386 # do (what does a copy from something not in your working copy even
2409 # do (what does a copy from something not in your working copy even
2387 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
2410 # mean?) and it causes bugs (eg, issue4476). Instead, we will warn
2388 # the user that copy information was dropped, so if they didn't
2411 # the user that copy information was dropped, so if they didn't
2389 # expect this outcome it can be fixed, but this is the correct
2412 # expect this outcome it can be fixed, but this is the correct
2390 # behavior in this circumstance.
2413 # behavior in this circumstance.
2391
2414
2392 if cnode:
2415 if cnode:
2393 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)))
2416 self.ui.debug(" %s: copy %s:%s\n" % (fname, cfname, hex(cnode)))
2394 if includecopymeta:
2417 if includecopymeta:
2395 meta["copy"] = cfname
2418 meta["copy"] = cfname
2396 meta["copyrev"] = hex(cnode)
2419 meta["copyrev"] = hex(cnode)
2397 fparent1, fparent2 = nullid, newfparent
2420 fparent1, fparent2 = nullid, newfparent
2398 else:
2421 else:
2399 self.ui.warn(_("warning: can't find ancestor for '%s' "
2422 self.ui.warn(_("warning: can't find ancestor for '%s' "
2400 "copied from '%s'!\n") % (fname, cfname))
2423 "copied from '%s'!\n") % (fname, cfname))
2401
2424
2402 elif fparent1 == nullid:
2425 elif fparent1 == nullid:
2403 fparent1, fparent2 = fparent2, nullid
2426 fparent1, fparent2 = fparent2, nullid
2404 elif fparent2 != nullid:
2427 elif fparent2 != nullid:
2405 # is one parent an ancestor of the other?
2428 # is one parent an ancestor of the other?
2406 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
2429 fparentancestors = flog.commonancestorsheads(fparent1, fparent2)
2407 if fparent1 in fparentancestors:
2430 if fparent1 in fparentancestors:
2408 fparent1, fparent2 = fparent2, nullid
2431 fparent1, fparent2 = fparent2, nullid
2409 elif fparent2 in fparentancestors:
2432 elif fparent2 in fparentancestors:
2410 fparent2 = nullid
2433 fparent2 = nullid
2411
2434
2412 # is the file changed?
2435 # is the file changed?
2413 text = fctx.data()
2436 text = fctx.data()
2414 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
2437 if fparent2 != nullid or flog.cmp(fparent1, text) or meta:
2415 changelist.append(fname)
2438 changelist.append(fname)
2416 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
2439 return flog.add(text, meta, tr, linkrev, fparent1, fparent2)
2417 # are just the flags changed during merge?
2440 # are just the flags changed during merge?
2418 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
2441 elif fname in manifest1 and manifest1.flags(fname) != fctx.flags():
2419 changelist.append(fname)
2442 changelist.append(fname)
2420
2443
2421 return fparent1
2444 return fparent1
2422
2445
2423 def checkcommitpatterns(self, wctx, vdirs, match, status, fail):
2446 def checkcommitpatterns(self, wctx, vdirs, match, status, fail):
2424 """check for commit arguments that aren't committable"""
2447 """check for commit arguments that aren't committable"""
2425 if match.isexact() or match.prefix():
2448 if match.isexact() or match.prefix():
2426 matched = set(status.modified + status.added + status.removed)
2449 matched = set(status.modified + status.added + status.removed)
2427
2450
2428 for f in match.files():
2451 for f in match.files():
2429 f = self.dirstate.normalize(f)
2452 f = self.dirstate.normalize(f)
2430 if f == '.' or f in matched or f in wctx.substate:
2453 if f == '.' or f in matched or f in wctx.substate:
2431 continue
2454 continue
2432 if f in status.deleted:
2455 if f in status.deleted:
2433 fail(f, _('file not found!'))
2456 fail(f, _('file not found!'))
2434 if f in vdirs: # visited directory
2457 if f in vdirs: # visited directory
2435 d = f + '/'
2458 d = f + '/'
2436 for mf in matched:
2459 for mf in matched:
2437 if mf.startswith(d):
2460 if mf.startswith(d):
2438 break
2461 break
2439 else:
2462 else:
2440 fail(f, _("no match under directory!"))
2463 fail(f, _("no match under directory!"))
2441 elif f not in self.dirstate:
2464 elif f not in self.dirstate:
2442 fail(f, _("file not tracked!"))
2465 fail(f, _("file not tracked!"))
2443
2466
2444 @unfilteredmethod
2467 @unfilteredmethod
2445 def commit(self, text="", user=None, date=None, match=None, force=False,
2468 def commit(self, text="", user=None, date=None, match=None, force=False,
2446 editor=False, extra=None):
2469 editor=False, extra=None):
2447 """Add a new revision to current repository.
2470 """Add a new revision to current repository.
2448
2471
2449 Revision information is gathered from the working directory,
2472 Revision information is gathered from the working directory,
2450 match can be used to filter the committed files. If editor is
2473 match can be used to filter the committed files. If editor is
2451 supplied, it is called to get a commit message.
2474 supplied, it is called to get a commit message.
2452 """
2475 """
2453 if extra is None:
2476 if extra is None:
2454 extra = {}
2477 extra = {}
2455
2478
2456 def fail(f, msg):
2479 def fail(f, msg):
2457 raise error.Abort('%s: %s' % (f, msg))
2480 raise error.Abort('%s: %s' % (f, msg))
2458
2481
2459 if not match:
2482 if not match:
2460 match = matchmod.always()
2483 match = matchmod.always()
2461
2484
2462 if not force:
2485 if not force:
2463 vdirs = []
2486 vdirs = []
2464 match.explicitdir = vdirs.append
2487 match.explicitdir = vdirs.append
2465 match.bad = fail
2488 match.bad = fail
2466
2489
2467 # lock() for recent changelog (see issue4368)
2490 # lock() for recent changelog (see issue4368)
2468 with self.wlock(), self.lock():
2491 with self.wlock(), self.lock():
2469 wctx = self[None]
2492 wctx = self[None]
2470 merge = len(wctx.parents()) > 1
2493 merge = len(wctx.parents()) > 1
2471
2494
2472 if not force and merge and not match.always():
2495 if not force and merge and not match.always():
2473 raise error.Abort(_('cannot partially commit a merge '
2496 raise error.Abort(_('cannot partially commit a merge '
2474 '(do not specify files or patterns)'))
2497 '(do not specify files or patterns)'))
2475
2498
2476 status = self.status(match=match, clean=force)
2499 status = self.status(match=match, clean=force)
2477 if force:
2500 if force:
2478 status.modified.extend(status.clean) # mq may commit clean files
2501 status.modified.extend(status.clean) # mq may commit clean files
2479
2502
2480 # check subrepos
2503 # check subrepos
2481 subs, commitsubs, newstate = subrepoutil.precommit(
2504 subs, commitsubs, newstate = subrepoutil.precommit(
2482 self.ui, wctx, status, match, force=force)
2505 self.ui, wctx, status, match, force=force)
2483
2506
2484 # make sure all explicit patterns are matched
2507 # make sure all explicit patterns are matched
2485 if not force:
2508 if not force:
2486 self.checkcommitpatterns(wctx, vdirs, match, status, fail)
2509 self.checkcommitpatterns(wctx, vdirs, match, status, fail)
2487
2510
2488 cctx = context.workingcommitctx(self, status,
2511 cctx = context.workingcommitctx(self, status,
2489 text, user, date, extra)
2512 text, user, date, extra)
2490
2513
2491 # internal config: ui.allowemptycommit
2514 # internal config: ui.allowemptycommit
2492 allowemptycommit = (wctx.branch() != wctx.p1().branch()
2515 allowemptycommit = (wctx.branch() != wctx.p1().branch()
2493 or extra.get('close') or merge or cctx.files()
2516 or extra.get('close') or merge or cctx.files()
2494 or self.ui.configbool('ui', 'allowemptycommit'))
2517 or self.ui.configbool('ui', 'allowemptycommit'))
2495 if not allowemptycommit:
2518 if not allowemptycommit:
2496 return None
2519 return None
2497
2520
2498 if merge and cctx.deleted():
2521 if merge and cctx.deleted():
2499 raise error.Abort(_("cannot commit merge with missing files"))
2522 raise error.Abort(_("cannot commit merge with missing files"))
2500
2523
2501 ms = mergemod.mergestate.read(self)
2524 ms = mergemod.mergestate.read(self)
2502 mergeutil.checkunresolved(ms)
2525 mergeutil.checkunresolved(ms)
2503
2526
2504 if editor:
2527 if editor:
2505 cctx._text = editor(self, cctx, subs)
2528 cctx._text = editor(self, cctx, subs)
2506 edited = (text != cctx._text)
2529 edited = (text != cctx._text)
2507
2530
2508 # Save commit message in case this transaction gets rolled back
2531 # Save commit message in case this transaction gets rolled back
2509 # (e.g. by a pretxncommit hook). Leave the content alone on
2532 # (e.g. by a pretxncommit hook). Leave the content alone on
2510 # the assumption that the user will use the same editor again.
2533 # the assumption that the user will use the same editor again.
2511 msgfn = self.savecommitmessage(cctx._text)
2534 msgfn = self.savecommitmessage(cctx._text)
2512
2535
2513 # commit subs and write new state
2536 # commit subs and write new state
2514 if subs:
2537 if subs:
2515 uipathfn = scmutil.getuipathfn(self)
2538 uipathfn = scmutil.getuipathfn(self)
2516 for s in sorted(commitsubs):
2539 for s in sorted(commitsubs):
2517 sub = wctx.sub(s)
2540 sub = wctx.sub(s)
2518 self.ui.status(_('committing subrepository %s\n') %
2541 self.ui.status(_('committing subrepository %s\n') %
2519 uipathfn(subrepoutil.subrelpath(sub)))
2542 uipathfn(subrepoutil.subrelpath(sub)))
2520 sr = sub.commit(cctx._text, user, date)
2543 sr = sub.commit(cctx._text, user, date)
2521 newstate[s] = (newstate[s][0], sr)
2544 newstate[s] = (newstate[s][0], sr)
2522 subrepoutil.writestate(self, newstate)
2545 subrepoutil.writestate(self, newstate)
2523
2546
2524 p1, p2 = self.dirstate.parents()
2547 p1, p2 = self.dirstate.parents()
2525 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
2548 hookp1, hookp2 = hex(p1), (p2 != nullid and hex(p2) or '')
2526 try:
2549 try:
2527 self.hook("precommit", throw=True, parent1=hookp1,
2550 self.hook("precommit", throw=True, parent1=hookp1,
2528 parent2=hookp2)
2551 parent2=hookp2)
2529 with self.transaction('commit'):
2552 with self.transaction('commit'):
2530 ret = self.commitctx(cctx, True)
2553 ret = self.commitctx(cctx, True)
2531 # update bookmarks, dirstate and mergestate
2554 # update bookmarks, dirstate and mergestate
2532 bookmarks.update(self, [p1, p2], ret)
2555 bookmarks.update(self, [p1, p2], ret)
2533 cctx.markcommitted(ret)
2556 cctx.markcommitted(ret)
2534 ms.reset()
2557 ms.reset()
2535 except: # re-raises
2558 except: # re-raises
2536 if edited:
2559 if edited:
2537 self.ui.write(
2560 self.ui.write(
2538 _('note: commit message saved in %s\n') % msgfn)
2561 _('note: commit message saved in %s\n') % msgfn)
2539 raise
2562 raise
2540
2563
2541 def commithook():
2564 def commithook():
2542 # hack for command that use a temporary commit (eg: histedit)
2565 # hack for command that use a temporary commit (eg: histedit)
2543 # temporary commit got stripped before hook release
2566 # temporary commit got stripped before hook release
2544 if self.changelog.hasnode(ret):
2567 if self.changelog.hasnode(ret):
2545 self.hook("commit", node=hex(ret), parent1=hookp1,
2568 self.hook("commit", node=hex(ret), parent1=hookp1,
2546 parent2=hookp2)
2569 parent2=hookp2)
2547 self._afterlock(commithook)
2570 self._afterlock(commithook)
2548 return ret
2571 return ret
2549
2572
2550 @unfilteredmethod
2573 @unfilteredmethod
2551 def commitctx(self, ctx, error=False):
2574 def commitctx(self, ctx, error=False):
2552 """Add a new revision to current repository.
2575 """Add a new revision to current repository.
2553 Revision information is passed via the context argument.
2576 Revision information is passed via the context argument.
2554
2577
2555 ctx.files() should list all files involved in this commit, i.e.
2578 ctx.files() should list all files involved in this commit, i.e.
2556 modified/added/removed files. On merge, it may be wider than the
2579 modified/added/removed files. On merge, it may be wider than the
2557 ctx.files() to be committed, since any file nodes derived directly
2580 ctx.files() to be committed, since any file nodes derived directly
2558 from p1 or p2 are excluded from the committed ctx.files().
2581 from p1 or p2 are excluded from the committed ctx.files().
2559 """
2582 """
2560
2583
2561 p1, p2 = ctx.p1(), ctx.p2()
2584 p1, p2 = ctx.p1(), ctx.p2()
2562 user = ctx.user()
2585 user = ctx.user()
2563
2586
2564 writecopiesto = self.ui.config('experimental', 'copies.write-to')
2587 writecopiesto = self.ui.config('experimental', 'copies.write-to')
2565 writefilecopymeta = writecopiesto != 'changeset-only'
2588 writefilecopymeta = writecopiesto != 'changeset-only'
2566 p1copies, p2copies = None, None
2589 p1copies, p2copies = None, None
2567 if writecopiesto in ('changeset-only', 'compatibility'):
2590 if writecopiesto in ('changeset-only', 'compatibility'):
2568 p1copies = ctx.p1copies()
2591 p1copies = ctx.p1copies()
2569 p2copies = ctx.p2copies()
2592 p2copies = ctx.p2copies()
2570 with self.lock(), self.transaction("commit") as tr:
2593 with self.lock(), self.transaction("commit") as tr:
2571 trp = weakref.proxy(tr)
2594 trp = weakref.proxy(tr)
2572
2595
2573 if ctx.manifestnode():
2596 if ctx.manifestnode():
2574 # reuse an existing manifest revision
2597 # reuse an existing manifest revision
2575 self.ui.debug('reusing known manifest\n')
2598 self.ui.debug('reusing known manifest\n')
2576 mn = ctx.manifestnode()
2599 mn = ctx.manifestnode()
2577 files = ctx.files()
2600 files = ctx.files()
2578 elif ctx.files():
2601 elif ctx.files():
2579 m1ctx = p1.manifestctx()
2602 m1ctx = p1.manifestctx()
2580 m2ctx = p2.manifestctx()
2603 m2ctx = p2.manifestctx()
2581 mctx = m1ctx.copy()
2604 mctx = m1ctx.copy()
2582
2605
2583 m = mctx.read()
2606 m = mctx.read()
2584 m1 = m1ctx.read()
2607 m1 = m1ctx.read()
2585 m2 = m2ctx.read()
2608 m2 = m2ctx.read()
2586
2609
2587 # check in files
2610 # check in files
2588 added = []
2611 added = []
2589 changed = []
2612 changed = []
2590 removed = list(ctx.removed())
2613 removed = list(ctx.removed())
2591 linkrev = len(self)
2614 linkrev = len(self)
2592 self.ui.note(_("committing files:\n"))
2615 self.ui.note(_("committing files:\n"))
2593 uipathfn = scmutil.getuipathfn(self)
2616 uipathfn = scmutil.getuipathfn(self)
2594 for f in sorted(ctx.modified() + ctx.added()):
2617 for f in sorted(ctx.modified() + ctx.added()):
2595 self.ui.note(uipathfn(f) + "\n")
2618 self.ui.note(uipathfn(f) + "\n")
2596 try:
2619 try:
2597 fctx = ctx[f]
2620 fctx = ctx[f]
2598 if fctx is None:
2621 if fctx is None:
2599 removed.append(f)
2622 removed.append(f)
2600 else:
2623 else:
2601 added.append(f)
2624 added.append(f)
2602 m[f] = self._filecommit(fctx, m1, m2, linkrev,
2625 m[f] = self._filecommit(fctx, m1, m2, linkrev,
2603 trp, changed,
2626 trp, changed,
2604 writefilecopymeta)
2627 writefilecopymeta)
2605 m.setflag(f, fctx.flags())
2628 m.setflag(f, fctx.flags())
2606 except OSError:
2629 except OSError:
2607 self.ui.warn(_("trouble committing %s!\n") %
2630 self.ui.warn(_("trouble committing %s!\n") %
2608 uipathfn(f))
2631 uipathfn(f))
2609 raise
2632 raise
2610 except IOError as inst:
2633 except IOError as inst:
2611 errcode = getattr(inst, 'errno', errno.ENOENT)
2634 errcode = getattr(inst, 'errno', errno.ENOENT)
2612 if error or errcode and errcode != errno.ENOENT:
2635 if error or errcode and errcode != errno.ENOENT:
2613 self.ui.warn(_("trouble committing %s!\n") %
2636 self.ui.warn(_("trouble committing %s!\n") %
2614 uipathfn(f))
2637 uipathfn(f))
2615 raise
2638 raise
2616
2639
2617 # update manifest
2640 # update manifest
2618 removed = [f for f in sorted(removed) if f in m1 or f in m2]
2641 removed = [f for f in sorted(removed) if f in m1 or f in m2]
2619 drop = [f for f in removed if f in m]
2642 drop = [f for f in removed if f in m]
2620 for f in drop:
2643 for f in drop:
2621 del m[f]
2644 del m[f]
2622 files = changed + removed
2645 files = changed + removed
2623 md = None
2646 md = None
2624 if not files:
2647 if not files:
2625 # if no "files" actually changed in terms of the changelog,
2648 # if no "files" actually changed in terms of the changelog,
2626 # try hard to detect unmodified manifest entry so that the
2649 # try hard to detect unmodified manifest entry so that the
2627 # exact same commit can be reproduced later on convert.
2650 # exact same commit can be reproduced later on convert.
2628 md = m1.diff(m, scmutil.matchfiles(self, ctx.files()))
2651 md = m1.diff(m, scmutil.matchfiles(self, ctx.files()))
2629 if not files and md:
2652 if not files and md:
2630 self.ui.debug('not reusing manifest (no file change in '
2653 self.ui.debug('not reusing manifest (no file change in '
2631 'changelog, but manifest differs)\n')
2654 'changelog, but manifest differs)\n')
2632 if files or md:
2655 if files or md:
2633 self.ui.note(_("committing manifest\n"))
2656 self.ui.note(_("committing manifest\n"))
2634 # we're using narrowmatch here since it's already applied at
2657 # we're using narrowmatch here since it's already applied at
2635 # other stages (such as dirstate.walk), so we're already
2658 # other stages (such as dirstate.walk), so we're already
2636 # ignoring things outside of narrowspec in most cases. The
2659 # ignoring things outside of narrowspec in most cases. The
2637 # one case where we might have files outside the narrowspec
2660 # one case where we might have files outside the narrowspec
2638 # at this point is merges, and we already error out in the
2661 # at this point is merges, and we already error out in the
2639 # case where the merge has files outside of the narrowspec,
2662 # case where the merge has files outside of the narrowspec,
2640 # so this is safe.
2663 # so this is safe.
2641 mn = mctx.write(trp, linkrev,
2664 mn = mctx.write(trp, linkrev,
2642 p1.manifestnode(), p2.manifestnode(),
2665 p1.manifestnode(), p2.manifestnode(),
2643 added, drop, match=self.narrowmatch())
2666 added, drop, match=self.narrowmatch())
2644 else:
2667 else:
2645 self.ui.debug('reusing manifest from p1 (listed files '
2668 self.ui.debug('reusing manifest from p1 (listed files '
2646 'actually unchanged)\n')
2669 'actually unchanged)\n')
2647 mn = p1.manifestnode()
2670 mn = p1.manifestnode()
2648 else:
2671 else:
2649 self.ui.debug('reusing manifest from p1 (no file change)\n')
2672 self.ui.debug('reusing manifest from p1 (no file change)\n')
2650 mn = p1.manifestnode()
2673 mn = p1.manifestnode()
2651 files = []
2674 files = []
2652
2675
2653 if writecopiesto == 'changeset-only':
2676 if writecopiesto == 'changeset-only':
2654 # If writing only to changeset extras, use None to indicate that
2677 # If writing only to changeset extras, use None to indicate that
2655 # no entry should be written. If writing to both, write an empty
2678 # no entry should be written. If writing to both, write an empty
2656 # entry to prevent the reader from falling back to reading
2679 # entry to prevent the reader from falling back to reading
2657 # filelogs.
2680 # filelogs.
2658 p1copies = p1copies or None
2681 p1copies = p1copies or None
2659 p2copies = p2copies or None
2682 p2copies = p2copies or None
2660
2683
2661 # update changelog
2684 # update changelog
2662 self.ui.note(_("committing changelog\n"))
2685 self.ui.note(_("committing changelog\n"))
2663 self.changelog.delayupdate(tr)
2686 self.changelog.delayupdate(tr)
2664 n = self.changelog.add(mn, files, ctx.description(),
2687 n = self.changelog.add(mn, files, ctx.description(),
2665 trp, p1.node(), p2.node(),
2688 trp, p1.node(), p2.node(),
2666 user, ctx.date(), ctx.extra().copy(),
2689 user, ctx.date(), ctx.extra().copy(),
2667 p1copies, p2copies)
2690 p1copies, p2copies)
2668 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
2691 xp1, xp2 = p1.hex(), p2 and p2.hex() or ''
2669 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
2692 self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
2670 parent2=xp2)
2693 parent2=xp2)
2671 # set the new commit is proper phase
2694 # set the new commit is proper phase
2672 targetphase = subrepoutil.newcommitphase(self.ui, ctx)
2695 targetphase = subrepoutil.newcommitphase(self.ui, ctx)
2673 if targetphase:
2696 if targetphase:
2674 # retract boundary do not alter parent changeset.
2697 # retract boundary do not alter parent changeset.
2675 # if a parent have higher the resulting phase will
2698 # if a parent have higher the resulting phase will
2676 # be compliant anyway
2699 # be compliant anyway
2677 #
2700 #
2678 # if minimal phase was 0 we don't need to retract anything
2701 # if minimal phase was 0 we don't need to retract anything
2679 phases.registernew(self, tr, targetphase, [n])
2702 phases.registernew(self, tr, targetphase, [n])
2680 return n
2703 return n
2681
2704
2682 @unfilteredmethod
2705 @unfilteredmethod
2683 def destroying(self):
2706 def destroying(self):
2684 '''Inform the repository that nodes are about to be destroyed.
2707 '''Inform the repository that nodes are about to be destroyed.
2685 Intended for use by strip and rollback, so there's a common
2708 Intended for use by strip and rollback, so there's a common
2686 place for anything that has to be done before destroying history.
2709 place for anything that has to be done before destroying history.
2687
2710
2688 This is mostly useful for saving state that is in memory and waiting
2711 This is mostly useful for saving state that is in memory and waiting
2689 to be flushed when the current lock is released. Because a call to
2712 to be flushed when the current lock is released. Because a call to
2690 destroyed is imminent, the repo will be invalidated causing those
2713 destroyed is imminent, the repo will be invalidated causing those
2691 changes to stay in memory (waiting for the next unlock), or vanish
2714 changes to stay in memory (waiting for the next unlock), or vanish
2692 completely.
2715 completely.
2693 '''
2716 '''
2694 # When using the same lock to commit and strip, the phasecache is left
2717 # When using the same lock to commit and strip, the phasecache is left
2695 # dirty after committing. Then when we strip, the repo is invalidated,
2718 # dirty after committing. Then when we strip, the repo is invalidated,
2696 # causing those changes to disappear.
2719 # causing those changes to disappear.
2697 if '_phasecache' in vars(self):
2720 if '_phasecache' in vars(self):
2698 self._phasecache.write()
2721 self._phasecache.write()
2699
2722
2700 @unfilteredmethod
2723 @unfilteredmethod
2701 def destroyed(self):
2724 def destroyed(self):
2702 '''Inform the repository that nodes have been destroyed.
2725 '''Inform the repository that nodes have been destroyed.
2703 Intended for use by strip and rollback, so there's a common
2726 Intended for use by strip and rollback, so there's a common
2704 place for anything that has to be done after destroying history.
2727 place for anything that has to be done after destroying history.
2705 '''
2728 '''
2706 # When one tries to:
2729 # When one tries to:
2707 # 1) destroy nodes thus calling this method (e.g. strip)
2730 # 1) destroy nodes thus calling this method (e.g. strip)
2708 # 2) use phasecache somewhere (e.g. commit)
2731 # 2) use phasecache somewhere (e.g. commit)
2709 #
2732 #
2710 # then 2) will fail because the phasecache contains nodes that were
2733 # then 2) will fail because the phasecache contains nodes that were
2711 # removed. We can either remove phasecache from the filecache,
2734 # removed. We can either remove phasecache from the filecache,
2712 # causing it to reload next time it is accessed, or simply filter
2735 # causing it to reload next time it is accessed, or simply filter
2713 # the removed nodes now and write the updated cache.
2736 # the removed nodes now and write the updated cache.
2714 self._phasecache.filterunknown(self)
2737 self._phasecache.filterunknown(self)
2715 self._phasecache.write()
2738 self._phasecache.write()
2716
2739
2717 # refresh all repository caches
2740 # refresh all repository caches
2718 self.updatecaches()
2741 self.updatecaches()
2719
2742
2720 # Ensure the persistent tag cache is updated. Doing it now
2743 # Ensure the persistent tag cache is updated. Doing it now
2721 # means that the tag cache only has to worry about destroyed
2744 # means that the tag cache only has to worry about destroyed
2722 # heads immediately after a strip/rollback. That in turn
2745 # heads immediately after a strip/rollback. That in turn
2723 # guarantees that "cachetip == currenttip" (comparing both rev
2746 # guarantees that "cachetip == currenttip" (comparing both rev
2724 # and node) always means no nodes have been added or destroyed.
2747 # and node) always means no nodes have been added or destroyed.
2725
2748
2726 # XXX this is suboptimal when qrefresh'ing: we strip the current
2749 # XXX this is suboptimal when qrefresh'ing: we strip the current
2727 # head, refresh the tag cache, then immediately add a new head.
2750 # head, refresh the tag cache, then immediately add a new head.
2728 # But I think doing it this way is necessary for the "instant
2751 # But I think doing it this way is necessary for the "instant
2729 # tag cache retrieval" case to work.
2752 # tag cache retrieval" case to work.
2730 self.invalidate()
2753 self.invalidate()
2731
2754
2732 def status(self, node1='.', node2=None, match=None,
2755 def status(self, node1='.', node2=None, match=None,
2733 ignored=False, clean=False, unknown=False,
2756 ignored=False, clean=False, unknown=False,
2734 listsubrepos=False):
2757 listsubrepos=False):
2735 '''a convenience method that calls node1.status(node2)'''
2758 '''a convenience method that calls node1.status(node2)'''
2736 return self[node1].status(node2, match, ignored, clean, unknown,
2759 return self[node1].status(node2, match, ignored, clean, unknown,
2737 listsubrepos)
2760 listsubrepos)
2738
2761
2739 def addpostdsstatus(self, ps):
2762 def addpostdsstatus(self, ps):
2740 """Add a callback to run within the wlock, at the point at which status
2763 """Add a callback to run within the wlock, at the point at which status
2741 fixups happen.
2764 fixups happen.
2742
2765
2743 On status completion, callback(wctx, status) will be called with the
2766 On status completion, callback(wctx, status) will be called with the
2744 wlock held, unless the dirstate has changed from underneath or the wlock
2767 wlock held, unless the dirstate has changed from underneath or the wlock
2745 couldn't be grabbed.
2768 couldn't be grabbed.
2746
2769
2747 Callbacks should not capture and use a cached copy of the dirstate --
2770 Callbacks should not capture and use a cached copy of the dirstate --
2748 it might change in the meanwhile. Instead, they should access the
2771 it might change in the meanwhile. Instead, they should access the
2749 dirstate via wctx.repo().dirstate.
2772 dirstate via wctx.repo().dirstate.
2750
2773
2751 This list is emptied out after each status run -- extensions should
2774 This list is emptied out after each status run -- extensions should
2752 make sure it adds to this list each time dirstate.status is called.
2775 make sure it adds to this list each time dirstate.status is called.
2753 Extensions should also make sure they don't call this for statuses
2776 Extensions should also make sure they don't call this for statuses
2754 that don't involve the dirstate.
2777 that don't involve the dirstate.
2755 """
2778 """
2756
2779
2757 # The list is located here for uniqueness reasons -- it is actually
2780 # The list is located here for uniqueness reasons -- it is actually
2758 # managed by the workingctx, but that isn't unique per-repo.
2781 # managed by the workingctx, but that isn't unique per-repo.
2759 self._postdsstatus.append(ps)
2782 self._postdsstatus.append(ps)
2760
2783
2761 def postdsstatus(self):
2784 def postdsstatus(self):
2762 """Used by workingctx to get the list of post-dirstate-status hooks."""
2785 """Used by workingctx to get the list of post-dirstate-status hooks."""
2763 return self._postdsstatus
2786 return self._postdsstatus
2764
2787
2765 def clearpostdsstatus(self):
2788 def clearpostdsstatus(self):
2766 """Used by workingctx to clear post-dirstate-status hooks."""
2789 """Used by workingctx to clear post-dirstate-status hooks."""
2767 del self._postdsstatus[:]
2790 del self._postdsstatus[:]
2768
2791
2769 def heads(self, start=None):
2792 def heads(self, start=None):
2770 if start is None:
2793 if start is None:
2771 cl = self.changelog
2794 cl = self.changelog
2772 headrevs = reversed(cl.headrevs())
2795 headrevs = reversed(cl.headrevs())
2773 return [cl.node(rev) for rev in headrevs]
2796 return [cl.node(rev) for rev in headrevs]
2774
2797
2775 heads = self.changelog.heads(start)
2798 heads = self.changelog.heads(start)
2776 # sort the output in rev descending order
2799 # sort the output in rev descending order
2777 return sorted(heads, key=self.changelog.rev, reverse=True)
2800 return sorted(heads, key=self.changelog.rev, reverse=True)
2778
2801
2779 def branchheads(self, branch=None, start=None, closed=False):
2802 def branchheads(self, branch=None, start=None, closed=False):
2780 '''return a (possibly filtered) list of heads for the given branch
2803 '''return a (possibly filtered) list of heads for the given branch
2781
2804
2782 Heads are returned in topological order, from newest to oldest.
2805 Heads are returned in topological order, from newest to oldest.
2783 If branch is None, use the dirstate branch.
2806 If branch is None, use the dirstate branch.
2784 If start is not None, return only heads reachable from start.
2807 If start is not None, return only heads reachable from start.
2785 If closed is True, return heads that are marked as closed as well.
2808 If closed is True, return heads that are marked as closed as well.
2786 '''
2809 '''
2787 if branch is None:
2810 if branch is None:
2788 branch = self[None].branch()
2811 branch = self[None].branch()
2789 branches = self.branchmap()
2812 branches = self.branchmap()
2790 if not branches.hasbranch(branch):
2813 if not branches.hasbranch(branch):
2791 return []
2814 return []
2792 # the cache returns heads ordered lowest to highest
2815 # the cache returns heads ordered lowest to highest
2793 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
2816 bheads = list(reversed(branches.branchheads(branch, closed=closed)))
2794 if start is not None:
2817 if start is not None:
2795 # filter out the heads that cannot be reached from startrev
2818 # filter out the heads that cannot be reached from startrev
2796 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
2819 fbheads = set(self.changelog.nodesbetween([start], bheads)[2])
2797 bheads = [h for h in bheads if h in fbheads]
2820 bheads = [h for h in bheads if h in fbheads]
2798 return bheads
2821 return bheads
2799
2822
2800 def branches(self, nodes):
2823 def branches(self, nodes):
2801 if not nodes:
2824 if not nodes:
2802 nodes = [self.changelog.tip()]
2825 nodes = [self.changelog.tip()]
2803 b = []
2826 b = []
2804 for n in nodes:
2827 for n in nodes:
2805 t = n
2828 t = n
2806 while True:
2829 while True:
2807 p = self.changelog.parents(n)
2830 p = self.changelog.parents(n)
2808 if p[1] != nullid or p[0] == nullid:
2831 if p[1] != nullid or p[0] == nullid:
2809 b.append((t, n, p[0], p[1]))
2832 b.append((t, n, p[0], p[1]))
2810 break
2833 break
2811 n = p[0]
2834 n = p[0]
2812 return b
2835 return b
2813
2836
2814 def between(self, pairs):
2837 def between(self, pairs):
2815 r = []
2838 r = []
2816
2839
2817 for top, bottom in pairs:
2840 for top, bottom in pairs:
2818 n, l, i = top, [], 0
2841 n, l, i = top, [], 0
2819 f = 1
2842 f = 1
2820
2843
2821 while n != bottom and n != nullid:
2844 while n != bottom and n != nullid:
2822 p = self.changelog.parents(n)[0]
2845 p = self.changelog.parents(n)[0]
2823 if i == f:
2846 if i == f:
2824 l.append(n)
2847 l.append(n)
2825 f = f * 2
2848 f = f * 2
2826 n = p
2849 n = p
2827 i += 1
2850 i += 1
2828
2851
2829 r.append(l)
2852 r.append(l)
2830
2853
2831 return r
2854 return r
2832
2855
2833 def checkpush(self, pushop):
2856 def checkpush(self, pushop):
2834 """Extensions can override this function if additional checks have
2857 """Extensions can override this function if additional checks have
2835 to be performed before pushing, or call it if they override push
2858 to be performed before pushing, or call it if they override push
2836 command.
2859 command.
2837 """
2860 """
2838
2861
2839 @unfilteredpropertycache
2862 @unfilteredpropertycache
2840 def prepushoutgoinghooks(self):
2863 def prepushoutgoinghooks(self):
2841 """Return util.hooks consists of a pushop with repo, remote, outgoing
2864 """Return util.hooks consists of a pushop with repo, remote, outgoing
2842 methods, which are called before pushing changesets.
2865 methods, which are called before pushing changesets.
2843 """
2866 """
2844 return util.hooks()
2867 return util.hooks()
2845
2868
2846 def pushkey(self, namespace, key, old, new):
2869 def pushkey(self, namespace, key, old, new):
2847 try:
2870 try:
2848 tr = self.currenttransaction()
2871 tr = self.currenttransaction()
2849 hookargs = {}
2872 hookargs = {}
2850 if tr is not None:
2873 if tr is not None:
2851 hookargs.update(tr.hookargs)
2874 hookargs.update(tr.hookargs)
2852 hookargs = pycompat.strkwargs(hookargs)
2875 hookargs = pycompat.strkwargs(hookargs)
2853 hookargs[r'namespace'] = namespace
2876 hookargs[r'namespace'] = namespace
2854 hookargs[r'key'] = key
2877 hookargs[r'key'] = key
2855 hookargs[r'old'] = old
2878 hookargs[r'old'] = old
2856 hookargs[r'new'] = new
2879 hookargs[r'new'] = new
2857 self.hook('prepushkey', throw=True, **hookargs)
2880 self.hook('prepushkey', throw=True, **hookargs)
2858 except error.HookAbort as exc:
2881 except error.HookAbort as exc:
2859 self.ui.write_err(_("pushkey-abort: %s\n") % exc)
2882 self.ui.write_err(_("pushkey-abort: %s\n") % exc)
2860 if exc.hint:
2883 if exc.hint:
2861 self.ui.write_err(_("(%s)\n") % exc.hint)
2884 self.ui.write_err(_("(%s)\n") % exc.hint)
2862 return False
2885 return False
2863 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
2886 self.ui.debug('pushing key for "%s:%s"\n' % (namespace, key))
2864 ret = pushkey.push(self, namespace, key, old, new)
2887 ret = pushkey.push(self, namespace, key, old, new)
2865 def runhook():
2888 def runhook():
2866 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
2889 self.hook('pushkey', namespace=namespace, key=key, old=old, new=new,
2867 ret=ret)
2890 ret=ret)
2868 self._afterlock(runhook)
2891 self._afterlock(runhook)
2869 return ret
2892 return ret
2870
2893
2871 def listkeys(self, namespace):
2894 def listkeys(self, namespace):
2872 self.hook('prelistkeys', throw=True, namespace=namespace)
2895 self.hook('prelistkeys', throw=True, namespace=namespace)
2873 self.ui.debug('listing keys for "%s"\n' % namespace)
2896 self.ui.debug('listing keys for "%s"\n' % namespace)
2874 values = pushkey.list(self, namespace)
2897 values = pushkey.list(self, namespace)
2875 self.hook('listkeys', namespace=namespace, values=values)
2898 self.hook('listkeys', namespace=namespace, values=values)
2876 return values
2899 return values
2877
2900
2878 def debugwireargs(self, one, two, three=None, four=None, five=None):
2901 def debugwireargs(self, one, two, three=None, four=None, five=None):
2879 '''used to test argument passing over the wire'''
2902 '''used to test argument passing over the wire'''
2880 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
2903 return "%s %s %s %s %s" % (one, two, pycompat.bytestr(three),
2881 pycompat.bytestr(four),
2904 pycompat.bytestr(four),
2882 pycompat.bytestr(five))
2905 pycompat.bytestr(five))
2883
2906
2884 def savecommitmessage(self, text):
2907 def savecommitmessage(self, text):
2885 fp = self.vfs('last-message.txt', 'wb')
2908 fp = self.vfs('last-message.txt', 'wb')
2886 try:
2909 try:
2887 fp.write(text)
2910 fp.write(text)
2888 finally:
2911 finally:
2889 fp.close()
2912 fp.close()
2890 return self.pathto(fp.name[len(self.root) + 1:])
2913 return self.pathto(fp.name[len(self.root) + 1:])
2891
2914
2892 # used to avoid circular references so destructors work
2915 # used to avoid circular references so destructors work
2893 def aftertrans(files):
2916 def aftertrans(files):
2894 renamefiles = [tuple(t) for t in files]
2917 renamefiles = [tuple(t) for t in files]
2895 def a():
2918 def a():
2896 for vfs, src, dest in renamefiles:
2919 for vfs, src, dest in renamefiles:
2897 # if src and dest refer to a same file, vfs.rename is a no-op,
2920 # if src and dest refer to a same file, vfs.rename is a no-op,
2898 # leaving both src and dest on disk. delete dest to make sure
2921 # leaving both src and dest on disk. delete dest to make sure
2899 # the rename couldn't be such a no-op.
2922 # the rename couldn't be such a no-op.
2900 vfs.tryunlink(dest)
2923 vfs.tryunlink(dest)
2901 try:
2924 try:
2902 vfs.rename(src, dest)
2925 vfs.rename(src, dest)
2903 except OSError: # journal file does not yet exist
2926 except OSError: # journal file does not yet exist
2904 pass
2927 pass
2905 return a
2928 return a
2906
2929
2907 def undoname(fn):
2930 def undoname(fn):
2908 base, name = os.path.split(fn)
2931 base, name = os.path.split(fn)
2909 assert name.startswith('journal')
2932 assert name.startswith('journal')
2910 return os.path.join(base, name.replace('journal', 'undo', 1))
2933 return os.path.join(base, name.replace('journal', 'undo', 1))
2911
2934
2912 def instance(ui, path, create, intents=None, createopts=None):
2935 def instance(ui, path, create, intents=None, createopts=None):
2913 localpath = util.urllocalpath(path)
2936 localpath = util.urllocalpath(path)
2914 if create:
2937 if create:
2915 createrepository(ui, localpath, createopts=createopts)
2938 createrepository(ui, localpath, createopts=createopts)
2916
2939
2917 return makelocalrepository(ui, localpath, intents=intents)
2940 return makelocalrepository(ui, localpath, intents=intents)
2918
2941
2919 def islocal(path):
2942 def islocal(path):
2920 return True
2943 return True
2921
2944
2922 def defaultcreateopts(ui, createopts=None):
2945 def defaultcreateopts(ui, createopts=None):
2923 """Populate the default creation options for a repository.
2946 """Populate the default creation options for a repository.
2924
2947
2925 A dictionary of explicitly requested creation options can be passed
2948 A dictionary of explicitly requested creation options can be passed
2926 in. Missing keys will be populated.
2949 in. Missing keys will be populated.
2927 """
2950 """
2928 createopts = dict(createopts or {})
2951 createopts = dict(createopts or {})
2929
2952
2930 if 'backend' not in createopts:
2953 if 'backend' not in createopts:
2931 # experimental config: storage.new-repo-backend
2954 # experimental config: storage.new-repo-backend
2932 createopts['backend'] = ui.config('storage', 'new-repo-backend')
2955 createopts['backend'] = ui.config('storage', 'new-repo-backend')
2933
2956
2934 return createopts
2957 return createopts
2935
2958
2936 def newreporequirements(ui, createopts):
2959 def newreporequirements(ui, createopts):
2937 """Determine the set of requirements for a new local repository.
2960 """Determine the set of requirements for a new local repository.
2938
2961
2939 Extensions can wrap this function to specify custom requirements for
2962 Extensions can wrap this function to specify custom requirements for
2940 new repositories.
2963 new repositories.
2941 """
2964 """
2942 # If the repo is being created from a shared repository, we copy
2965 # If the repo is being created from a shared repository, we copy
2943 # its requirements.
2966 # its requirements.
2944 if 'sharedrepo' in createopts:
2967 if 'sharedrepo' in createopts:
2945 requirements = set(createopts['sharedrepo'].requirements)
2968 requirements = set(createopts['sharedrepo'].requirements)
2946 if createopts.get('sharedrelative'):
2969 if createopts.get('sharedrelative'):
2947 requirements.add('relshared')
2970 requirements.add('relshared')
2948 else:
2971 else:
2949 requirements.add('shared')
2972 requirements.add('shared')
2950
2973
2951 return requirements
2974 return requirements
2952
2975
2953 if 'backend' not in createopts:
2976 if 'backend' not in createopts:
2954 raise error.ProgrammingError('backend key not present in createopts; '
2977 raise error.ProgrammingError('backend key not present in createopts; '
2955 'was defaultcreateopts() called?')
2978 'was defaultcreateopts() called?')
2956
2979
2957 if createopts['backend'] != 'revlogv1':
2980 if createopts['backend'] != 'revlogv1':
2958 raise error.Abort(_('unable to determine repository requirements for '
2981 raise error.Abort(_('unable to determine repository requirements for '
2959 'storage backend: %s') % createopts['backend'])
2982 'storage backend: %s') % createopts['backend'])
2960
2983
2961 requirements = {'revlogv1'}
2984 requirements = {'revlogv1'}
2962 if ui.configbool('format', 'usestore'):
2985 if ui.configbool('format', 'usestore'):
2963 requirements.add('store')
2986 requirements.add('store')
2964 if ui.configbool('format', 'usefncache'):
2987 if ui.configbool('format', 'usefncache'):
2965 requirements.add('fncache')
2988 requirements.add('fncache')
2966 if ui.configbool('format', 'dotencode'):
2989 if ui.configbool('format', 'dotencode'):
2967 requirements.add('dotencode')
2990 requirements.add('dotencode')
2968
2991
2969 compengine = ui.config('format', 'revlog-compression')
2992 compengine = ui.config('format', 'revlog-compression')
2970 if compengine not in util.compengines:
2993 if compengine not in util.compengines:
2971 raise error.Abort(_('compression engine %s defined by '
2994 raise error.Abort(_('compression engine %s defined by '
2972 'format.revlog-compression not available') %
2995 'format.revlog-compression not available') %
2973 compengine,
2996 compengine,
2974 hint=_('run "hg debuginstall" to list available '
2997 hint=_('run "hg debuginstall" to list available '
2975 'compression engines'))
2998 'compression engines'))
2976
2999
2977 # zlib is the historical default and doesn't need an explicit requirement.
3000 # zlib is the historical default and doesn't need an explicit requirement.
2978 elif compengine == 'zstd':
3001 elif compengine == 'zstd':
2979 requirements.add('revlog-compression-zstd')
3002 requirements.add('revlog-compression-zstd')
2980 elif compengine != 'zlib':
3003 elif compengine != 'zlib':
2981 requirements.add('exp-compression-%s' % compengine)
3004 requirements.add('exp-compression-%s' % compengine)
2982
3005
2983 if scmutil.gdinitconfig(ui):
3006 if scmutil.gdinitconfig(ui):
2984 requirements.add('generaldelta')
3007 requirements.add('generaldelta')
2985 if ui.configbool('format', 'sparse-revlog'):
3008 if ui.configbool('format', 'sparse-revlog'):
2986 requirements.add(SPARSEREVLOG_REQUIREMENT)
3009 requirements.add(SPARSEREVLOG_REQUIREMENT)
2987 if ui.configbool('experimental', 'treemanifest'):
3010 if ui.configbool('experimental', 'treemanifest'):
2988 requirements.add('treemanifest')
3011 requirements.add('treemanifest')
2989
3012
2990 revlogv2 = ui.config('experimental', 'revlogv2')
3013 revlogv2 = ui.config('experimental', 'revlogv2')
2991 if revlogv2 == 'enable-unstable-format-and-corrupt-my-data':
3014 if revlogv2 == 'enable-unstable-format-and-corrupt-my-data':
2992 requirements.remove('revlogv1')
3015 requirements.remove('revlogv1')
2993 # generaldelta is implied by revlogv2.
3016 # generaldelta is implied by revlogv2.
2994 requirements.discard('generaldelta')
3017 requirements.discard('generaldelta')
2995 requirements.add(REVLOGV2_REQUIREMENT)
3018 requirements.add(REVLOGV2_REQUIREMENT)
2996 # experimental config: format.internal-phase
3019 # experimental config: format.internal-phase
2997 if ui.configbool('format', 'internal-phase'):
3020 if ui.configbool('format', 'internal-phase'):
2998 requirements.add('internal-phase')
3021 requirements.add('internal-phase')
2999
3022
3000 if createopts.get('narrowfiles'):
3023 if createopts.get('narrowfiles'):
3001 requirements.add(repository.NARROW_REQUIREMENT)
3024 requirements.add(repository.NARROW_REQUIREMENT)
3002
3025
3003 if createopts.get('lfs'):
3026 if createopts.get('lfs'):
3004 requirements.add('lfs')
3027 requirements.add('lfs')
3005
3028
3029 if ui.configbool('format', 'bookmarks-in-store'):
3030 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3031
3006 return requirements
3032 return requirements
3007
3033
3008 def filterknowncreateopts(ui, createopts):
3034 def filterknowncreateopts(ui, createopts):
3009 """Filters a dict of repo creation options against options that are known.
3035 """Filters a dict of repo creation options against options that are known.
3010
3036
3011 Receives a dict of repo creation options and returns a dict of those
3037 Receives a dict of repo creation options and returns a dict of those
3012 options that we don't know how to handle.
3038 options that we don't know how to handle.
3013
3039
3014 This function is called as part of repository creation. If the
3040 This function is called as part of repository creation. If the
3015 returned dict contains any items, repository creation will not
3041 returned dict contains any items, repository creation will not
3016 be allowed, as it means there was a request to create a repository
3042 be allowed, as it means there was a request to create a repository
3017 with options not recognized by loaded code.
3043 with options not recognized by loaded code.
3018
3044
3019 Extensions can wrap this function to filter out creation options
3045 Extensions can wrap this function to filter out creation options
3020 they know how to handle.
3046 they know how to handle.
3021 """
3047 """
3022 known = {
3048 known = {
3023 'backend',
3049 'backend',
3024 'lfs',
3050 'lfs',
3025 'narrowfiles',
3051 'narrowfiles',
3026 'sharedrepo',
3052 'sharedrepo',
3027 'sharedrelative',
3053 'sharedrelative',
3028 'shareditems',
3054 'shareditems',
3029 'shallowfilestore',
3055 'shallowfilestore',
3030 }
3056 }
3031
3057
3032 return {k: v for k, v in createopts.items() if k not in known}
3058 return {k: v for k, v in createopts.items() if k not in known}
3033
3059
3034 def createrepository(ui, path, createopts=None):
3060 def createrepository(ui, path, createopts=None):
3035 """Create a new repository in a vfs.
3061 """Create a new repository in a vfs.
3036
3062
3037 ``path`` path to the new repo's working directory.
3063 ``path`` path to the new repo's working directory.
3038 ``createopts`` options for the new repository.
3064 ``createopts`` options for the new repository.
3039
3065
3040 The following keys for ``createopts`` are recognized:
3066 The following keys for ``createopts`` are recognized:
3041
3067
3042 backend
3068 backend
3043 The storage backend to use.
3069 The storage backend to use.
3044 lfs
3070 lfs
3045 Repository will be created with ``lfs`` requirement. The lfs extension
3071 Repository will be created with ``lfs`` requirement. The lfs extension
3046 will automatically be loaded when the repository is accessed.
3072 will automatically be loaded when the repository is accessed.
3047 narrowfiles
3073 narrowfiles
3048 Set up repository to support narrow file storage.
3074 Set up repository to support narrow file storage.
3049 sharedrepo
3075 sharedrepo
3050 Repository object from which storage should be shared.
3076 Repository object from which storage should be shared.
3051 sharedrelative
3077 sharedrelative
3052 Boolean indicating if the path to the shared repo should be
3078 Boolean indicating if the path to the shared repo should be
3053 stored as relative. By default, the pointer to the "parent" repo
3079 stored as relative. By default, the pointer to the "parent" repo
3054 is stored as an absolute path.
3080 is stored as an absolute path.
3055 shareditems
3081 shareditems
3056 Set of items to share to the new repository (in addition to storage).
3082 Set of items to share to the new repository (in addition to storage).
3057 shallowfilestore
3083 shallowfilestore
3058 Indicates that storage for files should be shallow (not all ancestor
3084 Indicates that storage for files should be shallow (not all ancestor
3059 revisions are known).
3085 revisions are known).
3060 """
3086 """
3061 createopts = defaultcreateopts(ui, createopts=createopts)
3087 createopts = defaultcreateopts(ui, createopts=createopts)
3062
3088
3063 unknownopts = filterknowncreateopts(ui, createopts)
3089 unknownopts = filterknowncreateopts(ui, createopts)
3064
3090
3065 if not isinstance(unknownopts, dict):
3091 if not isinstance(unknownopts, dict):
3066 raise error.ProgrammingError('filterknowncreateopts() did not return '
3092 raise error.ProgrammingError('filterknowncreateopts() did not return '
3067 'a dict')
3093 'a dict')
3068
3094
3069 if unknownopts:
3095 if unknownopts:
3070 raise error.Abort(_('unable to create repository because of unknown '
3096 raise error.Abort(_('unable to create repository because of unknown '
3071 'creation option: %s') %
3097 'creation option: %s') %
3072 ', '.join(sorted(unknownopts)),
3098 ', '.join(sorted(unknownopts)),
3073 hint=_('is a required extension not loaded?'))
3099 hint=_('is a required extension not loaded?'))
3074
3100
3075 requirements = newreporequirements(ui, createopts=createopts)
3101 requirements = newreporequirements(ui, createopts=createopts)
3076
3102
3077 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3103 wdirvfs = vfsmod.vfs(path, expandpath=True, realpath=True)
3078
3104
3079 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3105 hgvfs = vfsmod.vfs(wdirvfs.join(b'.hg'))
3080 if hgvfs.exists():
3106 if hgvfs.exists():
3081 raise error.RepoError(_('repository %s already exists') % path)
3107 raise error.RepoError(_('repository %s already exists') % path)
3082
3108
3083 if 'sharedrepo' in createopts:
3109 if 'sharedrepo' in createopts:
3084 sharedpath = createopts['sharedrepo'].sharedpath
3110 sharedpath = createopts['sharedrepo'].sharedpath
3085
3111
3086 if createopts.get('sharedrelative'):
3112 if createopts.get('sharedrelative'):
3087 try:
3113 try:
3088 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3114 sharedpath = os.path.relpath(sharedpath, hgvfs.base)
3089 except (IOError, ValueError) as e:
3115 except (IOError, ValueError) as e:
3090 # ValueError is raised on Windows if the drive letters differ
3116 # ValueError is raised on Windows if the drive letters differ
3091 # on each path.
3117 # on each path.
3092 raise error.Abort(_('cannot calculate relative path'),
3118 raise error.Abort(_('cannot calculate relative path'),
3093 hint=stringutil.forcebytestr(e))
3119 hint=stringutil.forcebytestr(e))
3094
3120
3095 if not wdirvfs.exists():
3121 if not wdirvfs.exists():
3096 wdirvfs.makedirs()
3122 wdirvfs.makedirs()
3097
3123
3098 hgvfs.makedir(notindexed=True)
3124 hgvfs.makedir(notindexed=True)
3099 if 'sharedrepo' not in createopts:
3125 if 'sharedrepo' not in createopts:
3100 hgvfs.mkdir(b'cache')
3126 hgvfs.mkdir(b'cache')
3101 hgvfs.mkdir(b'wcache')
3127 hgvfs.mkdir(b'wcache')
3102
3128
3103 if b'store' in requirements and 'sharedrepo' not in createopts:
3129 if b'store' in requirements and 'sharedrepo' not in createopts:
3104 hgvfs.mkdir(b'store')
3130 hgvfs.mkdir(b'store')
3105
3131
3106 # We create an invalid changelog outside the store so very old
3132 # We create an invalid changelog outside the store so very old
3107 # Mercurial versions (which didn't know about the requirements
3133 # Mercurial versions (which didn't know about the requirements
3108 # file) encounter an error on reading the changelog. This
3134 # file) encounter an error on reading the changelog. This
3109 # effectively locks out old clients and prevents them from
3135 # effectively locks out old clients and prevents them from
3110 # mucking with a repo in an unknown format.
3136 # mucking with a repo in an unknown format.
3111 #
3137 #
3112 # The revlog header has version 2, which won't be recognized by
3138 # The revlog header has version 2, which won't be recognized by
3113 # such old clients.
3139 # such old clients.
3114 hgvfs.append(b'00changelog.i',
3140 hgvfs.append(b'00changelog.i',
3115 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3141 b'\0\0\0\2 dummy changelog to prevent using the old repo '
3116 b'layout')
3142 b'layout')
3117
3143
3118 scmutil.writerequires(hgvfs, requirements)
3144 scmutil.writerequires(hgvfs, requirements)
3119
3145
3120 # Write out file telling readers where to find the shared store.
3146 # Write out file telling readers where to find the shared store.
3121 if 'sharedrepo' in createopts:
3147 if 'sharedrepo' in createopts:
3122 hgvfs.write(b'sharedpath', sharedpath)
3148 hgvfs.write(b'sharedpath', sharedpath)
3123
3149
3124 if createopts.get('shareditems'):
3150 if createopts.get('shareditems'):
3125 shared = b'\n'.join(sorted(createopts['shareditems'])) + b'\n'
3151 shared = b'\n'.join(sorted(createopts['shareditems'])) + b'\n'
3126 hgvfs.write(b'shared', shared)
3152 hgvfs.write(b'shared', shared)
3127
3153
3128 def poisonrepository(repo):
3154 def poisonrepository(repo):
3129 """Poison a repository instance so it can no longer be used."""
3155 """Poison a repository instance so it can no longer be used."""
3130 # Perform any cleanup on the instance.
3156 # Perform any cleanup on the instance.
3131 repo.close()
3157 repo.close()
3132
3158
3133 # Our strategy is to replace the type of the object with one that
3159 # Our strategy is to replace the type of the object with one that
3134 # has all attribute lookups result in error.
3160 # has all attribute lookups result in error.
3135 #
3161 #
3136 # But we have to allow the close() method because some constructors
3162 # But we have to allow the close() method because some constructors
3137 # of repos call close() on repo references.
3163 # of repos call close() on repo references.
3138 class poisonedrepository(object):
3164 class poisonedrepository(object):
3139 def __getattribute__(self, item):
3165 def __getattribute__(self, item):
3140 if item == r'close':
3166 if item == r'close':
3141 return object.__getattribute__(self, item)
3167 return object.__getattribute__(self, item)
3142
3168
3143 raise error.ProgrammingError('repo instances should not be used '
3169 raise error.ProgrammingError('repo instances should not be used '
3144 'after unshare')
3170 'after unshare')
3145
3171
3146 def close(self):
3172 def close(self):
3147 pass
3173 pass
3148
3174
3149 # We may have a repoview, which intercepts __setattr__. So be sure
3175 # We may have a repoview, which intercepts __setattr__. So be sure
3150 # we operate at the lowest level possible.
3176 # we operate at the lowest level possible.
3151 object.__setattr__(repo, r'__class__', poisonedrepository)
3177 object.__setattr__(repo, r'__class__', poisonedrepository)
@@ -1,654 +1,654 b''
1 # store.py - repository store handling for Mercurial
1 # store.py - repository store handling for Mercurial
2 #
2 #
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import errno
10 import errno
11 import functools
11 import functools
12 import hashlib
12 import hashlib
13 import os
13 import os
14 import stat
14 import stat
15
15
16 from .i18n import _
16 from .i18n import _
17 from . import (
17 from . import (
18 error,
18 error,
19 node,
19 node,
20 policy,
20 policy,
21 pycompat,
21 pycompat,
22 util,
22 util,
23 vfs as vfsmod,
23 vfs as vfsmod,
24 )
24 )
25
25
26 parsers = policy.importmod(r'parsers')
26 parsers = policy.importmod(r'parsers')
27 # how much bytes should be read from fncache in one read
27 # how much bytes should be read from fncache in one read
28 # It is done to prevent loading large fncache files into memory
28 # It is done to prevent loading large fncache files into memory
29 fncache_chunksize = 10 ** 6
29 fncache_chunksize = 10 ** 6
30
30
31 def _matchtrackedpath(path, matcher):
31 def _matchtrackedpath(path, matcher):
32 """parses a fncache entry and returns whether the entry is tracking a path
32 """parses a fncache entry and returns whether the entry is tracking a path
33 matched by matcher or not.
33 matched by matcher or not.
34
34
35 If matcher is None, returns True"""
35 If matcher is None, returns True"""
36
36
37 if matcher is None:
37 if matcher is None:
38 return True
38 return True
39 path = decodedir(path)
39 path = decodedir(path)
40 if path.startswith('data/'):
40 if path.startswith('data/'):
41 return matcher(path[len('data/'):-len('.i')])
41 return matcher(path[len('data/'):-len('.i')])
42 elif path.startswith('meta/'):
42 elif path.startswith('meta/'):
43 return matcher.visitdir(path[len('meta/'):-len('/00manifest.i')] or '.')
43 return matcher.visitdir(path[len('meta/'):-len('/00manifest.i')] or '.')
44
44
45 raise error.ProgrammingError("cannot decode path %s" % path)
45 raise error.ProgrammingError("cannot decode path %s" % path)
46
46
47 # This avoids a collision between a file named foo and a dir named
47 # This avoids a collision between a file named foo and a dir named
48 # foo.i or foo.d
48 # foo.i or foo.d
49 def _encodedir(path):
49 def _encodedir(path):
50 '''
50 '''
51 >>> _encodedir(b'data/foo.i')
51 >>> _encodedir(b'data/foo.i')
52 'data/foo.i'
52 'data/foo.i'
53 >>> _encodedir(b'data/foo.i/bla.i')
53 >>> _encodedir(b'data/foo.i/bla.i')
54 'data/foo.i.hg/bla.i'
54 'data/foo.i.hg/bla.i'
55 >>> _encodedir(b'data/foo.i.hg/bla.i')
55 >>> _encodedir(b'data/foo.i.hg/bla.i')
56 'data/foo.i.hg.hg/bla.i'
56 'data/foo.i.hg.hg/bla.i'
57 >>> _encodedir(b'data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
57 >>> _encodedir(b'data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
58 'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
58 'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
59 '''
59 '''
60 return (path
60 return (path
61 .replace(".hg/", ".hg.hg/")
61 .replace(".hg/", ".hg.hg/")
62 .replace(".i/", ".i.hg/")
62 .replace(".i/", ".i.hg/")
63 .replace(".d/", ".d.hg/"))
63 .replace(".d/", ".d.hg/"))
64
64
65 encodedir = getattr(parsers, 'encodedir', _encodedir)
65 encodedir = getattr(parsers, 'encodedir', _encodedir)
66
66
67 def decodedir(path):
67 def decodedir(path):
68 '''
68 '''
69 >>> decodedir(b'data/foo.i')
69 >>> decodedir(b'data/foo.i')
70 'data/foo.i'
70 'data/foo.i'
71 >>> decodedir(b'data/foo.i.hg/bla.i')
71 >>> decodedir(b'data/foo.i.hg/bla.i')
72 'data/foo.i/bla.i'
72 'data/foo.i/bla.i'
73 >>> decodedir(b'data/foo.i.hg.hg/bla.i')
73 >>> decodedir(b'data/foo.i.hg.hg/bla.i')
74 'data/foo.i.hg/bla.i'
74 'data/foo.i.hg/bla.i'
75 '''
75 '''
76 if ".hg/" not in path:
76 if ".hg/" not in path:
77 return path
77 return path
78 return (path
78 return (path
79 .replace(".d.hg/", ".d/")
79 .replace(".d.hg/", ".d/")
80 .replace(".i.hg/", ".i/")
80 .replace(".i.hg/", ".i/")
81 .replace(".hg.hg/", ".hg/"))
81 .replace(".hg.hg/", ".hg/"))
82
82
83 def _reserved():
83 def _reserved():
84 ''' characters that are problematic for filesystems
84 ''' characters that are problematic for filesystems
85
85
86 * ascii escapes (0..31)
86 * ascii escapes (0..31)
87 * ascii hi (126..255)
87 * ascii hi (126..255)
88 * windows specials
88 * windows specials
89
89
90 these characters will be escaped by encodefunctions
90 these characters will be escaped by encodefunctions
91 '''
91 '''
92 winreserved = [ord(x) for x in u'\\:*?"<>|']
92 winreserved = [ord(x) for x in u'\\:*?"<>|']
93 for x in range(32):
93 for x in range(32):
94 yield x
94 yield x
95 for x in range(126, 256):
95 for x in range(126, 256):
96 yield x
96 yield x
97 for x in winreserved:
97 for x in winreserved:
98 yield x
98 yield x
99
99
100 def _buildencodefun():
100 def _buildencodefun():
101 '''
101 '''
102 >>> enc, dec = _buildencodefun()
102 >>> enc, dec = _buildencodefun()
103
103
104 >>> enc(b'nothing/special.txt')
104 >>> enc(b'nothing/special.txt')
105 'nothing/special.txt'
105 'nothing/special.txt'
106 >>> dec(b'nothing/special.txt')
106 >>> dec(b'nothing/special.txt')
107 'nothing/special.txt'
107 'nothing/special.txt'
108
108
109 >>> enc(b'HELLO')
109 >>> enc(b'HELLO')
110 '_h_e_l_l_o'
110 '_h_e_l_l_o'
111 >>> dec(b'_h_e_l_l_o')
111 >>> dec(b'_h_e_l_l_o')
112 'HELLO'
112 'HELLO'
113
113
114 >>> enc(b'hello:world?')
114 >>> enc(b'hello:world?')
115 'hello~3aworld~3f'
115 'hello~3aworld~3f'
116 >>> dec(b'hello~3aworld~3f')
116 >>> dec(b'hello~3aworld~3f')
117 'hello:world?'
117 'hello:world?'
118
118
119 >>> enc(b'the\\x07quick\\xADshot')
119 >>> enc(b'the\\x07quick\\xADshot')
120 'the~07quick~adshot'
120 'the~07quick~adshot'
121 >>> dec(b'the~07quick~adshot')
121 >>> dec(b'the~07quick~adshot')
122 'the\\x07quick\\xadshot'
122 'the\\x07quick\\xadshot'
123 '''
123 '''
124 e = '_'
124 e = '_'
125 xchr = pycompat.bytechr
125 xchr = pycompat.bytechr
126 asciistr = list(map(xchr, range(127)))
126 asciistr = list(map(xchr, range(127)))
127 capitals = list(range(ord("A"), ord("Z") + 1))
127 capitals = list(range(ord("A"), ord("Z") + 1))
128
128
129 cmap = dict((x, x) for x in asciistr)
129 cmap = dict((x, x) for x in asciistr)
130 for x in _reserved():
130 for x in _reserved():
131 cmap[xchr(x)] = "~%02x" % x
131 cmap[xchr(x)] = "~%02x" % x
132 for x in capitals + [ord(e)]:
132 for x in capitals + [ord(e)]:
133 cmap[xchr(x)] = e + xchr(x).lower()
133 cmap[xchr(x)] = e + xchr(x).lower()
134
134
135 dmap = {}
135 dmap = {}
136 for k, v in cmap.iteritems():
136 for k, v in cmap.iteritems():
137 dmap[v] = k
137 dmap[v] = k
138 def decode(s):
138 def decode(s):
139 i = 0
139 i = 0
140 while i < len(s):
140 while i < len(s):
141 for l in pycompat.xrange(1, 4):
141 for l in pycompat.xrange(1, 4):
142 try:
142 try:
143 yield dmap[s[i:i + l]]
143 yield dmap[s[i:i + l]]
144 i += l
144 i += l
145 break
145 break
146 except KeyError:
146 except KeyError:
147 pass
147 pass
148 else:
148 else:
149 raise KeyError
149 raise KeyError
150 return (lambda s: ''.join([cmap[s[c:c + 1]]
150 return (lambda s: ''.join([cmap[s[c:c + 1]]
151 for c in pycompat.xrange(len(s))]),
151 for c in pycompat.xrange(len(s))]),
152 lambda s: ''.join(list(decode(s))))
152 lambda s: ''.join(list(decode(s))))
153
153
154 _encodefname, _decodefname = _buildencodefun()
154 _encodefname, _decodefname = _buildencodefun()
155
155
156 def encodefilename(s):
156 def encodefilename(s):
157 '''
157 '''
158 >>> encodefilename(b'foo.i/bar.d/bla.hg/hi:world?/HELLO')
158 >>> encodefilename(b'foo.i/bar.d/bla.hg/hi:world?/HELLO')
159 'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
159 'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
160 '''
160 '''
161 return _encodefname(encodedir(s))
161 return _encodefname(encodedir(s))
162
162
163 def decodefilename(s):
163 def decodefilename(s):
164 '''
164 '''
165 >>> decodefilename(b'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
165 >>> decodefilename(b'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
166 'foo.i/bar.d/bla.hg/hi:world?/HELLO'
166 'foo.i/bar.d/bla.hg/hi:world?/HELLO'
167 '''
167 '''
168 return decodedir(_decodefname(s))
168 return decodedir(_decodefname(s))
169
169
170 def _buildlowerencodefun():
170 def _buildlowerencodefun():
171 '''
171 '''
172 >>> f = _buildlowerencodefun()
172 >>> f = _buildlowerencodefun()
173 >>> f(b'nothing/special.txt')
173 >>> f(b'nothing/special.txt')
174 'nothing/special.txt'
174 'nothing/special.txt'
175 >>> f(b'HELLO')
175 >>> f(b'HELLO')
176 'hello'
176 'hello'
177 >>> f(b'hello:world?')
177 >>> f(b'hello:world?')
178 'hello~3aworld~3f'
178 'hello~3aworld~3f'
179 >>> f(b'the\\x07quick\\xADshot')
179 >>> f(b'the\\x07quick\\xADshot')
180 'the~07quick~adshot'
180 'the~07quick~adshot'
181 '''
181 '''
182 xchr = pycompat.bytechr
182 xchr = pycompat.bytechr
183 cmap = dict([(xchr(x), xchr(x)) for x in pycompat.xrange(127)])
183 cmap = dict([(xchr(x), xchr(x)) for x in pycompat.xrange(127)])
184 for x in _reserved():
184 for x in _reserved():
185 cmap[xchr(x)] = "~%02x" % x
185 cmap[xchr(x)] = "~%02x" % x
186 for x in range(ord("A"), ord("Z") + 1):
186 for x in range(ord("A"), ord("Z") + 1):
187 cmap[xchr(x)] = xchr(x).lower()
187 cmap[xchr(x)] = xchr(x).lower()
188 def lowerencode(s):
188 def lowerencode(s):
189 return "".join([cmap[c] for c in pycompat.iterbytestr(s)])
189 return "".join([cmap[c] for c in pycompat.iterbytestr(s)])
190 return lowerencode
190 return lowerencode
191
191
192 lowerencode = getattr(parsers, 'lowerencode', None) or _buildlowerencodefun()
192 lowerencode = getattr(parsers, 'lowerencode', None) or _buildlowerencodefun()
193
193
194 # Windows reserved names: con, prn, aux, nul, com1..com9, lpt1..lpt9
194 # Windows reserved names: con, prn, aux, nul, com1..com9, lpt1..lpt9
195 _winres3 = ('aux', 'con', 'prn', 'nul') # length 3
195 _winres3 = ('aux', 'con', 'prn', 'nul') # length 3
196 _winres4 = ('com', 'lpt') # length 4 (with trailing 1..9)
196 _winres4 = ('com', 'lpt') # length 4 (with trailing 1..9)
197 def _auxencode(path, dotencode):
197 def _auxencode(path, dotencode):
198 '''
198 '''
199 Encodes filenames containing names reserved by Windows or which end in
199 Encodes filenames containing names reserved by Windows or which end in
200 period or space. Does not touch other single reserved characters c.
200 period or space. Does not touch other single reserved characters c.
201 Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
201 Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
202 Additionally encodes space or period at the beginning, if dotencode is
202 Additionally encodes space or period at the beginning, if dotencode is
203 True. Parameter path is assumed to be all lowercase.
203 True. Parameter path is assumed to be all lowercase.
204 A segment only needs encoding if a reserved name appears as a
204 A segment only needs encoding if a reserved name appears as a
205 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
205 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
206 doesn't need encoding.
206 doesn't need encoding.
207
207
208 >>> s = b'.foo/aux.txt/txt.aux/con/prn/nul/foo.'
208 >>> s = b'.foo/aux.txt/txt.aux/con/prn/nul/foo.'
209 >>> _auxencode(s.split(b'/'), True)
209 >>> _auxencode(s.split(b'/'), True)
210 ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
210 ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
211 >>> s = b'.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
211 >>> s = b'.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
212 >>> _auxencode(s.split(b'/'), False)
212 >>> _auxencode(s.split(b'/'), False)
213 ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
213 ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
214 >>> _auxencode([b'foo. '], True)
214 >>> _auxencode([b'foo. '], True)
215 ['foo.~20']
215 ['foo.~20']
216 >>> _auxencode([b' .foo'], True)
216 >>> _auxencode([b' .foo'], True)
217 ['~20.foo']
217 ['~20.foo']
218 '''
218 '''
219 for i, n in enumerate(path):
219 for i, n in enumerate(path):
220 if not n:
220 if not n:
221 continue
221 continue
222 if dotencode and n[0] in '. ':
222 if dotencode and n[0] in '. ':
223 n = "~%02x" % ord(n[0:1]) + n[1:]
223 n = "~%02x" % ord(n[0:1]) + n[1:]
224 path[i] = n
224 path[i] = n
225 else:
225 else:
226 l = n.find('.')
226 l = n.find('.')
227 if l == -1:
227 if l == -1:
228 l = len(n)
228 l = len(n)
229 if ((l == 3 and n[:3] in _winres3) or
229 if ((l == 3 and n[:3] in _winres3) or
230 (l == 4 and n[3:4] <= '9' and n[3:4] >= '1'
230 (l == 4 and n[3:4] <= '9' and n[3:4] >= '1'
231 and n[:3] in _winres4)):
231 and n[:3] in _winres4)):
232 # encode third letter ('aux' -> 'au~78')
232 # encode third letter ('aux' -> 'au~78')
233 ec = "~%02x" % ord(n[2:3])
233 ec = "~%02x" % ord(n[2:3])
234 n = n[0:2] + ec + n[3:]
234 n = n[0:2] + ec + n[3:]
235 path[i] = n
235 path[i] = n
236 if n[-1] in '. ':
236 if n[-1] in '. ':
237 # encode last period or space ('foo...' -> 'foo..~2e')
237 # encode last period or space ('foo...' -> 'foo..~2e')
238 path[i] = n[:-1] + "~%02x" % ord(n[-1:])
238 path[i] = n[:-1] + "~%02x" % ord(n[-1:])
239 return path
239 return path
240
240
241 _maxstorepathlen = 120
241 _maxstorepathlen = 120
242 _dirprefixlen = 8
242 _dirprefixlen = 8
243 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
243 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
244
244
245 def _hashencode(path, dotencode):
245 def _hashencode(path, dotencode):
246 digest = node.hex(hashlib.sha1(path).digest())
246 digest = node.hex(hashlib.sha1(path).digest())
247 le = lowerencode(path[5:]).split('/') # skips prefix 'data/' or 'meta/'
247 le = lowerencode(path[5:]).split('/') # skips prefix 'data/' or 'meta/'
248 parts = _auxencode(le, dotencode)
248 parts = _auxencode(le, dotencode)
249 basename = parts[-1]
249 basename = parts[-1]
250 _root, ext = os.path.splitext(basename)
250 _root, ext = os.path.splitext(basename)
251 sdirs = []
251 sdirs = []
252 sdirslen = 0
252 sdirslen = 0
253 for p in parts[:-1]:
253 for p in parts[:-1]:
254 d = p[:_dirprefixlen]
254 d = p[:_dirprefixlen]
255 if d[-1] in '. ':
255 if d[-1] in '. ':
256 # Windows can't access dirs ending in period or space
256 # Windows can't access dirs ending in period or space
257 d = d[:-1] + '_'
257 d = d[:-1] + '_'
258 if sdirslen == 0:
258 if sdirslen == 0:
259 t = len(d)
259 t = len(d)
260 else:
260 else:
261 t = sdirslen + 1 + len(d)
261 t = sdirslen + 1 + len(d)
262 if t > _maxshortdirslen:
262 if t > _maxshortdirslen:
263 break
263 break
264 sdirs.append(d)
264 sdirs.append(d)
265 sdirslen = t
265 sdirslen = t
266 dirs = '/'.join(sdirs)
266 dirs = '/'.join(sdirs)
267 if len(dirs) > 0:
267 if len(dirs) > 0:
268 dirs += '/'
268 dirs += '/'
269 res = 'dh/' + dirs + digest + ext
269 res = 'dh/' + dirs + digest + ext
270 spaceleft = _maxstorepathlen - len(res)
270 spaceleft = _maxstorepathlen - len(res)
271 if spaceleft > 0:
271 if spaceleft > 0:
272 filler = basename[:spaceleft]
272 filler = basename[:spaceleft]
273 res = 'dh/' + dirs + filler + digest + ext
273 res = 'dh/' + dirs + filler + digest + ext
274 return res
274 return res
275
275
276 def _hybridencode(path, dotencode):
276 def _hybridencode(path, dotencode):
277 '''encodes path with a length limit
277 '''encodes path with a length limit
278
278
279 Encodes all paths that begin with 'data/', according to the following.
279 Encodes all paths that begin with 'data/', according to the following.
280
280
281 Default encoding (reversible):
281 Default encoding (reversible):
282
282
283 Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
283 Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
284 characters are encoded as '~xx', where xx is the two digit hex code
284 characters are encoded as '~xx', where xx is the two digit hex code
285 of the character (see encodefilename).
285 of the character (see encodefilename).
286 Relevant path components consisting of Windows reserved filenames are
286 Relevant path components consisting of Windows reserved filenames are
287 masked by encoding the third character ('aux' -> 'au~78', see _auxencode).
287 masked by encoding the third character ('aux' -> 'au~78', see _auxencode).
288
288
289 Hashed encoding (not reversible):
289 Hashed encoding (not reversible):
290
290
291 If the default-encoded path is longer than _maxstorepathlen, a
291 If the default-encoded path is longer than _maxstorepathlen, a
292 non-reversible hybrid hashing of the path is done instead.
292 non-reversible hybrid hashing of the path is done instead.
293 This encoding uses up to _dirprefixlen characters of all directory
293 This encoding uses up to _dirprefixlen characters of all directory
294 levels of the lowerencoded path, but not more levels than can fit into
294 levels of the lowerencoded path, but not more levels than can fit into
295 _maxshortdirslen.
295 _maxshortdirslen.
296 Then follows the filler followed by the sha digest of the full path.
296 Then follows the filler followed by the sha digest of the full path.
297 The filler is the beginning of the basename of the lowerencoded path
297 The filler is the beginning of the basename of the lowerencoded path
298 (the basename is everything after the last path separator). The filler
298 (the basename is everything after the last path separator). The filler
299 is as long as possible, filling in characters from the basename until
299 is as long as possible, filling in characters from the basename until
300 the encoded path has _maxstorepathlen characters (or all chars of the
300 the encoded path has _maxstorepathlen characters (or all chars of the
301 basename have been taken).
301 basename have been taken).
302 The extension (e.g. '.i' or '.d') is preserved.
302 The extension (e.g. '.i' or '.d') is preserved.
303
303
304 The string 'data/' at the beginning is replaced with 'dh/', if the hashed
304 The string 'data/' at the beginning is replaced with 'dh/', if the hashed
305 encoding was used.
305 encoding was used.
306 '''
306 '''
307 path = encodedir(path)
307 path = encodedir(path)
308 ef = _encodefname(path).split('/')
308 ef = _encodefname(path).split('/')
309 res = '/'.join(_auxencode(ef, dotencode))
309 res = '/'.join(_auxencode(ef, dotencode))
310 if len(res) > _maxstorepathlen:
310 if len(res) > _maxstorepathlen:
311 res = _hashencode(path, dotencode)
311 res = _hashencode(path, dotencode)
312 return res
312 return res
313
313
314 def _pathencode(path):
314 def _pathencode(path):
315 de = encodedir(path)
315 de = encodedir(path)
316 if len(path) > _maxstorepathlen:
316 if len(path) > _maxstorepathlen:
317 return _hashencode(de, True)
317 return _hashencode(de, True)
318 ef = _encodefname(de).split('/')
318 ef = _encodefname(de).split('/')
319 res = '/'.join(_auxencode(ef, True))
319 res = '/'.join(_auxencode(ef, True))
320 if len(res) > _maxstorepathlen:
320 if len(res) > _maxstorepathlen:
321 return _hashencode(de, True)
321 return _hashencode(de, True)
322 return res
322 return res
323
323
324 _pathencode = getattr(parsers, 'pathencode', _pathencode)
324 _pathencode = getattr(parsers, 'pathencode', _pathencode)
325
325
326 def _plainhybridencode(f):
326 def _plainhybridencode(f):
327 return _hybridencode(f, False)
327 return _hybridencode(f, False)
328
328
329 def _calcmode(vfs):
329 def _calcmode(vfs):
330 try:
330 try:
331 # files in .hg/ will be created using this mode
331 # files in .hg/ will be created using this mode
332 mode = vfs.stat().st_mode
332 mode = vfs.stat().st_mode
333 # avoid some useless chmods
333 # avoid some useless chmods
334 if (0o777 & ~util.umask) == (0o777 & mode):
334 if (0o777 & ~util.umask) == (0o777 & mode):
335 mode = None
335 mode = None
336 except OSError:
336 except OSError:
337 mode = None
337 mode = None
338 return mode
338 return mode
339
339
340 _data = ('narrowspec data meta 00manifest.d 00manifest.i'
340 _data = ('bookmarks narrowspec data meta 00manifest.d 00manifest.i'
341 ' 00changelog.d 00changelog.i phaseroots obsstore')
341 ' 00changelog.d 00changelog.i phaseroots obsstore')
342
342
343 def isrevlog(f, kind, st):
343 def isrevlog(f, kind, st):
344 return kind == stat.S_IFREG and f[-2:] in ('.i', '.d')
344 return kind == stat.S_IFREG and f[-2:] in ('.i', '.d')
345
345
346 class basicstore(object):
346 class basicstore(object):
347 '''base class for local repository stores'''
347 '''base class for local repository stores'''
348 def __init__(self, path, vfstype):
348 def __init__(self, path, vfstype):
349 vfs = vfstype(path)
349 vfs = vfstype(path)
350 self.path = vfs.base
350 self.path = vfs.base
351 self.createmode = _calcmode(vfs)
351 self.createmode = _calcmode(vfs)
352 vfs.createmode = self.createmode
352 vfs.createmode = self.createmode
353 self.rawvfs = vfs
353 self.rawvfs = vfs
354 self.vfs = vfsmod.filtervfs(vfs, encodedir)
354 self.vfs = vfsmod.filtervfs(vfs, encodedir)
355 self.opener = self.vfs
355 self.opener = self.vfs
356
356
357 def join(self, f):
357 def join(self, f):
358 return self.path + '/' + encodedir(f)
358 return self.path + '/' + encodedir(f)
359
359
360 def _walk(self, relpath, recurse, filefilter=isrevlog):
360 def _walk(self, relpath, recurse, filefilter=isrevlog):
361 '''yields (unencoded, encoded, size)'''
361 '''yields (unencoded, encoded, size)'''
362 path = self.path
362 path = self.path
363 if relpath:
363 if relpath:
364 path += '/' + relpath
364 path += '/' + relpath
365 striplen = len(self.path) + 1
365 striplen = len(self.path) + 1
366 l = []
366 l = []
367 if self.rawvfs.isdir(path):
367 if self.rawvfs.isdir(path):
368 visit = [path]
368 visit = [path]
369 readdir = self.rawvfs.readdir
369 readdir = self.rawvfs.readdir
370 while visit:
370 while visit:
371 p = visit.pop()
371 p = visit.pop()
372 for f, kind, st in readdir(p, stat=True):
372 for f, kind, st in readdir(p, stat=True):
373 fp = p + '/' + f
373 fp = p + '/' + f
374 if filefilter(f, kind, st):
374 if filefilter(f, kind, st):
375 n = util.pconvert(fp[striplen:])
375 n = util.pconvert(fp[striplen:])
376 l.append((decodedir(n), n, st.st_size))
376 l.append((decodedir(n), n, st.st_size))
377 elif kind == stat.S_IFDIR and recurse:
377 elif kind == stat.S_IFDIR and recurse:
378 visit.append(fp)
378 visit.append(fp)
379 l.sort()
379 l.sort()
380 return l
380 return l
381
381
382 def datafiles(self, matcher=None):
382 def datafiles(self, matcher=None):
383 return self._walk('data', True) + self._walk('meta', True)
383 return self._walk('data', True) + self._walk('meta', True)
384
384
385 def topfiles(self):
385 def topfiles(self):
386 # yield manifest before changelog
386 # yield manifest before changelog
387 return reversed(self._walk('', False))
387 return reversed(self._walk('', False))
388
388
389 def walk(self, matcher=None):
389 def walk(self, matcher=None):
390 '''yields (unencoded, encoded, size)
390 '''yields (unencoded, encoded, size)
391
391
392 if a matcher is passed, storage files of only those tracked paths
392 if a matcher is passed, storage files of only those tracked paths
393 are passed with matches the matcher
393 are passed with matches the matcher
394 '''
394 '''
395 # yield data files first
395 # yield data files first
396 for x in self.datafiles(matcher):
396 for x in self.datafiles(matcher):
397 yield x
397 yield x
398 for x in self.topfiles():
398 for x in self.topfiles():
399 yield x
399 yield x
400
400
401 def copylist(self):
401 def copylist(self):
402 return ['requires'] + _data.split()
402 return ['requires'] + _data.split()
403
403
404 def write(self, tr):
404 def write(self, tr):
405 pass
405 pass
406
406
407 def invalidatecaches(self):
407 def invalidatecaches(self):
408 pass
408 pass
409
409
410 def markremoved(self, fn):
410 def markremoved(self, fn):
411 pass
411 pass
412
412
413 def __contains__(self, path):
413 def __contains__(self, path):
414 '''Checks if the store contains path'''
414 '''Checks if the store contains path'''
415 path = "/".join(("data", path))
415 path = "/".join(("data", path))
416 # file?
416 # file?
417 if self.vfs.exists(path + ".i"):
417 if self.vfs.exists(path + ".i"):
418 return True
418 return True
419 # dir?
419 # dir?
420 if not path.endswith("/"):
420 if not path.endswith("/"):
421 path = path + "/"
421 path = path + "/"
422 return self.vfs.exists(path)
422 return self.vfs.exists(path)
423
423
424 class encodedstore(basicstore):
424 class encodedstore(basicstore):
425 def __init__(self, path, vfstype):
425 def __init__(self, path, vfstype):
426 vfs = vfstype(path + '/store')
426 vfs = vfstype(path + '/store')
427 self.path = vfs.base
427 self.path = vfs.base
428 self.createmode = _calcmode(vfs)
428 self.createmode = _calcmode(vfs)
429 vfs.createmode = self.createmode
429 vfs.createmode = self.createmode
430 self.rawvfs = vfs
430 self.rawvfs = vfs
431 self.vfs = vfsmod.filtervfs(vfs, encodefilename)
431 self.vfs = vfsmod.filtervfs(vfs, encodefilename)
432 self.opener = self.vfs
432 self.opener = self.vfs
433
433
434 def datafiles(self, matcher=None):
434 def datafiles(self, matcher=None):
435 for a, b, size in super(encodedstore, self).datafiles():
435 for a, b, size in super(encodedstore, self).datafiles():
436 try:
436 try:
437 a = decodefilename(a)
437 a = decodefilename(a)
438 except KeyError:
438 except KeyError:
439 a = None
439 a = None
440 if a is not None and not _matchtrackedpath(a, matcher):
440 if a is not None and not _matchtrackedpath(a, matcher):
441 continue
441 continue
442 yield a, b, size
442 yield a, b, size
443
443
444 def join(self, f):
444 def join(self, f):
445 return self.path + '/' + encodefilename(f)
445 return self.path + '/' + encodefilename(f)
446
446
447 def copylist(self):
447 def copylist(self):
448 return (['requires', '00changelog.i'] +
448 return (['requires', '00changelog.i'] +
449 ['store/' + f for f in _data.split()])
449 ['store/' + f for f in _data.split()])
450
450
451 class fncache(object):
451 class fncache(object):
452 # the filename used to be partially encoded
452 # the filename used to be partially encoded
453 # hence the encodedir/decodedir dance
453 # hence the encodedir/decodedir dance
454 def __init__(self, vfs):
454 def __init__(self, vfs):
455 self.vfs = vfs
455 self.vfs = vfs
456 self.entries = None
456 self.entries = None
457 self._dirty = False
457 self._dirty = False
458 # set of new additions to fncache
458 # set of new additions to fncache
459 self.addls = set()
459 self.addls = set()
460
460
461 def _load(self):
461 def _load(self):
462 '''fill the entries from the fncache file'''
462 '''fill the entries from the fncache file'''
463 self._dirty = False
463 self._dirty = False
464 try:
464 try:
465 fp = self.vfs('fncache', mode='rb')
465 fp = self.vfs('fncache', mode='rb')
466 except IOError:
466 except IOError:
467 # skip nonexistent file
467 # skip nonexistent file
468 self.entries = set()
468 self.entries = set()
469 return
469 return
470
470
471 self.entries = set()
471 self.entries = set()
472 chunk = b''
472 chunk = b''
473 for c in iter(functools.partial(fp.read, fncache_chunksize), b''):
473 for c in iter(functools.partial(fp.read, fncache_chunksize), b''):
474 chunk += c
474 chunk += c
475 try:
475 try:
476 p = chunk.rindex(b'\n')
476 p = chunk.rindex(b'\n')
477 self.entries.update(decodedir(chunk[:p + 1]).splitlines())
477 self.entries.update(decodedir(chunk[:p + 1]).splitlines())
478 chunk = chunk[p + 1:]
478 chunk = chunk[p + 1:]
479 except ValueError:
479 except ValueError:
480 # substring '\n' not found, maybe the entry is bigger than the
480 # substring '\n' not found, maybe the entry is bigger than the
481 # chunksize, so let's keep iterating
481 # chunksize, so let's keep iterating
482 pass
482 pass
483
483
484 if chunk:
484 if chunk:
485 raise error.Abort(_("fncache does not ends with a newline"),
485 raise error.Abort(_("fncache does not ends with a newline"),
486 hint=_("use 'hg debugrebuildfncache' to rebuild"
486 hint=_("use 'hg debugrebuildfncache' to rebuild"
487 " the fncache"))
487 " the fncache"))
488 self._checkentries(fp)
488 self._checkentries(fp)
489 fp.close()
489 fp.close()
490
490
491 def _checkentries(self, fp):
491 def _checkentries(self, fp):
492 """ make sure there is no empty string in entries """
492 """ make sure there is no empty string in entries """
493 if '' in self.entries:
493 if '' in self.entries:
494 fp.seek(0)
494 fp.seek(0)
495 for n, line in enumerate(util.iterfile(fp)):
495 for n, line in enumerate(util.iterfile(fp)):
496 if not line.rstrip('\n'):
496 if not line.rstrip('\n'):
497 t = _('invalid entry in fncache, line %d') % (n + 1)
497 t = _('invalid entry in fncache, line %d') % (n + 1)
498 raise error.Abort(t)
498 raise error.Abort(t)
499
499
500 def write(self, tr):
500 def write(self, tr):
501 if self._dirty:
501 if self._dirty:
502 assert self.entries is not None
502 assert self.entries is not None
503 self.entries = self.entries | self.addls
503 self.entries = self.entries | self.addls
504 self.addls = set()
504 self.addls = set()
505 tr.addbackup('fncache')
505 tr.addbackup('fncache')
506 fp = self.vfs('fncache', mode='wb', atomictemp=True)
506 fp = self.vfs('fncache', mode='wb', atomictemp=True)
507 if self.entries:
507 if self.entries:
508 fp.write(encodedir('\n'.join(self.entries) + '\n'))
508 fp.write(encodedir('\n'.join(self.entries) + '\n'))
509 fp.close()
509 fp.close()
510 self._dirty = False
510 self._dirty = False
511 if self.addls:
511 if self.addls:
512 # if we have just new entries, let's append them to the fncache
512 # if we have just new entries, let's append them to the fncache
513 tr.addbackup('fncache')
513 tr.addbackup('fncache')
514 fp = self.vfs('fncache', mode='ab', atomictemp=True)
514 fp = self.vfs('fncache', mode='ab', atomictemp=True)
515 if self.addls:
515 if self.addls:
516 fp.write(encodedir('\n'.join(self.addls) + '\n'))
516 fp.write(encodedir('\n'.join(self.addls) + '\n'))
517 fp.close()
517 fp.close()
518 self.entries = None
518 self.entries = None
519 self.addls = set()
519 self.addls = set()
520
520
521 def add(self, fn):
521 def add(self, fn):
522 if self.entries is None:
522 if self.entries is None:
523 self._load()
523 self._load()
524 if fn not in self.entries:
524 if fn not in self.entries:
525 self.addls.add(fn)
525 self.addls.add(fn)
526
526
527 def remove(self, fn):
527 def remove(self, fn):
528 if self.entries is None:
528 if self.entries is None:
529 self._load()
529 self._load()
530 if fn in self.addls:
530 if fn in self.addls:
531 self.addls.remove(fn)
531 self.addls.remove(fn)
532 return
532 return
533 try:
533 try:
534 self.entries.remove(fn)
534 self.entries.remove(fn)
535 self._dirty = True
535 self._dirty = True
536 except KeyError:
536 except KeyError:
537 pass
537 pass
538
538
539 def __contains__(self, fn):
539 def __contains__(self, fn):
540 if fn in self.addls:
540 if fn in self.addls:
541 return True
541 return True
542 if self.entries is None:
542 if self.entries is None:
543 self._load()
543 self._load()
544 return fn in self.entries
544 return fn in self.entries
545
545
546 def __iter__(self):
546 def __iter__(self):
547 if self.entries is None:
547 if self.entries is None:
548 self._load()
548 self._load()
549 return iter(self.entries | self.addls)
549 return iter(self.entries | self.addls)
550
550
551 class _fncachevfs(vfsmod.proxyvfs):
551 class _fncachevfs(vfsmod.proxyvfs):
552 def __init__(self, vfs, fnc, encode):
552 def __init__(self, vfs, fnc, encode):
553 vfsmod.proxyvfs.__init__(self, vfs)
553 vfsmod.proxyvfs.__init__(self, vfs)
554 self.fncache = fnc
554 self.fncache = fnc
555 self.encode = encode
555 self.encode = encode
556
556
557 def __call__(self, path, mode='r', *args, **kw):
557 def __call__(self, path, mode='r', *args, **kw):
558 encoded = self.encode(path)
558 encoded = self.encode(path)
559 if mode not in ('r', 'rb') and (path.startswith('data/') or
559 if mode not in ('r', 'rb') and (path.startswith('data/') or
560 path.startswith('meta/')):
560 path.startswith('meta/')):
561 # do not trigger a fncache load when adding a file that already is
561 # do not trigger a fncache load when adding a file that already is
562 # known to exist.
562 # known to exist.
563 notload = self.fncache.entries is None and self.vfs.exists(encoded)
563 notload = self.fncache.entries is None and self.vfs.exists(encoded)
564 if notload and 'a' in mode and not self.vfs.stat(encoded).st_size:
564 if notload and 'a' in mode and not self.vfs.stat(encoded).st_size:
565 # when appending to an existing file, if the file has size zero,
565 # when appending to an existing file, if the file has size zero,
566 # it should be considered as missing. Such zero-size files are
566 # it should be considered as missing. Such zero-size files are
567 # the result of truncation when a transaction is aborted.
567 # the result of truncation when a transaction is aborted.
568 notload = False
568 notload = False
569 if not notload:
569 if not notload:
570 self.fncache.add(path)
570 self.fncache.add(path)
571 return self.vfs(encoded, mode, *args, **kw)
571 return self.vfs(encoded, mode, *args, **kw)
572
572
573 def join(self, path):
573 def join(self, path):
574 if path:
574 if path:
575 return self.vfs.join(self.encode(path))
575 return self.vfs.join(self.encode(path))
576 else:
576 else:
577 return self.vfs.join(path)
577 return self.vfs.join(path)
578
578
579 class fncachestore(basicstore):
579 class fncachestore(basicstore):
580 def __init__(self, path, vfstype, dotencode):
580 def __init__(self, path, vfstype, dotencode):
581 if dotencode:
581 if dotencode:
582 encode = _pathencode
582 encode = _pathencode
583 else:
583 else:
584 encode = _plainhybridencode
584 encode = _plainhybridencode
585 self.encode = encode
585 self.encode = encode
586 vfs = vfstype(path + '/store')
586 vfs = vfstype(path + '/store')
587 self.path = vfs.base
587 self.path = vfs.base
588 self.pathsep = self.path + '/'
588 self.pathsep = self.path + '/'
589 self.createmode = _calcmode(vfs)
589 self.createmode = _calcmode(vfs)
590 vfs.createmode = self.createmode
590 vfs.createmode = self.createmode
591 self.rawvfs = vfs
591 self.rawvfs = vfs
592 fnc = fncache(vfs)
592 fnc = fncache(vfs)
593 self.fncache = fnc
593 self.fncache = fnc
594 self.vfs = _fncachevfs(vfs, fnc, encode)
594 self.vfs = _fncachevfs(vfs, fnc, encode)
595 self.opener = self.vfs
595 self.opener = self.vfs
596
596
597 def join(self, f):
597 def join(self, f):
598 return self.pathsep + self.encode(f)
598 return self.pathsep + self.encode(f)
599
599
600 def getsize(self, path):
600 def getsize(self, path):
601 return self.rawvfs.stat(path).st_size
601 return self.rawvfs.stat(path).st_size
602
602
603 def datafiles(self, matcher=None):
603 def datafiles(self, matcher=None):
604 for f in sorted(self.fncache):
604 for f in sorted(self.fncache):
605 if not _matchtrackedpath(f, matcher):
605 if not _matchtrackedpath(f, matcher):
606 continue
606 continue
607 ef = self.encode(f)
607 ef = self.encode(f)
608 try:
608 try:
609 yield f, ef, self.getsize(ef)
609 yield f, ef, self.getsize(ef)
610 except OSError as err:
610 except OSError as err:
611 if err.errno != errno.ENOENT:
611 if err.errno != errno.ENOENT:
612 raise
612 raise
613
613
614 def copylist(self):
614 def copylist(self):
615 d = ('narrowspec data meta dh fncache phaseroots obsstore'
615 d = ('bookmarks narrowspec data meta dh fncache phaseroots obsstore'
616 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i')
616 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i')
617 return (['requires', '00changelog.i'] +
617 return (['requires', '00changelog.i'] +
618 ['store/' + f for f in d.split()])
618 ['store/' + f for f in d.split()])
619
619
620 def write(self, tr):
620 def write(self, tr):
621 self.fncache.write(tr)
621 self.fncache.write(tr)
622
622
623 def invalidatecaches(self):
623 def invalidatecaches(self):
624 self.fncache.entries = None
624 self.fncache.entries = None
625 self.fncache.addls = set()
625 self.fncache.addls = set()
626
626
627 def markremoved(self, fn):
627 def markremoved(self, fn):
628 self.fncache.remove(fn)
628 self.fncache.remove(fn)
629
629
630 def _exists(self, f):
630 def _exists(self, f):
631 ef = self.encode(f)
631 ef = self.encode(f)
632 try:
632 try:
633 self.getsize(ef)
633 self.getsize(ef)
634 return True
634 return True
635 except OSError as err:
635 except OSError as err:
636 if err.errno != errno.ENOENT:
636 if err.errno != errno.ENOENT:
637 raise
637 raise
638 # nonexistent entry
638 # nonexistent entry
639 return False
639 return False
640
640
641 def __contains__(self, path):
641 def __contains__(self, path):
642 '''Checks if the store contains path'''
642 '''Checks if the store contains path'''
643 path = "/".join(("data", path))
643 path = "/".join(("data", path))
644 # check for files (exact match)
644 # check for files (exact match)
645 e = path + '.i'
645 e = path + '.i'
646 if e in self.fncache and self._exists(e):
646 if e in self.fncache and self._exists(e):
647 return True
647 return True
648 # now check for directories (prefix match)
648 # now check for directories (prefix match)
649 if not path.endswith('/'):
649 if not path.endswith('/'):
650 path += '/'
650 path += '/'
651 for e in self.fncache:
651 for e in self.fncache:
652 if e.startswith(path) and self._exists(e):
652 if e.startswith(path) and self._exists(e):
653 return True
653 return True
654 return False
654 return False
@@ -1,3837 +1,3839 b''
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge another revision into working directory
17 merge merge another revision into working directory
18 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
26 (use 'hg help' for the full list of commands or 'hg -v' for details)
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge another revision into working directory
38 merge merge another revision into working directory
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 Extra extensions will be printed in help output in a non-reliable order since
47 Extra extensions will be printed in help output in a non-reliable order since
48 the extension is unknown.
48 the extension is unknown.
49 #if no-extraextensions
49 #if no-extraextensions
50
50
51 $ hg help
51 $ hg help
52 Mercurial Distributed SCM
52 Mercurial Distributed SCM
53
53
54 list of commands:
54 list of commands:
55
55
56 Repository creation:
56 Repository creation:
57
57
58 clone make a copy of an existing repository
58 clone make a copy of an existing repository
59 init create a new repository in the given directory
59 init create a new repository in the given directory
60
60
61 Remote repository management:
61 Remote repository management:
62
62
63 incoming show new changesets found in source
63 incoming show new changesets found in source
64 outgoing show changesets not found in the destination
64 outgoing show changesets not found in the destination
65 paths show aliases for remote repositories
65 paths show aliases for remote repositories
66 pull pull changes from the specified source
66 pull pull changes from the specified source
67 push push changes to the specified destination
67 push push changes to the specified destination
68 serve start stand-alone webserver
68 serve start stand-alone webserver
69
69
70 Change creation:
70 Change creation:
71
71
72 commit commit the specified files or all outstanding changes
72 commit commit the specified files or all outstanding changes
73
73
74 Change manipulation:
74 Change manipulation:
75
75
76 backout reverse effect of earlier changeset
76 backout reverse effect of earlier changeset
77 graft copy changes from other branches onto the current branch
77 graft copy changes from other branches onto the current branch
78 merge merge another revision into working directory
78 merge merge another revision into working directory
79
79
80 Change organization:
80 Change organization:
81
81
82 bookmarks create a new bookmark or list existing bookmarks
82 bookmarks create a new bookmark or list existing bookmarks
83 branch set or show the current branch name
83 branch set or show the current branch name
84 branches list repository named branches
84 branches list repository named branches
85 phase set or show the current phase name
85 phase set or show the current phase name
86 tag add one or more tags for the current or given revision
86 tag add one or more tags for the current or given revision
87 tags list repository tags
87 tags list repository tags
88
88
89 File content management:
89 File content management:
90
90
91 annotate show changeset information by line for each file
91 annotate show changeset information by line for each file
92 cat output the current or given revision of files
92 cat output the current or given revision of files
93 copy mark files as copied for the next commit
93 copy mark files as copied for the next commit
94 diff diff repository (or selected files)
94 diff diff repository (or selected files)
95 grep search revision history for a pattern in specified files
95 grep search revision history for a pattern in specified files
96
96
97 Change navigation:
97 Change navigation:
98
98
99 bisect subdivision search of changesets
99 bisect subdivision search of changesets
100 heads show branch heads
100 heads show branch heads
101 identify identify the working directory or specified revision
101 identify identify the working directory or specified revision
102 log show revision history of entire repository or files
102 log show revision history of entire repository or files
103
103
104 Working directory management:
104 Working directory management:
105
105
106 add add the specified files on the next commit
106 add add the specified files on the next commit
107 addremove add all new files, delete all missing files
107 addremove add all new files, delete all missing files
108 files list tracked files
108 files list tracked files
109 forget forget the specified files on the next commit
109 forget forget the specified files on the next commit
110 remove remove the specified files on the next commit
110 remove remove the specified files on the next commit
111 rename rename files; equivalent of copy + remove
111 rename rename files; equivalent of copy + remove
112 resolve redo merges or set/view the merge status of files
112 resolve redo merges or set/view the merge status of files
113 revert restore files to their checkout state
113 revert restore files to their checkout state
114 root print the root (top) of the current working directory
114 root print the root (top) of the current working directory
115 status show changed files in the working directory
115 status show changed files in the working directory
116 summary summarize working directory state
116 summary summarize working directory state
117 update update working directory (or switch revisions)
117 update update working directory (or switch revisions)
118
118
119 Change import/export:
119 Change import/export:
120
120
121 archive create an unversioned archive of a repository revision
121 archive create an unversioned archive of a repository revision
122 bundle create a bundle file
122 bundle create a bundle file
123 export dump the header and diffs for one or more changesets
123 export dump the header and diffs for one or more changesets
124 import import an ordered set of patches
124 import import an ordered set of patches
125 unbundle apply one or more bundle files
125 unbundle apply one or more bundle files
126
126
127 Repository maintenance:
127 Repository maintenance:
128
128
129 manifest output the current or given revision of the project manifest
129 manifest output the current or given revision of the project manifest
130 recover roll back an interrupted transaction
130 recover roll back an interrupted transaction
131 verify verify the integrity of the repository
131 verify verify the integrity of the repository
132
132
133 Help:
133 Help:
134
134
135 config show combined config settings from all hgrc files
135 config show combined config settings from all hgrc files
136 help show help for a given topic or a help overview
136 help show help for a given topic or a help overview
137 version output version and copyright information
137 version output version and copyright information
138
138
139 additional help topics:
139 additional help topics:
140
140
141 Mercurial identifiers:
141 Mercurial identifiers:
142
142
143 filesets Specifying File Sets
143 filesets Specifying File Sets
144 hgignore Syntax for Mercurial Ignore Files
144 hgignore Syntax for Mercurial Ignore Files
145 patterns File Name Patterns
145 patterns File Name Patterns
146 revisions Specifying Revisions
146 revisions Specifying Revisions
147 urls URL Paths
147 urls URL Paths
148
148
149 Mercurial output:
149 Mercurial output:
150
150
151 color Colorizing Outputs
151 color Colorizing Outputs
152 dates Date Formats
152 dates Date Formats
153 diffs Diff Formats
153 diffs Diff Formats
154 templating Template Usage
154 templating Template Usage
155
155
156 Mercurial configuration:
156 Mercurial configuration:
157
157
158 config Configuration Files
158 config Configuration Files
159 environment Environment Variables
159 environment Environment Variables
160 extensions Using Additional Features
160 extensions Using Additional Features
161 flags Command-line flags
161 flags Command-line flags
162 hgweb Configuring hgweb
162 hgweb Configuring hgweb
163 merge-tools Merge Tools
163 merge-tools Merge Tools
164 pager Pager Support
164 pager Pager Support
165
165
166 Concepts:
166 Concepts:
167
167
168 bundlespec Bundle File Formats
168 bundlespec Bundle File Formats
169 glossary Glossary
169 glossary Glossary
170 phases Working with Phases
170 phases Working with Phases
171 subrepos Subrepositories
171 subrepos Subrepositories
172
172
173 Miscellaneous:
173 Miscellaneous:
174
174
175 deprecated Deprecated Features
175 deprecated Deprecated Features
176 internals Technical implementation topics
176 internals Technical implementation topics
177 scripting Using Mercurial from scripts and automation
177 scripting Using Mercurial from scripts and automation
178
178
179 (use 'hg help -v' to show built-in aliases and global options)
179 (use 'hg help -v' to show built-in aliases and global options)
180
180
181 $ hg -q help
181 $ hg -q help
182 Repository creation:
182 Repository creation:
183
183
184 clone make a copy of an existing repository
184 clone make a copy of an existing repository
185 init create a new repository in the given directory
185 init create a new repository in the given directory
186
186
187 Remote repository management:
187 Remote repository management:
188
188
189 incoming show new changesets found in source
189 incoming show new changesets found in source
190 outgoing show changesets not found in the destination
190 outgoing show changesets not found in the destination
191 paths show aliases for remote repositories
191 paths show aliases for remote repositories
192 pull pull changes from the specified source
192 pull pull changes from the specified source
193 push push changes to the specified destination
193 push push changes to the specified destination
194 serve start stand-alone webserver
194 serve start stand-alone webserver
195
195
196 Change creation:
196 Change creation:
197
197
198 commit commit the specified files or all outstanding changes
198 commit commit the specified files or all outstanding changes
199
199
200 Change manipulation:
200 Change manipulation:
201
201
202 backout reverse effect of earlier changeset
202 backout reverse effect of earlier changeset
203 graft copy changes from other branches onto the current branch
203 graft copy changes from other branches onto the current branch
204 merge merge another revision into working directory
204 merge merge another revision into working directory
205
205
206 Change organization:
206 Change organization:
207
207
208 bookmarks create a new bookmark or list existing bookmarks
208 bookmarks create a new bookmark or list existing bookmarks
209 branch set or show the current branch name
209 branch set or show the current branch name
210 branches list repository named branches
210 branches list repository named branches
211 phase set or show the current phase name
211 phase set or show the current phase name
212 tag add one or more tags for the current or given revision
212 tag add one or more tags for the current or given revision
213 tags list repository tags
213 tags list repository tags
214
214
215 File content management:
215 File content management:
216
216
217 annotate show changeset information by line for each file
217 annotate show changeset information by line for each file
218 cat output the current or given revision of files
218 cat output the current or given revision of files
219 copy mark files as copied for the next commit
219 copy mark files as copied for the next commit
220 diff diff repository (or selected files)
220 diff diff repository (or selected files)
221 grep search revision history for a pattern in specified files
221 grep search revision history for a pattern in specified files
222
222
223 Change navigation:
223 Change navigation:
224
224
225 bisect subdivision search of changesets
225 bisect subdivision search of changesets
226 heads show branch heads
226 heads show branch heads
227 identify identify the working directory or specified revision
227 identify identify the working directory or specified revision
228 log show revision history of entire repository or files
228 log show revision history of entire repository or files
229
229
230 Working directory management:
230 Working directory management:
231
231
232 add add the specified files on the next commit
232 add add the specified files on the next commit
233 addremove add all new files, delete all missing files
233 addremove add all new files, delete all missing files
234 files list tracked files
234 files list tracked files
235 forget forget the specified files on the next commit
235 forget forget the specified files on the next commit
236 remove remove the specified files on the next commit
236 remove remove the specified files on the next commit
237 rename rename files; equivalent of copy + remove
237 rename rename files; equivalent of copy + remove
238 resolve redo merges or set/view the merge status of files
238 resolve redo merges or set/view the merge status of files
239 revert restore files to their checkout state
239 revert restore files to their checkout state
240 root print the root (top) of the current working directory
240 root print the root (top) of the current working directory
241 status show changed files in the working directory
241 status show changed files in the working directory
242 summary summarize working directory state
242 summary summarize working directory state
243 update update working directory (or switch revisions)
243 update update working directory (or switch revisions)
244
244
245 Change import/export:
245 Change import/export:
246
246
247 archive create an unversioned archive of a repository revision
247 archive create an unversioned archive of a repository revision
248 bundle create a bundle file
248 bundle create a bundle file
249 export dump the header and diffs for one or more changesets
249 export dump the header and diffs for one or more changesets
250 import import an ordered set of patches
250 import import an ordered set of patches
251 unbundle apply one or more bundle files
251 unbundle apply one or more bundle files
252
252
253 Repository maintenance:
253 Repository maintenance:
254
254
255 manifest output the current or given revision of the project manifest
255 manifest output the current or given revision of the project manifest
256 recover roll back an interrupted transaction
256 recover roll back an interrupted transaction
257 verify verify the integrity of the repository
257 verify verify the integrity of the repository
258
258
259 Help:
259 Help:
260
260
261 config show combined config settings from all hgrc files
261 config show combined config settings from all hgrc files
262 help show help for a given topic or a help overview
262 help show help for a given topic or a help overview
263 version output version and copyright information
263 version output version and copyright information
264
264
265 additional help topics:
265 additional help topics:
266
266
267 Mercurial identifiers:
267 Mercurial identifiers:
268
268
269 filesets Specifying File Sets
269 filesets Specifying File Sets
270 hgignore Syntax for Mercurial Ignore Files
270 hgignore Syntax for Mercurial Ignore Files
271 patterns File Name Patterns
271 patterns File Name Patterns
272 revisions Specifying Revisions
272 revisions Specifying Revisions
273 urls URL Paths
273 urls URL Paths
274
274
275 Mercurial output:
275 Mercurial output:
276
276
277 color Colorizing Outputs
277 color Colorizing Outputs
278 dates Date Formats
278 dates Date Formats
279 diffs Diff Formats
279 diffs Diff Formats
280 templating Template Usage
280 templating Template Usage
281
281
282 Mercurial configuration:
282 Mercurial configuration:
283
283
284 config Configuration Files
284 config Configuration Files
285 environment Environment Variables
285 environment Environment Variables
286 extensions Using Additional Features
286 extensions Using Additional Features
287 flags Command-line flags
287 flags Command-line flags
288 hgweb Configuring hgweb
288 hgweb Configuring hgweb
289 merge-tools Merge Tools
289 merge-tools Merge Tools
290 pager Pager Support
290 pager Pager Support
291
291
292 Concepts:
292 Concepts:
293
293
294 bundlespec Bundle File Formats
294 bundlespec Bundle File Formats
295 glossary Glossary
295 glossary Glossary
296 phases Working with Phases
296 phases Working with Phases
297 subrepos Subrepositories
297 subrepos Subrepositories
298
298
299 Miscellaneous:
299 Miscellaneous:
300
300
301 deprecated Deprecated Features
301 deprecated Deprecated Features
302 internals Technical implementation topics
302 internals Technical implementation topics
303 scripting Using Mercurial from scripts and automation
303 scripting Using Mercurial from scripts and automation
304
304
305 Test extension help:
305 Test extension help:
306 $ hg help extensions --config extensions.rebase= --config extensions.children=
306 $ hg help extensions --config extensions.rebase= --config extensions.children=
307 Using Additional Features
307 Using Additional Features
308 """""""""""""""""""""""""
308 """""""""""""""""""""""""
309
309
310 Mercurial has the ability to add new features through the use of
310 Mercurial has the ability to add new features through the use of
311 extensions. Extensions may add new commands, add options to existing
311 extensions. Extensions may add new commands, add options to existing
312 commands, change the default behavior of commands, or implement hooks.
312 commands, change the default behavior of commands, or implement hooks.
313
313
314 To enable the "foo" extension, either shipped with Mercurial or in the
314 To enable the "foo" extension, either shipped with Mercurial or in the
315 Python search path, create an entry for it in your configuration file,
315 Python search path, create an entry for it in your configuration file,
316 like this:
316 like this:
317
317
318 [extensions]
318 [extensions]
319 foo =
319 foo =
320
320
321 You may also specify the full path to an extension:
321 You may also specify the full path to an extension:
322
322
323 [extensions]
323 [extensions]
324 myfeature = ~/.hgext/myfeature.py
324 myfeature = ~/.hgext/myfeature.py
325
325
326 See 'hg help config' for more information on configuration files.
326 See 'hg help config' for more information on configuration files.
327
327
328 Extensions are not loaded by default for a variety of reasons: they can
328 Extensions are not loaded by default for a variety of reasons: they can
329 increase startup overhead; they may be meant for advanced usage only; they
329 increase startup overhead; they may be meant for advanced usage only; they
330 may provide potentially dangerous abilities (such as letting you destroy
330 may provide potentially dangerous abilities (such as letting you destroy
331 or modify history); they might not be ready for prime time; or they may
331 or modify history); they might not be ready for prime time; or they may
332 alter some usual behaviors of stock Mercurial. It is thus up to the user
332 alter some usual behaviors of stock Mercurial. It is thus up to the user
333 to activate extensions as needed.
333 to activate extensions as needed.
334
334
335 To explicitly disable an extension enabled in a configuration file of
335 To explicitly disable an extension enabled in a configuration file of
336 broader scope, prepend its path with !:
336 broader scope, prepend its path with !:
337
337
338 [extensions]
338 [extensions]
339 # disabling extension bar residing in /path/to/extension/bar.py
339 # disabling extension bar residing in /path/to/extension/bar.py
340 bar = !/path/to/extension/bar.py
340 bar = !/path/to/extension/bar.py
341 # ditto, but no path was supplied for extension baz
341 # ditto, but no path was supplied for extension baz
342 baz = !
342 baz = !
343
343
344 enabled extensions:
344 enabled extensions:
345
345
346 children command to display child changesets (DEPRECATED)
346 children command to display child changesets (DEPRECATED)
347 rebase command to move sets of revisions to a different ancestor
347 rebase command to move sets of revisions to a different ancestor
348
348
349 disabled extensions:
349 disabled extensions:
350
350
351 acl hooks for controlling repository access
351 acl hooks for controlling repository access
352 blackbox log repository events to a blackbox for debugging
352 blackbox log repository events to a blackbox for debugging
353 bugzilla hooks for integrating with the Bugzilla bug tracker
353 bugzilla hooks for integrating with the Bugzilla bug tracker
354 censor erase file content at a given revision
354 censor erase file content at a given revision
355 churn command to display statistics about repository history
355 churn command to display statistics about repository history
356 clonebundles advertise pre-generated bundles to seed clones
356 clonebundles advertise pre-generated bundles to seed clones
357 closehead close arbitrary heads without checking them out first
357 closehead close arbitrary heads without checking them out first
358 convert import revisions from foreign VCS repositories into
358 convert import revisions from foreign VCS repositories into
359 Mercurial
359 Mercurial
360 eol automatically manage newlines in repository files
360 eol automatically manage newlines in repository files
361 extdiff command to allow external programs to compare revisions
361 extdiff command to allow external programs to compare revisions
362 factotum http authentication with factotum
362 factotum http authentication with factotum
363 githelp try mapping git commands to Mercurial commands
363 githelp try mapping git commands to Mercurial commands
364 gpg commands to sign and verify changesets
364 gpg commands to sign and verify changesets
365 hgk browse the repository in a graphical way
365 hgk browse the repository in a graphical way
366 highlight syntax highlighting for hgweb (requires Pygments)
366 highlight syntax highlighting for hgweb (requires Pygments)
367 histedit interactive history editing
367 histedit interactive history editing
368 keyword expand keywords in tracked files
368 keyword expand keywords in tracked files
369 largefiles track large binary files
369 largefiles track large binary files
370 mq manage a stack of patches
370 mq manage a stack of patches
371 notify hooks for sending email push notifications
371 notify hooks for sending email push notifications
372 patchbomb command to send changesets as (a series of) patch emails
372 patchbomb command to send changesets as (a series of) patch emails
373 purge command to delete untracked files from the working
373 purge command to delete untracked files from the working
374 directory
374 directory
375 relink recreates hardlinks between repository clones
375 relink recreates hardlinks between repository clones
376 schemes extend schemes with shortcuts to repository swarms
376 schemes extend schemes with shortcuts to repository swarms
377 share share a common history between several working directories
377 share share a common history between several working directories
378 shelve save and restore changes to the working directory
378 shelve save and restore changes to the working directory
379 strip strip changesets and their descendants from history
379 strip strip changesets and their descendants from history
380 transplant command to transplant changesets from another branch
380 transplant command to transplant changesets from another branch
381 win32mbcs allow the use of MBCS paths with problematic encodings
381 win32mbcs allow the use of MBCS paths with problematic encodings
382 zeroconf discover and advertise repositories on the local network
382 zeroconf discover and advertise repositories on the local network
383
383
384 #endif
384 #endif
385
385
386 Verify that deprecated extensions are included if --verbose:
386 Verify that deprecated extensions are included if --verbose:
387
387
388 $ hg -v help extensions | grep children
388 $ hg -v help extensions | grep children
389 children command to display child changesets (DEPRECATED)
389 children command to display child changesets (DEPRECATED)
390
390
391 Verify that extension keywords appear in help templates
391 Verify that extension keywords appear in help templates
392
392
393 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
393 $ hg help --config extensions.transplant= templating|grep transplant > /dev/null
394
394
395 Test short command list with verbose option
395 Test short command list with verbose option
396
396
397 $ hg -v help shortlist
397 $ hg -v help shortlist
398 Mercurial Distributed SCM
398 Mercurial Distributed SCM
399
399
400 basic commands:
400 basic commands:
401
401
402 add add the specified files on the next commit
402 add add the specified files on the next commit
403 annotate, blame
403 annotate, blame
404 show changeset information by line for each file
404 show changeset information by line for each file
405 clone make a copy of an existing repository
405 clone make a copy of an existing repository
406 commit, ci commit the specified files or all outstanding changes
406 commit, ci commit the specified files or all outstanding changes
407 diff diff repository (or selected files)
407 diff diff repository (or selected files)
408 export dump the header and diffs for one or more changesets
408 export dump the header and diffs for one or more changesets
409 forget forget the specified files on the next commit
409 forget forget the specified files on the next commit
410 init create a new repository in the given directory
410 init create a new repository in the given directory
411 log, history show revision history of entire repository or files
411 log, history show revision history of entire repository or files
412 merge merge another revision into working directory
412 merge merge another revision into working directory
413 pull pull changes from the specified source
413 pull pull changes from the specified source
414 push push changes to the specified destination
414 push push changes to the specified destination
415 remove, rm remove the specified files on the next commit
415 remove, rm remove the specified files on the next commit
416 serve start stand-alone webserver
416 serve start stand-alone webserver
417 status, st show changed files in the working directory
417 status, st show changed files in the working directory
418 summary, sum summarize working directory state
418 summary, sum summarize working directory state
419 update, up, checkout, co
419 update, up, checkout, co
420 update working directory (or switch revisions)
420 update working directory (or switch revisions)
421
421
422 global options ([+] can be repeated):
422 global options ([+] can be repeated):
423
423
424 -R --repository REPO repository root directory or name of overlay bundle
424 -R --repository REPO repository root directory or name of overlay bundle
425 file
425 file
426 --cwd DIR change working directory
426 --cwd DIR change working directory
427 -y --noninteractive do not prompt, automatically pick the first choice for
427 -y --noninteractive do not prompt, automatically pick the first choice for
428 all prompts
428 all prompts
429 -q --quiet suppress output
429 -q --quiet suppress output
430 -v --verbose enable additional output
430 -v --verbose enable additional output
431 --color TYPE when to colorize (boolean, always, auto, never, or
431 --color TYPE when to colorize (boolean, always, auto, never, or
432 debug)
432 debug)
433 --config CONFIG [+] set/override config option (use 'section.name=value')
433 --config CONFIG [+] set/override config option (use 'section.name=value')
434 --debug enable debugging output
434 --debug enable debugging output
435 --debugger start debugger
435 --debugger start debugger
436 --encoding ENCODE set the charset encoding (default: ascii)
436 --encoding ENCODE set the charset encoding (default: ascii)
437 --encodingmode MODE set the charset encoding mode (default: strict)
437 --encodingmode MODE set the charset encoding mode (default: strict)
438 --traceback always print a traceback on exception
438 --traceback always print a traceback on exception
439 --time time how long the command takes
439 --time time how long the command takes
440 --profile print command execution profile
440 --profile print command execution profile
441 --version output version information and exit
441 --version output version information and exit
442 -h --help display help and exit
442 -h --help display help and exit
443 --hidden consider hidden changesets
443 --hidden consider hidden changesets
444 --pager TYPE when to paginate (boolean, always, auto, or never)
444 --pager TYPE when to paginate (boolean, always, auto, or never)
445 (default: auto)
445 (default: auto)
446
446
447 (use 'hg help' for the full list of commands)
447 (use 'hg help' for the full list of commands)
448
448
449 $ hg add -h
449 $ hg add -h
450 hg add [OPTION]... [FILE]...
450 hg add [OPTION]... [FILE]...
451
451
452 add the specified files on the next commit
452 add the specified files on the next commit
453
453
454 Schedule files to be version controlled and added to the repository.
454 Schedule files to be version controlled and added to the repository.
455
455
456 The files will be added to the repository at the next commit. To undo an
456 The files will be added to the repository at the next commit. To undo an
457 add before that, see 'hg forget'.
457 add before that, see 'hg forget'.
458
458
459 If no names are given, add all files to the repository (except files
459 If no names are given, add all files to the repository (except files
460 matching ".hgignore").
460 matching ".hgignore").
461
461
462 Returns 0 if all files are successfully added.
462 Returns 0 if all files are successfully added.
463
463
464 options ([+] can be repeated):
464 options ([+] can be repeated):
465
465
466 -I --include PATTERN [+] include names matching the given patterns
466 -I --include PATTERN [+] include names matching the given patterns
467 -X --exclude PATTERN [+] exclude names matching the given patterns
467 -X --exclude PATTERN [+] exclude names matching the given patterns
468 -S --subrepos recurse into subrepositories
468 -S --subrepos recurse into subrepositories
469 -n --dry-run do not perform actions, just print output
469 -n --dry-run do not perform actions, just print output
470
470
471 (some details hidden, use --verbose to show complete help)
471 (some details hidden, use --verbose to show complete help)
472
472
473 Verbose help for add
473 Verbose help for add
474
474
475 $ hg add -hv
475 $ hg add -hv
476 hg add [OPTION]... [FILE]...
476 hg add [OPTION]... [FILE]...
477
477
478 add the specified files on the next commit
478 add the specified files on the next commit
479
479
480 Schedule files to be version controlled and added to the repository.
480 Schedule files to be version controlled and added to the repository.
481
481
482 The files will be added to the repository at the next commit. To undo an
482 The files will be added to the repository at the next commit. To undo an
483 add before that, see 'hg forget'.
483 add before that, see 'hg forget'.
484
484
485 If no names are given, add all files to the repository (except files
485 If no names are given, add all files to the repository (except files
486 matching ".hgignore").
486 matching ".hgignore").
487
487
488 Examples:
488 Examples:
489
489
490 - New (unknown) files are added automatically by 'hg add':
490 - New (unknown) files are added automatically by 'hg add':
491
491
492 $ ls
492 $ ls
493 foo.c
493 foo.c
494 $ hg status
494 $ hg status
495 ? foo.c
495 ? foo.c
496 $ hg add
496 $ hg add
497 adding foo.c
497 adding foo.c
498 $ hg status
498 $ hg status
499 A foo.c
499 A foo.c
500
500
501 - Specific files to be added can be specified:
501 - Specific files to be added can be specified:
502
502
503 $ ls
503 $ ls
504 bar.c foo.c
504 bar.c foo.c
505 $ hg status
505 $ hg status
506 ? bar.c
506 ? bar.c
507 ? foo.c
507 ? foo.c
508 $ hg add bar.c
508 $ hg add bar.c
509 $ hg status
509 $ hg status
510 A bar.c
510 A bar.c
511 ? foo.c
511 ? foo.c
512
512
513 Returns 0 if all files are successfully added.
513 Returns 0 if all files are successfully added.
514
514
515 options ([+] can be repeated):
515 options ([+] can be repeated):
516
516
517 -I --include PATTERN [+] include names matching the given patterns
517 -I --include PATTERN [+] include names matching the given patterns
518 -X --exclude PATTERN [+] exclude names matching the given patterns
518 -X --exclude PATTERN [+] exclude names matching the given patterns
519 -S --subrepos recurse into subrepositories
519 -S --subrepos recurse into subrepositories
520 -n --dry-run do not perform actions, just print output
520 -n --dry-run do not perform actions, just print output
521
521
522 global options ([+] can be repeated):
522 global options ([+] can be repeated):
523
523
524 -R --repository REPO repository root directory or name of overlay bundle
524 -R --repository REPO repository root directory or name of overlay bundle
525 file
525 file
526 --cwd DIR change working directory
526 --cwd DIR change working directory
527 -y --noninteractive do not prompt, automatically pick the first choice for
527 -y --noninteractive do not prompt, automatically pick the first choice for
528 all prompts
528 all prompts
529 -q --quiet suppress output
529 -q --quiet suppress output
530 -v --verbose enable additional output
530 -v --verbose enable additional output
531 --color TYPE when to colorize (boolean, always, auto, never, or
531 --color TYPE when to colorize (boolean, always, auto, never, or
532 debug)
532 debug)
533 --config CONFIG [+] set/override config option (use 'section.name=value')
533 --config CONFIG [+] set/override config option (use 'section.name=value')
534 --debug enable debugging output
534 --debug enable debugging output
535 --debugger start debugger
535 --debugger start debugger
536 --encoding ENCODE set the charset encoding (default: ascii)
536 --encoding ENCODE set the charset encoding (default: ascii)
537 --encodingmode MODE set the charset encoding mode (default: strict)
537 --encodingmode MODE set the charset encoding mode (default: strict)
538 --traceback always print a traceback on exception
538 --traceback always print a traceback on exception
539 --time time how long the command takes
539 --time time how long the command takes
540 --profile print command execution profile
540 --profile print command execution profile
541 --version output version information and exit
541 --version output version information and exit
542 -h --help display help and exit
542 -h --help display help and exit
543 --hidden consider hidden changesets
543 --hidden consider hidden changesets
544 --pager TYPE when to paginate (boolean, always, auto, or never)
544 --pager TYPE when to paginate (boolean, always, auto, or never)
545 (default: auto)
545 (default: auto)
546
546
547 Test the textwidth config option
547 Test the textwidth config option
548
548
549 $ hg root -h --config ui.textwidth=50
549 $ hg root -h --config ui.textwidth=50
550 hg root
550 hg root
551
551
552 print the root (top) of the current working
552 print the root (top) of the current working
553 directory
553 directory
554
554
555 Print the root directory of the current
555 Print the root directory of the current
556 repository.
556 repository.
557
557
558 Returns 0 on success.
558 Returns 0 on success.
559
559
560 (some details hidden, use --verbose to show
560 (some details hidden, use --verbose to show
561 complete help)
561 complete help)
562
562
563 Test help option with version option
563 Test help option with version option
564
564
565 $ hg add -h --version
565 $ hg add -h --version
566 Mercurial Distributed SCM (version *) (glob)
566 Mercurial Distributed SCM (version *) (glob)
567 (see https://mercurial-scm.org for more information)
567 (see https://mercurial-scm.org for more information)
568
568
569 Copyright (C) 2005-* Matt Mackall and others (glob)
569 Copyright (C) 2005-* Matt Mackall and others (glob)
570 This is free software; see the source for copying conditions. There is NO
570 This is free software; see the source for copying conditions. There is NO
571 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
571 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
572
572
573 $ hg add --skjdfks
573 $ hg add --skjdfks
574 hg add: option --skjdfks not recognized
574 hg add: option --skjdfks not recognized
575 hg add [OPTION]... [FILE]...
575 hg add [OPTION]... [FILE]...
576
576
577 add the specified files on the next commit
577 add the specified files on the next commit
578
578
579 options ([+] can be repeated):
579 options ([+] can be repeated):
580
580
581 -I --include PATTERN [+] include names matching the given patterns
581 -I --include PATTERN [+] include names matching the given patterns
582 -X --exclude PATTERN [+] exclude names matching the given patterns
582 -X --exclude PATTERN [+] exclude names matching the given patterns
583 -S --subrepos recurse into subrepositories
583 -S --subrepos recurse into subrepositories
584 -n --dry-run do not perform actions, just print output
584 -n --dry-run do not perform actions, just print output
585
585
586 (use 'hg add -h' to show more help)
586 (use 'hg add -h' to show more help)
587 [255]
587 [255]
588
588
589 Test ambiguous command help
589 Test ambiguous command help
590
590
591 $ hg help ad
591 $ hg help ad
592 list of commands:
592 list of commands:
593
593
594 add add the specified files on the next commit
594 add add the specified files on the next commit
595 addremove add all new files, delete all missing files
595 addremove add all new files, delete all missing files
596
596
597 (use 'hg help -v ad' to show built-in aliases and global options)
597 (use 'hg help -v ad' to show built-in aliases and global options)
598
598
599 Test command without options
599 Test command without options
600
600
601 $ hg help verify
601 $ hg help verify
602 hg verify
602 hg verify
603
603
604 verify the integrity of the repository
604 verify the integrity of the repository
605
605
606 Verify the integrity of the current repository.
606 Verify the integrity of the current repository.
607
607
608 This will perform an extensive check of the repository's integrity,
608 This will perform an extensive check of the repository's integrity,
609 validating the hashes and checksums of each entry in the changelog,
609 validating the hashes and checksums of each entry in the changelog,
610 manifest, and tracked files, as well as the integrity of their crosslinks
610 manifest, and tracked files, as well as the integrity of their crosslinks
611 and indices.
611 and indices.
612
612
613 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
613 Please see https://mercurial-scm.org/wiki/RepositoryCorruption for more
614 information about recovery from corruption of the repository.
614 information about recovery from corruption of the repository.
615
615
616 Returns 0 on success, 1 if errors are encountered.
616 Returns 0 on success, 1 if errors are encountered.
617
617
618 options:
618 options:
619
619
620 (some details hidden, use --verbose to show complete help)
620 (some details hidden, use --verbose to show complete help)
621
621
622 $ hg help diff
622 $ hg help diff
623 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
623 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
624
624
625 diff repository (or selected files)
625 diff repository (or selected files)
626
626
627 Show differences between revisions for the specified files.
627 Show differences between revisions for the specified files.
628
628
629 Differences between files are shown using the unified diff format.
629 Differences between files are shown using the unified diff format.
630
630
631 Note:
631 Note:
632 'hg diff' may generate unexpected results for merges, as it will
632 'hg diff' may generate unexpected results for merges, as it will
633 default to comparing against the working directory's first parent
633 default to comparing against the working directory's first parent
634 changeset if no revisions are specified.
634 changeset if no revisions are specified.
635
635
636 When two revision arguments are given, then changes are shown between
636 When two revision arguments are given, then changes are shown between
637 those revisions. If only one revision is specified then that revision is
637 those revisions. If only one revision is specified then that revision is
638 compared to the working directory, and, when no revisions are specified,
638 compared to the working directory, and, when no revisions are specified,
639 the working directory files are compared to its first parent.
639 the working directory files are compared to its first parent.
640
640
641 Alternatively you can specify -c/--change with a revision to see the
641 Alternatively you can specify -c/--change with a revision to see the
642 changes in that changeset relative to its first parent.
642 changes in that changeset relative to its first parent.
643
643
644 Without the -a/--text option, diff will avoid generating diffs of files it
644 Without the -a/--text option, diff will avoid generating diffs of files it
645 detects as binary. With -a, diff will generate a diff anyway, probably
645 detects as binary. With -a, diff will generate a diff anyway, probably
646 with undesirable results.
646 with undesirable results.
647
647
648 Use the -g/--git option to generate diffs in the git extended diff format.
648 Use the -g/--git option to generate diffs in the git extended diff format.
649 For more information, read 'hg help diffs'.
649 For more information, read 'hg help diffs'.
650
650
651 Returns 0 on success.
651 Returns 0 on success.
652
652
653 options ([+] can be repeated):
653 options ([+] can be repeated):
654
654
655 -r --rev REV [+] revision
655 -r --rev REV [+] revision
656 -c --change REV change made by revision
656 -c --change REV change made by revision
657 -a --text treat all files as text
657 -a --text treat all files as text
658 -g --git use git extended diff format
658 -g --git use git extended diff format
659 --binary generate binary diffs in git mode (default)
659 --binary generate binary diffs in git mode (default)
660 --nodates omit dates from diff headers
660 --nodates omit dates from diff headers
661 --noprefix omit a/ and b/ prefixes from filenames
661 --noprefix omit a/ and b/ prefixes from filenames
662 -p --show-function show which function each change is in
662 -p --show-function show which function each change is in
663 --reverse produce a diff that undoes the changes
663 --reverse produce a diff that undoes the changes
664 -w --ignore-all-space ignore white space when comparing lines
664 -w --ignore-all-space ignore white space when comparing lines
665 -b --ignore-space-change ignore changes in the amount of white space
665 -b --ignore-space-change ignore changes in the amount of white space
666 -B --ignore-blank-lines ignore changes whose lines are all blank
666 -B --ignore-blank-lines ignore changes whose lines are all blank
667 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
667 -Z --ignore-space-at-eol ignore changes in whitespace at EOL
668 -U --unified NUM number of lines of context to show
668 -U --unified NUM number of lines of context to show
669 --stat output diffstat-style summary of changes
669 --stat output diffstat-style summary of changes
670 --root DIR produce diffs relative to subdirectory
670 --root DIR produce diffs relative to subdirectory
671 -I --include PATTERN [+] include names matching the given patterns
671 -I --include PATTERN [+] include names matching the given patterns
672 -X --exclude PATTERN [+] exclude names matching the given patterns
672 -X --exclude PATTERN [+] exclude names matching the given patterns
673 -S --subrepos recurse into subrepositories
673 -S --subrepos recurse into subrepositories
674
674
675 (some details hidden, use --verbose to show complete help)
675 (some details hidden, use --verbose to show complete help)
676
676
677 $ hg help status
677 $ hg help status
678 hg status [OPTION]... [FILE]...
678 hg status [OPTION]... [FILE]...
679
679
680 aliases: st
680 aliases: st
681
681
682 show changed files in the working directory
682 show changed files in the working directory
683
683
684 Show status of files in the repository. If names are given, only files
684 Show status of files in the repository. If names are given, only files
685 that match are shown. Files that are clean or ignored or the source of a
685 that match are shown. Files that are clean or ignored or the source of a
686 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
686 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
687 -C/--copies or -A/--all are given. Unless options described with "show
687 -C/--copies or -A/--all are given. Unless options described with "show
688 only ..." are given, the options -mardu are used.
688 only ..." are given, the options -mardu are used.
689
689
690 Option -q/--quiet hides untracked (unknown and ignored) files unless
690 Option -q/--quiet hides untracked (unknown and ignored) files unless
691 explicitly requested with -u/--unknown or -i/--ignored.
691 explicitly requested with -u/--unknown or -i/--ignored.
692
692
693 Note:
693 Note:
694 'hg status' may appear to disagree with diff if permissions have
694 'hg status' may appear to disagree with diff if permissions have
695 changed or a merge has occurred. The standard diff format does not
695 changed or a merge has occurred. The standard diff format does not
696 report permission changes and diff only reports changes relative to one
696 report permission changes and diff only reports changes relative to one
697 merge parent.
697 merge parent.
698
698
699 If one revision is given, it is used as the base revision. If two
699 If one revision is given, it is used as the base revision. If two
700 revisions are given, the differences between them are shown. The --change
700 revisions are given, the differences between them are shown. The --change
701 option can also be used as a shortcut to list the changed files of a
701 option can also be used as a shortcut to list the changed files of a
702 revision from its first parent.
702 revision from its first parent.
703
703
704 The codes used to show the status of files are:
704 The codes used to show the status of files are:
705
705
706 M = modified
706 M = modified
707 A = added
707 A = added
708 R = removed
708 R = removed
709 C = clean
709 C = clean
710 ! = missing (deleted by non-hg command, but still tracked)
710 ! = missing (deleted by non-hg command, but still tracked)
711 ? = not tracked
711 ? = not tracked
712 I = ignored
712 I = ignored
713 = origin of the previous file (with --copies)
713 = origin of the previous file (with --copies)
714
714
715 Returns 0 on success.
715 Returns 0 on success.
716
716
717 options ([+] can be repeated):
717 options ([+] can be repeated):
718
718
719 -A --all show status of all files
719 -A --all show status of all files
720 -m --modified show only modified files
720 -m --modified show only modified files
721 -a --added show only added files
721 -a --added show only added files
722 -r --removed show only removed files
722 -r --removed show only removed files
723 -d --deleted show only deleted (but tracked) files
723 -d --deleted show only deleted (but tracked) files
724 -c --clean show only files without changes
724 -c --clean show only files without changes
725 -u --unknown show only unknown (not tracked) files
725 -u --unknown show only unknown (not tracked) files
726 -i --ignored show only ignored files
726 -i --ignored show only ignored files
727 -n --no-status hide status prefix
727 -n --no-status hide status prefix
728 -C --copies show source of copied files
728 -C --copies show source of copied files
729 -0 --print0 end filenames with NUL, for use with xargs
729 -0 --print0 end filenames with NUL, for use with xargs
730 --rev REV [+] show difference from revision
730 --rev REV [+] show difference from revision
731 --change REV list the changed files of a revision
731 --change REV list the changed files of a revision
732 -I --include PATTERN [+] include names matching the given patterns
732 -I --include PATTERN [+] include names matching the given patterns
733 -X --exclude PATTERN [+] exclude names matching the given patterns
733 -X --exclude PATTERN [+] exclude names matching the given patterns
734 -S --subrepos recurse into subrepositories
734 -S --subrepos recurse into subrepositories
735 -T --template TEMPLATE display with template
735 -T --template TEMPLATE display with template
736
736
737 (some details hidden, use --verbose to show complete help)
737 (some details hidden, use --verbose to show complete help)
738
738
739 $ hg -q help status
739 $ hg -q help status
740 hg status [OPTION]... [FILE]...
740 hg status [OPTION]... [FILE]...
741
741
742 show changed files in the working directory
742 show changed files in the working directory
743
743
744 $ hg help foo
744 $ hg help foo
745 abort: no such help topic: foo
745 abort: no such help topic: foo
746 (try 'hg help --keyword foo')
746 (try 'hg help --keyword foo')
747 [255]
747 [255]
748
748
749 $ hg skjdfks
749 $ hg skjdfks
750 hg: unknown command 'skjdfks'
750 hg: unknown command 'skjdfks'
751 (use 'hg help' for a list of commands)
751 (use 'hg help' for a list of commands)
752 [255]
752 [255]
753
753
754 Typoed command gives suggestion
754 Typoed command gives suggestion
755 $ hg puls
755 $ hg puls
756 hg: unknown command 'puls'
756 hg: unknown command 'puls'
757 (did you mean one of pull, push?)
757 (did you mean one of pull, push?)
758 [255]
758 [255]
759
759
760 Not enabled extension gets suggested
760 Not enabled extension gets suggested
761
761
762 $ hg rebase
762 $ hg rebase
763 hg: unknown command 'rebase'
763 hg: unknown command 'rebase'
764 'rebase' is provided by the following extension:
764 'rebase' is provided by the following extension:
765
765
766 rebase command to move sets of revisions to a different ancestor
766 rebase command to move sets of revisions to a different ancestor
767
767
768 (use 'hg help extensions' for information on enabling extensions)
768 (use 'hg help extensions' for information on enabling extensions)
769 [255]
769 [255]
770
770
771 Disabled extension gets suggested
771 Disabled extension gets suggested
772 $ hg --config extensions.rebase=! rebase
772 $ hg --config extensions.rebase=! rebase
773 hg: unknown command 'rebase'
773 hg: unknown command 'rebase'
774 'rebase' is provided by the following extension:
774 'rebase' is provided by the following extension:
775
775
776 rebase command to move sets of revisions to a different ancestor
776 rebase command to move sets of revisions to a different ancestor
777
777
778 (use 'hg help extensions' for information on enabling extensions)
778 (use 'hg help extensions' for information on enabling extensions)
779 [255]
779 [255]
780
780
781 Make sure that we don't run afoul of the help system thinking that
781 Make sure that we don't run afoul of the help system thinking that
782 this is a section and erroring out weirdly.
782 this is a section and erroring out weirdly.
783
783
784 $ hg .log
784 $ hg .log
785 hg: unknown command '.log'
785 hg: unknown command '.log'
786 (did you mean log?)
786 (did you mean log?)
787 [255]
787 [255]
788
788
789 $ hg log.
789 $ hg log.
790 hg: unknown command 'log.'
790 hg: unknown command 'log.'
791 (did you mean log?)
791 (did you mean log?)
792 [255]
792 [255]
793 $ hg pu.lh
793 $ hg pu.lh
794 hg: unknown command 'pu.lh'
794 hg: unknown command 'pu.lh'
795 (did you mean one of pull, push?)
795 (did you mean one of pull, push?)
796 [255]
796 [255]
797
797
798 $ cat > helpext.py <<EOF
798 $ cat > helpext.py <<EOF
799 > import os
799 > import os
800 > from mercurial import commands, fancyopts, registrar
800 > from mercurial import commands, fancyopts, registrar
801 >
801 >
802 > def func(arg):
802 > def func(arg):
803 > return '%sfoo' % arg
803 > return '%sfoo' % arg
804 > class customopt(fancyopts.customopt):
804 > class customopt(fancyopts.customopt):
805 > def newstate(self, oldstate, newparam, abort):
805 > def newstate(self, oldstate, newparam, abort):
806 > return '%sbar' % oldstate
806 > return '%sbar' % oldstate
807 > cmdtable = {}
807 > cmdtable = {}
808 > command = registrar.command(cmdtable)
808 > command = registrar.command(cmdtable)
809 >
809 >
810 > @command(b'nohelp',
810 > @command(b'nohelp',
811 > [(b'', b'longdesc', 3, b'x'*67),
811 > [(b'', b'longdesc', 3, b'x'*67),
812 > (b'n', b'', None, b'normal desc'),
812 > (b'n', b'', None, b'normal desc'),
813 > (b'', b'newline', b'', b'line1\nline2'),
813 > (b'', b'newline', b'', b'line1\nline2'),
814 > (b'', b'default-off', False, b'enable X'),
814 > (b'', b'default-off', False, b'enable X'),
815 > (b'', b'default-on', True, b'enable Y'),
815 > (b'', b'default-on', True, b'enable Y'),
816 > (b'', b'callableopt', func, b'adds foo'),
816 > (b'', b'callableopt', func, b'adds foo'),
817 > (b'', b'customopt', customopt(''), b'adds bar'),
817 > (b'', b'customopt', customopt(''), b'adds bar'),
818 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
818 > (b'', b'customopt-withdefault', customopt('foo'), b'adds bar')],
819 > b'hg nohelp',
819 > b'hg nohelp',
820 > norepo=True)
820 > norepo=True)
821 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
821 > @command(b'debugoptADV', [(b'', b'aopt', None, b'option is (ADVANCED)')])
822 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
822 > @command(b'debugoptDEP', [(b'', b'dopt', None, b'option is (DEPRECATED)')])
823 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
823 > @command(b'debugoptEXP', [(b'', b'eopt', None, b'option is (EXPERIMENTAL)')])
824 > def nohelp(ui, *args, **kwargs):
824 > def nohelp(ui, *args, **kwargs):
825 > pass
825 > pass
826 >
826 >
827 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
827 > @command(b'hashelp', [], b'hg hashelp', norepo=True)
828 > def hashelp(ui, *args, **kwargs):
828 > def hashelp(ui, *args, **kwargs):
829 > """Extension command's help"""
829 > """Extension command's help"""
830 >
830 >
831 > def uisetup(ui):
831 > def uisetup(ui):
832 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
832 > ui.setconfig(b'alias', b'shellalias', b'!echo hi', b'helpext')
833 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
833 > ui.setconfig(b'alias', b'hgalias', b'summary', b'helpext')
834 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
834 > ui.setconfig(b'alias', b'hgalias:doc', b'My doc', b'helpext')
835 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
835 > ui.setconfig(b'alias', b'hgalias:category', b'navigation', b'helpext')
836 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
836 > ui.setconfig(b'alias', b'hgaliasnodoc', b'summary', b'helpext')
837 >
837 >
838 > EOF
838 > EOF
839 $ echo '[extensions]' >> $HGRCPATH
839 $ echo '[extensions]' >> $HGRCPATH
840 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
840 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
841
841
842 Test for aliases
842 Test for aliases
843
843
844 $ hg help | grep hgalias
844 $ hg help | grep hgalias
845 hgalias My doc
845 hgalias My doc
846
846
847 $ hg help hgalias
847 $ hg help hgalias
848 hg hgalias [--remote]
848 hg hgalias [--remote]
849
849
850 alias for: hg summary
850 alias for: hg summary
851
851
852 My doc
852 My doc
853
853
854 defined by: helpext
854 defined by: helpext
855
855
856 options:
856 options:
857
857
858 --remote check for push and pull
858 --remote check for push and pull
859
859
860 (some details hidden, use --verbose to show complete help)
860 (some details hidden, use --verbose to show complete help)
861 $ hg help hgaliasnodoc
861 $ hg help hgaliasnodoc
862 hg hgaliasnodoc [--remote]
862 hg hgaliasnodoc [--remote]
863
863
864 alias for: hg summary
864 alias for: hg summary
865
865
866 summarize working directory state
866 summarize working directory state
867
867
868 This generates a brief summary of the working directory state, including
868 This generates a brief summary of the working directory state, including
869 parents, branch, commit status, phase and available updates.
869 parents, branch, commit status, phase and available updates.
870
870
871 With the --remote option, this will check the default paths for incoming
871 With the --remote option, this will check the default paths for incoming
872 and outgoing changes. This can be time-consuming.
872 and outgoing changes. This can be time-consuming.
873
873
874 Returns 0 on success.
874 Returns 0 on success.
875
875
876 defined by: helpext
876 defined by: helpext
877
877
878 options:
878 options:
879
879
880 --remote check for push and pull
880 --remote check for push and pull
881
881
882 (some details hidden, use --verbose to show complete help)
882 (some details hidden, use --verbose to show complete help)
883
883
884 $ hg help shellalias
884 $ hg help shellalias
885 hg shellalias
885 hg shellalias
886
886
887 shell alias for: echo hi
887 shell alias for: echo hi
888
888
889 (no help text available)
889 (no help text available)
890
890
891 defined by: helpext
891 defined by: helpext
892
892
893 (some details hidden, use --verbose to show complete help)
893 (some details hidden, use --verbose to show complete help)
894
894
895 Test command with no help text
895 Test command with no help text
896
896
897 $ hg help nohelp
897 $ hg help nohelp
898 hg nohelp
898 hg nohelp
899
899
900 (no help text available)
900 (no help text available)
901
901
902 options:
902 options:
903
903
904 --longdesc VALUE
904 --longdesc VALUE
905 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
905 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
906 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
906 xxxxxxxxxxxxxxxxxxxxxxx (default: 3)
907 -n -- normal desc
907 -n -- normal desc
908 --newline VALUE line1 line2
908 --newline VALUE line1 line2
909 --default-off enable X
909 --default-off enable X
910 --[no-]default-on enable Y (default: on)
910 --[no-]default-on enable Y (default: on)
911 --callableopt VALUE adds foo
911 --callableopt VALUE adds foo
912 --customopt VALUE adds bar
912 --customopt VALUE adds bar
913 --customopt-withdefault VALUE adds bar (default: foo)
913 --customopt-withdefault VALUE adds bar (default: foo)
914
914
915 (some details hidden, use --verbose to show complete help)
915 (some details hidden, use --verbose to show complete help)
916
916
917 Test that default list of commands includes extension commands that have help,
917 Test that default list of commands includes extension commands that have help,
918 but not those that don't, except in verbose mode, when a keyword is passed, or
918 but not those that don't, except in verbose mode, when a keyword is passed, or
919 when help about the extension is requested.
919 when help about the extension is requested.
920
920
921 #if no-extraextensions
921 #if no-extraextensions
922
922
923 $ hg help | grep hashelp
923 $ hg help | grep hashelp
924 hashelp Extension command's help
924 hashelp Extension command's help
925 $ hg help | grep nohelp
925 $ hg help | grep nohelp
926 [1]
926 [1]
927 $ hg help -v | grep nohelp
927 $ hg help -v | grep nohelp
928 nohelp (no help text available)
928 nohelp (no help text available)
929
929
930 $ hg help -k nohelp
930 $ hg help -k nohelp
931 Commands:
931 Commands:
932
932
933 nohelp hg nohelp
933 nohelp hg nohelp
934
934
935 Extension Commands:
935 Extension Commands:
936
936
937 nohelp (no help text available)
937 nohelp (no help text available)
938
938
939 $ hg help helpext
939 $ hg help helpext
940 helpext extension - no help text available
940 helpext extension - no help text available
941
941
942 list of commands:
942 list of commands:
943
943
944 hashelp Extension command's help
944 hashelp Extension command's help
945 nohelp (no help text available)
945 nohelp (no help text available)
946
946
947 (use 'hg help -v helpext' to show built-in aliases and global options)
947 (use 'hg help -v helpext' to show built-in aliases and global options)
948
948
949 #endif
949 #endif
950
950
951 Test list of internal help commands
951 Test list of internal help commands
952
952
953 $ hg help debug
953 $ hg help debug
954 debug commands (internal and unsupported):
954 debug commands (internal and unsupported):
955
955
956 debugancestor
956 debugancestor
957 find the ancestor revision of two revisions in a given index
957 find the ancestor revision of two revisions in a given index
958 debugapplystreamclonebundle
958 debugapplystreamclonebundle
959 apply a stream clone bundle file
959 apply a stream clone bundle file
960 debugbuilddag
960 debugbuilddag
961 builds a repo with a given DAG from scratch in the current
961 builds a repo with a given DAG from scratch in the current
962 empty repo
962 empty repo
963 debugbundle lists the contents of a bundle
963 debugbundle lists the contents of a bundle
964 debugcapabilities
964 debugcapabilities
965 lists the capabilities of a remote peer
965 lists the capabilities of a remote peer
966 debugcheckstate
966 debugcheckstate
967 validate the correctness of the current dirstate
967 validate the correctness of the current dirstate
968 debugcolor show available color, effects or style
968 debugcolor show available color, effects or style
969 debugcommands
969 debugcommands
970 list all available commands and options
970 list all available commands and options
971 debugcomplete
971 debugcomplete
972 returns the completion list associated with the given command
972 returns the completion list associated with the given command
973 debugcreatestreamclonebundle
973 debugcreatestreamclonebundle
974 create a stream clone bundle file
974 create a stream clone bundle file
975 debugdag format the changelog or an index DAG as a concise textual
975 debugdag format the changelog or an index DAG as a concise textual
976 description
976 description
977 debugdata dump the contents of a data file revision
977 debugdata dump the contents of a data file revision
978 debugdate parse and display a date
978 debugdate parse and display a date
979 debugdeltachain
979 debugdeltachain
980 dump information about delta chains in a revlog
980 dump information about delta chains in a revlog
981 debugdirstate
981 debugdirstate
982 show the contents of the current dirstate
982 show the contents of the current dirstate
983 debugdiscovery
983 debugdiscovery
984 runs the changeset discovery protocol in isolation
984 runs the changeset discovery protocol in isolation
985 debugdownload
985 debugdownload
986 download a resource using Mercurial logic and config
986 download a resource using Mercurial logic and config
987 debugextensions
987 debugextensions
988 show information about active extensions
988 show information about active extensions
989 debugfileset parse and apply a fileset specification
989 debugfileset parse and apply a fileset specification
990 debugformat display format information about the current repository
990 debugformat display format information about the current repository
991 debugfsinfo show information detected about current filesystem
991 debugfsinfo show information detected about current filesystem
992 debuggetbundle
992 debuggetbundle
993 retrieves a bundle from a repo
993 retrieves a bundle from a repo
994 debugignore display the combined ignore pattern and information about
994 debugignore display the combined ignore pattern and information about
995 ignored files
995 ignored files
996 debugindex dump index data for a storage primitive
996 debugindex dump index data for a storage primitive
997 debugindexdot
997 debugindexdot
998 dump an index DAG as a graphviz dot file
998 dump an index DAG as a graphviz dot file
999 debugindexstats
999 debugindexstats
1000 show stats related to the changelog index
1000 show stats related to the changelog index
1001 debuginstall test Mercurial installation
1001 debuginstall test Mercurial installation
1002 debugknown test whether node ids are known to a repo
1002 debugknown test whether node ids are known to a repo
1003 debuglocks show or modify state of locks
1003 debuglocks show or modify state of locks
1004 debugmanifestfulltextcache
1004 debugmanifestfulltextcache
1005 show, clear or amend the contents of the manifest fulltext
1005 show, clear or amend the contents of the manifest fulltext
1006 cache
1006 cache
1007 debugmergestate
1007 debugmergestate
1008 print merge state
1008 print merge state
1009 debugnamecomplete
1009 debugnamecomplete
1010 complete "names" - tags, open branch names, bookmark names
1010 complete "names" - tags, open branch names, bookmark names
1011 debugobsolete
1011 debugobsolete
1012 create arbitrary obsolete marker
1012 create arbitrary obsolete marker
1013 debugoptADV (no help text available)
1013 debugoptADV (no help text available)
1014 debugoptDEP (no help text available)
1014 debugoptDEP (no help text available)
1015 debugoptEXP (no help text available)
1015 debugoptEXP (no help text available)
1016 debugp1copies
1016 debugp1copies
1017 dump copy information compared to p1
1017 dump copy information compared to p1
1018 debugp2copies
1018 debugp2copies
1019 dump copy information compared to p2
1019 dump copy information compared to p2
1020 debugpathcomplete
1020 debugpathcomplete
1021 complete part or all of a tracked path
1021 complete part or all of a tracked path
1022 debugpathcopies
1022 debugpathcopies
1023 show copies between two revisions
1023 show copies between two revisions
1024 debugpeer establish a connection to a peer repository
1024 debugpeer establish a connection to a peer repository
1025 debugpickmergetool
1025 debugpickmergetool
1026 examine which merge tool is chosen for specified file
1026 examine which merge tool is chosen for specified file
1027 debugpushkey access the pushkey key/value protocol
1027 debugpushkey access the pushkey key/value protocol
1028 debugpvec (no help text available)
1028 debugpvec (no help text available)
1029 debugrebuilddirstate
1029 debugrebuilddirstate
1030 rebuild the dirstate as it would look like for the given
1030 rebuild the dirstate as it would look like for the given
1031 revision
1031 revision
1032 debugrebuildfncache
1032 debugrebuildfncache
1033 rebuild the fncache file
1033 rebuild the fncache file
1034 debugrename dump rename information
1034 debugrename dump rename information
1035 debugrevlog show data and statistics about a revlog
1035 debugrevlog show data and statistics about a revlog
1036 debugrevlogindex
1036 debugrevlogindex
1037 dump the contents of a revlog index
1037 dump the contents of a revlog index
1038 debugrevspec parse and apply a revision specification
1038 debugrevspec parse and apply a revision specification
1039 debugserve run a server with advanced settings
1039 debugserve run a server with advanced settings
1040 debugsetparents
1040 debugsetparents
1041 manually set the parents of the current working directory
1041 manually set the parents of the current working directory
1042 debugssl test a secure connection to a server
1042 debugssl test a secure connection to a server
1043 debugsub (no help text available)
1043 debugsub (no help text available)
1044 debugsuccessorssets
1044 debugsuccessorssets
1045 show set of successors for revision
1045 show set of successors for revision
1046 debugtemplate
1046 debugtemplate
1047 parse and apply a template
1047 parse and apply a template
1048 debuguigetpass
1048 debuguigetpass
1049 show prompt to type password
1049 show prompt to type password
1050 debuguiprompt
1050 debuguiprompt
1051 show plain prompt
1051 show plain prompt
1052 debugupdatecaches
1052 debugupdatecaches
1053 warm all known caches in the repository
1053 warm all known caches in the repository
1054 debugupgraderepo
1054 debugupgraderepo
1055 upgrade a repository to use different features
1055 upgrade a repository to use different features
1056 debugwalk show how files match on given patterns
1056 debugwalk show how files match on given patterns
1057 debugwhyunstable
1057 debugwhyunstable
1058 explain instabilities of a changeset
1058 explain instabilities of a changeset
1059 debugwireargs
1059 debugwireargs
1060 (no help text available)
1060 (no help text available)
1061 debugwireproto
1061 debugwireproto
1062 send wire protocol commands to a server
1062 send wire protocol commands to a server
1063
1063
1064 (use 'hg help -v debug' to show built-in aliases and global options)
1064 (use 'hg help -v debug' to show built-in aliases and global options)
1065
1065
1066 internals topic renders index of available sub-topics
1066 internals topic renders index of available sub-topics
1067
1067
1068 $ hg help internals
1068 $ hg help internals
1069 Technical implementation topics
1069 Technical implementation topics
1070 """""""""""""""""""""""""""""""
1070 """""""""""""""""""""""""""""""
1071
1071
1072 To access a subtopic, use "hg help internals.{subtopic-name}"
1072 To access a subtopic, use "hg help internals.{subtopic-name}"
1073
1073
1074 bundle2 Bundle2
1074 bundle2 Bundle2
1075 bundles Bundles
1075 bundles Bundles
1076 cbor CBOR
1076 cbor CBOR
1077 censor Censor
1077 censor Censor
1078 changegroups Changegroups
1078 changegroups Changegroups
1079 config Config Registrar
1079 config Config Registrar
1080 extensions Extension API
1080 extensions Extension API
1081 requirements Repository Requirements
1081 requirements Repository Requirements
1082 revlogs Revision Logs
1082 revlogs Revision Logs
1083 wireprotocol Wire Protocol
1083 wireprotocol Wire Protocol
1084 wireprotocolrpc
1084 wireprotocolrpc
1085 Wire Protocol RPC
1085 Wire Protocol RPC
1086 wireprotocolv2
1086 wireprotocolv2
1087 Wire Protocol Version 2
1087 Wire Protocol Version 2
1088
1088
1089 sub-topics can be accessed
1089 sub-topics can be accessed
1090
1090
1091 $ hg help internals.changegroups
1091 $ hg help internals.changegroups
1092 Changegroups
1092 Changegroups
1093 """"""""""""
1093 """"""""""""
1094
1094
1095 Changegroups are representations of repository revlog data, specifically
1095 Changegroups are representations of repository revlog data, specifically
1096 the changelog data, root/flat manifest data, treemanifest data, and
1096 the changelog data, root/flat manifest data, treemanifest data, and
1097 filelogs.
1097 filelogs.
1098
1098
1099 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1099 There are 3 versions of changegroups: "1", "2", and "3". From a high-
1100 level, versions "1" and "2" are almost exactly the same, with the only
1100 level, versions "1" and "2" are almost exactly the same, with the only
1101 difference being an additional item in the *delta header*. Version "3"
1101 difference being an additional item in the *delta header*. Version "3"
1102 adds support for storage flags in the *delta header* and optionally
1102 adds support for storage flags in the *delta header* and optionally
1103 exchanging treemanifests (enabled by setting an option on the
1103 exchanging treemanifests (enabled by setting an option on the
1104 "changegroup" part in the bundle2).
1104 "changegroup" part in the bundle2).
1105
1105
1106 Changegroups when not exchanging treemanifests consist of 3 logical
1106 Changegroups when not exchanging treemanifests consist of 3 logical
1107 segments:
1107 segments:
1108
1108
1109 +---------------------------------+
1109 +---------------------------------+
1110 | | | |
1110 | | | |
1111 | changeset | manifest | filelogs |
1111 | changeset | manifest | filelogs |
1112 | | | |
1112 | | | |
1113 | | | |
1113 | | | |
1114 +---------------------------------+
1114 +---------------------------------+
1115
1115
1116 When exchanging treemanifests, there are 4 logical segments:
1116 When exchanging treemanifests, there are 4 logical segments:
1117
1117
1118 +-------------------------------------------------+
1118 +-------------------------------------------------+
1119 | | | | |
1119 | | | | |
1120 | changeset | root | treemanifests | filelogs |
1120 | changeset | root | treemanifests | filelogs |
1121 | | manifest | | |
1121 | | manifest | | |
1122 | | | | |
1122 | | | | |
1123 +-------------------------------------------------+
1123 +-------------------------------------------------+
1124
1124
1125 The principle building block of each segment is a *chunk*. A *chunk* is a
1125 The principle building block of each segment is a *chunk*. A *chunk* is a
1126 framed piece of data:
1126 framed piece of data:
1127
1127
1128 +---------------------------------------+
1128 +---------------------------------------+
1129 | | |
1129 | | |
1130 | length | data |
1130 | length | data |
1131 | (4 bytes) | (<length - 4> bytes) |
1131 | (4 bytes) | (<length - 4> bytes) |
1132 | | |
1132 | | |
1133 +---------------------------------------+
1133 +---------------------------------------+
1134
1134
1135 All integers are big-endian signed integers. Each chunk starts with a
1135 All integers are big-endian signed integers. Each chunk starts with a
1136 32-bit integer indicating the length of the entire chunk (including the
1136 32-bit integer indicating the length of the entire chunk (including the
1137 length field itself).
1137 length field itself).
1138
1138
1139 There is a special case chunk that has a value of 0 for the length
1139 There is a special case chunk that has a value of 0 for the length
1140 ("0x00000000"). We call this an *empty chunk*.
1140 ("0x00000000"). We call this an *empty chunk*.
1141
1141
1142 Delta Groups
1142 Delta Groups
1143 ============
1143 ============
1144
1144
1145 A *delta group* expresses the content of a revlog as a series of deltas,
1145 A *delta group* expresses the content of a revlog as a series of deltas,
1146 or patches against previous revisions.
1146 or patches against previous revisions.
1147
1147
1148 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1148 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
1149 to signal the end of the delta group:
1149 to signal the end of the delta group:
1150
1150
1151 +------------------------------------------------------------------------+
1151 +------------------------------------------------------------------------+
1152 | | | | | |
1152 | | | | | |
1153 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1153 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
1154 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1154 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
1155 | | | | | |
1155 | | | | | |
1156 +------------------------------------------------------------------------+
1156 +------------------------------------------------------------------------+
1157
1157
1158 Each *chunk*'s data consists of the following:
1158 Each *chunk*'s data consists of the following:
1159
1159
1160 +---------------------------------------+
1160 +---------------------------------------+
1161 | | |
1161 | | |
1162 | delta header | delta data |
1162 | delta header | delta data |
1163 | (various by version) | (various) |
1163 | (various by version) | (various) |
1164 | | |
1164 | | |
1165 +---------------------------------------+
1165 +---------------------------------------+
1166
1166
1167 The *delta data* is a series of *delta*s that describe a diff from an
1167 The *delta data* is a series of *delta*s that describe a diff from an
1168 existing entry (either that the recipient already has, or previously
1168 existing entry (either that the recipient already has, or previously
1169 specified in the bundle/changegroup).
1169 specified in the bundle/changegroup).
1170
1170
1171 The *delta header* is different between versions "1", "2", and "3" of the
1171 The *delta header* is different between versions "1", "2", and "3" of the
1172 changegroup format.
1172 changegroup format.
1173
1173
1174 Version 1 (headerlen=80):
1174 Version 1 (headerlen=80):
1175
1175
1176 +------------------------------------------------------+
1176 +------------------------------------------------------+
1177 | | | | |
1177 | | | | |
1178 | node | p1 node | p2 node | link node |
1178 | node | p1 node | p2 node | link node |
1179 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1179 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1180 | | | | |
1180 | | | | |
1181 +------------------------------------------------------+
1181 +------------------------------------------------------+
1182
1182
1183 Version 2 (headerlen=100):
1183 Version 2 (headerlen=100):
1184
1184
1185 +------------------------------------------------------------------+
1185 +------------------------------------------------------------------+
1186 | | | | | |
1186 | | | | | |
1187 | node | p1 node | p2 node | base node | link node |
1187 | node | p1 node | p2 node | base node | link node |
1188 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1188 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
1189 | | | | | |
1189 | | | | | |
1190 +------------------------------------------------------------------+
1190 +------------------------------------------------------------------+
1191
1191
1192 Version 3 (headerlen=102):
1192 Version 3 (headerlen=102):
1193
1193
1194 +------------------------------------------------------------------------------+
1194 +------------------------------------------------------------------------------+
1195 | | | | | | |
1195 | | | | | | |
1196 | node | p1 node | p2 node | base node | link node | flags |
1196 | node | p1 node | p2 node | base node | link node | flags |
1197 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1197 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
1198 | | | | | | |
1198 | | | | | | |
1199 +------------------------------------------------------------------------------+
1199 +------------------------------------------------------------------------------+
1200
1200
1201 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1201 The *delta data* consists of "chunklen - 4 - headerlen" bytes, which
1202 contain a series of *delta*s, densely packed (no separators). These deltas
1202 contain a series of *delta*s, densely packed (no separators). These deltas
1203 describe a diff from an existing entry (either that the recipient already
1203 describe a diff from an existing entry (either that the recipient already
1204 has, or previously specified in the bundle/changegroup). The format is
1204 has, or previously specified in the bundle/changegroup). The format is
1205 described more fully in "hg help internals.bdiff", but briefly:
1205 described more fully in "hg help internals.bdiff", but briefly:
1206
1206
1207 +---------------------------------------------------------------+
1207 +---------------------------------------------------------------+
1208 | | | | |
1208 | | | | |
1209 | start offset | end offset | new length | content |
1209 | start offset | end offset | new length | content |
1210 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1210 | (4 bytes) | (4 bytes) | (4 bytes) | (<new length> bytes) |
1211 | | | | |
1211 | | | | |
1212 +---------------------------------------------------------------+
1212 +---------------------------------------------------------------+
1213
1213
1214 Please note that the length field in the delta data does *not* include
1214 Please note that the length field in the delta data does *not* include
1215 itself.
1215 itself.
1216
1216
1217 In version 1, the delta is always applied against the previous node from
1217 In version 1, the delta is always applied against the previous node from
1218 the changegroup or the first parent if this is the first entry in the
1218 the changegroup or the first parent if this is the first entry in the
1219 changegroup.
1219 changegroup.
1220
1220
1221 In version 2 and up, the delta base node is encoded in the entry in the
1221 In version 2 and up, the delta base node is encoded in the entry in the
1222 changegroup. This allows the delta to be expressed against any parent,
1222 changegroup. This allows the delta to be expressed against any parent,
1223 which can result in smaller deltas and more efficient encoding of data.
1223 which can result in smaller deltas and more efficient encoding of data.
1224
1224
1225 The *flags* field holds bitwise flags affecting the processing of revision
1225 The *flags* field holds bitwise flags affecting the processing of revision
1226 data. The following flags are defined:
1226 data. The following flags are defined:
1227
1227
1228 32768
1228 32768
1229 Censored revision. The revision's fulltext has been replaced by censor
1229 Censored revision. The revision's fulltext has been replaced by censor
1230 metadata. May only occur on file revisions.
1230 metadata. May only occur on file revisions.
1231
1231
1232 16384
1232 16384
1233 Ellipsis revision. Revision hash does not match data (likely due to
1233 Ellipsis revision. Revision hash does not match data (likely due to
1234 rewritten parents).
1234 rewritten parents).
1235
1235
1236 8192
1236 8192
1237 Externally stored. The revision fulltext contains "key:value" "\n"
1237 Externally stored. The revision fulltext contains "key:value" "\n"
1238 delimited metadata defining an object stored elsewhere. Used by the LFS
1238 delimited metadata defining an object stored elsewhere. Used by the LFS
1239 extension.
1239 extension.
1240
1240
1241 For historical reasons, the integer values are identical to revlog version
1241 For historical reasons, the integer values are identical to revlog version
1242 1 per-revision storage flags and correspond to bits being set in this
1242 1 per-revision storage flags and correspond to bits being set in this
1243 2-byte field. Bits were allocated starting from the most-significant bit,
1243 2-byte field. Bits were allocated starting from the most-significant bit,
1244 hence the reverse ordering and allocation of these flags.
1244 hence the reverse ordering and allocation of these flags.
1245
1245
1246 Changeset Segment
1246 Changeset Segment
1247 =================
1247 =================
1248
1248
1249 The *changeset segment* consists of a single *delta group* holding
1249 The *changeset segment* consists of a single *delta group* holding
1250 changelog data. The *empty chunk* at the end of the *delta group* denotes
1250 changelog data. The *empty chunk* at the end of the *delta group* denotes
1251 the boundary to the *manifest segment*.
1251 the boundary to the *manifest segment*.
1252
1252
1253 Manifest Segment
1253 Manifest Segment
1254 ================
1254 ================
1255
1255
1256 The *manifest segment* consists of a single *delta group* holding manifest
1256 The *manifest segment* consists of a single *delta group* holding manifest
1257 data. If treemanifests are in use, it contains only the manifest for the
1257 data. If treemanifests are in use, it contains only the manifest for the
1258 root directory of the repository. Otherwise, it contains the entire
1258 root directory of the repository. Otherwise, it contains the entire
1259 manifest data. The *empty chunk* at the end of the *delta group* denotes
1259 manifest data. The *empty chunk* at the end of the *delta group* denotes
1260 the boundary to the next segment (either the *treemanifests segment* or
1260 the boundary to the next segment (either the *treemanifests segment* or
1261 the *filelogs segment*, depending on version and the request options).
1261 the *filelogs segment*, depending on version and the request options).
1262
1262
1263 Treemanifests Segment
1263 Treemanifests Segment
1264 ---------------------
1264 ---------------------
1265
1265
1266 The *treemanifests segment* only exists in changegroup version "3", and
1266 The *treemanifests segment* only exists in changegroup version "3", and
1267 only if the 'treemanifest' param is part of the bundle2 changegroup part
1267 only if the 'treemanifest' param is part of the bundle2 changegroup part
1268 (it is not possible to use changegroup version 3 outside of bundle2).
1268 (it is not possible to use changegroup version 3 outside of bundle2).
1269 Aside from the filenames in the *treemanifests segment* containing a
1269 Aside from the filenames in the *treemanifests segment* containing a
1270 trailing "/" character, it behaves identically to the *filelogs segment*
1270 trailing "/" character, it behaves identically to the *filelogs segment*
1271 (see below). The final sub-segment is followed by an *empty chunk*
1271 (see below). The final sub-segment is followed by an *empty chunk*
1272 (logically, a sub-segment with filename size 0). This denotes the boundary
1272 (logically, a sub-segment with filename size 0). This denotes the boundary
1273 to the *filelogs segment*.
1273 to the *filelogs segment*.
1274
1274
1275 Filelogs Segment
1275 Filelogs Segment
1276 ================
1276 ================
1277
1277
1278 The *filelogs segment* consists of multiple sub-segments, each
1278 The *filelogs segment* consists of multiple sub-segments, each
1279 corresponding to an individual file whose data is being described:
1279 corresponding to an individual file whose data is being described:
1280
1280
1281 +--------------------------------------------------+
1281 +--------------------------------------------------+
1282 | | | | | |
1282 | | | | | |
1283 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1283 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
1284 | | | | | (4 bytes) |
1284 | | | | | (4 bytes) |
1285 | | | | | |
1285 | | | | | |
1286 +--------------------------------------------------+
1286 +--------------------------------------------------+
1287
1287
1288 The final filelog sub-segment is followed by an *empty chunk* (logically,
1288 The final filelog sub-segment is followed by an *empty chunk* (logically,
1289 a sub-segment with filename size 0). This denotes the end of the segment
1289 a sub-segment with filename size 0). This denotes the end of the segment
1290 and of the overall changegroup.
1290 and of the overall changegroup.
1291
1291
1292 Each filelog sub-segment consists of the following:
1292 Each filelog sub-segment consists of the following:
1293
1293
1294 +------------------------------------------------------+
1294 +------------------------------------------------------+
1295 | | | |
1295 | | | |
1296 | filename length | filename | delta group |
1296 | filename length | filename | delta group |
1297 | (4 bytes) | (<length - 4> bytes) | (various) |
1297 | (4 bytes) | (<length - 4> bytes) | (various) |
1298 | | | |
1298 | | | |
1299 +------------------------------------------------------+
1299 +------------------------------------------------------+
1300
1300
1301 That is, a *chunk* consisting of the filename (not terminated or padded)
1301 That is, a *chunk* consisting of the filename (not terminated or padded)
1302 followed by N chunks constituting the *delta group* for this file. The
1302 followed by N chunks constituting the *delta group* for this file. The
1303 *empty chunk* at the end of each *delta group* denotes the boundary to the
1303 *empty chunk* at the end of each *delta group* denotes the boundary to the
1304 next filelog sub-segment.
1304 next filelog sub-segment.
1305
1305
1306 test advanced, deprecated and experimental options are hidden in command help
1306 test advanced, deprecated and experimental options are hidden in command help
1307 $ hg help debugoptADV
1307 $ hg help debugoptADV
1308 hg debugoptADV
1308 hg debugoptADV
1309
1309
1310 (no help text available)
1310 (no help text available)
1311
1311
1312 options:
1312 options:
1313
1313
1314 (some details hidden, use --verbose to show complete help)
1314 (some details hidden, use --verbose to show complete help)
1315 $ hg help debugoptDEP
1315 $ hg help debugoptDEP
1316 hg debugoptDEP
1316 hg debugoptDEP
1317
1317
1318 (no help text available)
1318 (no help text available)
1319
1319
1320 options:
1320 options:
1321
1321
1322 (some details hidden, use --verbose to show complete help)
1322 (some details hidden, use --verbose to show complete help)
1323
1323
1324 $ hg help debugoptEXP
1324 $ hg help debugoptEXP
1325 hg debugoptEXP
1325 hg debugoptEXP
1326
1326
1327 (no help text available)
1327 (no help text available)
1328
1328
1329 options:
1329 options:
1330
1330
1331 (some details hidden, use --verbose to show complete help)
1331 (some details hidden, use --verbose to show complete help)
1332
1332
1333 test advanced, deprecated and experimental options are shown with -v
1333 test advanced, deprecated and experimental options are shown with -v
1334 $ hg help -v debugoptADV | grep aopt
1334 $ hg help -v debugoptADV | grep aopt
1335 --aopt option is (ADVANCED)
1335 --aopt option is (ADVANCED)
1336 $ hg help -v debugoptDEP | grep dopt
1336 $ hg help -v debugoptDEP | grep dopt
1337 --dopt option is (DEPRECATED)
1337 --dopt option is (DEPRECATED)
1338 $ hg help -v debugoptEXP | grep eopt
1338 $ hg help -v debugoptEXP | grep eopt
1339 --eopt option is (EXPERIMENTAL)
1339 --eopt option is (EXPERIMENTAL)
1340
1340
1341 #if gettext
1341 #if gettext
1342 test deprecated option is hidden with translation with untranslated description
1342 test deprecated option is hidden with translation with untranslated description
1343 (use many globy for not failing on changed transaction)
1343 (use many globy for not failing on changed transaction)
1344 $ LANGUAGE=sv hg help debugoptDEP
1344 $ LANGUAGE=sv hg help debugoptDEP
1345 hg debugoptDEP
1345 hg debugoptDEP
1346
1346
1347 (*) (glob)
1347 (*) (glob)
1348
1348
1349 options:
1349 options:
1350
1350
1351 (some details hidden, use --verbose to show complete help)
1351 (some details hidden, use --verbose to show complete help)
1352 #endif
1352 #endif
1353
1353
1354 Test commands that collide with topics (issue4240)
1354 Test commands that collide with topics (issue4240)
1355
1355
1356 $ hg config -hq
1356 $ hg config -hq
1357 hg config [-u] [NAME]...
1357 hg config [-u] [NAME]...
1358
1358
1359 show combined config settings from all hgrc files
1359 show combined config settings from all hgrc files
1360 $ hg showconfig -hq
1360 $ hg showconfig -hq
1361 hg config [-u] [NAME]...
1361 hg config [-u] [NAME]...
1362
1362
1363 show combined config settings from all hgrc files
1363 show combined config settings from all hgrc files
1364
1364
1365 Test a help topic
1365 Test a help topic
1366
1366
1367 $ hg help dates
1367 $ hg help dates
1368 Date Formats
1368 Date Formats
1369 """"""""""""
1369 """"""""""""
1370
1370
1371 Some commands allow the user to specify a date, e.g.:
1371 Some commands allow the user to specify a date, e.g.:
1372
1372
1373 - backout, commit, import, tag: Specify the commit date.
1373 - backout, commit, import, tag: Specify the commit date.
1374 - log, revert, update: Select revision(s) by date.
1374 - log, revert, update: Select revision(s) by date.
1375
1375
1376 Many date formats are valid. Here are some examples:
1376 Many date formats are valid. Here are some examples:
1377
1377
1378 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1378 - "Wed Dec 6 13:18:29 2006" (local timezone assumed)
1379 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1379 - "Dec 6 13:18 -0600" (year assumed, time offset provided)
1380 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1380 - "Dec 6 13:18 UTC" (UTC and GMT are aliases for +0000)
1381 - "Dec 6" (midnight)
1381 - "Dec 6" (midnight)
1382 - "13:18" (today assumed)
1382 - "13:18" (today assumed)
1383 - "3:39" (3:39AM assumed)
1383 - "3:39" (3:39AM assumed)
1384 - "3:39pm" (15:39)
1384 - "3:39pm" (15:39)
1385 - "2006-12-06 13:18:29" (ISO 8601 format)
1385 - "2006-12-06 13:18:29" (ISO 8601 format)
1386 - "2006-12-6 13:18"
1386 - "2006-12-6 13:18"
1387 - "2006-12-6"
1387 - "2006-12-6"
1388 - "12-6"
1388 - "12-6"
1389 - "12/6"
1389 - "12/6"
1390 - "12/6/6" (Dec 6 2006)
1390 - "12/6/6" (Dec 6 2006)
1391 - "today" (midnight)
1391 - "today" (midnight)
1392 - "yesterday" (midnight)
1392 - "yesterday" (midnight)
1393 - "now" - right now
1393 - "now" - right now
1394
1394
1395 Lastly, there is Mercurial's internal format:
1395 Lastly, there is Mercurial's internal format:
1396
1396
1397 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1397 - "1165411109 0" (Wed Dec 6 13:18:29 2006 UTC)
1398
1398
1399 This is the internal representation format for dates. The first number is
1399 This is the internal representation format for dates. The first number is
1400 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1400 the number of seconds since the epoch (1970-01-01 00:00 UTC). The second
1401 is the offset of the local timezone, in seconds west of UTC (negative if
1401 is the offset of the local timezone, in seconds west of UTC (negative if
1402 the timezone is east of UTC).
1402 the timezone is east of UTC).
1403
1403
1404 The log command also accepts date ranges:
1404 The log command also accepts date ranges:
1405
1405
1406 - "<DATE" - at or before a given date/time
1406 - "<DATE" - at or before a given date/time
1407 - ">DATE" - on or after a given date/time
1407 - ">DATE" - on or after a given date/time
1408 - "DATE to DATE" - a date range, inclusive
1408 - "DATE to DATE" - a date range, inclusive
1409 - "-DAYS" - within a given number of days of today
1409 - "-DAYS" - within a given number of days of today
1410
1410
1411 Test repeated config section name
1411 Test repeated config section name
1412
1412
1413 $ hg help config.host
1413 $ hg help config.host
1414 "http_proxy.host"
1414 "http_proxy.host"
1415 Host name and (optional) port of the proxy server, for example
1415 Host name and (optional) port of the proxy server, for example
1416 "myproxy:8000".
1416 "myproxy:8000".
1417
1417
1418 "smtp.host"
1418 "smtp.host"
1419 Host name of mail server, e.g. "mail.example.com".
1419 Host name of mail server, e.g. "mail.example.com".
1420
1420
1421
1421
1422 Test section name with dot
1422 Test section name with dot
1423
1423
1424 $ hg help config.ui.username
1424 $ hg help config.ui.username
1425 "ui.username"
1425 "ui.username"
1426 The committer of a changeset created when running "commit". Typically
1426 The committer of a changeset created when running "commit". Typically
1427 a person's name and email address, e.g. "Fred Widget
1427 a person's name and email address, e.g. "Fred Widget
1428 <fred@example.com>". Environment variables in the username are
1428 <fred@example.com>". Environment variables in the username are
1429 expanded.
1429 expanded.
1430
1430
1431 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1431 (default: "$EMAIL" or "username@hostname". If the username in hgrc is
1432 empty, e.g. if the system admin set "username =" in the system hgrc,
1432 empty, e.g. if the system admin set "username =" in the system hgrc,
1433 it has to be specified manually or in a different hgrc file)
1433 it has to be specified manually or in a different hgrc file)
1434
1434
1435
1435
1436 $ hg help config.annotate.git
1436 $ hg help config.annotate.git
1437 abort: help section not found: config.annotate.git
1437 abort: help section not found: config.annotate.git
1438 [255]
1438 [255]
1439
1439
1440 $ hg help config.update.check
1440 $ hg help config.update.check
1441 "commands.update.check"
1441 "commands.update.check"
1442 Determines what level of checking 'hg update' will perform before
1442 Determines what level of checking 'hg update' will perform before
1443 moving to a destination revision. Valid values are "abort", "none",
1443 moving to a destination revision. Valid values are "abort", "none",
1444 "linear", and "noconflict". "abort" always fails if the working
1444 "linear", and "noconflict". "abort" always fails if the working
1445 directory has uncommitted changes. "none" performs no checking, and
1445 directory has uncommitted changes. "none" performs no checking, and
1446 may result in a merge with uncommitted changes. "linear" allows any
1446 may result in a merge with uncommitted changes. "linear" allows any
1447 update as long as it follows a straight line in the revision history,
1447 update as long as it follows a straight line in the revision history,
1448 and may trigger a merge with uncommitted changes. "noconflict" will
1448 and may trigger a merge with uncommitted changes. "noconflict" will
1449 allow any update which would not trigger a merge with uncommitted
1449 allow any update which would not trigger a merge with uncommitted
1450 changes, if any are present. (default: "linear")
1450 changes, if any are present. (default: "linear")
1451
1451
1452
1452
1453 $ hg help config.commands.update.check
1453 $ hg help config.commands.update.check
1454 "commands.update.check"
1454 "commands.update.check"
1455 Determines what level of checking 'hg update' will perform before
1455 Determines what level of checking 'hg update' will perform before
1456 moving to a destination revision. Valid values are "abort", "none",
1456 moving to a destination revision. Valid values are "abort", "none",
1457 "linear", and "noconflict". "abort" always fails if the working
1457 "linear", and "noconflict". "abort" always fails if the working
1458 directory has uncommitted changes. "none" performs no checking, and
1458 directory has uncommitted changes. "none" performs no checking, and
1459 may result in a merge with uncommitted changes. "linear" allows any
1459 may result in a merge with uncommitted changes. "linear" allows any
1460 update as long as it follows a straight line in the revision history,
1460 update as long as it follows a straight line in the revision history,
1461 and may trigger a merge with uncommitted changes. "noconflict" will
1461 and may trigger a merge with uncommitted changes. "noconflict" will
1462 allow any update which would not trigger a merge with uncommitted
1462 allow any update which would not trigger a merge with uncommitted
1463 changes, if any are present. (default: "linear")
1463 changes, if any are present. (default: "linear")
1464
1464
1465
1465
1466 $ hg help config.ommands.update.check
1466 $ hg help config.ommands.update.check
1467 abort: help section not found: config.ommands.update.check
1467 abort: help section not found: config.ommands.update.check
1468 [255]
1468 [255]
1469
1469
1470 Unrelated trailing paragraphs shouldn't be included
1470 Unrelated trailing paragraphs shouldn't be included
1471
1471
1472 $ hg help config.extramsg | grep '^$'
1472 $ hg help config.extramsg | grep '^$'
1473
1473
1474
1474
1475 Test capitalized section name
1475 Test capitalized section name
1476
1476
1477 $ hg help scripting.HGPLAIN > /dev/null
1477 $ hg help scripting.HGPLAIN > /dev/null
1478
1478
1479 Help subsection:
1479 Help subsection:
1480
1480
1481 $ hg help config.charsets |grep "Email example:" > /dev/null
1481 $ hg help config.charsets |grep "Email example:" > /dev/null
1482 [1]
1482 [1]
1483
1483
1484 Show nested definitions
1484 Show nested definitions
1485 ("profiling.type"[break]"ls"[break]"stat"[break])
1485 ("profiling.type"[break]"ls"[break]"stat"[break])
1486
1486
1487 $ hg help config.type | egrep '^$'|wc -l
1487 $ hg help config.type | egrep '^$'|wc -l
1488 \s*3 (re)
1488 \s*3 (re)
1489
1489
1490 $ hg help config.profiling.type.ls
1490 $ hg help config.profiling.type.ls
1491 "profiling.type.ls"
1491 "profiling.type.ls"
1492 Use Python's built-in instrumenting profiler. This profiler works on
1492 Use Python's built-in instrumenting profiler. This profiler works on
1493 all platforms, but each line number it reports is the first line of
1493 all platforms, but each line number it reports is the first line of
1494 a function. This restriction makes it difficult to identify the
1494 a function. This restriction makes it difficult to identify the
1495 expensive parts of a non-trivial function.
1495 expensive parts of a non-trivial function.
1496
1496
1497
1497
1498 Separate sections from subsections
1498 Separate sections from subsections
1499
1499
1500 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1500 $ hg help config.format | egrep '^ ("|-)|^\s*$' | uniq
1501 "format"
1501 "format"
1502 --------
1502 --------
1503
1503
1504 "usegeneraldelta"
1504 "usegeneraldelta"
1505
1505
1506 "dotencode"
1506 "dotencode"
1507
1507
1508 "usefncache"
1508 "usefncache"
1509
1509
1510 "usestore"
1510 "usestore"
1511
1511
1512 "sparse-revlog"
1512 "sparse-revlog"
1513
1513
1514 "revlog-compression"
1514 "revlog-compression"
1515
1515
1516 "bookmarks-in-store"
1517
1516 "profiling"
1518 "profiling"
1517 -----------
1519 -----------
1518
1520
1519 "format"
1521 "format"
1520
1522
1521 "progress"
1523 "progress"
1522 ----------
1524 ----------
1523
1525
1524 "format"
1526 "format"
1525
1527
1526
1528
1527 Last item in help config.*:
1529 Last item in help config.*:
1528
1530
1529 $ hg help config.`hg help config|grep '^ "'| \
1531 $ hg help config.`hg help config|grep '^ "'| \
1530 > tail -1|sed 's![ "]*!!g'`| \
1532 > tail -1|sed 's![ "]*!!g'`| \
1531 > grep 'hg help -c config' > /dev/null
1533 > grep 'hg help -c config' > /dev/null
1532 [1]
1534 [1]
1533
1535
1534 note to use help -c for general hg help config:
1536 note to use help -c for general hg help config:
1535
1537
1536 $ hg help config |grep 'hg help -c config' > /dev/null
1538 $ hg help config |grep 'hg help -c config' > /dev/null
1537
1539
1538 Test templating help
1540 Test templating help
1539
1541
1540 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1542 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
1541 desc String. The text of the changeset description.
1543 desc String. The text of the changeset description.
1542 diffstat String. Statistics of changes with the following format:
1544 diffstat String. Statistics of changes with the following format:
1543 firstline Any text. Returns the first line of text.
1545 firstline Any text. Returns the first line of text.
1544 nonempty Any text. Returns '(none)' if the string is empty.
1546 nonempty Any text. Returns '(none)' if the string is empty.
1545
1547
1546 Test deprecated items
1548 Test deprecated items
1547
1549
1548 $ hg help -v templating | grep currentbookmark
1550 $ hg help -v templating | grep currentbookmark
1549 currentbookmark
1551 currentbookmark
1550 $ hg help templating | (grep currentbookmark || true)
1552 $ hg help templating | (grep currentbookmark || true)
1551
1553
1552 Test help hooks
1554 Test help hooks
1553
1555
1554 $ cat > helphook1.py <<EOF
1556 $ cat > helphook1.py <<EOF
1555 > from mercurial import help
1557 > from mercurial import help
1556 >
1558 >
1557 > def rewrite(ui, topic, doc):
1559 > def rewrite(ui, topic, doc):
1558 > return doc + b'\nhelphook1\n'
1560 > return doc + b'\nhelphook1\n'
1559 >
1561 >
1560 > def extsetup(ui):
1562 > def extsetup(ui):
1561 > help.addtopichook(b'revisions', rewrite)
1563 > help.addtopichook(b'revisions', rewrite)
1562 > EOF
1564 > EOF
1563 $ cat > helphook2.py <<EOF
1565 $ cat > helphook2.py <<EOF
1564 > from mercurial import help
1566 > from mercurial import help
1565 >
1567 >
1566 > def rewrite(ui, topic, doc):
1568 > def rewrite(ui, topic, doc):
1567 > return doc + b'\nhelphook2\n'
1569 > return doc + b'\nhelphook2\n'
1568 >
1570 >
1569 > def extsetup(ui):
1571 > def extsetup(ui):
1570 > help.addtopichook(b'revisions', rewrite)
1572 > help.addtopichook(b'revisions', rewrite)
1571 > EOF
1573 > EOF
1572 $ echo '[extensions]' >> $HGRCPATH
1574 $ echo '[extensions]' >> $HGRCPATH
1573 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1575 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
1574 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1576 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
1575 $ hg help revsets | grep helphook
1577 $ hg help revsets | grep helphook
1576 helphook1
1578 helphook1
1577 helphook2
1579 helphook2
1578
1580
1579 help -c should only show debug --debug
1581 help -c should only show debug --debug
1580
1582
1581 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1583 $ hg help -c --debug|egrep debug|wc -l|egrep '^\s*0\s*$'
1582 [1]
1584 [1]
1583
1585
1584 help -c should only show deprecated for -v
1586 help -c should only show deprecated for -v
1585
1587
1586 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1588 $ hg help -c -v|egrep DEPRECATED|wc -l|egrep '^\s*0\s*$'
1587 [1]
1589 [1]
1588
1590
1589 Test -s / --system
1591 Test -s / --system
1590
1592
1591 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1593 $ hg help config.files -s windows |grep 'etc/mercurial' | \
1592 > wc -l | sed -e 's/ //g'
1594 > wc -l | sed -e 's/ //g'
1593 0
1595 0
1594 $ hg help config.files --system unix | grep 'USER' | \
1596 $ hg help config.files --system unix | grep 'USER' | \
1595 > wc -l | sed -e 's/ //g'
1597 > wc -l | sed -e 's/ //g'
1596 0
1598 0
1597
1599
1598 Test -e / -c / -k combinations
1600 Test -e / -c / -k combinations
1599
1601
1600 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1602 $ hg help -c|egrep '^[A-Z].*:|^ debug'
1601 Commands:
1603 Commands:
1602 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1604 $ hg help -e|egrep '^[A-Z].*:|^ debug'
1603 Extensions:
1605 Extensions:
1604 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1606 $ hg help -k|egrep '^[A-Z].*:|^ debug'
1605 Topics:
1607 Topics:
1606 Commands:
1608 Commands:
1607 Extensions:
1609 Extensions:
1608 Extension Commands:
1610 Extension Commands:
1609 $ hg help -c schemes
1611 $ hg help -c schemes
1610 abort: no such help topic: schemes
1612 abort: no such help topic: schemes
1611 (try 'hg help --keyword schemes')
1613 (try 'hg help --keyword schemes')
1612 [255]
1614 [255]
1613 $ hg help -e schemes |head -1
1615 $ hg help -e schemes |head -1
1614 schemes extension - extend schemes with shortcuts to repository swarms
1616 schemes extension - extend schemes with shortcuts to repository swarms
1615 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1617 $ hg help -c -k dates |egrep '^(Topics|Extensions|Commands):'
1616 Commands:
1618 Commands:
1617 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1619 $ hg help -e -k a |egrep '^(Topics|Extensions|Commands):'
1618 Extensions:
1620 Extensions:
1619 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1621 $ hg help -e -c -k date |egrep '^(Topics|Extensions|Commands):'
1620 Extensions:
1622 Extensions:
1621 Commands:
1623 Commands:
1622 $ hg help -c commit > /dev/null
1624 $ hg help -c commit > /dev/null
1623 $ hg help -e -c commit > /dev/null
1625 $ hg help -e -c commit > /dev/null
1624 $ hg help -e commit
1626 $ hg help -e commit
1625 abort: no such help topic: commit
1627 abort: no such help topic: commit
1626 (try 'hg help --keyword commit')
1628 (try 'hg help --keyword commit')
1627 [255]
1629 [255]
1628
1630
1629 Test keyword search help
1631 Test keyword search help
1630
1632
1631 $ cat > prefixedname.py <<EOF
1633 $ cat > prefixedname.py <<EOF
1632 > '''matched against word "clone"
1634 > '''matched against word "clone"
1633 > '''
1635 > '''
1634 > EOF
1636 > EOF
1635 $ echo '[extensions]' >> $HGRCPATH
1637 $ echo '[extensions]' >> $HGRCPATH
1636 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1638 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
1637 $ hg help -k clone
1639 $ hg help -k clone
1638 Topics:
1640 Topics:
1639
1641
1640 config Configuration Files
1642 config Configuration Files
1641 extensions Using Additional Features
1643 extensions Using Additional Features
1642 glossary Glossary
1644 glossary Glossary
1643 phases Working with Phases
1645 phases Working with Phases
1644 subrepos Subrepositories
1646 subrepos Subrepositories
1645 urls URL Paths
1647 urls URL Paths
1646
1648
1647 Commands:
1649 Commands:
1648
1650
1649 bookmarks create a new bookmark or list existing bookmarks
1651 bookmarks create a new bookmark or list existing bookmarks
1650 clone make a copy of an existing repository
1652 clone make a copy of an existing repository
1651 paths show aliases for remote repositories
1653 paths show aliases for remote repositories
1652 pull pull changes from the specified source
1654 pull pull changes from the specified source
1653 update update working directory (or switch revisions)
1655 update update working directory (or switch revisions)
1654
1656
1655 Extensions:
1657 Extensions:
1656
1658
1657 clonebundles advertise pre-generated bundles to seed clones
1659 clonebundles advertise pre-generated bundles to seed clones
1658 narrow create clones which fetch history data for subset of files
1660 narrow create clones which fetch history data for subset of files
1659 (EXPERIMENTAL)
1661 (EXPERIMENTAL)
1660 prefixedname matched against word "clone"
1662 prefixedname matched against word "clone"
1661 relink recreates hardlinks between repository clones
1663 relink recreates hardlinks between repository clones
1662
1664
1663 Extension Commands:
1665 Extension Commands:
1664
1666
1665 qclone clone main and patch repository at same time
1667 qclone clone main and patch repository at same time
1666
1668
1667 Test unfound topic
1669 Test unfound topic
1668
1670
1669 $ hg help nonexistingtopicthatwillneverexisteverever
1671 $ hg help nonexistingtopicthatwillneverexisteverever
1670 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1672 abort: no such help topic: nonexistingtopicthatwillneverexisteverever
1671 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1673 (try 'hg help --keyword nonexistingtopicthatwillneverexisteverever')
1672 [255]
1674 [255]
1673
1675
1674 Test unfound keyword
1676 Test unfound keyword
1675
1677
1676 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1678 $ hg help --keyword nonexistingwordthatwillneverexisteverever
1677 abort: no matches
1679 abort: no matches
1678 (try 'hg help' for a list of topics)
1680 (try 'hg help' for a list of topics)
1679 [255]
1681 [255]
1680
1682
1681 Test omit indicating for help
1683 Test omit indicating for help
1682
1684
1683 $ cat > addverboseitems.py <<EOF
1685 $ cat > addverboseitems.py <<EOF
1684 > r'''extension to test omit indicating.
1686 > r'''extension to test omit indicating.
1685 >
1687 >
1686 > This paragraph is never omitted (for extension)
1688 > This paragraph is never omitted (for extension)
1687 >
1689 >
1688 > .. container:: verbose
1690 > .. container:: verbose
1689 >
1691 >
1690 > This paragraph is omitted,
1692 > This paragraph is omitted,
1691 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1693 > if :hg:\`help\` is invoked without \`\`-v\`\` (for extension)
1692 >
1694 >
1693 > This paragraph is never omitted, too (for extension)
1695 > This paragraph is never omitted, too (for extension)
1694 > '''
1696 > '''
1695 > from __future__ import absolute_import
1697 > from __future__ import absolute_import
1696 > from mercurial import commands, help
1698 > from mercurial import commands, help
1697 > testtopic = br"""This paragraph is never omitted (for topic).
1699 > testtopic = br"""This paragraph is never omitted (for topic).
1698 >
1700 >
1699 > .. container:: verbose
1701 > .. container:: verbose
1700 >
1702 >
1701 > This paragraph is omitted,
1703 > This paragraph is omitted,
1702 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1704 > if :hg:\`help\` is invoked without \`\`-v\`\` (for topic)
1703 >
1705 >
1704 > This paragraph is never omitted, too (for topic)
1706 > This paragraph is never omitted, too (for topic)
1705 > """
1707 > """
1706 > def extsetup(ui):
1708 > def extsetup(ui):
1707 > help.helptable.append(([b"topic-containing-verbose"],
1709 > help.helptable.append(([b"topic-containing-verbose"],
1708 > b"This is the topic to test omit indicating.",
1710 > b"This is the topic to test omit indicating.",
1709 > lambda ui: testtopic))
1711 > lambda ui: testtopic))
1710 > EOF
1712 > EOF
1711 $ echo '[extensions]' >> $HGRCPATH
1713 $ echo '[extensions]' >> $HGRCPATH
1712 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1714 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
1713 $ hg help addverboseitems
1715 $ hg help addverboseitems
1714 addverboseitems extension - extension to test omit indicating.
1716 addverboseitems extension - extension to test omit indicating.
1715
1717
1716 This paragraph is never omitted (for extension)
1718 This paragraph is never omitted (for extension)
1717
1719
1718 This paragraph is never omitted, too (for extension)
1720 This paragraph is never omitted, too (for extension)
1719
1721
1720 (some details hidden, use --verbose to show complete help)
1722 (some details hidden, use --verbose to show complete help)
1721
1723
1722 no commands defined
1724 no commands defined
1723 $ hg help -v addverboseitems
1725 $ hg help -v addverboseitems
1724 addverboseitems extension - extension to test omit indicating.
1726 addverboseitems extension - extension to test omit indicating.
1725
1727
1726 This paragraph is never omitted (for extension)
1728 This paragraph is never omitted (for extension)
1727
1729
1728 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1730 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1729 extension)
1731 extension)
1730
1732
1731 This paragraph is never omitted, too (for extension)
1733 This paragraph is never omitted, too (for extension)
1732
1734
1733 no commands defined
1735 no commands defined
1734 $ hg help topic-containing-verbose
1736 $ hg help topic-containing-verbose
1735 This is the topic to test omit indicating.
1737 This is the topic to test omit indicating.
1736 """"""""""""""""""""""""""""""""""""""""""
1738 """"""""""""""""""""""""""""""""""""""""""
1737
1739
1738 This paragraph is never omitted (for topic).
1740 This paragraph is never omitted (for topic).
1739
1741
1740 This paragraph is never omitted, too (for topic)
1742 This paragraph is never omitted, too (for topic)
1741
1743
1742 (some details hidden, use --verbose to show complete help)
1744 (some details hidden, use --verbose to show complete help)
1743 $ hg help -v topic-containing-verbose
1745 $ hg help -v topic-containing-verbose
1744 This is the topic to test omit indicating.
1746 This is the topic to test omit indicating.
1745 """"""""""""""""""""""""""""""""""""""""""
1747 """"""""""""""""""""""""""""""""""""""""""
1746
1748
1747 This paragraph is never omitted (for topic).
1749 This paragraph is never omitted (for topic).
1748
1750
1749 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1751 This paragraph is omitted, if 'hg help' is invoked without "-v" (for
1750 topic)
1752 topic)
1751
1753
1752 This paragraph is never omitted, too (for topic)
1754 This paragraph is never omitted, too (for topic)
1753
1755
1754 Test section lookup
1756 Test section lookup
1755
1757
1756 $ hg help revset.merge
1758 $ hg help revset.merge
1757 "merge()"
1759 "merge()"
1758 Changeset is a merge changeset.
1760 Changeset is a merge changeset.
1759
1761
1760 $ hg help glossary.dag
1762 $ hg help glossary.dag
1761 DAG
1763 DAG
1762 The repository of changesets of a distributed version control system
1764 The repository of changesets of a distributed version control system
1763 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1765 (DVCS) can be described as a directed acyclic graph (DAG), consisting
1764 of nodes and edges, where nodes correspond to changesets and edges
1766 of nodes and edges, where nodes correspond to changesets and edges
1765 imply a parent -> child relation. This graph can be visualized by
1767 imply a parent -> child relation. This graph can be visualized by
1766 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1768 graphical tools such as 'hg log --graph'. In Mercurial, the DAG is
1767 limited by the requirement for children to have at most two parents.
1769 limited by the requirement for children to have at most two parents.
1768
1770
1769
1771
1770 $ hg help hgrc.paths
1772 $ hg help hgrc.paths
1771 "paths"
1773 "paths"
1772 -------
1774 -------
1773
1775
1774 Assigns symbolic names and behavior to repositories.
1776 Assigns symbolic names and behavior to repositories.
1775
1777
1776 Options are symbolic names defining the URL or directory that is the
1778 Options are symbolic names defining the URL or directory that is the
1777 location of the repository. Example:
1779 location of the repository. Example:
1778
1780
1779 [paths]
1781 [paths]
1780 my_server = https://example.com/my_repo
1782 my_server = https://example.com/my_repo
1781 local_path = /home/me/repo
1783 local_path = /home/me/repo
1782
1784
1783 These symbolic names can be used from the command line. To pull from
1785 These symbolic names can be used from the command line. To pull from
1784 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1786 "my_server": 'hg pull my_server'. To push to "local_path": 'hg push
1785 local_path'.
1787 local_path'.
1786
1788
1787 Options containing colons (":") denote sub-options that can influence
1789 Options containing colons (":") denote sub-options that can influence
1788 behavior for that specific path. Example:
1790 behavior for that specific path. Example:
1789
1791
1790 [paths]
1792 [paths]
1791 my_server = https://example.com/my_path
1793 my_server = https://example.com/my_path
1792 my_server:pushurl = ssh://example.com/my_path
1794 my_server:pushurl = ssh://example.com/my_path
1793
1795
1794 The following sub-options can be defined:
1796 The following sub-options can be defined:
1795
1797
1796 "pushurl"
1798 "pushurl"
1797 The URL to use for push operations. If not defined, the location
1799 The URL to use for push operations. If not defined, the location
1798 defined by the path's main entry is used.
1800 defined by the path's main entry is used.
1799
1801
1800 "pushrev"
1802 "pushrev"
1801 A revset defining which revisions to push by default.
1803 A revset defining which revisions to push by default.
1802
1804
1803 When 'hg push' is executed without a "-r" argument, the revset defined
1805 When 'hg push' is executed without a "-r" argument, the revset defined
1804 by this sub-option is evaluated to determine what to push.
1806 by this sub-option is evaluated to determine what to push.
1805
1807
1806 For example, a value of "." will push the working directory's revision
1808 For example, a value of "." will push the working directory's revision
1807 by default.
1809 by default.
1808
1810
1809 Revsets specifying bookmarks will not result in the bookmark being
1811 Revsets specifying bookmarks will not result in the bookmark being
1810 pushed.
1812 pushed.
1811
1813
1812 The following special named paths exist:
1814 The following special named paths exist:
1813
1815
1814 "default"
1816 "default"
1815 The URL or directory to use when no source or remote is specified.
1817 The URL or directory to use when no source or remote is specified.
1816
1818
1817 'hg clone' will automatically define this path to the location the
1819 'hg clone' will automatically define this path to the location the
1818 repository was cloned from.
1820 repository was cloned from.
1819
1821
1820 "default-push"
1822 "default-push"
1821 (deprecated) The URL or directory for the default 'hg push' location.
1823 (deprecated) The URL or directory for the default 'hg push' location.
1822 "default:pushurl" should be used instead.
1824 "default:pushurl" should be used instead.
1823
1825
1824 $ hg help glossary.mcguffin
1826 $ hg help glossary.mcguffin
1825 abort: help section not found: glossary.mcguffin
1827 abort: help section not found: glossary.mcguffin
1826 [255]
1828 [255]
1827
1829
1828 $ hg help glossary.mc.guffin
1830 $ hg help glossary.mc.guffin
1829 abort: help section not found: glossary.mc.guffin
1831 abort: help section not found: glossary.mc.guffin
1830 [255]
1832 [255]
1831
1833
1832 $ hg help template.files
1834 $ hg help template.files
1833 files List of strings. All files modified, added, or removed by
1835 files List of strings. All files modified, added, or removed by
1834 this changeset.
1836 this changeset.
1835 files(pattern)
1837 files(pattern)
1836 All files of the current changeset matching the pattern. See
1838 All files of the current changeset matching the pattern. See
1837 'hg help patterns'.
1839 'hg help patterns'.
1838
1840
1839 Test section lookup by translated message
1841 Test section lookup by translated message
1840
1842
1841 str.lower() instead of encoding.lower(str) on translated message might
1843 str.lower() instead of encoding.lower(str) on translated message might
1842 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1844 make message meaningless, because some encoding uses 0x41(A) - 0x5a(Z)
1843 as the second or later byte of multi-byte character.
1845 as the second or later byte of multi-byte character.
1844
1846
1845 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1847 For example, "\x8bL\x98^" (translation of "record" in ja_JP.cp932)
1846 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1848 contains 0x4c (L). str.lower() replaces 0x4c(L) by 0x6c(l) and this
1847 replacement makes message meaningless.
1849 replacement makes message meaningless.
1848
1850
1849 This tests that section lookup by translated string isn't broken by
1851 This tests that section lookup by translated string isn't broken by
1850 such str.lower().
1852 such str.lower().
1851
1853
1852 $ "$PYTHON" <<EOF
1854 $ "$PYTHON" <<EOF
1853 > def escape(s):
1855 > def escape(s):
1854 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1856 > return b''.join(b'\\u%x' % ord(uc) for uc in s.decode('cp932'))
1855 > # translation of "record" in ja_JP.cp932
1857 > # translation of "record" in ja_JP.cp932
1856 > upper = b"\x8bL\x98^"
1858 > upper = b"\x8bL\x98^"
1857 > # str.lower()-ed section name should be treated as different one
1859 > # str.lower()-ed section name should be treated as different one
1858 > lower = b"\x8bl\x98^"
1860 > lower = b"\x8bl\x98^"
1859 > with open('ambiguous.py', 'wb') as fp:
1861 > with open('ambiguous.py', 'wb') as fp:
1860 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1862 > fp.write(b"""# ambiguous section names in ja_JP.cp932
1861 > u'''summary of extension
1863 > u'''summary of extension
1862 >
1864 >
1863 > %s
1865 > %s
1864 > ----
1866 > ----
1865 >
1867 >
1866 > Upper name should show only this message
1868 > Upper name should show only this message
1867 >
1869 >
1868 > %s
1870 > %s
1869 > ----
1871 > ----
1870 >
1872 >
1871 > Lower name should show only this message
1873 > Lower name should show only this message
1872 >
1874 >
1873 > subsequent section
1875 > subsequent section
1874 > ------------------
1876 > ------------------
1875 >
1877 >
1876 > This should be hidden at 'hg help ambiguous' with section name.
1878 > This should be hidden at 'hg help ambiguous' with section name.
1877 > '''
1879 > '''
1878 > """ % (escape(upper), escape(lower)))
1880 > """ % (escape(upper), escape(lower)))
1879 > EOF
1881 > EOF
1880
1882
1881 $ cat >> $HGRCPATH <<EOF
1883 $ cat >> $HGRCPATH <<EOF
1882 > [extensions]
1884 > [extensions]
1883 > ambiguous = ./ambiguous.py
1885 > ambiguous = ./ambiguous.py
1884 > EOF
1886 > EOF
1885
1887
1886 $ "$PYTHON" <<EOF | sh
1888 $ "$PYTHON" <<EOF | sh
1887 > from mercurial import pycompat
1889 > from mercurial import pycompat
1888 > upper = b"\x8bL\x98^"
1890 > upper = b"\x8bL\x98^"
1889 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1891 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % upper)
1890 > EOF
1892 > EOF
1891 \x8bL\x98^ (esc)
1893 \x8bL\x98^ (esc)
1892 ----
1894 ----
1893
1895
1894 Upper name should show only this message
1896 Upper name should show only this message
1895
1897
1896
1898
1897 $ "$PYTHON" <<EOF | sh
1899 $ "$PYTHON" <<EOF | sh
1898 > from mercurial import pycompat
1900 > from mercurial import pycompat
1899 > lower = b"\x8bl\x98^"
1901 > lower = b"\x8bl\x98^"
1900 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1902 > pycompat.stdout.write(b"hg --encoding cp932 help -e ambiguous.%s\n" % lower)
1901 > EOF
1903 > EOF
1902 \x8bl\x98^ (esc)
1904 \x8bl\x98^ (esc)
1903 ----
1905 ----
1904
1906
1905 Lower name should show only this message
1907 Lower name should show only this message
1906
1908
1907
1909
1908 $ cat >> $HGRCPATH <<EOF
1910 $ cat >> $HGRCPATH <<EOF
1909 > [extensions]
1911 > [extensions]
1910 > ambiguous = !
1912 > ambiguous = !
1911 > EOF
1913 > EOF
1912
1914
1913 Show help content of disabled extensions
1915 Show help content of disabled extensions
1914
1916
1915 $ cat >> $HGRCPATH <<EOF
1917 $ cat >> $HGRCPATH <<EOF
1916 > [extensions]
1918 > [extensions]
1917 > ambiguous = !./ambiguous.py
1919 > ambiguous = !./ambiguous.py
1918 > EOF
1920 > EOF
1919 $ hg help -e ambiguous
1921 $ hg help -e ambiguous
1920 ambiguous extension - (no help text available)
1922 ambiguous extension - (no help text available)
1921
1923
1922 (use 'hg help extensions' for information on enabling extensions)
1924 (use 'hg help extensions' for information on enabling extensions)
1923
1925
1924 Test dynamic list of merge tools only shows up once
1926 Test dynamic list of merge tools only shows up once
1925 $ hg help merge-tools
1927 $ hg help merge-tools
1926 Merge Tools
1928 Merge Tools
1927 """""""""""
1929 """""""""""
1928
1930
1929 To merge files Mercurial uses merge tools.
1931 To merge files Mercurial uses merge tools.
1930
1932
1931 A merge tool combines two different versions of a file into a merged file.
1933 A merge tool combines two different versions of a file into a merged file.
1932 Merge tools are given the two files and the greatest common ancestor of
1934 Merge tools are given the two files and the greatest common ancestor of
1933 the two file versions, so they can determine the changes made on both
1935 the two file versions, so they can determine the changes made on both
1934 branches.
1936 branches.
1935
1937
1936 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1938 Merge tools are used both for 'hg resolve', 'hg merge', 'hg update', 'hg
1937 backout' and in several extensions.
1939 backout' and in several extensions.
1938
1940
1939 Usually, the merge tool tries to automatically reconcile the files by
1941 Usually, the merge tool tries to automatically reconcile the files by
1940 combining all non-overlapping changes that occurred separately in the two
1942 combining all non-overlapping changes that occurred separately in the two
1941 different evolutions of the same initial base file. Furthermore, some
1943 different evolutions of the same initial base file. Furthermore, some
1942 interactive merge programs make it easier to manually resolve conflicting
1944 interactive merge programs make it easier to manually resolve conflicting
1943 merges, either in a graphical way, or by inserting some conflict markers.
1945 merges, either in a graphical way, or by inserting some conflict markers.
1944 Mercurial does not include any interactive merge programs but relies on
1946 Mercurial does not include any interactive merge programs but relies on
1945 external tools for that.
1947 external tools for that.
1946
1948
1947 Available merge tools
1949 Available merge tools
1948 =====================
1950 =====================
1949
1951
1950 External merge tools and their properties are configured in the merge-
1952 External merge tools and their properties are configured in the merge-
1951 tools configuration section - see hgrc(5) - but they can often just be
1953 tools configuration section - see hgrc(5) - but they can often just be
1952 named by their executable.
1954 named by their executable.
1953
1955
1954 A merge tool is generally usable if its executable can be found on the
1956 A merge tool is generally usable if its executable can be found on the
1955 system and if it can handle the merge. The executable is found if it is an
1957 system and if it can handle the merge. The executable is found if it is an
1956 absolute or relative executable path or the name of an application in the
1958 absolute or relative executable path or the name of an application in the
1957 executable search path. The tool is assumed to be able to handle the merge
1959 executable search path. The tool is assumed to be able to handle the merge
1958 if it can handle symlinks if the file is a symlink, if it can handle
1960 if it can handle symlinks if the file is a symlink, if it can handle
1959 binary files if the file is binary, and if a GUI is available if the tool
1961 binary files if the file is binary, and if a GUI is available if the tool
1960 requires a GUI.
1962 requires a GUI.
1961
1963
1962 There are some internal merge tools which can be used. The internal merge
1964 There are some internal merge tools which can be used. The internal merge
1963 tools are:
1965 tools are:
1964
1966
1965 ":dump"
1967 ":dump"
1966 Creates three versions of the files to merge, containing the contents of
1968 Creates three versions of the files to merge, containing the contents of
1967 local, other and base. These files can then be used to perform a merge
1969 local, other and base. These files can then be used to perform a merge
1968 manually. If the file to be merged is named "a.txt", these files will
1970 manually. If the file to be merged is named "a.txt", these files will
1969 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1971 accordingly be named "a.txt.local", "a.txt.other" and "a.txt.base" and
1970 they will be placed in the same directory as "a.txt".
1972 they will be placed in the same directory as "a.txt".
1971
1973
1972 This implies premerge. Therefore, files aren't dumped, if premerge runs
1974 This implies premerge. Therefore, files aren't dumped, if premerge runs
1973 successfully. Use :forcedump to forcibly write files out.
1975 successfully. Use :forcedump to forcibly write files out.
1974
1976
1975 (actual capabilities: binary, symlink)
1977 (actual capabilities: binary, symlink)
1976
1978
1977 ":fail"
1979 ":fail"
1978 Rather than attempting to merge files that were modified on both
1980 Rather than attempting to merge files that were modified on both
1979 branches, it marks them as unresolved. The resolve command must be used
1981 branches, it marks them as unresolved. The resolve command must be used
1980 to resolve these conflicts.
1982 to resolve these conflicts.
1981
1983
1982 (actual capabilities: binary, symlink)
1984 (actual capabilities: binary, symlink)
1983
1985
1984 ":forcedump"
1986 ":forcedump"
1985 Creates three versions of the files as same as :dump, but omits
1987 Creates three versions of the files as same as :dump, but omits
1986 premerge.
1988 premerge.
1987
1989
1988 (actual capabilities: binary, symlink)
1990 (actual capabilities: binary, symlink)
1989
1991
1990 ":local"
1992 ":local"
1991 Uses the local 'p1()' version of files as the merged version.
1993 Uses the local 'p1()' version of files as the merged version.
1992
1994
1993 (actual capabilities: binary, symlink)
1995 (actual capabilities: binary, symlink)
1994
1996
1995 ":merge"
1997 ":merge"
1996 Uses the internal non-interactive simple merge algorithm for merging
1998 Uses the internal non-interactive simple merge algorithm for merging
1997 files. It will fail if there are any conflicts and leave markers in the
1999 files. It will fail if there are any conflicts and leave markers in the
1998 partially merged file. Markers will have two sections, one for each side
2000 partially merged file. Markers will have two sections, one for each side
1999 of merge.
2001 of merge.
2000
2002
2001 ":merge-local"
2003 ":merge-local"
2002 Like :merge, but resolve all conflicts non-interactively in favor of the
2004 Like :merge, but resolve all conflicts non-interactively in favor of the
2003 local 'p1()' changes.
2005 local 'p1()' changes.
2004
2006
2005 ":merge-other"
2007 ":merge-other"
2006 Like :merge, but resolve all conflicts non-interactively in favor of the
2008 Like :merge, but resolve all conflicts non-interactively in favor of the
2007 other 'p2()' changes.
2009 other 'p2()' changes.
2008
2010
2009 ":merge3"
2011 ":merge3"
2010 Uses the internal non-interactive simple merge algorithm for merging
2012 Uses the internal non-interactive simple merge algorithm for merging
2011 files. It will fail if there are any conflicts and leave markers in the
2013 files. It will fail if there are any conflicts and leave markers in the
2012 partially merged file. Marker will have three sections, one from each
2014 partially merged file. Marker will have three sections, one from each
2013 side of the merge and one for the base content.
2015 side of the merge and one for the base content.
2014
2016
2015 ":other"
2017 ":other"
2016 Uses the other 'p2()' version of files as the merged version.
2018 Uses the other 'p2()' version of files as the merged version.
2017
2019
2018 (actual capabilities: binary, symlink)
2020 (actual capabilities: binary, symlink)
2019
2021
2020 ":prompt"
2022 ":prompt"
2021 Asks the user which of the local 'p1()' or the other 'p2()' version to
2023 Asks the user which of the local 'p1()' or the other 'p2()' version to
2022 keep as the merged version.
2024 keep as the merged version.
2023
2025
2024 (actual capabilities: binary, symlink)
2026 (actual capabilities: binary, symlink)
2025
2027
2026 ":tagmerge"
2028 ":tagmerge"
2027 Uses the internal tag merge algorithm (experimental).
2029 Uses the internal tag merge algorithm (experimental).
2028
2030
2029 ":union"
2031 ":union"
2030 Uses the internal non-interactive simple merge algorithm for merging
2032 Uses the internal non-interactive simple merge algorithm for merging
2031 files. It will use both left and right sides for conflict regions. No
2033 files. It will use both left and right sides for conflict regions. No
2032 markers are inserted.
2034 markers are inserted.
2033
2035
2034 Internal tools are always available and do not require a GUI but will by
2036 Internal tools are always available and do not require a GUI but will by
2035 default not handle symlinks or binary files. See next section for detail
2037 default not handle symlinks or binary files. See next section for detail
2036 about "actual capabilities" described above.
2038 about "actual capabilities" described above.
2037
2039
2038 Choosing a merge tool
2040 Choosing a merge tool
2039 =====================
2041 =====================
2040
2042
2041 Mercurial uses these rules when deciding which merge tool to use:
2043 Mercurial uses these rules when deciding which merge tool to use:
2042
2044
2043 1. If a tool has been specified with the --tool option to merge or
2045 1. If a tool has been specified with the --tool option to merge or
2044 resolve, it is used. If it is the name of a tool in the merge-tools
2046 resolve, it is used. If it is the name of a tool in the merge-tools
2045 configuration, its configuration is used. Otherwise the specified tool
2047 configuration, its configuration is used. Otherwise the specified tool
2046 must be executable by the shell.
2048 must be executable by the shell.
2047 2. If the "HGMERGE" environment variable is present, its value is used and
2049 2. If the "HGMERGE" environment variable is present, its value is used and
2048 must be executable by the shell.
2050 must be executable by the shell.
2049 3. If the filename of the file to be merged matches any of the patterns in
2051 3. If the filename of the file to be merged matches any of the patterns in
2050 the merge-patterns configuration section, the first usable merge tool
2052 the merge-patterns configuration section, the first usable merge tool
2051 corresponding to a matching pattern is used.
2053 corresponding to a matching pattern is used.
2052 4. If ui.merge is set it will be considered next. If the value is not the
2054 4. If ui.merge is set it will be considered next. If the value is not the
2053 name of a configured tool, the specified value is used and must be
2055 name of a configured tool, the specified value is used and must be
2054 executable by the shell. Otherwise the named tool is used if it is
2056 executable by the shell. Otherwise the named tool is used if it is
2055 usable.
2057 usable.
2056 5. If any usable merge tools are present in the merge-tools configuration
2058 5. If any usable merge tools are present in the merge-tools configuration
2057 section, the one with the highest priority is used.
2059 section, the one with the highest priority is used.
2058 6. If a program named "hgmerge" can be found on the system, it is used -
2060 6. If a program named "hgmerge" can be found on the system, it is used -
2059 but it will by default not be used for symlinks and binary files.
2061 but it will by default not be used for symlinks and binary files.
2060 7. If the file to be merged is not binary and is not a symlink, then
2062 7. If the file to be merged is not binary and is not a symlink, then
2061 internal ":merge" is used.
2063 internal ":merge" is used.
2062 8. Otherwise, ":prompt" is used.
2064 8. Otherwise, ":prompt" is used.
2063
2065
2064 For historical reason, Mercurial treats merge tools as below while
2066 For historical reason, Mercurial treats merge tools as below while
2065 examining rules above.
2067 examining rules above.
2066
2068
2067 step specified via binary symlink
2069 step specified via binary symlink
2068 ----------------------------------
2070 ----------------------------------
2069 1. --tool o/o o/o
2071 1. --tool o/o o/o
2070 2. HGMERGE o/o o/o
2072 2. HGMERGE o/o o/o
2071 3. merge-patterns o/o(*) x/?(*)
2073 3. merge-patterns o/o(*) x/?(*)
2072 4. ui.merge x/?(*) x/?(*)
2074 4. ui.merge x/?(*) x/?(*)
2073
2075
2074 Each capability column indicates Mercurial behavior for internal/external
2076 Each capability column indicates Mercurial behavior for internal/external
2075 merge tools at examining each rule.
2077 merge tools at examining each rule.
2076
2078
2077 - "o": "assume that a tool has capability"
2079 - "o": "assume that a tool has capability"
2078 - "x": "assume that a tool does not have capability"
2080 - "x": "assume that a tool does not have capability"
2079 - "?": "check actual capability of a tool"
2081 - "?": "check actual capability of a tool"
2080
2082
2081 If "merge.strict-capability-check" configuration is true, Mercurial checks
2083 If "merge.strict-capability-check" configuration is true, Mercurial checks
2082 capabilities of merge tools strictly in (*) cases above (= each capability
2084 capabilities of merge tools strictly in (*) cases above (= each capability
2083 column becomes "?/?"). It is false by default for backward compatibility.
2085 column becomes "?/?"). It is false by default for backward compatibility.
2084
2086
2085 Note:
2087 Note:
2086 After selecting a merge program, Mercurial will by default attempt to
2088 After selecting a merge program, Mercurial will by default attempt to
2087 merge the files using a simple merge algorithm first. Only if it
2089 merge the files using a simple merge algorithm first. Only if it
2088 doesn't succeed because of conflicting changes will Mercurial actually
2090 doesn't succeed because of conflicting changes will Mercurial actually
2089 execute the merge program. Whether to use the simple merge algorithm
2091 execute the merge program. Whether to use the simple merge algorithm
2090 first can be controlled by the premerge setting of the merge tool.
2092 first can be controlled by the premerge setting of the merge tool.
2091 Premerge is enabled by default unless the file is binary or a symlink.
2093 Premerge is enabled by default unless the file is binary or a symlink.
2092
2094
2093 See the merge-tools and ui sections of hgrc(5) for details on the
2095 See the merge-tools and ui sections of hgrc(5) for details on the
2094 configuration of merge tools.
2096 configuration of merge tools.
2095
2097
2096 Compression engines listed in `hg help bundlespec`
2098 Compression engines listed in `hg help bundlespec`
2097
2099
2098 $ hg help bundlespec | grep gzip
2100 $ hg help bundlespec | grep gzip
2099 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2101 "v1" bundles can only use the "gzip", "bzip2", and "none" compression
2100 An algorithm that produces smaller bundles than "gzip".
2102 An algorithm that produces smaller bundles than "gzip".
2101 This engine will likely produce smaller bundles than "gzip" but will be
2103 This engine will likely produce smaller bundles than "gzip" but will be
2102 "gzip"
2104 "gzip"
2103 better compression than "gzip". It also frequently yields better (?)
2105 better compression than "gzip". It also frequently yields better (?)
2104
2106
2105 Test usage of section marks in help documents
2107 Test usage of section marks in help documents
2106
2108
2107 $ cd "$TESTDIR"/../doc
2109 $ cd "$TESTDIR"/../doc
2108 $ "$PYTHON" check-seclevel.py
2110 $ "$PYTHON" check-seclevel.py
2109 $ cd $TESTTMP
2111 $ cd $TESTTMP
2110
2112
2111 #if serve
2113 #if serve
2112
2114
2113 Test the help pages in hgweb.
2115 Test the help pages in hgweb.
2114
2116
2115 Dish up an empty repo; serve it cold.
2117 Dish up an empty repo; serve it cold.
2116
2118
2117 $ hg init "$TESTTMP/test"
2119 $ hg init "$TESTTMP/test"
2118 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2120 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
2119 $ cat hg.pid >> $DAEMON_PIDS
2121 $ cat hg.pid >> $DAEMON_PIDS
2120
2122
2121 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2123 $ get-with-headers.py $LOCALIP:$HGPORT "help"
2122 200 Script output follows
2124 200 Script output follows
2123
2125
2124 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2126 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2125 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2127 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2126 <head>
2128 <head>
2127 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2129 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2128 <meta name="robots" content="index, nofollow" />
2130 <meta name="robots" content="index, nofollow" />
2129 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2131 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2130 <script type="text/javascript" src="/static/mercurial.js"></script>
2132 <script type="text/javascript" src="/static/mercurial.js"></script>
2131
2133
2132 <title>Help: Index</title>
2134 <title>Help: Index</title>
2133 </head>
2135 </head>
2134 <body>
2136 <body>
2135
2137
2136 <div class="container">
2138 <div class="container">
2137 <div class="menu">
2139 <div class="menu">
2138 <div class="logo">
2140 <div class="logo">
2139 <a href="https://mercurial-scm.org/">
2141 <a href="https://mercurial-scm.org/">
2140 <img src="/static/hglogo.png" alt="mercurial" /></a>
2142 <img src="/static/hglogo.png" alt="mercurial" /></a>
2141 </div>
2143 </div>
2142 <ul>
2144 <ul>
2143 <li><a href="/shortlog">log</a></li>
2145 <li><a href="/shortlog">log</a></li>
2144 <li><a href="/graph">graph</a></li>
2146 <li><a href="/graph">graph</a></li>
2145 <li><a href="/tags">tags</a></li>
2147 <li><a href="/tags">tags</a></li>
2146 <li><a href="/bookmarks">bookmarks</a></li>
2148 <li><a href="/bookmarks">bookmarks</a></li>
2147 <li><a href="/branches">branches</a></li>
2149 <li><a href="/branches">branches</a></li>
2148 </ul>
2150 </ul>
2149 <ul>
2151 <ul>
2150 <li class="active">help</li>
2152 <li class="active">help</li>
2151 </ul>
2153 </ul>
2152 </div>
2154 </div>
2153
2155
2154 <div class="main">
2156 <div class="main">
2155 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2157 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2156
2158
2157 <form class="search" action="/log">
2159 <form class="search" action="/log">
2158
2160
2159 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2161 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2160 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2162 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2161 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2163 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2162 </form>
2164 </form>
2163 <table class="bigtable">
2165 <table class="bigtable">
2164 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2166 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
2165
2167
2166 <tr><td>
2168 <tr><td>
2167 <a href="/help/bundlespec">
2169 <a href="/help/bundlespec">
2168 bundlespec
2170 bundlespec
2169 </a>
2171 </a>
2170 </td><td>
2172 </td><td>
2171 Bundle File Formats
2173 Bundle File Formats
2172 </td></tr>
2174 </td></tr>
2173 <tr><td>
2175 <tr><td>
2174 <a href="/help/color">
2176 <a href="/help/color">
2175 color
2177 color
2176 </a>
2178 </a>
2177 </td><td>
2179 </td><td>
2178 Colorizing Outputs
2180 Colorizing Outputs
2179 </td></tr>
2181 </td></tr>
2180 <tr><td>
2182 <tr><td>
2181 <a href="/help/config">
2183 <a href="/help/config">
2182 config
2184 config
2183 </a>
2185 </a>
2184 </td><td>
2186 </td><td>
2185 Configuration Files
2187 Configuration Files
2186 </td></tr>
2188 </td></tr>
2187 <tr><td>
2189 <tr><td>
2188 <a href="/help/dates">
2190 <a href="/help/dates">
2189 dates
2191 dates
2190 </a>
2192 </a>
2191 </td><td>
2193 </td><td>
2192 Date Formats
2194 Date Formats
2193 </td></tr>
2195 </td></tr>
2194 <tr><td>
2196 <tr><td>
2195 <a href="/help/deprecated">
2197 <a href="/help/deprecated">
2196 deprecated
2198 deprecated
2197 </a>
2199 </a>
2198 </td><td>
2200 </td><td>
2199 Deprecated Features
2201 Deprecated Features
2200 </td></tr>
2202 </td></tr>
2201 <tr><td>
2203 <tr><td>
2202 <a href="/help/diffs">
2204 <a href="/help/diffs">
2203 diffs
2205 diffs
2204 </a>
2206 </a>
2205 </td><td>
2207 </td><td>
2206 Diff Formats
2208 Diff Formats
2207 </td></tr>
2209 </td></tr>
2208 <tr><td>
2210 <tr><td>
2209 <a href="/help/environment">
2211 <a href="/help/environment">
2210 environment
2212 environment
2211 </a>
2213 </a>
2212 </td><td>
2214 </td><td>
2213 Environment Variables
2215 Environment Variables
2214 </td></tr>
2216 </td></tr>
2215 <tr><td>
2217 <tr><td>
2216 <a href="/help/extensions">
2218 <a href="/help/extensions">
2217 extensions
2219 extensions
2218 </a>
2220 </a>
2219 </td><td>
2221 </td><td>
2220 Using Additional Features
2222 Using Additional Features
2221 </td></tr>
2223 </td></tr>
2222 <tr><td>
2224 <tr><td>
2223 <a href="/help/filesets">
2225 <a href="/help/filesets">
2224 filesets
2226 filesets
2225 </a>
2227 </a>
2226 </td><td>
2228 </td><td>
2227 Specifying File Sets
2229 Specifying File Sets
2228 </td></tr>
2230 </td></tr>
2229 <tr><td>
2231 <tr><td>
2230 <a href="/help/flags">
2232 <a href="/help/flags">
2231 flags
2233 flags
2232 </a>
2234 </a>
2233 </td><td>
2235 </td><td>
2234 Command-line flags
2236 Command-line flags
2235 </td></tr>
2237 </td></tr>
2236 <tr><td>
2238 <tr><td>
2237 <a href="/help/glossary">
2239 <a href="/help/glossary">
2238 glossary
2240 glossary
2239 </a>
2241 </a>
2240 </td><td>
2242 </td><td>
2241 Glossary
2243 Glossary
2242 </td></tr>
2244 </td></tr>
2243 <tr><td>
2245 <tr><td>
2244 <a href="/help/hgignore">
2246 <a href="/help/hgignore">
2245 hgignore
2247 hgignore
2246 </a>
2248 </a>
2247 </td><td>
2249 </td><td>
2248 Syntax for Mercurial Ignore Files
2250 Syntax for Mercurial Ignore Files
2249 </td></tr>
2251 </td></tr>
2250 <tr><td>
2252 <tr><td>
2251 <a href="/help/hgweb">
2253 <a href="/help/hgweb">
2252 hgweb
2254 hgweb
2253 </a>
2255 </a>
2254 </td><td>
2256 </td><td>
2255 Configuring hgweb
2257 Configuring hgweb
2256 </td></tr>
2258 </td></tr>
2257 <tr><td>
2259 <tr><td>
2258 <a href="/help/internals">
2260 <a href="/help/internals">
2259 internals
2261 internals
2260 </a>
2262 </a>
2261 </td><td>
2263 </td><td>
2262 Technical implementation topics
2264 Technical implementation topics
2263 </td></tr>
2265 </td></tr>
2264 <tr><td>
2266 <tr><td>
2265 <a href="/help/merge-tools">
2267 <a href="/help/merge-tools">
2266 merge-tools
2268 merge-tools
2267 </a>
2269 </a>
2268 </td><td>
2270 </td><td>
2269 Merge Tools
2271 Merge Tools
2270 </td></tr>
2272 </td></tr>
2271 <tr><td>
2273 <tr><td>
2272 <a href="/help/pager">
2274 <a href="/help/pager">
2273 pager
2275 pager
2274 </a>
2276 </a>
2275 </td><td>
2277 </td><td>
2276 Pager Support
2278 Pager Support
2277 </td></tr>
2279 </td></tr>
2278 <tr><td>
2280 <tr><td>
2279 <a href="/help/patterns">
2281 <a href="/help/patterns">
2280 patterns
2282 patterns
2281 </a>
2283 </a>
2282 </td><td>
2284 </td><td>
2283 File Name Patterns
2285 File Name Patterns
2284 </td></tr>
2286 </td></tr>
2285 <tr><td>
2287 <tr><td>
2286 <a href="/help/phases">
2288 <a href="/help/phases">
2287 phases
2289 phases
2288 </a>
2290 </a>
2289 </td><td>
2291 </td><td>
2290 Working with Phases
2292 Working with Phases
2291 </td></tr>
2293 </td></tr>
2292 <tr><td>
2294 <tr><td>
2293 <a href="/help/revisions">
2295 <a href="/help/revisions">
2294 revisions
2296 revisions
2295 </a>
2297 </a>
2296 </td><td>
2298 </td><td>
2297 Specifying Revisions
2299 Specifying Revisions
2298 </td></tr>
2300 </td></tr>
2299 <tr><td>
2301 <tr><td>
2300 <a href="/help/scripting">
2302 <a href="/help/scripting">
2301 scripting
2303 scripting
2302 </a>
2304 </a>
2303 </td><td>
2305 </td><td>
2304 Using Mercurial from scripts and automation
2306 Using Mercurial from scripts and automation
2305 </td></tr>
2307 </td></tr>
2306 <tr><td>
2308 <tr><td>
2307 <a href="/help/subrepos">
2309 <a href="/help/subrepos">
2308 subrepos
2310 subrepos
2309 </a>
2311 </a>
2310 </td><td>
2312 </td><td>
2311 Subrepositories
2313 Subrepositories
2312 </td></tr>
2314 </td></tr>
2313 <tr><td>
2315 <tr><td>
2314 <a href="/help/templating">
2316 <a href="/help/templating">
2315 templating
2317 templating
2316 </a>
2318 </a>
2317 </td><td>
2319 </td><td>
2318 Template Usage
2320 Template Usage
2319 </td></tr>
2321 </td></tr>
2320 <tr><td>
2322 <tr><td>
2321 <a href="/help/urls">
2323 <a href="/help/urls">
2322 urls
2324 urls
2323 </a>
2325 </a>
2324 </td><td>
2326 </td><td>
2325 URL Paths
2327 URL Paths
2326 </td></tr>
2328 </td></tr>
2327 <tr><td>
2329 <tr><td>
2328 <a href="/help/topic-containing-verbose">
2330 <a href="/help/topic-containing-verbose">
2329 topic-containing-verbose
2331 topic-containing-verbose
2330 </a>
2332 </a>
2331 </td><td>
2333 </td><td>
2332 This is the topic to test omit indicating.
2334 This is the topic to test omit indicating.
2333 </td></tr>
2335 </td></tr>
2334
2336
2335
2337
2336 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2338 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
2337
2339
2338 <tr><td>
2340 <tr><td>
2339 <a href="/help/add">
2341 <a href="/help/add">
2340 add
2342 add
2341 </a>
2343 </a>
2342 </td><td>
2344 </td><td>
2343 add the specified files on the next commit
2345 add the specified files on the next commit
2344 </td></tr>
2346 </td></tr>
2345 <tr><td>
2347 <tr><td>
2346 <a href="/help/annotate">
2348 <a href="/help/annotate">
2347 annotate
2349 annotate
2348 </a>
2350 </a>
2349 </td><td>
2351 </td><td>
2350 show changeset information by line for each file
2352 show changeset information by line for each file
2351 </td></tr>
2353 </td></tr>
2352 <tr><td>
2354 <tr><td>
2353 <a href="/help/clone">
2355 <a href="/help/clone">
2354 clone
2356 clone
2355 </a>
2357 </a>
2356 </td><td>
2358 </td><td>
2357 make a copy of an existing repository
2359 make a copy of an existing repository
2358 </td></tr>
2360 </td></tr>
2359 <tr><td>
2361 <tr><td>
2360 <a href="/help/commit">
2362 <a href="/help/commit">
2361 commit
2363 commit
2362 </a>
2364 </a>
2363 </td><td>
2365 </td><td>
2364 commit the specified files or all outstanding changes
2366 commit the specified files or all outstanding changes
2365 </td></tr>
2367 </td></tr>
2366 <tr><td>
2368 <tr><td>
2367 <a href="/help/diff">
2369 <a href="/help/diff">
2368 diff
2370 diff
2369 </a>
2371 </a>
2370 </td><td>
2372 </td><td>
2371 diff repository (or selected files)
2373 diff repository (or selected files)
2372 </td></tr>
2374 </td></tr>
2373 <tr><td>
2375 <tr><td>
2374 <a href="/help/export">
2376 <a href="/help/export">
2375 export
2377 export
2376 </a>
2378 </a>
2377 </td><td>
2379 </td><td>
2378 dump the header and diffs for one or more changesets
2380 dump the header and diffs for one or more changesets
2379 </td></tr>
2381 </td></tr>
2380 <tr><td>
2382 <tr><td>
2381 <a href="/help/forget">
2383 <a href="/help/forget">
2382 forget
2384 forget
2383 </a>
2385 </a>
2384 </td><td>
2386 </td><td>
2385 forget the specified files on the next commit
2387 forget the specified files on the next commit
2386 </td></tr>
2388 </td></tr>
2387 <tr><td>
2389 <tr><td>
2388 <a href="/help/init">
2390 <a href="/help/init">
2389 init
2391 init
2390 </a>
2392 </a>
2391 </td><td>
2393 </td><td>
2392 create a new repository in the given directory
2394 create a new repository in the given directory
2393 </td></tr>
2395 </td></tr>
2394 <tr><td>
2396 <tr><td>
2395 <a href="/help/log">
2397 <a href="/help/log">
2396 log
2398 log
2397 </a>
2399 </a>
2398 </td><td>
2400 </td><td>
2399 show revision history of entire repository or files
2401 show revision history of entire repository or files
2400 </td></tr>
2402 </td></tr>
2401 <tr><td>
2403 <tr><td>
2402 <a href="/help/merge">
2404 <a href="/help/merge">
2403 merge
2405 merge
2404 </a>
2406 </a>
2405 </td><td>
2407 </td><td>
2406 merge another revision into working directory
2408 merge another revision into working directory
2407 </td></tr>
2409 </td></tr>
2408 <tr><td>
2410 <tr><td>
2409 <a href="/help/pull">
2411 <a href="/help/pull">
2410 pull
2412 pull
2411 </a>
2413 </a>
2412 </td><td>
2414 </td><td>
2413 pull changes from the specified source
2415 pull changes from the specified source
2414 </td></tr>
2416 </td></tr>
2415 <tr><td>
2417 <tr><td>
2416 <a href="/help/push">
2418 <a href="/help/push">
2417 push
2419 push
2418 </a>
2420 </a>
2419 </td><td>
2421 </td><td>
2420 push changes to the specified destination
2422 push changes to the specified destination
2421 </td></tr>
2423 </td></tr>
2422 <tr><td>
2424 <tr><td>
2423 <a href="/help/remove">
2425 <a href="/help/remove">
2424 remove
2426 remove
2425 </a>
2427 </a>
2426 </td><td>
2428 </td><td>
2427 remove the specified files on the next commit
2429 remove the specified files on the next commit
2428 </td></tr>
2430 </td></tr>
2429 <tr><td>
2431 <tr><td>
2430 <a href="/help/serve">
2432 <a href="/help/serve">
2431 serve
2433 serve
2432 </a>
2434 </a>
2433 </td><td>
2435 </td><td>
2434 start stand-alone webserver
2436 start stand-alone webserver
2435 </td></tr>
2437 </td></tr>
2436 <tr><td>
2438 <tr><td>
2437 <a href="/help/status">
2439 <a href="/help/status">
2438 status
2440 status
2439 </a>
2441 </a>
2440 </td><td>
2442 </td><td>
2441 show changed files in the working directory
2443 show changed files in the working directory
2442 </td></tr>
2444 </td></tr>
2443 <tr><td>
2445 <tr><td>
2444 <a href="/help/summary">
2446 <a href="/help/summary">
2445 summary
2447 summary
2446 </a>
2448 </a>
2447 </td><td>
2449 </td><td>
2448 summarize working directory state
2450 summarize working directory state
2449 </td></tr>
2451 </td></tr>
2450 <tr><td>
2452 <tr><td>
2451 <a href="/help/update">
2453 <a href="/help/update">
2452 update
2454 update
2453 </a>
2455 </a>
2454 </td><td>
2456 </td><td>
2455 update working directory (or switch revisions)
2457 update working directory (or switch revisions)
2456 </td></tr>
2458 </td></tr>
2457
2459
2458
2460
2459
2461
2460 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2462 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
2461
2463
2462 <tr><td>
2464 <tr><td>
2463 <a href="/help/addremove">
2465 <a href="/help/addremove">
2464 addremove
2466 addremove
2465 </a>
2467 </a>
2466 </td><td>
2468 </td><td>
2467 add all new files, delete all missing files
2469 add all new files, delete all missing files
2468 </td></tr>
2470 </td></tr>
2469 <tr><td>
2471 <tr><td>
2470 <a href="/help/archive">
2472 <a href="/help/archive">
2471 archive
2473 archive
2472 </a>
2474 </a>
2473 </td><td>
2475 </td><td>
2474 create an unversioned archive of a repository revision
2476 create an unversioned archive of a repository revision
2475 </td></tr>
2477 </td></tr>
2476 <tr><td>
2478 <tr><td>
2477 <a href="/help/backout">
2479 <a href="/help/backout">
2478 backout
2480 backout
2479 </a>
2481 </a>
2480 </td><td>
2482 </td><td>
2481 reverse effect of earlier changeset
2483 reverse effect of earlier changeset
2482 </td></tr>
2484 </td></tr>
2483 <tr><td>
2485 <tr><td>
2484 <a href="/help/bisect">
2486 <a href="/help/bisect">
2485 bisect
2487 bisect
2486 </a>
2488 </a>
2487 </td><td>
2489 </td><td>
2488 subdivision search of changesets
2490 subdivision search of changesets
2489 </td></tr>
2491 </td></tr>
2490 <tr><td>
2492 <tr><td>
2491 <a href="/help/bookmarks">
2493 <a href="/help/bookmarks">
2492 bookmarks
2494 bookmarks
2493 </a>
2495 </a>
2494 </td><td>
2496 </td><td>
2495 create a new bookmark or list existing bookmarks
2497 create a new bookmark or list existing bookmarks
2496 </td></tr>
2498 </td></tr>
2497 <tr><td>
2499 <tr><td>
2498 <a href="/help/branch">
2500 <a href="/help/branch">
2499 branch
2501 branch
2500 </a>
2502 </a>
2501 </td><td>
2503 </td><td>
2502 set or show the current branch name
2504 set or show the current branch name
2503 </td></tr>
2505 </td></tr>
2504 <tr><td>
2506 <tr><td>
2505 <a href="/help/branches">
2507 <a href="/help/branches">
2506 branches
2508 branches
2507 </a>
2509 </a>
2508 </td><td>
2510 </td><td>
2509 list repository named branches
2511 list repository named branches
2510 </td></tr>
2512 </td></tr>
2511 <tr><td>
2513 <tr><td>
2512 <a href="/help/bundle">
2514 <a href="/help/bundle">
2513 bundle
2515 bundle
2514 </a>
2516 </a>
2515 </td><td>
2517 </td><td>
2516 create a bundle file
2518 create a bundle file
2517 </td></tr>
2519 </td></tr>
2518 <tr><td>
2520 <tr><td>
2519 <a href="/help/cat">
2521 <a href="/help/cat">
2520 cat
2522 cat
2521 </a>
2523 </a>
2522 </td><td>
2524 </td><td>
2523 output the current or given revision of files
2525 output the current or given revision of files
2524 </td></tr>
2526 </td></tr>
2525 <tr><td>
2527 <tr><td>
2526 <a href="/help/config">
2528 <a href="/help/config">
2527 config
2529 config
2528 </a>
2530 </a>
2529 </td><td>
2531 </td><td>
2530 show combined config settings from all hgrc files
2532 show combined config settings from all hgrc files
2531 </td></tr>
2533 </td></tr>
2532 <tr><td>
2534 <tr><td>
2533 <a href="/help/copy">
2535 <a href="/help/copy">
2534 copy
2536 copy
2535 </a>
2537 </a>
2536 </td><td>
2538 </td><td>
2537 mark files as copied for the next commit
2539 mark files as copied for the next commit
2538 </td></tr>
2540 </td></tr>
2539 <tr><td>
2541 <tr><td>
2540 <a href="/help/files">
2542 <a href="/help/files">
2541 files
2543 files
2542 </a>
2544 </a>
2543 </td><td>
2545 </td><td>
2544 list tracked files
2546 list tracked files
2545 </td></tr>
2547 </td></tr>
2546 <tr><td>
2548 <tr><td>
2547 <a href="/help/graft">
2549 <a href="/help/graft">
2548 graft
2550 graft
2549 </a>
2551 </a>
2550 </td><td>
2552 </td><td>
2551 copy changes from other branches onto the current branch
2553 copy changes from other branches onto the current branch
2552 </td></tr>
2554 </td></tr>
2553 <tr><td>
2555 <tr><td>
2554 <a href="/help/grep">
2556 <a href="/help/grep">
2555 grep
2557 grep
2556 </a>
2558 </a>
2557 </td><td>
2559 </td><td>
2558 search revision history for a pattern in specified files
2560 search revision history for a pattern in specified files
2559 </td></tr>
2561 </td></tr>
2560 <tr><td>
2562 <tr><td>
2561 <a href="/help/hashelp">
2563 <a href="/help/hashelp">
2562 hashelp
2564 hashelp
2563 </a>
2565 </a>
2564 </td><td>
2566 </td><td>
2565 Extension command's help
2567 Extension command's help
2566 </td></tr>
2568 </td></tr>
2567 <tr><td>
2569 <tr><td>
2568 <a href="/help/heads">
2570 <a href="/help/heads">
2569 heads
2571 heads
2570 </a>
2572 </a>
2571 </td><td>
2573 </td><td>
2572 show branch heads
2574 show branch heads
2573 </td></tr>
2575 </td></tr>
2574 <tr><td>
2576 <tr><td>
2575 <a href="/help/help">
2577 <a href="/help/help">
2576 help
2578 help
2577 </a>
2579 </a>
2578 </td><td>
2580 </td><td>
2579 show help for a given topic or a help overview
2581 show help for a given topic or a help overview
2580 </td></tr>
2582 </td></tr>
2581 <tr><td>
2583 <tr><td>
2582 <a href="/help/hgalias">
2584 <a href="/help/hgalias">
2583 hgalias
2585 hgalias
2584 </a>
2586 </a>
2585 </td><td>
2587 </td><td>
2586 My doc
2588 My doc
2587 </td></tr>
2589 </td></tr>
2588 <tr><td>
2590 <tr><td>
2589 <a href="/help/hgaliasnodoc">
2591 <a href="/help/hgaliasnodoc">
2590 hgaliasnodoc
2592 hgaliasnodoc
2591 </a>
2593 </a>
2592 </td><td>
2594 </td><td>
2593 summarize working directory state
2595 summarize working directory state
2594 </td></tr>
2596 </td></tr>
2595 <tr><td>
2597 <tr><td>
2596 <a href="/help/identify">
2598 <a href="/help/identify">
2597 identify
2599 identify
2598 </a>
2600 </a>
2599 </td><td>
2601 </td><td>
2600 identify the working directory or specified revision
2602 identify the working directory or specified revision
2601 </td></tr>
2603 </td></tr>
2602 <tr><td>
2604 <tr><td>
2603 <a href="/help/import">
2605 <a href="/help/import">
2604 import
2606 import
2605 </a>
2607 </a>
2606 </td><td>
2608 </td><td>
2607 import an ordered set of patches
2609 import an ordered set of patches
2608 </td></tr>
2610 </td></tr>
2609 <tr><td>
2611 <tr><td>
2610 <a href="/help/incoming">
2612 <a href="/help/incoming">
2611 incoming
2613 incoming
2612 </a>
2614 </a>
2613 </td><td>
2615 </td><td>
2614 show new changesets found in source
2616 show new changesets found in source
2615 </td></tr>
2617 </td></tr>
2616 <tr><td>
2618 <tr><td>
2617 <a href="/help/manifest">
2619 <a href="/help/manifest">
2618 manifest
2620 manifest
2619 </a>
2621 </a>
2620 </td><td>
2622 </td><td>
2621 output the current or given revision of the project manifest
2623 output the current or given revision of the project manifest
2622 </td></tr>
2624 </td></tr>
2623 <tr><td>
2625 <tr><td>
2624 <a href="/help/nohelp">
2626 <a href="/help/nohelp">
2625 nohelp
2627 nohelp
2626 </a>
2628 </a>
2627 </td><td>
2629 </td><td>
2628 (no help text available)
2630 (no help text available)
2629 </td></tr>
2631 </td></tr>
2630 <tr><td>
2632 <tr><td>
2631 <a href="/help/outgoing">
2633 <a href="/help/outgoing">
2632 outgoing
2634 outgoing
2633 </a>
2635 </a>
2634 </td><td>
2636 </td><td>
2635 show changesets not found in the destination
2637 show changesets not found in the destination
2636 </td></tr>
2638 </td></tr>
2637 <tr><td>
2639 <tr><td>
2638 <a href="/help/paths">
2640 <a href="/help/paths">
2639 paths
2641 paths
2640 </a>
2642 </a>
2641 </td><td>
2643 </td><td>
2642 show aliases for remote repositories
2644 show aliases for remote repositories
2643 </td></tr>
2645 </td></tr>
2644 <tr><td>
2646 <tr><td>
2645 <a href="/help/phase">
2647 <a href="/help/phase">
2646 phase
2648 phase
2647 </a>
2649 </a>
2648 </td><td>
2650 </td><td>
2649 set or show the current phase name
2651 set or show the current phase name
2650 </td></tr>
2652 </td></tr>
2651 <tr><td>
2653 <tr><td>
2652 <a href="/help/recover">
2654 <a href="/help/recover">
2653 recover
2655 recover
2654 </a>
2656 </a>
2655 </td><td>
2657 </td><td>
2656 roll back an interrupted transaction
2658 roll back an interrupted transaction
2657 </td></tr>
2659 </td></tr>
2658 <tr><td>
2660 <tr><td>
2659 <a href="/help/rename">
2661 <a href="/help/rename">
2660 rename
2662 rename
2661 </a>
2663 </a>
2662 </td><td>
2664 </td><td>
2663 rename files; equivalent of copy + remove
2665 rename files; equivalent of copy + remove
2664 </td></tr>
2666 </td></tr>
2665 <tr><td>
2667 <tr><td>
2666 <a href="/help/resolve">
2668 <a href="/help/resolve">
2667 resolve
2669 resolve
2668 </a>
2670 </a>
2669 </td><td>
2671 </td><td>
2670 redo merges or set/view the merge status of files
2672 redo merges or set/view the merge status of files
2671 </td></tr>
2673 </td></tr>
2672 <tr><td>
2674 <tr><td>
2673 <a href="/help/revert">
2675 <a href="/help/revert">
2674 revert
2676 revert
2675 </a>
2677 </a>
2676 </td><td>
2678 </td><td>
2677 restore files to their checkout state
2679 restore files to their checkout state
2678 </td></tr>
2680 </td></tr>
2679 <tr><td>
2681 <tr><td>
2680 <a href="/help/root">
2682 <a href="/help/root">
2681 root
2683 root
2682 </a>
2684 </a>
2683 </td><td>
2685 </td><td>
2684 print the root (top) of the current working directory
2686 print the root (top) of the current working directory
2685 </td></tr>
2687 </td></tr>
2686 <tr><td>
2688 <tr><td>
2687 <a href="/help/shellalias">
2689 <a href="/help/shellalias">
2688 shellalias
2690 shellalias
2689 </a>
2691 </a>
2690 </td><td>
2692 </td><td>
2691 (no help text available)
2693 (no help text available)
2692 </td></tr>
2694 </td></tr>
2693 <tr><td>
2695 <tr><td>
2694 <a href="/help/tag">
2696 <a href="/help/tag">
2695 tag
2697 tag
2696 </a>
2698 </a>
2697 </td><td>
2699 </td><td>
2698 add one or more tags for the current or given revision
2700 add one or more tags for the current or given revision
2699 </td></tr>
2701 </td></tr>
2700 <tr><td>
2702 <tr><td>
2701 <a href="/help/tags">
2703 <a href="/help/tags">
2702 tags
2704 tags
2703 </a>
2705 </a>
2704 </td><td>
2706 </td><td>
2705 list repository tags
2707 list repository tags
2706 </td></tr>
2708 </td></tr>
2707 <tr><td>
2709 <tr><td>
2708 <a href="/help/unbundle">
2710 <a href="/help/unbundle">
2709 unbundle
2711 unbundle
2710 </a>
2712 </a>
2711 </td><td>
2713 </td><td>
2712 apply one or more bundle files
2714 apply one or more bundle files
2713 </td></tr>
2715 </td></tr>
2714 <tr><td>
2716 <tr><td>
2715 <a href="/help/verify">
2717 <a href="/help/verify">
2716 verify
2718 verify
2717 </a>
2719 </a>
2718 </td><td>
2720 </td><td>
2719 verify the integrity of the repository
2721 verify the integrity of the repository
2720 </td></tr>
2722 </td></tr>
2721 <tr><td>
2723 <tr><td>
2722 <a href="/help/version">
2724 <a href="/help/version">
2723 version
2725 version
2724 </a>
2726 </a>
2725 </td><td>
2727 </td><td>
2726 output version and copyright information
2728 output version and copyright information
2727 </td></tr>
2729 </td></tr>
2728
2730
2729
2731
2730 </table>
2732 </table>
2731 </div>
2733 </div>
2732 </div>
2734 </div>
2733
2735
2734
2736
2735
2737
2736 </body>
2738 </body>
2737 </html>
2739 </html>
2738
2740
2739
2741
2740 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2742 $ get-with-headers.py $LOCALIP:$HGPORT "help/add"
2741 200 Script output follows
2743 200 Script output follows
2742
2744
2743 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2745 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2744 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2746 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2745 <head>
2747 <head>
2746 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2748 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2747 <meta name="robots" content="index, nofollow" />
2749 <meta name="robots" content="index, nofollow" />
2748 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2750 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2749 <script type="text/javascript" src="/static/mercurial.js"></script>
2751 <script type="text/javascript" src="/static/mercurial.js"></script>
2750
2752
2751 <title>Help: add</title>
2753 <title>Help: add</title>
2752 </head>
2754 </head>
2753 <body>
2755 <body>
2754
2756
2755 <div class="container">
2757 <div class="container">
2756 <div class="menu">
2758 <div class="menu">
2757 <div class="logo">
2759 <div class="logo">
2758 <a href="https://mercurial-scm.org/">
2760 <a href="https://mercurial-scm.org/">
2759 <img src="/static/hglogo.png" alt="mercurial" /></a>
2761 <img src="/static/hglogo.png" alt="mercurial" /></a>
2760 </div>
2762 </div>
2761 <ul>
2763 <ul>
2762 <li><a href="/shortlog">log</a></li>
2764 <li><a href="/shortlog">log</a></li>
2763 <li><a href="/graph">graph</a></li>
2765 <li><a href="/graph">graph</a></li>
2764 <li><a href="/tags">tags</a></li>
2766 <li><a href="/tags">tags</a></li>
2765 <li><a href="/bookmarks">bookmarks</a></li>
2767 <li><a href="/bookmarks">bookmarks</a></li>
2766 <li><a href="/branches">branches</a></li>
2768 <li><a href="/branches">branches</a></li>
2767 </ul>
2769 </ul>
2768 <ul>
2770 <ul>
2769 <li class="active"><a href="/help">help</a></li>
2771 <li class="active"><a href="/help">help</a></li>
2770 </ul>
2772 </ul>
2771 </div>
2773 </div>
2772
2774
2773 <div class="main">
2775 <div class="main">
2774 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2776 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2775 <h3>Help: add</h3>
2777 <h3>Help: add</h3>
2776
2778
2777 <form class="search" action="/log">
2779 <form class="search" action="/log">
2778
2780
2779 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2781 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2780 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2782 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2781 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2783 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2782 </form>
2784 </form>
2783 <div id="doc">
2785 <div id="doc">
2784 <p>
2786 <p>
2785 hg add [OPTION]... [FILE]...
2787 hg add [OPTION]... [FILE]...
2786 </p>
2788 </p>
2787 <p>
2789 <p>
2788 add the specified files on the next commit
2790 add the specified files on the next commit
2789 </p>
2791 </p>
2790 <p>
2792 <p>
2791 Schedule files to be version controlled and added to the
2793 Schedule files to be version controlled and added to the
2792 repository.
2794 repository.
2793 </p>
2795 </p>
2794 <p>
2796 <p>
2795 The files will be added to the repository at the next commit. To
2797 The files will be added to the repository at the next commit. To
2796 undo an add before that, see 'hg forget'.
2798 undo an add before that, see 'hg forget'.
2797 </p>
2799 </p>
2798 <p>
2800 <p>
2799 If no names are given, add all files to the repository (except
2801 If no names are given, add all files to the repository (except
2800 files matching &quot;.hgignore&quot;).
2802 files matching &quot;.hgignore&quot;).
2801 </p>
2803 </p>
2802 <p>
2804 <p>
2803 Examples:
2805 Examples:
2804 </p>
2806 </p>
2805 <ul>
2807 <ul>
2806 <li> New (unknown) files are added automatically by 'hg add':
2808 <li> New (unknown) files are added automatically by 'hg add':
2807 <pre>
2809 <pre>
2808 \$ ls (re)
2810 \$ ls (re)
2809 foo.c
2811 foo.c
2810 \$ hg status (re)
2812 \$ hg status (re)
2811 ? foo.c
2813 ? foo.c
2812 \$ hg add (re)
2814 \$ hg add (re)
2813 adding foo.c
2815 adding foo.c
2814 \$ hg status (re)
2816 \$ hg status (re)
2815 A foo.c
2817 A foo.c
2816 </pre>
2818 </pre>
2817 <li> Specific files to be added can be specified:
2819 <li> Specific files to be added can be specified:
2818 <pre>
2820 <pre>
2819 \$ ls (re)
2821 \$ ls (re)
2820 bar.c foo.c
2822 bar.c foo.c
2821 \$ hg status (re)
2823 \$ hg status (re)
2822 ? bar.c
2824 ? bar.c
2823 ? foo.c
2825 ? foo.c
2824 \$ hg add bar.c (re)
2826 \$ hg add bar.c (re)
2825 \$ hg status (re)
2827 \$ hg status (re)
2826 A bar.c
2828 A bar.c
2827 ? foo.c
2829 ? foo.c
2828 </pre>
2830 </pre>
2829 </ul>
2831 </ul>
2830 <p>
2832 <p>
2831 Returns 0 if all files are successfully added.
2833 Returns 0 if all files are successfully added.
2832 </p>
2834 </p>
2833 <p>
2835 <p>
2834 options ([+] can be repeated):
2836 options ([+] can be repeated):
2835 </p>
2837 </p>
2836 <table>
2838 <table>
2837 <tr><td>-I</td>
2839 <tr><td>-I</td>
2838 <td>--include PATTERN [+]</td>
2840 <td>--include PATTERN [+]</td>
2839 <td>include names matching the given patterns</td></tr>
2841 <td>include names matching the given patterns</td></tr>
2840 <tr><td>-X</td>
2842 <tr><td>-X</td>
2841 <td>--exclude PATTERN [+]</td>
2843 <td>--exclude PATTERN [+]</td>
2842 <td>exclude names matching the given patterns</td></tr>
2844 <td>exclude names matching the given patterns</td></tr>
2843 <tr><td>-S</td>
2845 <tr><td>-S</td>
2844 <td>--subrepos</td>
2846 <td>--subrepos</td>
2845 <td>recurse into subrepositories</td></tr>
2847 <td>recurse into subrepositories</td></tr>
2846 <tr><td>-n</td>
2848 <tr><td>-n</td>
2847 <td>--dry-run</td>
2849 <td>--dry-run</td>
2848 <td>do not perform actions, just print output</td></tr>
2850 <td>do not perform actions, just print output</td></tr>
2849 </table>
2851 </table>
2850 <p>
2852 <p>
2851 global options ([+] can be repeated):
2853 global options ([+] can be repeated):
2852 </p>
2854 </p>
2853 <table>
2855 <table>
2854 <tr><td>-R</td>
2856 <tr><td>-R</td>
2855 <td>--repository REPO</td>
2857 <td>--repository REPO</td>
2856 <td>repository root directory or name of overlay bundle file</td></tr>
2858 <td>repository root directory or name of overlay bundle file</td></tr>
2857 <tr><td></td>
2859 <tr><td></td>
2858 <td>--cwd DIR</td>
2860 <td>--cwd DIR</td>
2859 <td>change working directory</td></tr>
2861 <td>change working directory</td></tr>
2860 <tr><td>-y</td>
2862 <tr><td>-y</td>
2861 <td>--noninteractive</td>
2863 <td>--noninteractive</td>
2862 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2864 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
2863 <tr><td>-q</td>
2865 <tr><td>-q</td>
2864 <td>--quiet</td>
2866 <td>--quiet</td>
2865 <td>suppress output</td></tr>
2867 <td>suppress output</td></tr>
2866 <tr><td>-v</td>
2868 <tr><td>-v</td>
2867 <td>--verbose</td>
2869 <td>--verbose</td>
2868 <td>enable additional output</td></tr>
2870 <td>enable additional output</td></tr>
2869 <tr><td></td>
2871 <tr><td></td>
2870 <td>--color TYPE</td>
2872 <td>--color TYPE</td>
2871 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2873 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
2872 <tr><td></td>
2874 <tr><td></td>
2873 <td>--config CONFIG [+]</td>
2875 <td>--config CONFIG [+]</td>
2874 <td>set/override config option (use 'section.name=value')</td></tr>
2876 <td>set/override config option (use 'section.name=value')</td></tr>
2875 <tr><td></td>
2877 <tr><td></td>
2876 <td>--debug</td>
2878 <td>--debug</td>
2877 <td>enable debugging output</td></tr>
2879 <td>enable debugging output</td></tr>
2878 <tr><td></td>
2880 <tr><td></td>
2879 <td>--debugger</td>
2881 <td>--debugger</td>
2880 <td>start debugger</td></tr>
2882 <td>start debugger</td></tr>
2881 <tr><td></td>
2883 <tr><td></td>
2882 <td>--encoding ENCODE</td>
2884 <td>--encoding ENCODE</td>
2883 <td>set the charset encoding (default: ascii)</td></tr>
2885 <td>set the charset encoding (default: ascii)</td></tr>
2884 <tr><td></td>
2886 <tr><td></td>
2885 <td>--encodingmode MODE</td>
2887 <td>--encodingmode MODE</td>
2886 <td>set the charset encoding mode (default: strict)</td></tr>
2888 <td>set the charset encoding mode (default: strict)</td></tr>
2887 <tr><td></td>
2889 <tr><td></td>
2888 <td>--traceback</td>
2890 <td>--traceback</td>
2889 <td>always print a traceback on exception</td></tr>
2891 <td>always print a traceback on exception</td></tr>
2890 <tr><td></td>
2892 <tr><td></td>
2891 <td>--time</td>
2893 <td>--time</td>
2892 <td>time how long the command takes</td></tr>
2894 <td>time how long the command takes</td></tr>
2893 <tr><td></td>
2895 <tr><td></td>
2894 <td>--profile</td>
2896 <td>--profile</td>
2895 <td>print command execution profile</td></tr>
2897 <td>print command execution profile</td></tr>
2896 <tr><td></td>
2898 <tr><td></td>
2897 <td>--version</td>
2899 <td>--version</td>
2898 <td>output version information and exit</td></tr>
2900 <td>output version information and exit</td></tr>
2899 <tr><td>-h</td>
2901 <tr><td>-h</td>
2900 <td>--help</td>
2902 <td>--help</td>
2901 <td>display help and exit</td></tr>
2903 <td>display help and exit</td></tr>
2902 <tr><td></td>
2904 <tr><td></td>
2903 <td>--hidden</td>
2905 <td>--hidden</td>
2904 <td>consider hidden changesets</td></tr>
2906 <td>consider hidden changesets</td></tr>
2905 <tr><td></td>
2907 <tr><td></td>
2906 <td>--pager TYPE</td>
2908 <td>--pager TYPE</td>
2907 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2909 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
2908 </table>
2910 </table>
2909
2911
2910 </div>
2912 </div>
2911 </div>
2913 </div>
2912 </div>
2914 </div>
2913
2915
2914
2916
2915
2917
2916 </body>
2918 </body>
2917 </html>
2919 </html>
2918
2920
2919
2921
2920 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2922 $ get-with-headers.py $LOCALIP:$HGPORT "help/remove"
2921 200 Script output follows
2923 200 Script output follows
2922
2924
2923 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2925 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2924 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2926 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
2925 <head>
2927 <head>
2926 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2928 <link rel="icon" href="/static/hgicon.png" type="image/png" />
2927 <meta name="robots" content="index, nofollow" />
2929 <meta name="robots" content="index, nofollow" />
2928 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2930 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
2929 <script type="text/javascript" src="/static/mercurial.js"></script>
2931 <script type="text/javascript" src="/static/mercurial.js"></script>
2930
2932
2931 <title>Help: remove</title>
2933 <title>Help: remove</title>
2932 </head>
2934 </head>
2933 <body>
2935 <body>
2934
2936
2935 <div class="container">
2937 <div class="container">
2936 <div class="menu">
2938 <div class="menu">
2937 <div class="logo">
2939 <div class="logo">
2938 <a href="https://mercurial-scm.org/">
2940 <a href="https://mercurial-scm.org/">
2939 <img src="/static/hglogo.png" alt="mercurial" /></a>
2941 <img src="/static/hglogo.png" alt="mercurial" /></a>
2940 </div>
2942 </div>
2941 <ul>
2943 <ul>
2942 <li><a href="/shortlog">log</a></li>
2944 <li><a href="/shortlog">log</a></li>
2943 <li><a href="/graph">graph</a></li>
2945 <li><a href="/graph">graph</a></li>
2944 <li><a href="/tags">tags</a></li>
2946 <li><a href="/tags">tags</a></li>
2945 <li><a href="/bookmarks">bookmarks</a></li>
2947 <li><a href="/bookmarks">bookmarks</a></li>
2946 <li><a href="/branches">branches</a></li>
2948 <li><a href="/branches">branches</a></li>
2947 </ul>
2949 </ul>
2948 <ul>
2950 <ul>
2949 <li class="active"><a href="/help">help</a></li>
2951 <li class="active"><a href="/help">help</a></li>
2950 </ul>
2952 </ul>
2951 </div>
2953 </div>
2952
2954
2953 <div class="main">
2955 <div class="main">
2954 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2956 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
2955 <h3>Help: remove</h3>
2957 <h3>Help: remove</h3>
2956
2958
2957 <form class="search" action="/log">
2959 <form class="search" action="/log">
2958
2960
2959 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2961 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
2960 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2962 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
2961 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2963 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
2962 </form>
2964 </form>
2963 <div id="doc">
2965 <div id="doc">
2964 <p>
2966 <p>
2965 hg remove [OPTION]... FILE...
2967 hg remove [OPTION]... FILE...
2966 </p>
2968 </p>
2967 <p>
2969 <p>
2968 aliases: rm
2970 aliases: rm
2969 </p>
2971 </p>
2970 <p>
2972 <p>
2971 remove the specified files on the next commit
2973 remove the specified files on the next commit
2972 </p>
2974 </p>
2973 <p>
2975 <p>
2974 Schedule the indicated files for removal from the current branch.
2976 Schedule the indicated files for removal from the current branch.
2975 </p>
2977 </p>
2976 <p>
2978 <p>
2977 This command schedules the files to be removed at the next commit.
2979 This command schedules the files to be removed at the next commit.
2978 To undo a remove before that, see 'hg revert'. To undo added
2980 To undo a remove before that, see 'hg revert'. To undo added
2979 files, see 'hg forget'.
2981 files, see 'hg forget'.
2980 </p>
2982 </p>
2981 <p>
2983 <p>
2982 -A/--after can be used to remove only files that have already
2984 -A/--after can be used to remove only files that have already
2983 been deleted, -f/--force can be used to force deletion, and -Af
2985 been deleted, -f/--force can be used to force deletion, and -Af
2984 can be used to remove files from the next revision without
2986 can be used to remove files from the next revision without
2985 deleting them from the working directory.
2987 deleting them from the working directory.
2986 </p>
2988 </p>
2987 <p>
2989 <p>
2988 The following table details the behavior of remove for different
2990 The following table details the behavior of remove for different
2989 file states (columns) and option combinations (rows). The file
2991 file states (columns) and option combinations (rows). The file
2990 states are Added [A], Clean [C], Modified [M] and Missing [!]
2992 states are Added [A], Clean [C], Modified [M] and Missing [!]
2991 (as reported by 'hg status'). The actions are Warn, Remove
2993 (as reported by 'hg status'). The actions are Warn, Remove
2992 (from branch) and Delete (from disk):
2994 (from branch) and Delete (from disk):
2993 </p>
2995 </p>
2994 <table>
2996 <table>
2995 <tr><td>opt/state</td>
2997 <tr><td>opt/state</td>
2996 <td>A</td>
2998 <td>A</td>
2997 <td>C</td>
2999 <td>C</td>
2998 <td>M</td>
3000 <td>M</td>
2999 <td>!</td></tr>
3001 <td>!</td></tr>
3000 <tr><td>none</td>
3002 <tr><td>none</td>
3001 <td>W</td>
3003 <td>W</td>
3002 <td>RD</td>
3004 <td>RD</td>
3003 <td>W</td>
3005 <td>W</td>
3004 <td>R</td></tr>
3006 <td>R</td></tr>
3005 <tr><td>-f</td>
3007 <tr><td>-f</td>
3006 <td>R</td>
3008 <td>R</td>
3007 <td>RD</td>
3009 <td>RD</td>
3008 <td>RD</td>
3010 <td>RD</td>
3009 <td>R</td></tr>
3011 <td>R</td></tr>
3010 <tr><td>-A</td>
3012 <tr><td>-A</td>
3011 <td>W</td>
3013 <td>W</td>
3012 <td>W</td>
3014 <td>W</td>
3013 <td>W</td>
3015 <td>W</td>
3014 <td>R</td></tr>
3016 <td>R</td></tr>
3015 <tr><td>-Af</td>
3017 <tr><td>-Af</td>
3016 <td>R</td>
3018 <td>R</td>
3017 <td>R</td>
3019 <td>R</td>
3018 <td>R</td>
3020 <td>R</td>
3019 <td>R</td></tr>
3021 <td>R</td></tr>
3020 </table>
3022 </table>
3021 <p>
3023 <p>
3022 <b>Note:</b>
3024 <b>Note:</b>
3023 </p>
3025 </p>
3024 <p>
3026 <p>
3025 'hg remove' never deletes files in Added [A] state from the
3027 'hg remove' never deletes files in Added [A] state from the
3026 working directory, not even if &quot;--force&quot; is specified.
3028 working directory, not even if &quot;--force&quot; is specified.
3027 </p>
3029 </p>
3028 <p>
3030 <p>
3029 Returns 0 on success, 1 if any warnings encountered.
3031 Returns 0 on success, 1 if any warnings encountered.
3030 </p>
3032 </p>
3031 <p>
3033 <p>
3032 options ([+] can be repeated):
3034 options ([+] can be repeated):
3033 </p>
3035 </p>
3034 <table>
3036 <table>
3035 <tr><td>-A</td>
3037 <tr><td>-A</td>
3036 <td>--after</td>
3038 <td>--after</td>
3037 <td>record delete for missing files</td></tr>
3039 <td>record delete for missing files</td></tr>
3038 <tr><td>-f</td>
3040 <tr><td>-f</td>
3039 <td>--force</td>
3041 <td>--force</td>
3040 <td>forget added files, delete modified files</td></tr>
3042 <td>forget added files, delete modified files</td></tr>
3041 <tr><td>-S</td>
3043 <tr><td>-S</td>
3042 <td>--subrepos</td>
3044 <td>--subrepos</td>
3043 <td>recurse into subrepositories</td></tr>
3045 <td>recurse into subrepositories</td></tr>
3044 <tr><td>-I</td>
3046 <tr><td>-I</td>
3045 <td>--include PATTERN [+]</td>
3047 <td>--include PATTERN [+]</td>
3046 <td>include names matching the given patterns</td></tr>
3048 <td>include names matching the given patterns</td></tr>
3047 <tr><td>-X</td>
3049 <tr><td>-X</td>
3048 <td>--exclude PATTERN [+]</td>
3050 <td>--exclude PATTERN [+]</td>
3049 <td>exclude names matching the given patterns</td></tr>
3051 <td>exclude names matching the given patterns</td></tr>
3050 <tr><td>-n</td>
3052 <tr><td>-n</td>
3051 <td>--dry-run</td>
3053 <td>--dry-run</td>
3052 <td>do not perform actions, just print output</td></tr>
3054 <td>do not perform actions, just print output</td></tr>
3053 </table>
3055 </table>
3054 <p>
3056 <p>
3055 global options ([+] can be repeated):
3057 global options ([+] can be repeated):
3056 </p>
3058 </p>
3057 <table>
3059 <table>
3058 <tr><td>-R</td>
3060 <tr><td>-R</td>
3059 <td>--repository REPO</td>
3061 <td>--repository REPO</td>
3060 <td>repository root directory or name of overlay bundle file</td></tr>
3062 <td>repository root directory or name of overlay bundle file</td></tr>
3061 <tr><td></td>
3063 <tr><td></td>
3062 <td>--cwd DIR</td>
3064 <td>--cwd DIR</td>
3063 <td>change working directory</td></tr>
3065 <td>change working directory</td></tr>
3064 <tr><td>-y</td>
3066 <tr><td>-y</td>
3065 <td>--noninteractive</td>
3067 <td>--noninteractive</td>
3066 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3068 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
3067 <tr><td>-q</td>
3069 <tr><td>-q</td>
3068 <td>--quiet</td>
3070 <td>--quiet</td>
3069 <td>suppress output</td></tr>
3071 <td>suppress output</td></tr>
3070 <tr><td>-v</td>
3072 <tr><td>-v</td>
3071 <td>--verbose</td>
3073 <td>--verbose</td>
3072 <td>enable additional output</td></tr>
3074 <td>enable additional output</td></tr>
3073 <tr><td></td>
3075 <tr><td></td>
3074 <td>--color TYPE</td>
3076 <td>--color TYPE</td>
3075 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3077 <td>when to colorize (boolean, always, auto, never, or debug)</td></tr>
3076 <tr><td></td>
3078 <tr><td></td>
3077 <td>--config CONFIG [+]</td>
3079 <td>--config CONFIG [+]</td>
3078 <td>set/override config option (use 'section.name=value')</td></tr>
3080 <td>set/override config option (use 'section.name=value')</td></tr>
3079 <tr><td></td>
3081 <tr><td></td>
3080 <td>--debug</td>
3082 <td>--debug</td>
3081 <td>enable debugging output</td></tr>
3083 <td>enable debugging output</td></tr>
3082 <tr><td></td>
3084 <tr><td></td>
3083 <td>--debugger</td>
3085 <td>--debugger</td>
3084 <td>start debugger</td></tr>
3086 <td>start debugger</td></tr>
3085 <tr><td></td>
3087 <tr><td></td>
3086 <td>--encoding ENCODE</td>
3088 <td>--encoding ENCODE</td>
3087 <td>set the charset encoding (default: ascii)</td></tr>
3089 <td>set the charset encoding (default: ascii)</td></tr>
3088 <tr><td></td>
3090 <tr><td></td>
3089 <td>--encodingmode MODE</td>
3091 <td>--encodingmode MODE</td>
3090 <td>set the charset encoding mode (default: strict)</td></tr>
3092 <td>set the charset encoding mode (default: strict)</td></tr>
3091 <tr><td></td>
3093 <tr><td></td>
3092 <td>--traceback</td>
3094 <td>--traceback</td>
3093 <td>always print a traceback on exception</td></tr>
3095 <td>always print a traceback on exception</td></tr>
3094 <tr><td></td>
3096 <tr><td></td>
3095 <td>--time</td>
3097 <td>--time</td>
3096 <td>time how long the command takes</td></tr>
3098 <td>time how long the command takes</td></tr>
3097 <tr><td></td>
3099 <tr><td></td>
3098 <td>--profile</td>
3100 <td>--profile</td>
3099 <td>print command execution profile</td></tr>
3101 <td>print command execution profile</td></tr>
3100 <tr><td></td>
3102 <tr><td></td>
3101 <td>--version</td>
3103 <td>--version</td>
3102 <td>output version information and exit</td></tr>
3104 <td>output version information and exit</td></tr>
3103 <tr><td>-h</td>
3105 <tr><td>-h</td>
3104 <td>--help</td>
3106 <td>--help</td>
3105 <td>display help and exit</td></tr>
3107 <td>display help and exit</td></tr>
3106 <tr><td></td>
3108 <tr><td></td>
3107 <td>--hidden</td>
3109 <td>--hidden</td>
3108 <td>consider hidden changesets</td></tr>
3110 <td>consider hidden changesets</td></tr>
3109 <tr><td></td>
3111 <tr><td></td>
3110 <td>--pager TYPE</td>
3112 <td>--pager TYPE</td>
3111 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3113 <td>when to paginate (boolean, always, auto, or never) (default: auto)</td></tr>
3112 </table>
3114 </table>
3113
3115
3114 </div>
3116 </div>
3115 </div>
3117 </div>
3116 </div>
3118 </div>
3117
3119
3118
3120
3119
3121
3120 </body>
3122 </body>
3121 </html>
3123 </html>
3122
3124
3123
3125
3124 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3126 $ get-with-headers.py $LOCALIP:$HGPORT "help/dates"
3125 200 Script output follows
3127 200 Script output follows
3126
3128
3127 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3129 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3128 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3130 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3129 <head>
3131 <head>
3130 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3132 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3131 <meta name="robots" content="index, nofollow" />
3133 <meta name="robots" content="index, nofollow" />
3132 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3134 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3133 <script type="text/javascript" src="/static/mercurial.js"></script>
3135 <script type="text/javascript" src="/static/mercurial.js"></script>
3134
3136
3135 <title>Help: dates</title>
3137 <title>Help: dates</title>
3136 </head>
3138 </head>
3137 <body>
3139 <body>
3138
3140
3139 <div class="container">
3141 <div class="container">
3140 <div class="menu">
3142 <div class="menu">
3141 <div class="logo">
3143 <div class="logo">
3142 <a href="https://mercurial-scm.org/">
3144 <a href="https://mercurial-scm.org/">
3143 <img src="/static/hglogo.png" alt="mercurial" /></a>
3145 <img src="/static/hglogo.png" alt="mercurial" /></a>
3144 </div>
3146 </div>
3145 <ul>
3147 <ul>
3146 <li><a href="/shortlog">log</a></li>
3148 <li><a href="/shortlog">log</a></li>
3147 <li><a href="/graph">graph</a></li>
3149 <li><a href="/graph">graph</a></li>
3148 <li><a href="/tags">tags</a></li>
3150 <li><a href="/tags">tags</a></li>
3149 <li><a href="/bookmarks">bookmarks</a></li>
3151 <li><a href="/bookmarks">bookmarks</a></li>
3150 <li><a href="/branches">branches</a></li>
3152 <li><a href="/branches">branches</a></li>
3151 </ul>
3153 </ul>
3152 <ul>
3154 <ul>
3153 <li class="active"><a href="/help">help</a></li>
3155 <li class="active"><a href="/help">help</a></li>
3154 </ul>
3156 </ul>
3155 </div>
3157 </div>
3156
3158
3157 <div class="main">
3159 <div class="main">
3158 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3160 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3159 <h3>Help: dates</h3>
3161 <h3>Help: dates</h3>
3160
3162
3161 <form class="search" action="/log">
3163 <form class="search" action="/log">
3162
3164
3163 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3165 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3164 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3166 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3165 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3167 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3166 </form>
3168 </form>
3167 <div id="doc">
3169 <div id="doc">
3168 <h1>Date Formats</h1>
3170 <h1>Date Formats</h1>
3169 <p>
3171 <p>
3170 Some commands allow the user to specify a date, e.g.:
3172 Some commands allow the user to specify a date, e.g.:
3171 </p>
3173 </p>
3172 <ul>
3174 <ul>
3173 <li> backout, commit, import, tag: Specify the commit date.
3175 <li> backout, commit, import, tag: Specify the commit date.
3174 <li> log, revert, update: Select revision(s) by date.
3176 <li> log, revert, update: Select revision(s) by date.
3175 </ul>
3177 </ul>
3176 <p>
3178 <p>
3177 Many date formats are valid. Here are some examples:
3179 Many date formats are valid. Here are some examples:
3178 </p>
3180 </p>
3179 <ul>
3181 <ul>
3180 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3182 <li> &quot;Wed Dec 6 13:18:29 2006&quot; (local timezone assumed)
3181 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3183 <li> &quot;Dec 6 13:18 -0600&quot; (year assumed, time offset provided)
3182 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3184 <li> &quot;Dec 6 13:18 UTC&quot; (UTC and GMT are aliases for +0000)
3183 <li> &quot;Dec 6&quot; (midnight)
3185 <li> &quot;Dec 6&quot; (midnight)
3184 <li> &quot;13:18&quot; (today assumed)
3186 <li> &quot;13:18&quot; (today assumed)
3185 <li> &quot;3:39&quot; (3:39AM assumed)
3187 <li> &quot;3:39&quot; (3:39AM assumed)
3186 <li> &quot;3:39pm&quot; (15:39)
3188 <li> &quot;3:39pm&quot; (15:39)
3187 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3189 <li> &quot;2006-12-06 13:18:29&quot; (ISO 8601 format)
3188 <li> &quot;2006-12-6 13:18&quot;
3190 <li> &quot;2006-12-6 13:18&quot;
3189 <li> &quot;2006-12-6&quot;
3191 <li> &quot;2006-12-6&quot;
3190 <li> &quot;12-6&quot;
3192 <li> &quot;12-6&quot;
3191 <li> &quot;12/6&quot;
3193 <li> &quot;12/6&quot;
3192 <li> &quot;12/6/6&quot; (Dec 6 2006)
3194 <li> &quot;12/6/6&quot; (Dec 6 2006)
3193 <li> &quot;today&quot; (midnight)
3195 <li> &quot;today&quot; (midnight)
3194 <li> &quot;yesterday&quot; (midnight)
3196 <li> &quot;yesterday&quot; (midnight)
3195 <li> &quot;now&quot; - right now
3197 <li> &quot;now&quot; - right now
3196 </ul>
3198 </ul>
3197 <p>
3199 <p>
3198 Lastly, there is Mercurial's internal format:
3200 Lastly, there is Mercurial's internal format:
3199 </p>
3201 </p>
3200 <ul>
3202 <ul>
3201 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3203 <li> &quot;1165411109 0&quot; (Wed Dec 6 13:18:29 2006 UTC)
3202 </ul>
3204 </ul>
3203 <p>
3205 <p>
3204 This is the internal representation format for dates. The first number
3206 This is the internal representation format for dates. The first number
3205 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3207 is the number of seconds since the epoch (1970-01-01 00:00 UTC). The
3206 second is the offset of the local timezone, in seconds west of UTC
3208 second is the offset of the local timezone, in seconds west of UTC
3207 (negative if the timezone is east of UTC).
3209 (negative if the timezone is east of UTC).
3208 </p>
3210 </p>
3209 <p>
3211 <p>
3210 The log command also accepts date ranges:
3212 The log command also accepts date ranges:
3211 </p>
3213 </p>
3212 <ul>
3214 <ul>
3213 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3215 <li> &quot;&lt;DATE&quot; - at or before a given date/time
3214 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3216 <li> &quot;&gt;DATE&quot; - on or after a given date/time
3215 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3217 <li> &quot;DATE to DATE&quot; - a date range, inclusive
3216 <li> &quot;-DAYS&quot; - within a given number of days of today
3218 <li> &quot;-DAYS&quot; - within a given number of days of today
3217 </ul>
3219 </ul>
3218
3220
3219 </div>
3221 </div>
3220 </div>
3222 </div>
3221 </div>
3223 </div>
3222
3224
3223
3225
3224
3226
3225 </body>
3227 </body>
3226 </html>
3228 </html>
3227
3229
3228
3230
3229 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3231 $ get-with-headers.py $LOCALIP:$HGPORT "help/pager"
3230 200 Script output follows
3232 200 Script output follows
3231
3233
3232 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3234 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3233 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3235 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3234 <head>
3236 <head>
3235 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3237 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3236 <meta name="robots" content="index, nofollow" />
3238 <meta name="robots" content="index, nofollow" />
3237 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3239 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3238 <script type="text/javascript" src="/static/mercurial.js"></script>
3240 <script type="text/javascript" src="/static/mercurial.js"></script>
3239
3241
3240 <title>Help: pager</title>
3242 <title>Help: pager</title>
3241 </head>
3243 </head>
3242 <body>
3244 <body>
3243
3245
3244 <div class="container">
3246 <div class="container">
3245 <div class="menu">
3247 <div class="menu">
3246 <div class="logo">
3248 <div class="logo">
3247 <a href="https://mercurial-scm.org/">
3249 <a href="https://mercurial-scm.org/">
3248 <img src="/static/hglogo.png" alt="mercurial" /></a>
3250 <img src="/static/hglogo.png" alt="mercurial" /></a>
3249 </div>
3251 </div>
3250 <ul>
3252 <ul>
3251 <li><a href="/shortlog">log</a></li>
3253 <li><a href="/shortlog">log</a></li>
3252 <li><a href="/graph">graph</a></li>
3254 <li><a href="/graph">graph</a></li>
3253 <li><a href="/tags">tags</a></li>
3255 <li><a href="/tags">tags</a></li>
3254 <li><a href="/bookmarks">bookmarks</a></li>
3256 <li><a href="/bookmarks">bookmarks</a></li>
3255 <li><a href="/branches">branches</a></li>
3257 <li><a href="/branches">branches</a></li>
3256 </ul>
3258 </ul>
3257 <ul>
3259 <ul>
3258 <li class="active"><a href="/help">help</a></li>
3260 <li class="active"><a href="/help">help</a></li>
3259 </ul>
3261 </ul>
3260 </div>
3262 </div>
3261
3263
3262 <div class="main">
3264 <div class="main">
3263 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3265 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3264 <h3>Help: pager</h3>
3266 <h3>Help: pager</h3>
3265
3267
3266 <form class="search" action="/log">
3268 <form class="search" action="/log">
3267
3269
3268 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3270 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3269 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3271 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3270 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3272 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3271 </form>
3273 </form>
3272 <div id="doc">
3274 <div id="doc">
3273 <h1>Pager Support</h1>
3275 <h1>Pager Support</h1>
3274 <p>
3276 <p>
3275 Some Mercurial commands can produce a lot of output, and Mercurial will
3277 Some Mercurial commands can produce a lot of output, and Mercurial will
3276 attempt to use a pager to make those commands more pleasant.
3278 attempt to use a pager to make those commands more pleasant.
3277 </p>
3279 </p>
3278 <p>
3280 <p>
3279 To set the pager that should be used, set the application variable:
3281 To set the pager that should be used, set the application variable:
3280 </p>
3282 </p>
3281 <pre>
3283 <pre>
3282 [pager]
3284 [pager]
3283 pager = less -FRX
3285 pager = less -FRX
3284 </pre>
3286 </pre>
3285 <p>
3287 <p>
3286 If no pager is set in the user or repository configuration, Mercurial uses the
3288 If no pager is set in the user or repository configuration, Mercurial uses the
3287 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3289 environment variable $PAGER. If $PAGER is not set, pager.pager from the default
3288 or system configuration is used. If none of these are set, a default pager will
3290 or system configuration is used. If none of these are set, a default pager will
3289 be used, typically 'less' on Unix and 'more' on Windows.
3291 be used, typically 'less' on Unix and 'more' on Windows.
3290 </p>
3292 </p>
3291 <p>
3293 <p>
3292 You can disable the pager for certain commands by adding them to the
3294 You can disable the pager for certain commands by adding them to the
3293 pager.ignore list:
3295 pager.ignore list:
3294 </p>
3296 </p>
3295 <pre>
3297 <pre>
3296 [pager]
3298 [pager]
3297 ignore = version, help, update
3299 ignore = version, help, update
3298 </pre>
3300 </pre>
3299 <p>
3301 <p>
3300 To ignore global commands like 'hg version' or 'hg help', you have
3302 To ignore global commands like 'hg version' or 'hg help', you have
3301 to specify them in your user configuration file.
3303 to specify them in your user configuration file.
3302 </p>
3304 </p>
3303 <p>
3305 <p>
3304 To control whether the pager is used at all for an individual command,
3306 To control whether the pager is used at all for an individual command,
3305 you can use --pager=&lt;value&gt;:
3307 you can use --pager=&lt;value&gt;:
3306 </p>
3308 </p>
3307 <ul>
3309 <ul>
3308 <li> use as needed: 'auto'.
3310 <li> use as needed: 'auto'.
3309 <li> require the pager: 'yes' or 'on'.
3311 <li> require the pager: 'yes' or 'on'.
3310 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3312 <li> suppress the pager: 'no' or 'off' (any unrecognized value will also work).
3311 </ul>
3313 </ul>
3312 <p>
3314 <p>
3313 To globally turn off all attempts to use a pager, set:
3315 To globally turn off all attempts to use a pager, set:
3314 </p>
3316 </p>
3315 <pre>
3317 <pre>
3316 [ui]
3318 [ui]
3317 paginate = never
3319 paginate = never
3318 </pre>
3320 </pre>
3319 <p>
3321 <p>
3320 which will prevent the pager from running.
3322 which will prevent the pager from running.
3321 </p>
3323 </p>
3322
3324
3323 </div>
3325 </div>
3324 </div>
3326 </div>
3325 </div>
3327 </div>
3326
3328
3327
3329
3328
3330
3329 </body>
3331 </body>
3330 </html>
3332 </html>
3331
3333
3332
3334
3333 Sub-topic indexes rendered properly
3335 Sub-topic indexes rendered properly
3334
3336
3335 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3337 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals"
3336 200 Script output follows
3338 200 Script output follows
3337
3339
3338 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3340 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3339 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3341 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3340 <head>
3342 <head>
3341 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3343 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3342 <meta name="robots" content="index, nofollow" />
3344 <meta name="robots" content="index, nofollow" />
3343 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3345 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3344 <script type="text/javascript" src="/static/mercurial.js"></script>
3346 <script type="text/javascript" src="/static/mercurial.js"></script>
3345
3347
3346 <title>Help: internals</title>
3348 <title>Help: internals</title>
3347 </head>
3349 </head>
3348 <body>
3350 <body>
3349
3351
3350 <div class="container">
3352 <div class="container">
3351 <div class="menu">
3353 <div class="menu">
3352 <div class="logo">
3354 <div class="logo">
3353 <a href="https://mercurial-scm.org/">
3355 <a href="https://mercurial-scm.org/">
3354 <img src="/static/hglogo.png" alt="mercurial" /></a>
3356 <img src="/static/hglogo.png" alt="mercurial" /></a>
3355 </div>
3357 </div>
3356 <ul>
3358 <ul>
3357 <li><a href="/shortlog">log</a></li>
3359 <li><a href="/shortlog">log</a></li>
3358 <li><a href="/graph">graph</a></li>
3360 <li><a href="/graph">graph</a></li>
3359 <li><a href="/tags">tags</a></li>
3361 <li><a href="/tags">tags</a></li>
3360 <li><a href="/bookmarks">bookmarks</a></li>
3362 <li><a href="/bookmarks">bookmarks</a></li>
3361 <li><a href="/branches">branches</a></li>
3363 <li><a href="/branches">branches</a></li>
3362 </ul>
3364 </ul>
3363 <ul>
3365 <ul>
3364 <li><a href="/help">help</a></li>
3366 <li><a href="/help">help</a></li>
3365 </ul>
3367 </ul>
3366 </div>
3368 </div>
3367
3369
3368 <div class="main">
3370 <div class="main">
3369 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3371 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3370
3372
3371 <form class="search" action="/log">
3373 <form class="search" action="/log">
3372
3374
3373 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3375 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3374 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3376 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3375 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3377 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3376 </form>
3378 </form>
3377 <table class="bigtable">
3379 <table class="bigtable">
3378 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3380 <tr><td colspan="2"><h2><a name="topics" href="#topics">Topics</a></h2></td></tr>
3379
3381
3380 <tr><td>
3382 <tr><td>
3381 <a href="/help/internals.bundle2">
3383 <a href="/help/internals.bundle2">
3382 bundle2
3384 bundle2
3383 </a>
3385 </a>
3384 </td><td>
3386 </td><td>
3385 Bundle2
3387 Bundle2
3386 </td></tr>
3388 </td></tr>
3387 <tr><td>
3389 <tr><td>
3388 <a href="/help/internals.bundles">
3390 <a href="/help/internals.bundles">
3389 bundles
3391 bundles
3390 </a>
3392 </a>
3391 </td><td>
3393 </td><td>
3392 Bundles
3394 Bundles
3393 </td></tr>
3395 </td></tr>
3394 <tr><td>
3396 <tr><td>
3395 <a href="/help/internals.cbor">
3397 <a href="/help/internals.cbor">
3396 cbor
3398 cbor
3397 </a>
3399 </a>
3398 </td><td>
3400 </td><td>
3399 CBOR
3401 CBOR
3400 </td></tr>
3402 </td></tr>
3401 <tr><td>
3403 <tr><td>
3402 <a href="/help/internals.censor">
3404 <a href="/help/internals.censor">
3403 censor
3405 censor
3404 </a>
3406 </a>
3405 </td><td>
3407 </td><td>
3406 Censor
3408 Censor
3407 </td></tr>
3409 </td></tr>
3408 <tr><td>
3410 <tr><td>
3409 <a href="/help/internals.changegroups">
3411 <a href="/help/internals.changegroups">
3410 changegroups
3412 changegroups
3411 </a>
3413 </a>
3412 </td><td>
3414 </td><td>
3413 Changegroups
3415 Changegroups
3414 </td></tr>
3416 </td></tr>
3415 <tr><td>
3417 <tr><td>
3416 <a href="/help/internals.config">
3418 <a href="/help/internals.config">
3417 config
3419 config
3418 </a>
3420 </a>
3419 </td><td>
3421 </td><td>
3420 Config Registrar
3422 Config Registrar
3421 </td></tr>
3423 </td></tr>
3422 <tr><td>
3424 <tr><td>
3423 <a href="/help/internals.extensions">
3425 <a href="/help/internals.extensions">
3424 extensions
3426 extensions
3425 </a>
3427 </a>
3426 </td><td>
3428 </td><td>
3427 Extension API
3429 Extension API
3428 </td></tr>
3430 </td></tr>
3429 <tr><td>
3431 <tr><td>
3430 <a href="/help/internals.requirements">
3432 <a href="/help/internals.requirements">
3431 requirements
3433 requirements
3432 </a>
3434 </a>
3433 </td><td>
3435 </td><td>
3434 Repository Requirements
3436 Repository Requirements
3435 </td></tr>
3437 </td></tr>
3436 <tr><td>
3438 <tr><td>
3437 <a href="/help/internals.revlogs">
3439 <a href="/help/internals.revlogs">
3438 revlogs
3440 revlogs
3439 </a>
3441 </a>
3440 </td><td>
3442 </td><td>
3441 Revision Logs
3443 Revision Logs
3442 </td></tr>
3444 </td></tr>
3443 <tr><td>
3445 <tr><td>
3444 <a href="/help/internals.wireprotocol">
3446 <a href="/help/internals.wireprotocol">
3445 wireprotocol
3447 wireprotocol
3446 </a>
3448 </a>
3447 </td><td>
3449 </td><td>
3448 Wire Protocol
3450 Wire Protocol
3449 </td></tr>
3451 </td></tr>
3450 <tr><td>
3452 <tr><td>
3451 <a href="/help/internals.wireprotocolrpc">
3453 <a href="/help/internals.wireprotocolrpc">
3452 wireprotocolrpc
3454 wireprotocolrpc
3453 </a>
3455 </a>
3454 </td><td>
3456 </td><td>
3455 Wire Protocol RPC
3457 Wire Protocol RPC
3456 </td></tr>
3458 </td></tr>
3457 <tr><td>
3459 <tr><td>
3458 <a href="/help/internals.wireprotocolv2">
3460 <a href="/help/internals.wireprotocolv2">
3459 wireprotocolv2
3461 wireprotocolv2
3460 </a>
3462 </a>
3461 </td><td>
3463 </td><td>
3462 Wire Protocol Version 2
3464 Wire Protocol Version 2
3463 </td></tr>
3465 </td></tr>
3464
3466
3465
3467
3466
3468
3467
3469
3468
3470
3469 </table>
3471 </table>
3470 </div>
3472 </div>
3471 </div>
3473 </div>
3472
3474
3473
3475
3474
3476
3475 </body>
3477 </body>
3476 </html>
3478 </html>
3477
3479
3478
3480
3479 Sub-topic topics rendered properly
3481 Sub-topic topics rendered properly
3480
3482
3481 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3483 $ get-with-headers.py $LOCALIP:$HGPORT "help/internals.changegroups"
3482 200 Script output follows
3484 200 Script output follows
3483
3485
3484 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3486 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3485 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3487 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3486 <head>
3488 <head>
3487 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3489 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3488 <meta name="robots" content="index, nofollow" />
3490 <meta name="robots" content="index, nofollow" />
3489 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3491 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3490 <script type="text/javascript" src="/static/mercurial.js"></script>
3492 <script type="text/javascript" src="/static/mercurial.js"></script>
3491
3493
3492 <title>Help: internals.changegroups</title>
3494 <title>Help: internals.changegroups</title>
3493 </head>
3495 </head>
3494 <body>
3496 <body>
3495
3497
3496 <div class="container">
3498 <div class="container">
3497 <div class="menu">
3499 <div class="menu">
3498 <div class="logo">
3500 <div class="logo">
3499 <a href="https://mercurial-scm.org/">
3501 <a href="https://mercurial-scm.org/">
3500 <img src="/static/hglogo.png" alt="mercurial" /></a>
3502 <img src="/static/hglogo.png" alt="mercurial" /></a>
3501 </div>
3503 </div>
3502 <ul>
3504 <ul>
3503 <li><a href="/shortlog">log</a></li>
3505 <li><a href="/shortlog">log</a></li>
3504 <li><a href="/graph">graph</a></li>
3506 <li><a href="/graph">graph</a></li>
3505 <li><a href="/tags">tags</a></li>
3507 <li><a href="/tags">tags</a></li>
3506 <li><a href="/bookmarks">bookmarks</a></li>
3508 <li><a href="/bookmarks">bookmarks</a></li>
3507 <li><a href="/branches">branches</a></li>
3509 <li><a href="/branches">branches</a></li>
3508 </ul>
3510 </ul>
3509 <ul>
3511 <ul>
3510 <li class="active"><a href="/help">help</a></li>
3512 <li class="active"><a href="/help">help</a></li>
3511 </ul>
3513 </ul>
3512 </div>
3514 </div>
3513
3515
3514 <div class="main">
3516 <div class="main">
3515 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3517 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3516 <h3>Help: internals.changegroups</h3>
3518 <h3>Help: internals.changegroups</h3>
3517
3519
3518 <form class="search" action="/log">
3520 <form class="search" action="/log">
3519
3521
3520 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3522 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3521 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3523 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3522 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3524 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3523 </form>
3525 </form>
3524 <div id="doc">
3526 <div id="doc">
3525 <h1>Changegroups</h1>
3527 <h1>Changegroups</h1>
3526 <p>
3528 <p>
3527 Changegroups are representations of repository revlog data, specifically
3529 Changegroups are representations of repository revlog data, specifically
3528 the changelog data, root/flat manifest data, treemanifest data, and
3530 the changelog data, root/flat manifest data, treemanifest data, and
3529 filelogs.
3531 filelogs.
3530 </p>
3532 </p>
3531 <p>
3533 <p>
3532 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3534 There are 3 versions of changegroups: &quot;1&quot;, &quot;2&quot;, and &quot;3&quot;. From a
3533 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3535 high-level, versions &quot;1&quot; and &quot;2&quot; are almost exactly the same, with the
3534 only difference being an additional item in the *delta header*. Version
3536 only difference being an additional item in the *delta header*. Version
3535 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3537 &quot;3&quot; adds support for storage flags in the *delta header* and optionally
3536 exchanging treemanifests (enabled by setting an option on the
3538 exchanging treemanifests (enabled by setting an option on the
3537 &quot;changegroup&quot; part in the bundle2).
3539 &quot;changegroup&quot; part in the bundle2).
3538 </p>
3540 </p>
3539 <p>
3541 <p>
3540 Changegroups when not exchanging treemanifests consist of 3 logical
3542 Changegroups when not exchanging treemanifests consist of 3 logical
3541 segments:
3543 segments:
3542 </p>
3544 </p>
3543 <pre>
3545 <pre>
3544 +---------------------------------+
3546 +---------------------------------+
3545 | | | |
3547 | | | |
3546 | changeset | manifest | filelogs |
3548 | changeset | manifest | filelogs |
3547 | | | |
3549 | | | |
3548 | | | |
3550 | | | |
3549 +---------------------------------+
3551 +---------------------------------+
3550 </pre>
3552 </pre>
3551 <p>
3553 <p>
3552 When exchanging treemanifests, there are 4 logical segments:
3554 When exchanging treemanifests, there are 4 logical segments:
3553 </p>
3555 </p>
3554 <pre>
3556 <pre>
3555 +-------------------------------------------------+
3557 +-------------------------------------------------+
3556 | | | | |
3558 | | | | |
3557 | changeset | root | treemanifests | filelogs |
3559 | changeset | root | treemanifests | filelogs |
3558 | | manifest | | |
3560 | | manifest | | |
3559 | | | | |
3561 | | | | |
3560 +-------------------------------------------------+
3562 +-------------------------------------------------+
3561 </pre>
3563 </pre>
3562 <p>
3564 <p>
3563 The principle building block of each segment is a *chunk*. A *chunk*
3565 The principle building block of each segment is a *chunk*. A *chunk*
3564 is a framed piece of data:
3566 is a framed piece of data:
3565 </p>
3567 </p>
3566 <pre>
3568 <pre>
3567 +---------------------------------------+
3569 +---------------------------------------+
3568 | | |
3570 | | |
3569 | length | data |
3571 | length | data |
3570 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3572 | (4 bytes) | (&lt;length - 4&gt; bytes) |
3571 | | |
3573 | | |
3572 +---------------------------------------+
3574 +---------------------------------------+
3573 </pre>
3575 </pre>
3574 <p>
3576 <p>
3575 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3577 All integers are big-endian signed integers. Each chunk starts with a 32-bit
3576 integer indicating the length of the entire chunk (including the length field
3578 integer indicating the length of the entire chunk (including the length field
3577 itself).
3579 itself).
3578 </p>
3580 </p>
3579 <p>
3581 <p>
3580 There is a special case chunk that has a value of 0 for the length
3582 There is a special case chunk that has a value of 0 for the length
3581 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3583 (&quot;0x00000000&quot;). We call this an *empty chunk*.
3582 </p>
3584 </p>
3583 <h2>Delta Groups</h2>
3585 <h2>Delta Groups</h2>
3584 <p>
3586 <p>
3585 A *delta group* expresses the content of a revlog as a series of deltas,
3587 A *delta group* expresses the content of a revlog as a series of deltas,
3586 or patches against previous revisions.
3588 or patches against previous revisions.
3587 </p>
3589 </p>
3588 <p>
3590 <p>
3589 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3591 Delta groups consist of 0 or more *chunks* followed by the *empty chunk*
3590 to signal the end of the delta group:
3592 to signal the end of the delta group:
3591 </p>
3593 </p>
3592 <pre>
3594 <pre>
3593 +------------------------------------------------------------------------+
3595 +------------------------------------------------------------------------+
3594 | | | | | |
3596 | | | | | |
3595 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3597 | chunk0 length | chunk0 data | chunk1 length | chunk1 data | 0x0 |
3596 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3598 | (4 bytes) | (various) | (4 bytes) | (various) | (4 bytes) |
3597 | | | | | |
3599 | | | | | |
3598 +------------------------------------------------------------------------+
3600 +------------------------------------------------------------------------+
3599 </pre>
3601 </pre>
3600 <p>
3602 <p>
3601 Each *chunk*'s data consists of the following:
3603 Each *chunk*'s data consists of the following:
3602 </p>
3604 </p>
3603 <pre>
3605 <pre>
3604 +---------------------------------------+
3606 +---------------------------------------+
3605 | | |
3607 | | |
3606 | delta header | delta data |
3608 | delta header | delta data |
3607 | (various by version) | (various) |
3609 | (various by version) | (various) |
3608 | | |
3610 | | |
3609 +---------------------------------------+
3611 +---------------------------------------+
3610 </pre>
3612 </pre>
3611 <p>
3613 <p>
3612 The *delta data* is a series of *delta*s that describe a diff from an existing
3614 The *delta data* is a series of *delta*s that describe a diff from an existing
3613 entry (either that the recipient already has, or previously specified in the
3615 entry (either that the recipient already has, or previously specified in the
3614 bundle/changegroup).
3616 bundle/changegroup).
3615 </p>
3617 </p>
3616 <p>
3618 <p>
3617 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3619 The *delta header* is different between versions &quot;1&quot;, &quot;2&quot;, and
3618 &quot;3&quot; of the changegroup format.
3620 &quot;3&quot; of the changegroup format.
3619 </p>
3621 </p>
3620 <p>
3622 <p>
3621 Version 1 (headerlen=80):
3623 Version 1 (headerlen=80):
3622 </p>
3624 </p>
3623 <pre>
3625 <pre>
3624 +------------------------------------------------------+
3626 +------------------------------------------------------+
3625 | | | | |
3627 | | | | |
3626 | node | p1 node | p2 node | link node |
3628 | node | p1 node | p2 node | link node |
3627 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3629 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3628 | | | | |
3630 | | | | |
3629 +------------------------------------------------------+
3631 +------------------------------------------------------+
3630 </pre>
3632 </pre>
3631 <p>
3633 <p>
3632 Version 2 (headerlen=100):
3634 Version 2 (headerlen=100):
3633 </p>
3635 </p>
3634 <pre>
3636 <pre>
3635 +------------------------------------------------------------------+
3637 +------------------------------------------------------------------+
3636 | | | | | |
3638 | | | | | |
3637 | node | p1 node | p2 node | base node | link node |
3639 | node | p1 node | p2 node | base node | link node |
3638 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3640 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) |
3639 | | | | | |
3641 | | | | | |
3640 +------------------------------------------------------------------+
3642 +------------------------------------------------------------------+
3641 </pre>
3643 </pre>
3642 <p>
3644 <p>
3643 Version 3 (headerlen=102):
3645 Version 3 (headerlen=102):
3644 </p>
3646 </p>
3645 <pre>
3647 <pre>
3646 +------------------------------------------------------------------------------+
3648 +------------------------------------------------------------------------------+
3647 | | | | | | |
3649 | | | | | | |
3648 | node | p1 node | p2 node | base node | link node | flags |
3650 | node | p1 node | p2 node | base node | link node | flags |
3649 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3651 | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (20 bytes) | (2 bytes) |
3650 | | | | | | |
3652 | | | | | | |
3651 +------------------------------------------------------------------------------+
3653 +------------------------------------------------------------------------------+
3652 </pre>
3654 </pre>
3653 <p>
3655 <p>
3654 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3656 The *delta data* consists of &quot;chunklen - 4 - headerlen&quot; bytes, which contain a
3655 series of *delta*s, densely packed (no separators). These deltas describe a diff
3657 series of *delta*s, densely packed (no separators). These deltas describe a diff
3656 from an existing entry (either that the recipient already has, or previously
3658 from an existing entry (either that the recipient already has, or previously
3657 specified in the bundle/changegroup). The format is described more fully in
3659 specified in the bundle/changegroup). The format is described more fully in
3658 &quot;hg help internals.bdiff&quot;, but briefly:
3660 &quot;hg help internals.bdiff&quot;, but briefly:
3659 </p>
3661 </p>
3660 <pre>
3662 <pre>
3661 +---------------------------------------------------------------+
3663 +---------------------------------------------------------------+
3662 | | | | |
3664 | | | | |
3663 | start offset | end offset | new length | content |
3665 | start offset | end offset | new length | content |
3664 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3666 | (4 bytes) | (4 bytes) | (4 bytes) | (&lt;new length&gt; bytes) |
3665 | | | | |
3667 | | | | |
3666 +---------------------------------------------------------------+
3668 +---------------------------------------------------------------+
3667 </pre>
3669 </pre>
3668 <p>
3670 <p>
3669 Please note that the length field in the delta data does *not* include itself.
3671 Please note that the length field in the delta data does *not* include itself.
3670 </p>
3672 </p>
3671 <p>
3673 <p>
3672 In version 1, the delta is always applied against the previous node from
3674 In version 1, the delta is always applied against the previous node from
3673 the changegroup or the first parent if this is the first entry in the
3675 the changegroup or the first parent if this is the first entry in the
3674 changegroup.
3676 changegroup.
3675 </p>
3677 </p>
3676 <p>
3678 <p>
3677 In version 2 and up, the delta base node is encoded in the entry in the
3679 In version 2 and up, the delta base node is encoded in the entry in the
3678 changegroup. This allows the delta to be expressed against any parent,
3680 changegroup. This allows the delta to be expressed against any parent,
3679 which can result in smaller deltas and more efficient encoding of data.
3681 which can result in smaller deltas and more efficient encoding of data.
3680 </p>
3682 </p>
3681 <p>
3683 <p>
3682 The *flags* field holds bitwise flags affecting the processing of revision
3684 The *flags* field holds bitwise flags affecting the processing of revision
3683 data. The following flags are defined:
3685 data. The following flags are defined:
3684 </p>
3686 </p>
3685 <dl>
3687 <dl>
3686 <dt>32768
3688 <dt>32768
3687 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3689 <dd>Censored revision. The revision's fulltext has been replaced by censor metadata. May only occur on file revisions.
3688 <dt>16384
3690 <dt>16384
3689 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3691 <dd>Ellipsis revision. Revision hash does not match data (likely due to rewritten parents).
3690 <dt>8192
3692 <dt>8192
3691 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3693 <dd>Externally stored. The revision fulltext contains &quot;key:value&quot; &quot;\n&quot; delimited metadata defining an object stored elsewhere. Used by the LFS extension.
3692 </dl>
3694 </dl>
3693 <p>
3695 <p>
3694 For historical reasons, the integer values are identical to revlog version 1
3696 For historical reasons, the integer values are identical to revlog version 1
3695 per-revision storage flags and correspond to bits being set in this 2-byte
3697 per-revision storage flags and correspond to bits being set in this 2-byte
3696 field. Bits were allocated starting from the most-significant bit, hence the
3698 field. Bits were allocated starting from the most-significant bit, hence the
3697 reverse ordering and allocation of these flags.
3699 reverse ordering and allocation of these flags.
3698 </p>
3700 </p>
3699 <h2>Changeset Segment</h2>
3701 <h2>Changeset Segment</h2>
3700 <p>
3702 <p>
3701 The *changeset segment* consists of a single *delta group* holding
3703 The *changeset segment* consists of a single *delta group* holding
3702 changelog data. The *empty chunk* at the end of the *delta group* denotes
3704 changelog data. The *empty chunk* at the end of the *delta group* denotes
3703 the boundary to the *manifest segment*.
3705 the boundary to the *manifest segment*.
3704 </p>
3706 </p>
3705 <h2>Manifest Segment</h2>
3707 <h2>Manifest Segment</h2>
3706 <p>
3708 <p>
3707 The *manifest segment* consists of a single *delta group* holding manifest
3709 The *manifest segment* consists of a single *delta group* holding manifest
3708 data. If treemanifests are in use, it contains only the manifest for the
3710 data. If treemanifests are in use, it contains only the manifest for the
3709 root directory of the repository. Otherwise, it contains the entire
3711 root directory of the repository. Otherwise, it contains the entire
3710 manifest data. The *empty chunk* at the end of the *delta group* denotes
3712 manifest data. The *empty chunk* at the end of the *delta group* denotes
3711 the boundary to the next segment (either the *treemanifests segment* or the
3713 the boundary to the next segment (either the *treemanifests segment* or the
3712 *filelogs segment*, depending on version and the request options).
3714 *filelogs segment*, depending on version and the request options).
3713 </p>
3715 </p>
3714 <h3>Treemanifests Segment</h3>
3716 <h3>Treemanifests Segment</h3>
3715 <p>
3717 <p>
3716 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3718 The *treemanifests segment* only exists in changegroup version &quot;3&quot;, and
3717 only if the 'treemanifest' param is part of the bundle2 changegroup part
3719 only if the 'treemanifest' param is part of the bundle2 changegroup part
3718 (it is not possible to use changegroup version 3 outside of bundle2).
3720 (it is not possible to use changegroup version 3 outside of bundle2).
3719 Aside from the filenames in the *treemanifests segment* containing a
3721 Aside from the filenames in the *treemanifests segment* containing a
3720 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3722 trailing &quot;/&quot; character, it behaves identically to the *filelogs segment*
3721 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3723 (see below). The final sub-segment is followed by an *empty chunk* (logically,
3722 a sub-segment with filename size 0). This denotes the boundary to the
3724 a sub-segment with filename size 0). This denotes the boundary to the
3723 *filelogs segment*.
3725 *filelogs segment*.
3724 </p>
3726 </p>
3725 <h2>Filelogs Segment</h2>
3727 <h2>Filelogs Segment</h2>
3726 <p>
3728 <p>
3727 The *filelogs segment* consists of multiple sub-segments, each
3729 The *filelogs segment* consists of multiple sub-segments, each
3728 corresponding to an individual file whose data is being described:
3730 corresponding to an individual file whose data is being described:
3729 </p>
3731 </p>
3730 <pre>
3732 <pre>
3731 +--------------------------------------------------+
3733 +--------------------------------------------------+
3732 | | | | | |
3734 | | | | | |
3733 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3735 | filelog0 | filelog1 | filelog2 | ... | 0x0 |
3734 | | | | | (4 bytes) |
3736 | | | | | (4 bytes) |
3735 | | | | | |
3737 | | | | | |
3736 +--------------------------------------------------+
3738 +--------------------------------------------------+
3737 </pre>
3739 </pre>
3738 <p>
3740 <p>
3739 The final filelog sub-segment is followed by an *empty chunk* (logically,
3741 The final filelog sub-segment is followed by an *empty chunk* (logically,
3740 a sub-segment with filename size 0). This denotes the end of the segment
3742 a sub-segment with filename size 0). This denotes the end of the segment
3741 and of the overall changegroup.
3743 and of the overall changegroup.
3742 </p>
3744 </p>
3743 <p>
3745 <p>
3744 Each filelog sub-segment consists of the following:
3746 Each filelog sub-segment consists of the following:
3745 </p>
3747 </p>
3746 <pre>
3748 <pre>
3747 +------------------------------------------------------+
3749 +------------------------------------------------------+
3748 | | | |
3750 | | | |
3749 | filename length | filename | delta group |
3751 | filename length | filename | delta group |
3750 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3752 | (4 bytes) | (&lt;length - 4&gt; bytes) | (various) |
3751 | | | |
3753 | | | |
3752 +------------------------------------------------------+
3754 +------------------------------------------------------+
3753 </pre>
3755 </pre>
3754 <p>
3756 <p>
3755 That is, a *chunk* consisting of the filename (not terminated or padded)
3757 That is, a *chunk* consisting of the filename (not terminated or padded)
3756 followed by N chunks constituting the *delta group* for this file. The
3758 followed by N chunks constituting the *delta group* for this file. The
3757 *empty chunk* at the end of each *delta group* denotes the boundary to the
3759 *empty chunk* at the end of each *delta group* denotes the boundary to the
3758 next filelog sub-segment.
3760 next filelog sub-segment.
3759 </p>
3761 </p>
3760
3762
3761 </div>
3763 </div>
3762 </div>
3764 </div>
3763 </div>
3765 </div>
3764
3766
3765
3767
3766
3768
3767 </body>
3769 </body>
3768 </html>
3770 </html>
3769
3771
3770
3772
3771 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3773 $ get-with-headers.py 127.0.0.1:$HGPORT "help/unknowntopic"
3772 404 Not Found
3774 404 Not Found
3773
3775
3774 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3776 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
3775 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3777 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
3776 <head>
3778 <head>
3777 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3779 <link rel="icon" href="/static/hgicon.png" type="image/png" />
3778 <meta name="robots" content="index, nofollow" />
3780 <meta name="robots" content="index, nofollow" />
3779 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3781 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
3780 <script type="text/javascript" src="/static/mercurial.js"></script>
3782 <script type="text/javascript" src="/static/mercurial.js"></script>
3781
3783
3782 <title>test: error</title>
3784 <title>test: error</title>
3783 </head>
3785 </head>
3784 <body>
3786 <body>
3785
3787
3786 <div class="container">
3788 <div class="container">
3787 <div class="menu">
3789 <div class="menu">
3788 <div class="logo">
3790 <div class="logo">
3789 <a href="https://mercurial-scm.org/">
3791 <a href="https://mercurial-scm.org/">
3790 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3792 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
3791 </div>
3793 </div>
3792 <ul>
3794 <ul>
3793 <li><a href="/shortlog">log</a></li>
3795 <li><a href="/shortlog">log</a></li>
3794 <li><a href="/graph">graph</a></li>
3796 <li><a href="/graph">graph</a></li>
3795 <li><a href="/tags">tags</a></li>
3797 <li><a href="/tags">tags</a></li>
3796 <li><a href="/bookmarks">bookmarks</a></li>
3798 <li><a href="/bookmarks">bookmarks</a></li>
3797 <li><a href="/branches">branches</a></li>
3799 <li><a href="/branches">branches</a></li>
3798 </ul>
3800 </ul>
3799 <ul>
3801 <ul>
3800 <li><a href="/help">help</a></li>
3802 <li><a href="/help">help</a></li>
3801 </ul>
3803 </ul>
3802 </div>
3804 </div>
3803
3805
3804 <div class="main">
3806 <div class="main">
3805
3807
3806 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3808 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
3807 <h3>error</h3>
3809 <h3>error</h3>
3808
3810
3809
3811
3810 <form class="search" action="/log">
3812 <form class="search" action="/log">
3811
3813
3812 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3814 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
3813 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3815 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
3814 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3816 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
3815 </form>
3817 </form>
3816
3818
3817 <div class="description">
3819 <div class="description">
3818 <p>
3820 <p>
3819 An error occurred while processing your request:
3821 An error occurred while processing your request:
3820 </p>
3822 </p>
3821 <p>
3823 <p>
3822 Not Found
3824 Not Found
3823 </p>
3825 </p>
3824 </div>
3826 </div>
3825 </div>
3827 </div>
3826 </div>
3828 </div>
3827
3829
3828
3830
3829
3831
3830 </body>
3832 </body>
3831 </html>
3833 </html>
3832
3834
3833 [1]
3835 [1]
3834
3836
3835 $ killdaemons.py
3837 $ killdaemons.py
3836
3838
3837 #endif
3839 #endif
@@ -1,257 +1,281 b''
1 #testcases vfs svfs
2
1 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "share = " >> $HGRCPATH
4 $ echo "share = " >> $HGRCPATH
3
5
6 #if svfs
7 $ echo "[format]" >> $HGRCPATH
8 $ echo "bookmarks-in-store = yes " >> $HGRCPATH
9 #endif
10
4 prepare repo1
11 prepare repo1
5
12
6 $ hg init repo1
13 $ hg init repo1
7 $ cd repo1
14 $ cd repo1
8 $ echo a > a
15 $ echo a > a
9 $ hg commit -A -m'init'
16 $ hg commit -A -m'init'
10 adding a
17 adding a
11 $ echo a >> a
18 $ echo a >> a
12 $ hg commit -m'change in shared clone'
19 $ hg commit -m'change in shared clone'
13 $ echo b > b
20 $ echo b > b
14 $ hg commit -A -m'another file'
21 $ hg commit -A -m'another file'
15 adding b
22 adding b
16
23
17 share it
24 share it
18
25
19 $ cd ..
26 $ cd ..
20 $ hg share repo1 repo2
27 $ hg share repo1 repo2
21 updating working directory
28 updating working directory
22 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
23
30
24 test sharing bookmarks
31 test sharing bookmarks
25
32
26 $ hg share -B repo1 repo3
33 $ hg share -B repo1 repo3
27 updating working directory
34 updating working directory
28 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
35 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
29 $ cd repo1
36 $ cd repo1
30 $ hg bookmark bm1
37 $ hg bookmark bm1
31 $ hg bookmarks
38 $ hg bookmarks
32 * bm1 2:c2e0ac586386
39 * bm1 2:c2e0ac586386
33 $ cd ../repo2
40 $ cd ../repo2
34 $ hg book bm2
41 $ hg book bm2
35 $ hg bookmarks
42 $ hg bookmarks
43 bm1 2:c2e0ac586386 (svfs !)
36 * bm2 2:c2e0ac586386
44 * bm2 2:c2e0ac586386
37 $ cd ../repo3
45 $ cd ../repo3
38 $ hg bookmarks
46 $ hg bookmarks
39 bm1 2:c2e0ac586386
47 bm1 2:c2e0ac586386
48 bm2 2:c2e0ac586386 (svfs !)
40 $ hg book bm3
49 $ hg book bm3
41 $ hg bookmarks
50 $ hg bookmarks
42 bm1 2:c2e0ac586386
51 bm1 2:c2e0ac586386
52 bm2 2:c2e0ac586386 (svfs !)
43 * bm3 2:c2e0ac586386
53 * bm3 2:c2e0ac586386
44 $ cd ../repo1
54 $ cd ../repo1
45 $ hg bookmarks
55 $ hg bookmarks
46 * bm1 2:c2e0ac586386
56 * bm1 2:c2e0ac586386
57 bm2 2:c2e0ac586386 (svfs !)
47 bm3 2:c2e0ac586386
58 bm3 2:c2e0ac586386
48
59
49 check whether HG_PENDING makes pending changes only in relatd
60 check whether HG_PENDING makes pending changes only in relatd
50 repositories visible to an external hook.
61 repositories visible to an external hook.
51
62
52 In "hg share" case, another transaction can't run in other
63 In "hg share" case, another transaction can't run in other
53 repositories sharing same source repository, because starting
64 repositories sharing same source repository, because starting
54 transaction requires locking store of source repository.
65 transaction requires locking store of source repository.
55
66
56 Therefore, this test scenario ignores checking visibility of
67 Therefore, this test scenario ignores checking visibility of
57 .hg/bookmarks.pending in repo2, which shares repo1 without bookmarks.
68 .hg/bookmarks.pending in repo2, which shares repo1 without bookmarks.
58
69
59 $ cat > $TESTTMP/checkbookmarks.sh <<EOF
70 $ cat > $TESTTMP/checkbookmarks.sh <<EOF
60 > echo "@repo1"
71 > echo "@repo1"
61 > hg -R "$TESTTMP/repo1" bookmarks
72 > hg -R "$TESTTMP/repo1" bookmarks
62 > echo "@repo2"
73 > echo "@repo2"
63 > hg -R "$TESTTMP/repo2" bookmarks
74 > hg -R "$TESTTMP/repo2" bookmarks
64 > echo "@repo3"
75 > echo "@repo3"
65 > hg -R "$TESTTMP/repo3" bookmarks
76 > hg -R "$TESTTMP/repo3" bookmarks
66 > exit 1 # to avoid adding new bookmark for subsequent tests
77 > exit 1 # to avoid adding new bookmark for subsequent tests
67 > EOF
78 > EOF
68
79
69 $ cd ../repo1
80 $ cd ../repo1
70 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
81 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
71 @repo1
82 @repo1
72 bm1 2:c2e0ac586386
83 bm1 2:c2e0ac586386
84 bm2 2:c2e0ac586386 (svfs !)
73 bm3 2:c2e0ac586386
85 bm3 2:c2e0ac586386
74 * bmX 2:c2e0ac586386
86 * bmX 2:c2e0ac586386
75 @repo2
87 @repo2
88 bm1 2:c2e0ac586386 (svfs !)
76 * bm2 2:c2e0ac586386
89 * bm2 2:c2e0ac586386
90 bm3 2:c2e0ac586386 (svfs !)
77 @repo3
91 @repo3
78 bm1 2:c2e0ac586386
92 bm1 2:c2e0ac586386
93 bm2 2:c2e0ac586386 (svfs !)
79 * bm3 2:c2e0ac586386
94 * bm3 2:c2e0ac586386
80 bmX 2:c2e0ac586386
95 bmX 2:c2e0ac586386 (vfs !)
81 transaction abort!
96 transaction abort!
82 rollback completed
97 rollback completed
83 abort: pretxnclose hook exited with status 1
98 abort: pretxnclose hook exited with status 1
84 [255]
99 [255]
85 $ hg book bm1
100 $ hg book bm1
86
101
87 FYI, in contrast to above test, bmX is invisible in repo1 (= shared
102 FYI, in contrast to above test, bmX is invisible in repo1 (= shared
88 src), because (1) HG_PENDING refers only repo3 and (2)
103 src), because (1) HG_PENDING refers only repo3 and (2)
89 "bookmarks.pending" is written only into repo3.
104 "bookmarks.pending" is written only into repo3.
90
105
91 $ cd ../repo3
106 $ cd ../repo3
92 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
107 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
93 @repo1
108 @repo1
94 * bm1 2:c2e0ac586386
109 * bm1 2:c2e0ac586386
110 bm2 2:c2e0ac586386 (svfs !)
95 bm3 2:c2e0ac586386
111 bm3 2:c2e0ac586386
96 @repo2
112 @repo2
113 bm1 2:c2e0ac586386 (svfs !)
97 * bm2 2:c2e0ac586386
114 * bm2 2:c2e0ac586386
115 bm3 2:c2e0ac586386 (svfs !)
98 @repo3
116 @repo3
99 bm1 2:c2e0ac586386
117 bm1 2:c2e0ac586386
118 bm2 2:c2e0ac586386 (svfs !)
100 bm3 2:c2e0ac586386
119 bm3 2:c2e0ac586386
101 * bmX 2:c2e0ac586386
120 * bmX 2:c2e0ac586386
102 transaction abort!
121 transaction abort!
103 rollback completed
122 rollback completed
104 abort: pretxnclose hook exited with status 1
123 abort: pretxnclose hook exited with status 1
105 [255]
124 [255]
106 $ hg book bm3
125 $ hg book bm3
107
126
127 clean up bm2 since it's uninteresting (not shared in the vfs case and
128 same as bm3 in the svfs case)
129 $ cd ../repo2
130 $ hg book -d bm2
131
108 $ cd ../repo1
132 $ cd ../repo1
109
133
110 test that commits work
134 test that commits work
111
135
112 $ echo 'shared bookmarks' > a
136 $ echo 'shared bookmarks' > a
113 $ hg commit -m 'testing shared bookmarks'
137 $ hg commit -m 'testing shared bookmarks'
114 $ hg bookmarks
138 $ hg bookmarks
115 * bm1 3:b87954705719
139 * bm1 3:b87954705719
116 bm3 2:c2e0ac586386
140 bm3 2:c2e0ac586386
117 $ cd ../repo3
141 $ cd ../repo3
118 $ hg bookmarks
142 $ hg bookmarks
119 bm1 3:b87954705719
143 bm1 3:b87954705719
120 * bm3 2:c2e0ac586386
144 * bm3 2:c2e0ac586386
121 $ echo 'more shared bookmarks' > a
145 $ echo 'more shared bookmarks' > a
122 $ hg commit -m 'testing shared bookmarks'
146 $ hg commit -m 'testing shared bookmarks'
123 created new head
147 created new head
124 $ hg bookmarks
148 $ hg bookmarks
125 bm1 3:b87954705719
149 bm1 3:b87954705719
126 * bm3 4:62f4ded848e4
150 * bm3 4:62f4ded848e4
127 $ cd ../repo1
151 $ cd ../repo1
128 $ hg bookmarks
152 $ hg bookmarks
129 * bm1 3:b87954705719
153 * bm1 3:b87954705719
130 bm3 4:62f4ded848e4
154 bm3 4:62f4ded848e4
131 $ cd ..
155 $ cd ..
132
156
133 test pushing bookmarks works
157 test pushing bookmarks works
134
158
135 $ hg clone repo3 repo4
159 $ hg clone repo3 repo4
136 updating to branch default
160 updating to branch default
137 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
161 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
138 $ cd repo4
162 $ cd repo4
139 $ hg boo bm4
163 $ hg boo bm4
140 $ echo foo > b
164 $ echo foo > b
141 $ hg commit -m 'foo in b'
165 $ hg commit -m 'foo in b'
142 $ hg boo
166 $ hg boo
143 bm1 3:b87954705719
167 bm1 3:b87954705719
144 bm3 4:62f4ded848e4
168 bm3 4:62f4ded848e4
145 * bm4 5:92793bfc8cad
169 * bm4 5:92793bfc8cad
146 $ hg push -B bm4
170 $ hg push -B bm4
147 pushing to $TESTTMP/repo3
171 pushing to $TESTTMP/repo3
148 searching for changes
172 searching for changes
149 adding changesets
173 adding changesets
150 adding manifests
174 adding manifests
151 adding file changes
175 adding file changes
152 added 1 changesets with 1 changes to 1 files
176 added 1 changesets with 1 changes to 1 files
153 exporting bookmark bm4
177 exporting bookmark bm4
154 $ cd ../repo1
178 $ cd ../repo1
155 $ hg bookmarks
179 $ hg bookmarks
156 * bm1 3:b87954705719
180 * bm1 3:b87954705719
157 bm3 4:62f4ded848e4
181 bm3 4:62f4ded848e4
158 bm4 5:92793bfc8cad
182 bm4 5:92793bfc8cad
159 $ cd ../repo3
183 $ cd ../repo3
160 $ hg bookmarks
184 $ hg bookmarks
161 bm1 3:b87954705719
185 bm1 3:b87954705719
162 * bm3 4:62f4ded848e4
186 * bm3 4:62f4ded848e4
163 bm4 5:92793bfc8cad
187 bm4 5:92793bfc8cad
164 $ cd ..
188 $ cd ..
165
189
166 test behavior when sharing a shared repo
190 test behavior when sharing a shared repo
167
191
168 $ hg share -B repo3 missingdir/repo5
192 $ hg share -B repo3 missingdir/repo5
169 updating working directory
193 updating working directory
170 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
194 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
171 $ cd missingdir/repo5
195 $ cd missingdir/repo5
172 $ hg book
196 $ hg book
173 bm1 3:b87954705719
197 bm1 3:b87954705719
174 bm3 4:62f4ded848e4
198 bm3 4:62f4ded848e4
175 bm4 5:92793bfc8cad
199 bm4 5:92793bfc8cad
176 $ cd ../..
200 $ cd ../..
177
201
178 test what happens when an active bookmark is deleted
202 test what happens when an active bookmark is deleted
179
203
180 $ cd repo1
204 $ cd repo1
181 $ hg boo -d bm3
205 $ hg boo -d bm3
182 $ hg boo
206 $ hg boo
183 * bm1 3:b87954705719
207 * bm1 3:b87954705719
184 bm4 5:92793bfc8cad
208 bm4 5:92793bfc8cad
185 $ cd ../repo3
209 $ cd ../repo3
186 $ hg boo
210 $ hg boo
187 bm1 3:b87954705719
211 bm1 3:b87954705719
188 bm4 5:92793bfc8cad
212 bm4 5:92793bfc8cad
189 $ cd ..
213 $ cd ..
190
214
191 verify that bookmarks are not written on failed transaction
215 verify that bookmarks are not written on failed transaction
192
216
193 $ cat > failpullbookmarks.py << EOF
217 $ cat > failpullbookmarks.py << EOF
194 > """A small extension that makes bookmark pulls fail, for testing"""
218 > """A small extension that makes bookmark pulls fail, for testing"""
195 > from __future__ import absolute_import
219 > from __future__ import absolute_import
196 > from mercurial import (
220 > from mercurial import (
197 > error,
221 > error,
198 > exchange,
222 > exchange,
199 > extensions,
223 > extensions,
200 > )
224 > )
201 > def _pullbookmarks(orig, pullop):
225 > def _pullbookmarks(orig, pullop):
202 > orig(pullop)
226 > orig(pullop)
203 > raise error.HookAbort('forced failure by extension')
227 > raise error.HookAbort('forced failure by extension')
204 > def extsetup(ui):
228 > def extsetup(ui):
205 > extensions.wrapfunction(exchange, '_pullbookmarks', _pullbookmarks)
229 > extensions.wrapfunction(exchange, '_pullbookmarks', _pullbookmarks)
206 > EOF
230 > EOF
207 $ cd repo4
231 $ cd repo4
208 $ hg boo
232 $ hg boo
209 bm1 3:b87954705719
233 bm1 3:b87954705719
210 bm3 4:62f4ded848e4
234 bm3 4:62f4ded848e4
211 * bm4 5:92793bfc8cad
235 * bm4 5:92793bfc8cad
212 $ cd ../repo3
236 $ cd ../repo3
213 $ hg boo
237 $ hg boo
214 bm1 3:b87954705719
238 bm1 3:b87954705719
215 bm4 5:92793bfc8cad
239 bm4 5:92793bfc8cad
216 $ hg --config "extensions.failpullbookmarks=$TESTTMP/failpullbookmarks.py" pull $TESTTMP/repo4
240 $ hg --config "extensions.failpullbookmarks=$TESTTMP/failpullbookmarks.py" pull $TESTTMP/repo4
217 pulling from $TESTTMP/repo4
241 pulling from $TESTTMP/repo4
218 searching for changes
242 searching for changes
219 no changes found
243 no changes found
220 adding remote bookmark bm3
244 adding remote bookmark bm3
221 abort: forced failure by extension
245 abort: forced failure by extension
222 [255]
246 [255]
223 $ hg boo
247 $ hg boo
224 bm1 3:b87954705719
248 bm1 3:b87954705719
225 bm4 5:92793bfc8cad
249 bm4 5:92793bfc8cad
226 $ hg pull $TESTTMP/repo4
250 $ hg pull $TESTTMP/repo4
227 pulling from $TESTTMP/repo4
251 pulling from $TESTTMP/repo4
228 searching for changes
252 searching for changes
229 no changes found
253 no changes found
230 adding remote bookmark bm3
254 adding remote bookmark bm3
231 1 local changesets published
255 1 local changesets published
232 $ hg boo
256 $ hg boo
233 bm1 3:b87954705719
257 bm1 3:b87954705719
234 * bm3 4:62f4ded848e4
258 * bm3 4:62f4ded848e4
235 bm4 5:92793bfc8cad
259 bm4 5:92793bfc8cad
236 $ cd ..
260 $ cd ..
237
261
238 verify bookmark behavior after unshare
262 verify bookmark behavior after unshare
239
263
240 $ cd repo3
264 $ cd repo3
241 $ hg unshare
265 $ hg unshare
242 $ hg boo
266 $ hg boo
243 bm1 3:b87954705719
267 bm1 3:b87954705719
244 * bm3 4:62f4ded848e4
268 * bm3 4:62f4ded848e4
245 bm4 5:92793bfc8cad
269 bm4 5:92793bfc8cad
246 $ hg boo -d bm4
270 $ hg boo -d bm4
247 $ hg boo bm5
271 $ hg boo bm5
248 $ hg boo
272 $ hg boo
249 bm1 3:b87954705719
273 bm1 3:b87954705719
250 bm3 4:62f4ded848e4
274 bm3 4:62f4ded848e4
251 * bm5 4:62f4ded848e4
275 * bm5 4:62f4ded848e4
252 $ cd ../repo1
276 $ cd ../repo1
253 $ hg boo
277 $ hg boo
254 * bm1 3:b87954705719
278 * bm1 3:b87954705719
255 bm3 4:62f4ded848e4
279 bm3 4:62f4ded848e4
256 bm4 5:92793bfc8cad
280 bm4 5:92793bfc8cad
257 $ cd ..
281 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now