##// END OF EJS Templates
localrepo: store branchheads sorted
Mads Kiilerich -
r18357:a4ab37ca default
parent child Browse files
Show More
@@ -1,223 +1,223
1 # branchmap.py - logic to computes, maintain and stores branchmap for local repo
1 # branchmap.py - logic to computes, maintain and stores branchmap for local repo
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 node import bin, hex, nullid, nullrev
8 from node import bin, hex, nullid, nullrev
9 import encoding
9 import encoding
10 import util, repoview
10 import util, repoview
11
11
12 def _filename(repo):
12 def _filename(repo):
13 """name of a branchcache file for a given repo or repoview"""
13 """name of a branchcache file for a given repo or repoview"""
14 filename = "cache/branchheads"
14 filename = "cache/branchheads"
15 if repo.filtername:
15 if repo.filtername:
16 filename = '%s-%s' % (filename, repo.filtername)
16 filename = '%s-%s' % (filename, repo.filtername)
17 return filename
17 return filename
18
18
19 def read(repo):
19 def read(repo):
20 try:
20 try:
21 f = repo.opener(_filename(repo))
21 f = repo.opener(_filename(repo))
22 lines = f.read().split('\n')
22 lines = f.read().split('\n')
23 f.close()
23 f.close()
24 except (IOError, OSError):
24 except (IOError, OSError):
25 return None
25 return None
26
26
27 try:
27 try:
28 cachekey = lines.pop(0).split(" ", 2)
28 cachekey = lines.pop(0).split(" ", 2)
29 last, lrev = cachekey[:2]
29 last, lrev = cachekey[:2]
30 last, lrev = bin(last), int(lrev)
30 last, lrev = bin(last), int(lrev)
31 filteredhash = None
31 filteredhash = None
32 if len(cachekey) > 2:
32 if len(cachekey) > 2:
33 filteredhash = bin(cachekey[2])
33 filteredhash = bin(cachekey[2])
34 partial = branchcache(tipnode=last, tiprev=lrev,
34 partial = branchcache(tipnode=last, tiprev=lrev,
35 filteredhash=filteredhash)
35 filteredhash=filteredhash)
36 if not partial.validfor(repo):
36 if not partial.validfor(repo):
37 # invalidate the cache
37 # invalidate the cache
38 raise ValueError('tip differs')
38 raise ValueError('tip differs')
39 for l in lines:
39 for l in lines:
40 if not l:
40 if not l:
41 continue
41 continue
42 node, label = l.split(" ", 1)
42 node, label = l.split(" ", 1)
43 label = encoding.tolocal(label.strip())
43 label = encoding.tolocal(label.strip())
44 if not node in repo:
44 if not node in repo:
45 raise ValueError('node %s does not exist' % node)
45 raise ValueError('node %s does not exist' % node)
46 partial.setdefault(label, []).append(bin(node))
46 partial.setdefault(label, []).append(bin(node))
47 except KeyboardInterrupt:
47 except KeyboardInterrupt:
48 raise
48 raise
49 except Exception, inst:
49 except Exception, inst:
50 if repo.ui.debugflag:
50 if repo.ui.debugflag:
51 msg = 'invalid branchheads cache'
51 msg = 'invalid branchheads cache'
52 if repo.filtername is not None:
52 if repo.filtername is not None:
53 msg += ' (%s)' % repo.filtername
53 msg += ' (%s)' % repo.filtername
54 msg += ': %s\n'
54 msg += ': %s\n'
55 repo.ui.warn(msg % inst)
55 repo.ui.warn(msg % inst)
56 partial = None
56 partial = None
57 return partial
57 return partial
58
58
59
59
60
60
61 def updatecache(repo):
61 def updatecache(repo):
62 cl = repo.changelog
62 cl = repo.changelog
63 filtername = repo.filtername
63 filtername = repo.filtername
64 partial = repo._branchcaches.get(filtername)
64 partial = repo._branchcaches.get(filtername)
65
65
66 revs = []
66 revs = []
67 if partial is None or not partial.validfor(repo):
67 if partial is None or not partial.validfor(repo):
68 partial = read(repo)
68 partial = read(repo)
69 if partial is None:
69 if partial is None:
70 subsetname = repoview.subsettable.get(filtername)
70 subsetname = repoview.subsettable.get(filtername)
71 if subsetname is None:
71 if subsetname is None:
72 partial = branchcache()
72 partial = branchcache()
73 else:
73 else:
74 subset = repo.filtered(subsetname)
74 subset = repo.filtered(subsetname)
75 partial = subset.branchmap().copy()
75 partial = subset.branchmap().copy()
76 extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
76 extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
77 revs.extend(r for r in extrarevs if r <= partial.tiprev)
77 revs.extend(r for r in extrarevs if r <= partial.tiprev)
78 revs.extend(cl.revs(start=partial.tiprev + 1))
78 revs.extend(cl.revs(start=partial.tiprev + 1))
79 if revs:
79 if revs:
80 partial.update(repo, revs)
80 partial.update(repo, revs)
81 partial.write(repo)
81 partial.write(repo)
82 assert partial.validfor(repo)
82 assert partial.validfor(repo)
83 repo._branchcaches[repo.filtername] = partial
83 repo._branchcaches[repo.filtername] = partial
84
84
85 class branchcache(dict):
85 class branchcache(dict):
86 """A dict like object that hold branches heads cache"""
86 """A dict like object that hold branches heads cache"""
87
87
88 def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
88 def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
89 filteredhash=None):
89 filteredhash=None):
90 super(branchcache, self).__init__(entries)
90 super(branchcache, self).__init__(entries)
91 self.tipnode = tipnode
91 self.tipnode = tipnode
92 self.tiprev = tiprev
92 self.tiprev = tiprev
93 self.filteredhash = filteredhash
93 self.filteredhash = filteredhash
94
94
95 def _hashfiltered(self, repo):
95 def _hashfiltered(self, repo):
96 """build hash of revision filtered in the current cache
96 """build hash of revision filtered in the current cache
97
97
98 Tracking tipnode and tiprev is not enough to ensure validaty of the
98 Tracking tipnode and tiprev is not enough to ensure validaty of the
99 cache as they do not help to distinct cache that ignored various
99 cache as they do not help to distinct cache that ignored various
100 revision bellow tiprev.
100 revision bellow tiprev.
101
101
102 To detect such difference, we build a cache of all ignored revisions.
102 To detect such difference, we build a cache of all ignored revisions.
103 """
103 """
104 cl = repo.changelog
104 cl = repo.changelog
105 if not cl.filteredrevs:
105 if not cl.filteredrevs:
106 return None
106 return None
107 key = None
107 key = None
108 revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev)
108 revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev)
109 if revs:
109 if revs:
110 s = util.sha1()
110 s = util.sha1()
111 for rev in revs:
111 for rev in revs:
112 s.update('%s;' % rev)
112 s.update('%s;' % rev)
113 key = s.digest()
113 key = s.digest()
114 return key
114 return key
115
115
116 def validfor(self, repo):
116 def validfor(self, repo):
117 """Is the cache content valide regarding a repo
117 """Is the cache content valide regarding a repo
118
118
119 - False when cached tipnode are unknown or if we detect a strip.
119 - False when cached tipnode are unknown or if we detect a strip.
120 - True when cache is up to date or a subset of current repo."""
120 - True when cache is up to date or a subset of current repo."""
121 try:
121 try:
122 return ((self.tipnode == repo.changelog.node(self.tiprev))
122 return ((self.tipnode == repo.changelog.node(self.tiprev))
123 and (self.filteredhash == self._hashfiltered(repo)))
123 and (self.filteredhash == self._hashfiltered(repo)))
124 except IndexError:
124 except IndexError:
125 return False
125 return False
126
126
127 def copy(self):
127 def copy(self):
128 """return an deep copy of the branchcache object"""
128 """return an deep copy of the branchcache object"""
129 return branchcache(self, self.tipnode, self.tiprev, self.filteredhash)
129 return branchcache(self, self.tipnode, self.tiprev, self.filteredhash)
130
130
131 def write(self, repo):
131 def write(self, repo):
132 try:
132 try:
133 f = repo.opener(_filename(repo), "w", atomictemp=True)
133 f = repo.opener(_filename(repo), "w", atomictemp=True)
134 cachekey = [hex(self.tipnode), str(self.tiprev)]
134 cachekey = [hex(self.tipnode), str(self.tiprev)]
135 if self.filteredhash is not None:
135 if self.filteredhash is not None:
136 cachekey.append(hex(self.filteredhash))
136 cachekey.append(hex(self.filteredhash))
137 f.write(" ".join(cachekey) + '\n')
137 f.write(" ".join(cachekey) + '\n')
138 for label, nodes in self.iteritems():
138 for label, nodes in sorted(self.iteritems()):
139 for node in nodes:
139 for node in nodes:
140 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
140 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
141 f.close()
141 f.close()
142 except (IOError, OSError, util.Abort):
142 except (IOError, OSError, util.Abort):
143 # Abort may be raise by read only opener
143 # Abort may be raise by read only opener
144 pass
144 pass
145
145
146 def update(self, repo, revgen):
146 def update(self, repo, revgen):
147 """Given a branchhead cache, self, that may have extra nodes or be
147 """Given a branchhead cache, self, that may have extra nodes or be
148 missing heads, and a generator of nodes that are at least a superset of
148 missing heads, and a generator of nodes that are at least a superset of
149 heads missing, this function updates self to be correct.
149 heads missing, this function updates self to be correct.
150 """
150 """
151 cl = repo.changelog
151 cl = repo.changelog
152 # collect new branch entries
152 # collect new branch entries
153 newbranches = {}
153 newbranches = {}
154 getbranch = cl.branch
154 getbranch = cl.branch
155 for r in revgen:
155 for r in revgen:
156 newbranches.setdefault(getbranch(r), []).append(cl.node(r))
156 newbranches.setdefault(getbranch(r), []).append(cl.node(r))
157 # if older branchheads are reachable from new ones, they aren't
157 # if older branchheads are reachable from new ones, they aren't
158 # really branchheads. Note checking parents is insufficient:
158 # really branchheads. Note checking parents is insufficient:
159 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
159 # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
160 for branch, newnodes in newbranches.iteritems():
160 for branch, newnodes in newbranches.iteritems():
161 bheads = self.setdefault(branch, [])
161 bheads = self.setdefault(branch, [])
162 # Remove candidate heads that no longer are in the repo (e.g., as
162 # Remove candidate heads that no longer are in the repo (e.g., as
163 # the result of a strip that just happened). Avoid using 'node in
163 # the result of a strip that just happened). Avoid using 'node in
164 # self' here because that dives down into branchcache code somewhat
164 # self' here because that dives down into branchcache code somewhat
165 # recursively.
165 # recursively.
166 bheadrevs = [cl.rev(node) for node in bheads
166 bheadrevs = [cl.rev(node) for node in bheads
167 if cl.hasnode(node)]
167 if cl.hasnode(node)]
168 newheadrevs = [cl.rev(node) for node in newnodes
168 newheadrevs = [cl.rev(node) for node in newnodes
169 if cl.hasnode(node)]
169 if cl.hasnode(node)]
170 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs)
170 ctxisnew = bheadrevs and min(newheadrevs) > max(bheadrevs)
171 # Remove duplicates - nodes that are in newheadrevs and are already
171 # Remove duplicates - nodes that are in newheadrevs and are already
172 # in bheadrevs. This can happen if you strip a node whose parent
172 # in bheadrevs. This can happen if you strip a node whose parent
173 # was already a head (because they're on different branches).
173 # was already a head (because they're on different branches).
174 bheadrevs = sorted(set(bheadrevs).union(newheadrevs))
174 bheadrevs = sorted(set(bheadrevs).union(newheadrevs))
175
175
176 # Starting from tip means fewer passes over reachable. If we know
176 # Starting from tip means fewer passes over reachable. If we know
177 # the new candidates are not ancestors of existing heads, we don't
177 # the new candidates are not ancestors of existing heads, we don't
178 # have to examine ancestors of existing heads
178 # have to examine ancestors of existing heads
179 if ctxisnew:
179 if ctxisnew:
180 iterrevs = sorted(newheadrevs)
180 iterrevs = sorted(newheadrevs)
181 else:
181 else:
182 iterrevs = list(bheadrevs)
182 iterrevs = list(bheadrevs)
183
183
184 # This loop prunes out two kinds of heads - heads that are
184 # This loop prunes out two kinds of heads - heads that are
185 # superseded by a head in newheadrevs, and newheadrevs that are not
185 # superseded by a head in newheadrevs, and newheadrevs that are not
186 # heads because an existing head is their descendant.
186 # heads because an existing head is their descendant.
187 while iterrevs:
187 while iterrevs:
188 latest = iterrevs.pop()
188 latest = iterrevs.pop()
189 if latest not in bheadrevs:
189 if latest not in bheadrevs:
190 continue
190 continue
191 ancestors = set(cl.ancestors([latest],
191 ancestors = set(cl.ancestors([latest],
192 bheadrevs[0]))
192 bheadrevs[0]))
193 if ancestors:
193 if ancestors:
194 bheadrevs = [b for b in bheadrevs if b not in ancestors]
194 bheadrevs = [b for b in bheadrevs if b not in ancestors]
195 self[branch] = [cl.node(rev) for rev in bheadrevs]
195 self[branch] = [cl.node(rev) for rev in bheadrevs]
196 tiprev = max(bheadrevs)
196 tiprev = max(bheadrevs)
197 if tiprev > self.tiprev:
197 if tiprev > self.tiprev:
198 self.tipnode = cl.node(tiprev)
198 self.tipnode = cl.node(tiprev)
199 self.tiprev = tiprev
199 self.tiprev = tiprev
200
200
201 # There may be branches that cease to exist when the last commit in the
201 # There may be branches that cease to exist when the last commit in the
202 # branch was stripped. This code filters them out. Note that the
202 # branch was stripped. This code filters them out. Note that the
203 # branch that ceased to exist may not be in newbranches because
203 # branch that ceased to exist may not be in newbranches because
204 # newbranches is the set of candidate heads, which when you strip the
204 # newbranches is the set of candidate heads, which when you strip the
205 # last commit in a branch will be the parent branch.
205 # last commit in a branch will be the parent branch.
206 droppednodes = []
206 droppednodes = []
207 for branch in self.keys():
207 for branch in self.keys():
208 nodes = [head for head in self[branch]
208 nodes = [head for head in self[branch]
209 if cl.hasnode(head)]
209 if cl.hasnode(head)]
210 if not nodes:
210 if not nodes:
211 droppednodes.extend(nodes)
211 droppednodes.extend(nodes)
212 del self[branch]
212 del self[branch]
213 if ((not self.validfor(repo)) or (self.tipnode in droppednodes)):
213 if ((not self.validfor(repo)) or (self.tipnode in droppednodes)):
214
214
215 # cache key are not valid anymore
215 # cache key are not valid anymore
216 self.tipnode = nullid
216 self.tipnode = nullid
217 self.tiprev = nullrev
217 self.tiprev = nullrev
218 for heads in self.values():
218 for heads in self.values():
219 tiprev = max(cl.rev(node) for node in heads)
219 tiprev = max(cl.rev(node) for node in heads)
220 if tiprev > self.tiprev:
220 if tiprev > self.tiprev:
221 self.tipnode = cl.node(tiprev)
221 self.tipnode = cl.node(tiprev)
222 self.tiprev = tiprev
222 self.tiprev = tiprev
223 self.filteredhash = self._hashfiltered(repo)
223 self.filteredhash = self._hashfiltered(repo)
@@ -1,344 +1,344
1 $ branchcache=.hg/cache/branchheads
1 $ branchcache=.hg/cache/branchheads
2
2
3 $ listbranchcaches() {
3 $ listbranchcaches() {
4 > for f in .hg/cache/branchheads*;
4 > for f in .hg/cache/branchheads*;
5 > do echo === $f ===;
5 > do echo === $f ===;
6 > cat $f;
6 > cat $f;
7 > done;
7 > done;
8 > }
8 > }
9 $ purgebranchcaches() {
9 $ purgebranchcaches() {
10 > rm .hg/cache/branchheads*
10 > rm .hg/cache/branchheads*
11 > }
11 > }
12
12
13 $ hg init t
13 $ hg init t
14 $ cd t
14 $ cd t
15
15
16 $ hg branches
16 $ hg branches
17 $ echo foo > a
17 $ echo foo > a
18 $ hg add a
18 $ hg add a
19 $ hg ci -m "initial"
19 $ hg ci -m "initial"
20 $ hg branch foo
20 $ hg branch foo
21 marked working directory as branch foo
21 marked working directory as branch foo
22 (branches are permanent and global, did you want a bookmark?)
22 (branches are permanent and global, did you want a bookmark?)
23 $ hg branch
23 $ hg branch
24 foo
24 foo
25 $ hg ci -m "add branch name"
25 $ hg ci -m "add branch name"
26 $ hg branch bar
26 $ hg branch bar
27 marked working directory as branch bar
27 marked working directory as branch bar
28 (branches are permanent and global, did you want a bookmark?)
28 (branches are permanent and global, did you want a bookmark?)
29 $ hg ci -m "change branch name"
29 $ hg ci -m "change branch name"
30
30
31 Branch shadowing:
31 Branch shadowing:
32
32
33 $ hg branch default
33 $ hg branch default
34 abort: a branch of the same name already exists
34 abort: a branch of the same name already exists
35 (use 'hg update' to switch to it)
35 (use 'hg update' to switch to it)
36 [255]
36 [255]
37
37
38 $ hg branch -f default
38 $ hg branch -f default
39 marked working directory as branch default
39 marked working directory as branch default
40 (branches are permanent and global, did you want a bookmark?)
40 (branches are permanent and global, did you want a bookmark?)
41
41
42 $ hg ci -m "clear branch name"
42 $ hg ci -m "clear branch name"
43 created new head
43 created new head
44
44
45 There should be only one default branch head
45 There should be only one default branch head
46
46
47 $ hg heads .
47 $ hg heads .
48 changeset: 3:1c28f494dae6
48 changeset: 3:1c28f494dae6
49 tag: tip
49 tag: tip
50 user: test
50 user: test
51 date: Thu Jan 01 00:00:00 1970 +0000
51 date: Thu Jan 01 00:00:00 1970 +0000
52 summary: clear branch name
52 summary: clear branch name
53
53
54
54
55 $ hg co foo
55 $ hg co foo
56 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
56 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 $ hg branch
57 $ hg branch
58 foo
58 foo
59 $ echo bleah > a
59 $ echo bleah > a
60 $ hg ci -m "modify a branch"
60 $ hg ci -m "modify a branch"
61
61
62 $ hg merge default
62 $ hg merge default
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 (branch merge, don't forget to commit)
64 (branch merge, don't forget to commit)
65
65
66 $ hg branch
66 $ hg branch
67 foo
67 foo
68 $ hg ci -m "merge"
68 $ hg ci -m "merge"
69
69
70 $ hg log
70 $ hg log
71 changeset: 5:530046499edf
71 changeset: 5:530046499edf
72 branch: foo
72 branch: foo
73 tag: tip
73 tag: tip
74 parent: 4:adf1a74a7f7b
74 parent: 4:adf1a74a7f7b
75 parent: 3:1c28f494dae6
75 parent: 3:1c28f494dae6
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:00 1970 +0000
77 date: Thu Jan 01 00:00:00 1970 +0000
78 summary: merge
78 summary: merge
79
79
80 changeset: 4:adf1a74a7f7b
80 changeset: 4:adf1a74a7f7b
81 branch: foo
81 branch: foo
82 parent: 1:6c0e42da283a
82 parent: 1:6c0e42da283a
83 user: test
83 user: test
84 date: Thu Jan 01 00:00:00 1970 +0000
84 date: Thu Jan 01 00:00:00 1970 +0000
85 summary: modify a branch
85 summary: modify a branch
86
86
87 changeset: 3:1c28f494dae6
87 changeset: 3:1c28f494dae6
88 user: test
88 user: test
89 date: Thu Jan 01 00:00:00 1970 +0000
89 date: Thu Jan 01 00:00:00 1970 +0000
90 summary: clear branch name
90 summary: clear branch name
91
91
92 changeset: 2:c21617b13b22
92 changeset: 2:c21617b13b22
93 branch: bar
93 branch: bar
94 user: test
94 user: test
95 date: Thu Jan 01 00:00:00 1970 +0000
95 date: Thu Jan 01 00:00:00 1970 +0000
96 summary: change branch name
96 summary: change branch name
97
97
98 changeset: 1:6c0e42da283a
98 changeset: 1:6c0e42da283a
99 branch: foo
99 branch: foo
100 user: test
100 user: test
101 date: Thu Jan 01 00:00:00 1970 +0000
101 date: Thu Jan 01 00:00:00 1970 +0000
102 summary: add branch name
102 summary: add branch name
103
103
104 changeset: 0:db01e8ea3388
104 changeset: 0:db01e8ea3388
105 user: test
105 user: test
106 date: Thu Jan 01 00:00:00 1970 +0000
106 date: Thu Jan 01 00:00:00 1970 +0000
107 summary: initial
107 summary: initial
108
108
109 $ hg branches
109 $ hg branches
110 foo 5:530046499edf
110 foo 5:530046499edf
111 default 3:1c28f494dae6 (inactive)
111 default 3:1c28f494dae6 (inactive)
112 bar 2:c21617b13b22 (inactive)
112 bar 2:c21617b13b22 (inactive)
113
113
114 $ hg branches -q
114 $ hg branches -q
115 foo
115 foo
116 default
116 default
117 bar
117 bar
118
118
119 Test for invalid branch cache:
119 Test for invalid branch cache:
120
120
121 $ hg rollback
121 $ hg rollback
122 repository tip rolled back to revision 4 (undo commit)
122 repository tip rolled back to revision 4 (undo commit)
123 working directory now based on revisions 4 and 3
123 working directory now based on revisions 4 and 3
124
124
125 $ cp ${branchcache}-unserved .hg/bc-invalid
125 $ cp ${branchcache}-unserved .hg/bc-invalid
126
126
127 $ hg log -r foo
127 $ hg log -r foo
128 changeset: 4:adf1a74a7f7b
128 changeset: 4:adf1a74a7f7b
129 branch: foo
129 branch: foo
130 tag: tip
130 tag: tip
131 parent: 1:6c0e42da283a
131 parent: 1:6c0e42da283a
132 user: test
132 user: test
133 date: Thu Jan 01 00:00:00 1970 +0000
133 date: Thu Jan 01 00:00:00 1970 +0000
134 summary: modify a branch
134 summary: modify a branch
135
135
136 $ cp .hg/bc-invalid $branchcache
136 $ cp .hg/bc-invalid $branchcache
137
137
138 $ hg --debug log -r foo
138 $ hg --debug log -r foo
139 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
139 changeset: 4:adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6
140 branch: foo
140 branch: foo
141 tag: tip
141 tag: tip
142 phase: draft
142 phase: draft
143 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
143 parent: 1:6c0e42da283a56b5edc5b4fadb491365ec7f5fa8
144 parent: -1:0000000000000000000000000000000000000000
144 parent: -1:0000000000000000000000000000000000000000
145 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
145 manifest: 1:8c342a37dfba0b3d3ce073562a00d8a813c54ffe
146 user: test
146 user: test
147 date: Thu Jan 01 00:00:00 1970 +0000
147 date: Thu Jan 01 00:00:00 1970 +0000
148 files: a
148 files: a
149 extra: branch=foo
149 extra: branch=foo
150 description:
150 description:
151 modify a branch
151 modify a branch
152
152
153
153
154 $ purgebranchcaches
154 $ purgebranchcaches
155 $ echo corrupted > $branchcache
155 $ echo corrupted > $branchcache
156
156
157 $ hg log -qr foo
157 $ hg log -qr foo
158 4:adf1a74a7f7b
158 4:adf1a74a7f7b
159
159
160 $ listbranchcaches
160 $ listbranchcaches
161 === .hg/cache/branchheads ===
161 === .hg/cache/branchheads ===
162 corrupted
162 corrupted
163 === .hg/cache/branchheads-unserved ===
163 === .hg/cache/branchheads-unserved ===
164 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
164 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
165 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
165 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
166 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
166 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
167 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
167 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
168
168
169 Push should update the branch cache:
169 Push should update the branch cache:
170
170
171 $ hg init ../target
171 $ hg init ../target
172
172
173 Pushing just rev 0:
173 Pushing just rev 0:
174
174
175 $ hg push -qr 0 ../target
175 $ hg push -qr 0 ../target
176
176
177 $ (cd ../target/; listbranchcaches)
177 $ (cd ../target/; listbranchcaches)
178 === .hg/cache/branchheads-impactable ===
178 === .hg/cache/branchheads-impactable ===
179 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
179 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
180 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
180 db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
181
181
182 Pushing everything:
182 Pushing everything:
183
183
184 $ hg push -qf ../target
184 $ hg push -qf ../target
185
185
186 $ (cd ../target/; listbranchcaches)
186 $ (cd ../target/; listbranchcaches)
187 === .hg/cache/branchheads-impactable ===
187 === .hg/cache/branchheads-impactable ===
188 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
188 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
189 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
189 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
190 1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
190 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
191 adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
191 c21617b13b220988e7a2e26290fbe4325ffa7139 bar
192
192
193 Update with no arguments: tipmost revision of the current branch:
193 Update with no arguments: tipmost revision of the current branch:
194
194
195 $ hg up -q -C 0
195 $ hg up -q -C 0
196 $ hg up -q
196 $ hg up -q
197 $ hg id
197 $ hg id
198 1c28f494dae6
198 1c28f494dae6
199
199
200 $ hg up -q 1
200 $ hg up -q 1
201 $ hg up -q
201 $ hg up -q
202 $ hg id
202 $ hg id
203 adf1a74a7f7b (foo) tip
203 adf1a74a7f7b (foo) tip
204
204
205 $ hg branch foobar
205 $ hg branch foobar
206 marked working directory as branch foobar
206 marked working directory as branch foobar
207 (branches are permanent and global, did you want a bookmark?)
207 (branches are permanent and global, did you want a bookmark?)
208
208
209 $ hg up
209 $ hg up
210 abort: branch foobar not found
210 abort: branch foobar not found
211 [255]
211 [255]
212
212
213 Fastforward merge:
213 Fastforward merge:
214
214
215 $ hg branch ff
215 $ hg branch ff
216 marked working directory as branch ff
216 marked working directory as branch ff
217 (branches are permanent and global, did you want a bookmark?)
217 (branches are permanent and global, did you want a bookmark?)
218
218
219 $ echo ff > ff
219 $ echo ff > ff
220 $ hg ci -Am'fast forward'
220 $ hg ci -Am'fast forward'
221 adding ff
221 adding ff
222
222
223 $ hg up foo
223 $ hg up foo
224 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
224 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
225
225
226 $ hg merge ff
226 $ hg merge ff
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
228 (branch merge, don't forget to commit)
228 (branch merge, don't forget to commit)
229
229
230 $ hg branch
230 $ hg branch
231 foo
231 foo
232 $ hg commit -m'Merge ff into foo'
232 $ hg commit -m'Merge ff into foo'
233 $ hg parents
233 $ hg parents
234 changeset: 6:185ffbfefa30
234 changeset: 6:185ffbfefa30
235 branch: foo
235 branch: foo
236 tag: tip
236 tag: tip
237 parent: 4:adf1a74a7f7b
237 parent: 4:adf1a74a7f7b
238 parent: 5:1a3c27dc5e11
238 parent: 5:1a3c27dc5e11
239 user: test
239 user: test
240 date: Thu Jan 01 00:00:00 1970 +0000
240 date: Thu Jan 01 00:00:00 1970 +0000
241 summary: Merge ff into foo
241 summary: Merge ff into foo
242
242
243 $ hg manifest
243 $ hg manifest
244 a
244 a
245 ff
245 ff
246
246
247
247
248 Test merging, add 3 default heads and one test head:
248 Test merging, add 3 default heads and one test head:
249
249
250 $ cd ..
250 $ cd ..
251 $ hg init merges
251 $ hg init merges
252 $ cd merges
252 $ cd merges
253 $ echo a > a
253 $ echo a > a
254 $ hg ci -Ama
254 $ hg ci -Ama
255 adding a
255 adding a
256
256
257 $ echo b > b
257 $ echo b > b
258 $ hg ci -Amb
258 $ hg ci -Amb
259 adding b
259 adding b
260
260
261 $ hg up 0
261 $ hg up 0
262 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
262 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
263 $ echo c > c
263 $ echo c > c
264 $ hg ci -Amc
264 $ hg ci -Amc
265 adding c
265 adding c
266 created new head
266 created new head
267
267
268 $ hg up 0
268 $ hg up 0
269 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
269 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
270 $ echo d > d
270 $ echo d > d
271 $ hg ci -Amd
271 $ hg ci -Amd
272 adding d
272 adding d
273 created new head
273 created new head
274
274
275 $ hg up 0
275 $ hg up 0
276 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
276 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
277 $ hg branch test
277 $ hg branch test
278 marked working directory as branch test
278 marked working directory as branch test
279 (branches are permanent and global, did you want a bookmark?)
279 (branches are permanent and global, did you want a bookmark?)
280 $ echo e >> e
280 $ echo e >> e
281 $ hg ci -Ame
281 $ hg ci -Ame
282 adding e
282 adding e
283
283
284 $ hg log
284 $ hg log
285 changeset: 4:3a1e01ed1df4
285 changeset: 4:3a1e01ed1df4
286 branch: test
286 branch: test
287 tag: tip
287 tag: tip
288 parent: 0:cb9a9f314b8b
288 parent: 0:cb9a9f314b8b
289 user: test
289 user: test
290 date: Thu Jan 01 00:00:00 1970 +0000
290 date: Thu Jan 01 00:00:00 1970 +0000
291 summary: e
291 summary: e
292
292
293 changeset: 3:980f7dc84c29
293 changeset: 3:980f7dc84c29
294 parent: 0:cb9a9f314b8b
294 parent: 0:cb9a9f314b8b
295 user: test
295 user: test
296 date: Thu Jan 01 00:00:00 1970 +0000
296 date: Thu Jan 01 00:00:00 1970 +0000
297 summary: d
297 summary: d
298
298
299 changeset: 2:d36c0562f908
299 changeset: 2:d36c0562f908
300 parent: 0:cb9a9f314b8b
300 parent: 0:cb9a9f314b8b
301 user: test
301 user: test
302 date: Thu Jan 01 00:00:00 1970 +0000
302 date: Thu Jan 01 00:00:00 1970 +0000
303 summary: c
303 summary: c
304
304
305 changeset: 1:d2ae7f538514
305 changeset: 1:d2ae7f538514
306 user: test
306 user: test
307 date: Thu Jan 01 00:00:00 1970 +0000
307 date: Thu Jan 01 00:00:00 1970 +0000
308 summary: b
308 summary: b
309
309
310 changeset: 0:cb9a9f314b8b
310 changeset: 0:cb9a9f314b8b
311 user: test
311 user: test
312 date: Thu Jan 01 00:00:00 1970 +0000
312 date: Thu Jan 01 00:00:00 1970 +0000
313 summary: a
313 summary: a
314
314
315 Implicit merge with test branch as parent:
315 Implicit merge with test branch as parent:
316
316
317 $ hg merge
317 $ hg merge
318 abort: branch 'test' has one head - please merge with an explicit rev
318 abort: branch 'test' has one head - please merge with an explicit rev
319 (run 'hg heads' to see all heads)
319 (run 'hg heads' to see all heads)
320 [255]
320 [255]
321 $ hg up -C default
321 $ hg up -C default
322 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
322 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
323
323
324 Implicit merge with default branch as parent:
324 Implicit merge with default branch as parent:
325
325
326 $ hg merge
326 $ hg merge
327 abort: branch 'default' has 3 heads - please merge with an explicit rev
327 abort: branch 'default' has 3 heads - please merge with an explicit rev
328 (run 'hg heads .' to see heads)
328 (run 'hg heads .' to see heads)
329 [255]
329 [255]
330
330
331 3 branch heads, explicit merge required:
331 3 branch heads, explicit merge required:
332
332
333 $ hg merge 2
333 $ hg merge 2
334 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
335 (branch merge, don't forget to commit)
335 (branch merge, don't forget to commit)
336 $ hg ci -m merge
336 $ hg ci -m merge
337
337
338 2 branch heads, implicit merge works:
338 2 branch heads, implicit merge works:
339
339
340 $ hg merge
340 $ hg merge
341 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
341 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 (branch merge, don't forget to commit)
342 (branch merge, don't forget to commit)
343
343
344 $ cd ..
344 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now