Show More
@@ -0,0 +1,278 b'' | |||
|
1 | ||
|
2 | Set up repo | |
|
3 | ||
|
4 | $ hg --config experimental.treemanifest=True init repo | |
|
5 | $ cd repo | |
|
6 | ||
|
7 | Requirements get set on init | |
|
8 | ||
|
9 | $ grep treemanifest .hg/requires | |
|
10 | treemanifest | |
|
11 | ||
|
12 | Without directories, looks like any other repo | |
|
13 | ||
|
14 | $ echo 0 > a | |
|
15 | $ echo 0 > b | |
|
16 | $ hg ci -Aqm initial | |
|
17 | $ hg debugdata -m 0 | |
|
18 | a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc) | |
|
19 | b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc) | |
|
20 | ||
|
21 | Submanifest is stored in separate revlog | |
|
22 | ||
|
23 | $ mkdir dir1 | |
|
24 | $ echo 1 > dir1/a | |
|
25 | $ echo 1 > dir1/b | |
|
26 | $ echo 1 > e | |
|
27 | $ hg ci -Aqm 'add dir1' | |
|
28 | $ hg debugdata -m 1 | |
|
29 | a\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc) | |
|
30 | b\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe (esc) | |
|
31 | dir1\x008b3ffd73f901e83304c83d33132c8e774ceac44ed (esc) | |
|
32 | e\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) | |
|
33 | $ hg debugdata .hg/store/meta/dir1/00manifest.i 0 | |
|
34 | a\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) | |
|
35 | b\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) | |
|
36 | ||
|
37 | Can add nested directories | |
|
38 | ||
|
39 | $ mkdir dir1/dir1 | |
|
40 | $ echo 2 > dir1/dir1/a | |
|
41 | $ echo 2 > dir1/dir1/b | |
|
42 | $ mkdir dir1/dir2 | |
|
43 | $ echo 2 > dir1/dir2/a | |
|
44 | $ echo 2 > dir1/dir2/b | |
|
45 | $ hg ci -Aqm 'add dir1/dir1' | |
|
46 | $ hg files -r . | |
|
47 | a | |
|
48 | b | |
|
49 | dir1/a | |
|
50 | dir1/b | |
|
51 | dir1/dir1/a | |
|
52 | dir1/dir1/b | |
|
53 | dir1/dir2/a | |
|
54 | dir1/dir2/b | |
|
55 | e | |
|
56 | ||
|
57 | Revision is not created for unchanged directory | |
|
58 | ||
|
59 | $ mkdir dir2 | |
|
60 | $ echo 3 > dir2/a | |
|
61 | $ hg add dir2 | |
|
62 | adding dir2/a | |
|
63 | $ hg debugindex .hg/store/meta/dir1/00manifest.i > before | |
|
64 | $ hg ci -qm 'add dir2' | |
|
65 | $ hg debugindex .hg/store/meta/dir1/00manifest.i > after | |
|
66 | $ diff before after | |
|
67 | $ rm before after | |
|
68 | ||
|
69 | Removing directory does not create an revlog entry | |
|
70 | ||
|
71 | $ hg rm dir1/dir1 | |
|
72 | removing dir1/dir1/a | |
|
73 | removing dir1/dir1/b | |
|
74 | $ hg debugindex .hg/store/meta/dir1/dir1/00manifest.i > before | |
|
75 | $ hg ci -qm 'remove dir1/dir1' | |
|
76 | $ hg debugindex .hg/store/meta/dir1/dir1/00manifest.i > after | |
|
77 | $ diff before after | |
|
78 | $ rm before after | |
|
79 | ||
|
80 | Check that hg files (calls treemanifest.walk()) works | |
|
81 | ||
|
82 | $ hg co 'desc("add dir2")' | |
|
83 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
84 | $ hg files -r . dir1 | |
|
85 | dir1/a | |
|
86 | dir1/b | |
|
87 | dir1/dir1/a | |
|
88 | dir1/dir1/b | |
|
89 | dir1/dir2/a | |
|
90 | dir1/dir2/b | |
|
91 | ||
|
92 | Check that status between revisions works (calls treemanifest.matches()) | |
|
93 | ||
|
94 | $ hg status --rev 'desc("add dir1")' --rev . dir1 | |
|
95 | A dir1/dir1/a | |
|
96 | A dir1/dir1/b | |
|
97 | A dir1/dir2/a | |
|
98 | A dir1/dir2/b | |
|
99 | ||
|
100 | Merge creates 2-parent revision of directory revlog | |
|
101 | ||
|
102 | $ echo 5 > dir1/a | |
|
103 | $ hg ci -Aqm 'modify dir1/a' | |
|
104 | $ hg co '.^' | |
|
105 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
106 | $ echo 6 > dir1/b | |
|
107 | $ hg ci -Aqm 'modify dir1/b' | |
|
108 | $ hg merge 'desc("modify dir1/a")' | |
|
109 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
110 | (branch merge, don't forget to commit) | |
|
111 | $ hg ci -m 'conflict-free merge involving dir1/' | |
|
112 | $ cat dir1/a | |
|
113 | 5 | |
|
114 | $ cat dir1/b | |
|
115 | 6 | |
|
116 | $ hg debugindex .hg/store/meta/dir1/00manifest.i | |
|
117 | rev offset length base linkrev nodeid p1 p2 | |
|
118 | 0 0 54 0 1 8b3ffd73f901 000000000000 000000000000 | |
|
119 | 1 54 68 0 2 b66d046c644f 8b3ffd73f901 000000000000 | |
|
120 | 2 122 12 0 4 b87265673c8a b66d046c644f 000000000000 | |
|
121 | 3 134 95 0 5 aa5d3adcec72 b66d046c644f 000000000000 | |
|
122 | 4 229 81 0 6 e29b066b91ad b66d046c644f 000000000000 | |
|
123 | 5 310 107 5 7 a120ce2b83f5 e29b066b91ad aa5d3adcec72 | |
|
124 | ||
|
125 | Merge keeping directory from parent 1 does not create revlog entry. (Note that | |
|
126 | dir1's manifest does change, but only because dir1/a's filelog changes.) | |
|
127 | ||
|
128 | $ hg co 'desc("add dir2")' | |
|
129 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
130 | $ echo 8 > dir2/a | |
|
131 | $ hg ci -m 'modify dir2/a' | |
|
132 | created new head | |
|
133 | ||
|
134 | $ hg debugindex .hg/store/meta/dir2/00manifest.i > before | |
|
135 | $ hg merge 'desc("modify dir1/a")' | |
|
136 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
137 | (branch merge, don't forget to commit) | |
|
138 | $ hg revert -r 'desc("modify dir2/a")' . | |
|
139 | reverting dir1/a (glob) | |
|
140 | $ hg ci -m 'merge, keeping parent 1' | |
|
141 | $ hg debugindex .hg/store/meta/dir2/00manifest.i > after | |
|
142 | $ diff before after | |
|
143 | $ rm before after | |
|
144 | ||
|
145 | Merge keeping directory from parent 2 does not create revlog entry. (Note that | |
|
146 | dir2's manifest does change, but only because dir2/a's filelog changes.) | |
|
147 | ||
|
148 | $ hg co 'desc("modify dir2/a")' | |
|
149 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
150 | $ hg debugindex .hg/store/meta/dir1/00manifest.i > before | |
|
151 | $ hg merge 'desc("modify dir1/a")' | |
|
152 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
153 | (branch merge, don't forget to commit) | |
|
154 | $ hg revert -r 'desc("modify dir1/a")' . | |
|
155 | reverting dir2/a (glob) | |
|
156 | $ hg ci -m 'merge, keeping parent 2' | |
|
157 | created new head | |
|
158 | $ hg debugindex .hg/store/meta/dir1/00manifest.i > after | |
|
159 | $ diff before after | |
|
160 | $ rm before after | |
|
161 | ||
|
162 | Create flat source repo for tests with mixed flat/tree manifests | |
|
163 | ||
|
164 | $ cd .. | |
|
165 | $ hg init repo-flat | |
|
166 | $ cd repo-flat | |
|
167 | ||
|
168 | Create a few commits with flat manifest | |
|
169 | ||
|
170 | $ echo 0 > a | |
|
171 | $ echo 0 > b | |
|
172 | $ echo 0 > e | |
|
173 | $ for d in dir1 dir1/dir1 dir1/dir2 dir2 | |
|
174 | > do | |
|
175 | > mkdir $d | |
|
176 | > echo 0 > $d/a | |
|
177 | > echo 0 > $d/b | |
|
178 | > done | |
|
179 | $ hg ci -Aqm initial | |
|
180 | ||
|
181 | $ echo 1 > a | |
|
182 | $ echo 1 > dir1/a | |
|
183 | $ echo 1 > dir1/dir1/a | |
|
184 | $ hg ci -Aqm 'modify on branch 1' | |
|
185 | ||
|
186 | $ hg co 0 | |
|
187 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
188 | $ echo 2 > b | |
|
189 | $ echo 2 > dir1/b | |
|
190 | $ echo 2 > dir1/dir1/b | |
|
191 | $ hg ci -Aqm 'modify on branch 2' | |
|
192 | ||
|
193 | $ hg merge 1 | |
|
194 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
195 | (branch merge, don't forget to commit) | |
|
196 | $ hg ci -m 'merge of flat manifests to new flat manifest' | |
|
197 | ||
|
198 | Create clone with tree manifests enabled | |
|
199 | ||
|
200 | $ cd .. | |
|
201 | $ hg clone --pull --config experimental.treemanifest=1 repo-flat repo-mixed | |
|
202 | requesting all changes | |
|
203 | adding changesets | |
|
204 | adding manifests | |
|
205 | adding file changes | |
|
206 | added 4 changesets with 17 changes to 11 files | |
|
207 | updating to branch default | |
|
208 | 11 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
209 | $ cd repo-mixed | |
|
210 | $ test -f .hg/store/meta | |
|
211 | [1] | |
|
212 | $ grep treemanifest .hg/requires | |
|
213 | treemanifest | |
|
214 | ||
|
215 | Commit should store revlog per directory | |
|
216 | ||
|
217 | $ hg co 1 | |
|
218 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
219 | $ echo 3 > a | |
|
220 | $ echo 3 > dir1/a | |
|
221 | $ echo 3 > dir1/dir1/a | |
|
222 | $ hg ci -m 'first tree' | |
|
223 | created new head | |
|
224 | $ find .hg/store/meta | sort | |
|
225 | .hg/store/meta | |
|
226 | .hg/store/meta/dir1 | |
|
227 | .hg/store/meta/dir1/00manifest.i | |
|
228 | .hg/store/meta/dir1/dir1 | |
|
229 | .hg/store/meta/dir1/dir1/00manifest.i | |
|
230 | .hg/store/meta/dir1/dir2 | |
|
231 | .hg/store/meta/dir1/dir2/00manifest.i | |
|
232 | .hg/store/meta/dir2 | |
|
233 | .hg/store/meta/dir2/00manifest.i | |
|
234 | ||
|
235 | Merge of two trees | |
|
236 | ||
|
237 | $ hg co 2 | |
|
238 | 6 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
239 | $ hg merge 1 | |
|
240 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
241 | (branch merge, don't forget to commit) | |
|
242 | $ hg ci -m 'merge of flat manifests to new tree manifest' | |
|
243 | created new head | |
|
244 | $ hg diff -r 3 | |
|
245 | ||
|
246 | Parent of tree root manifest should be flat manifest, and two for merge | |
|
247 | ||
|
248 | $ hg debugindex -m | |
|
249 | rev offset length base linkrev nodeid p1 p2 | |
|
250 | 0 0 80 0 0 40536115ed9e 000000000000 000000000000 | |
|
251 | 1 80 83 0 1 f3376063c255 40536115ed9e 000000000000 | |
|
252 | 2 163 103 0 2 5d9b9da231a2 40536115ed9e 000000000000 | |
|
253 | 3 266 83 0 3 d17d663cbd8a 5d9b9da231a2 f3376063c255 | |
|
254 | 4 349 132 4 4 c05a51345f86 f3376063c255 000000000000 | |
|
255 | 5 481 110 4 5 82594b1f557d 5d9b9da231a2 f3376063c255 | |
|
256 | ||
|
257 | ||
|
258 | Status across flat/tree boundary should work | |
|
259 | ||
|
260 | $ hg status --rev '.^' --rev . | |
|
261 | M a | |
|
262 | M dir1/a | |
|
263 | M dir1/dir1/a | |
|
264 | ||
|
265 | ||
|
266 | Turning off treemanifest config has no effect | |
|
267 | ||
|
268 | $ hg debugindex .hg/store/meta/dir1/00manifest.i | |
|
269 | rev offset length base linkrev nodeid p1 p2 | |
|
270 | 0 0 125 0 4 63c9c0557d24 000000000000 000000000000 | |
|
271 | 1 125 109 0 5 23d12a1f6e0e 000000000000 000000000000 | |
|
272 | $ echo 2 > dir1/a | |
|
273 | $ hg --config experimental.treemanifest=False ci -qm 'modify dir1/a' | |
|
274 | $ hg debugindex .hg/store/meta/dir1/00manifest.i | |
|
275 | rev offset length base linkrev nodeid p1 p2 | |
|
276 | 0 0 125 0 4 63c9c0557d24 000000000000 000000000000 | |
|
277 | 1 125 109 0 5 23d12a1f6e0e 000000000000 000000000000 | |
|
278 | 2 234 55 0 6 3cb2d87b4250 23d12a1f6e0e 000000000000 |
@@ -444,11 +444,15 b' def _splittopdir(f):' | |||
|
444 | 444 | class treemanifest(object): |
|
445 | 445 | def __init__(self, dir='', text=''): |
|
446 | 446 | self._dir = dir |
|
447 | self._node = revlog.nullid | |
|
447 | 448 | self._dirs = {} |
|
448 | 449 | # Using _lazymanifest here is a little slower than plain old dicts |
|
449 | 450 | self._files = {} |
|
450 | 451 | self._flags = {} |
|
451 | self.parse(text) | |
|
452 | def readsubtree(subdir, subm): | |
|
453 | raise AssertionError('treemanifest constructor only accepts ' | |
|
454 | 'flat manifests') | |
|
455 | self.parse(text, readsubtree) | |
|
452 | 456 | |
|
453 | 457 | def _subpath(self, path): |
|
454 | 458 | return self._dir + path |
@@ -464,7 +468,22 b' class treemanifest(object):' | |||
|
464 | 468 | util.all(m._isempty() for m in self._dirs.values()))) |
|
465 | 469 | |
|
466 | 470 | def __str__(self): |
|
467 |
return '<treemanifest dir=%s>' % |
|
|
471 | return ('<treemanifest dir=%s, node=%s>' % | |
|
472 | (self._dir, revlog.hex(self._node))) | |
|
473 | ||
|
474 | def dir(self): | |
|
475 | '''The directory that this tree manifest represents, including a | |
|
476 | trailing '/'. Empty string for the repo root directory.''' | |
|
477 | return self._dir | |
|
478 | ||
|
479 | def node(self): | |
|
480 | '''This node of this instance. nullid for unsaved instances. Should | |
|
481 | be updated when the instance is read or written from a revlog. | |
|
482 | ''' | |
|
483 | return self._node | |
|
484 | ||
|
485 | def setnode(self, node): | |
|
486 | self._node = node | |
|
468 | 487 | |
|
469 | 488 | def iteritems(self): |
|
470 | 489 | for p, n in sorted(self._dirs.items() + self._files.items()): |
@@ -557,6 +576,7 b' class treemanifest(object):' | |||
|
557 | 576 | |
|
558 | 577 | def setflag(self, f, flags): |
|
559 | 578 | """Set the flags (symlink, executable) for path f.""" |
|
579 | assert 'd' not in flags | |
|
560 | 580 | dir, subpath = _splittopdir(f) |
|
561 | 581 | if dir: |
|
562 | 582 | if dir not in self._dirs: |
@@ -567,6 +587,7 b' class treemanifest(object):' | |||
|
567 | 587 | |
|
568 | 588 | def copy(self): |
|
569 | 589 | copy = treemanifest(self._dir) |
|
590 | copy._node = self._node | |
|
570 | 591 | for d in self._dirs: |
|
571 | 592 | copy._dirs[d] = self._dirs[d].copy() |
|
572 | 593 | copy._files = dict.copy(self._files) |
@@ -737,11 +758,18 b' class treemanifest(object):' | |||
|
737 | 758 | _diff(self, m2) |
|
738 | 759 | return result |
|
739 | 760 | |
|
740 | def parse(self, text): | |
|
761 | def parse(self, text, readsubtree): | |
|
741 | 762 | for f, n, fl in _parse(text): |
|
742 |
|
|
|
743 |
|
|
|
744 | self.setflag(f, fl) | |
|
763 | if fl == 'd': | |
|
764 | f = f + '/' | |
|
765 | self._dirs[f] = readsubtree(self._subpath(f), n) | |
|
766 | else: | |
|
767 | # Use __setitem__ and setflag rather than assigning directly | |
|
768 | # to _files and _flags, thereby letting us parse flat manifests | |
|
769 | # as well as tree manifests. | |
|
770 | self[f] = n | |
|
771 | if fl: | |
|
772 | self.setflag(f, fl) | |
|
745 | 773 | |
|
746 | 774 | def text(self, usemanifestv2=False): |
|
747 | 775 | """Get the full data of this manifest as a bytestring.""" |
@@ -749,8 +777,26 b' class treemanifest(object):' | |||
|
749 | 777 | return _text(((f, self[f], flags(f)) for f in self.keys()), |
|
750 | 778 | usemanifestv2) |
|
751 | 779 | |
|
780 | def dirtext(self, usemanifestv2=False): | |
|
781 | """Get the full data of this directory as a bytestring. Make sure that | |
|
782 | any submanifests have been written first, so their nodeids are correct. | |
|
783 | """ | |
|
784 | flags = self.flags | |
|
785 | dirs = [(d[:-1], self._dirs[d]._node, 'd') for d in self._dirs] | |
|
786 | files = [(f, self._files[f], flags(f)) for f in self._files] | |
|
787 | return _text(sorted(dirs + files), usemanifestv2) | |
|
788 | ||
|
789 | def writesubtrees(self, m1, m2, writesubtree): | |
|
790 | emptytree = treemanifest() | |
|
791 | for d, subm in self._dirs.iteritems(): | |
|
792 | subp1 = m1._dirs.get(d, emptytree)._node | |
|
793 | subp2 = m2._dirs.get(d, emptytree)._node | |
|
794 | if subp1 == revlog.nullid: | |
|
795 | subp1, subp2 = subp2, subp1 | |
|
796 | writesubtree(subm, subp1, subp2) | |
|
797 | ||
|
752 | 798 | class manifest(revlog.revlog): |
|
753 | def __init__(self, opener): | |
|
799 | def __init__(self, opener, dir=''): | |
|
754 | 800 | # During normal operations, we expect to deal with not more than four |
|
755 | 801 | # revs at a time (such as during commit --amend). When rebasing large |
|
756 | 802 | # stacks of commits, the number can go up, hence the config knob below. |
@@ -763,14 +809,19 b' class manifest(revlog.revlog):' | |||
|
763 | 809 | usetreemanifest = opts.get('treemanifest', usetreemanifest) |
|
764 | 810 | usemanifestv2 = opts.get('manifestv2', usemanifestv2) |
|
765 | 811 | self._mancache = util.lrucachedict(cachesize) |
|
766 | revlog.revlog.__init__(self, opener, "00manifest.i") | |
|
767 | 812 | self._treeinmem = usetreemanifest |
|
768 | 813 | self._treeondisk = usetreemanifest |
|
769 | 814 | self._usemanifestv2 = usemanifestv2 |
|
815 | indexfile = "00manifest.i" | |
|
816 | if dir: | |
|
817 | assert self._treeondisk | |
|
818 | indexfile = "meta/" + dir + "00manifest.i" | |
|
819 | revlog.revlog.__init__(self, opener, indexfile) | |
|
820 | self._dir = dir | |
|
770 | 821 | |
|
771 | 822 | def _newmanifest(self, data=''): |
|
772 | 823 | if self._treeinmem: |
|
773 |
return treemanifest( |
|
|
824 | return treemanifest(self._dir, data) | |
|
774 | 825 | return manifestdict(data) |
|
775 | 826 | |
|
776 | 827 | def _slowreaddelta(self, node): |
@@ -812,8 +863,17 b' class manifest(revlog.revlog):' | |||
|
812 | 863 | if node in self._mancache: |
|
813 | 864 | return self._mancache[node][0] |
|
814 | 865 | text = self.revision(node) |
|
815 | arraytext = array.array('c', text) | |
|
816 | m = self._newmanifest(text) | |
|
866 | if self._treeondisk: | |
|
867 | def readsubtree(dir, subm): | |
|
868 | sublog = manifest(self.opener, dir) | |
|
869 | return sublog.read(subm) | |
|
870 | m = self._newmanifest() | |
|
871 | m.parse(text, readsubtree) | |
|
872 | m.setnode(node) | |
|
873 | arraytext = None | |
|
874 | else: | |
|
875 | m = self._newmanifest(text) | |
|
876 | arraytext = array.array('c', text) | |
|
817 | 877 | self._mancache[node] = (m, arraytext) |
|
818 | 878 | return m |
|
819 | 879 | |
@@ -851,10 +911,34 b' class manifest(revlog.revlog):' | |||
|
851 | 911 | # just encode a fulltext of the manifest and pass that |
|
852 | 912 | # through to the revlog layer, and let it handle the delta |
|
853 | 913 | # process. |
|
854 | text = m.text(self._usemanifestv2) | |
|
855 | arraytext = array.array('c', text) | |
|
856 | n = self.addrevision(text, transaction, link, p1, p2) | |
|
914 | if self._treeondisk: | |
|
915 | m1 = self.read(p1) | |
|
916 | m2 = self.read(p2) | |
|
917 | n = self._addtree(m, transaction, link, m1, m2) | |
|
918 | arraytext = None | |
|
919 | else: | |
|
920 | text = m.text(self._usemanifestv2) | |
|
921 | n = self.addrevision(text, transaction, link, p1, p2) | |
|
922 | arraytext = array.array('c', text) | |
|
857 | 923 | |
|
858 | 924 | self._mancache[n] = (m, arraytext) |
|
859 | 925 | |
|
860 | 926 | return n |
|
927 | ||
|
928 | def _addtree(self, m, transaction, link, m1, m2): | |
|
929 | def writesubtree(subm, subp1, subp2): | |
|
930 | sublog = manifest(self.opener, subm.dir()) | |
|
931 | sublog.add(subm, transaction, link, subp1, subp2, None, None) | |
|
932 | m.writesubtrees(m1, m2, writesubtree) | |
|
933 | text = m.dirtext(self._usemanifestv2) | |
|
934 | # If the manifest is unchanged compared to one parent, | |
|
935 | # don't write a new revision | |
|
936 | if text == m1.dirtext(self._usemanifestv2): | |
|
937 | n = m1.node() | |
|
938 | elif text == m2.dirtext(self._usemanifestv2): | |
|
939 | n = m2.node() | |
|
940 | else: | |
|
941 | n = self.addrevision(text, transaction, link, m1.node(), m2.node()) | |
|
942 | # Save nodeid so parent manifest can calculate its nodeid | |
|
943 | m.setnode(n) | |
|
944 | return n |
@@ -187,7 +187,7 b' def _auxencode(path, dotencode):' | |||
|
187 | 187 | |
|
188 | 188 | def _hashencode(path, dotencode): |
|
189 | 189 | digest = _sha(path).hexdigest() |
|
190 | le = lowerencode(path[5:]).split('/') # skips prefix 'data/' | |
|
190 | le = lowerencode(path[5:]).split('/') # skips prefix 'data/' or 'meta/' | |
|
191 | 191 | parts = _auxencode(le, dotencode) |
|
192 | 192 | basename = parts[-1] |
|
193 | 193 | _root, ext = os.path.splitext(basename) |
General Comments 0
You need to be logged in to leave comments.
Login now