Show More
@@ -20,6 +20,8 b' from hgext import rebase' | |||||
20 | import lfutil |
|
20 | import lfutil | |
21 | import lfcommands |
|
21 | import lfcommands | |
22 |
|
22 | |||
|
23 | # -- Utility functions: commonly/repeatedly needed functionality --------------- | |||
|
24 | ||||
23 | def installnormalfilesmatchfn(manifest): |
|
25 | def installnormalfilesmatchfn(manifest): | |
24 | '''overrides scmutil.match so that the matcher it returns will ignore all |
|
26 | '''overrides scmutil.match so that the matcher it returns will ignore all | |
25 | largefiles''' |
|
27 | largefiles''' | |
@@ -51,13 +53,7 b' def restorematchfn():' | |||||
51 | restore matchfn to reverse''' |
|
53 | restore matchfn to reverse''' | |
52 | scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match) |
|
54 | scmutil.match = getattr(scmutil.match, 'oldmatch', scmutil.match) | |
53 |
|
55 | |||
54 | # -- Wrappers: modify existing commands -------------------------------- |
|
56 | def add_largefiles(ui, repo, *pats, **opts): | |
55 |
|
||||
56 | # Add works by going through the files that the user wanted to add and |
|
|||
57 | # checking if they should be added as largefiles. Then it makes a new |
|
|||
58 | # matcher which matches only the normal files and runs the original |
|
|||
59 | # version of add. |
|
|||
60 | def override_add(orig, ui, repo, *pats, **opts): |
|
|||
61 | large = opts.pop('large', None) |
|
57 | large = opts.pop('large', None) | |
62 | lfsize = lfutil.getminsize( |
|
58 | lfsize = lfutil.getminsize( | |
63 | ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None)) |
|
59 | ui, lfutil.islfilesrepo(repo), opts.pop('lfsize', None)) | |
@@ -117,19 +113,9 b' def override_add(orig, ui, repo, *pats, ' | |||||
117 | if f in m.files()] |
|
113 | if f in m.files()] | |
118 | finally: |
|
114 | finally: | |
119 | wlock.release() |
|
115 | wlock.release() | |
120 |
|
116 | return bad | ||
121 | installnormalfilesmatchfn(repo[None].manifest()) |
|
|||
122 | result = orig(ui, repo, *pats, **opts) |
|
|||
123 | restorematchfn() |
|
|||
124 |
|
||||
125 | return (result == 1 or bad) and 1 or 0 |
|
|||
126 |
|
117 | |||
127 |
def |
|
118 | def remove_largefiles(ui, repo, *pats, **opts): | |
128 | manifest = repo[None].manifest() |
|
|||
129 | installnormalfilesmatchfn(manifest) |
|
|||
130 | orig(ui, repo, *pats, **opts) |
|
|||
131 | restorematchfn() |
|
|||
132 |
|
||||
133 | after = opts.get('after') |
|
119 | after = opts.get('after') | |
134 | if not pats and not after: |
|
120 | if not pats and not after: | |
135 | raise util.Abort(_('no files specified')) |
|
121 | raise util.Abort(_('no files specified')) | |
@@ -139,6 +125,7 b' def override_remove(orig, ui, repo, *pat' | |||||
139 | s = repo.status(match=m, clean=True) |
|
125 | s = repo.status(match=m, clean=True) | |
140 | finally: |
|
126 | finally: | |
141 | repo.lfstatus = False |
|
127 | repo.lfstatus = False | |
|
128 | manifest = repo[None].manifest() | |||
142 | modified, added, deleted, clean = [[f for f in list |
|
129 | modified, added, deleted, clean = [[f for f in list | |
143 | if lfutil.standin(f) in manifest] |
|
130 | if lfutil.standin(f) in manifest] | |
144 | for list in [s[0], s[1], s[3], s[6]]] |
|
131 | for list in [s[0], s[1], s[3], s[6]]] | |
@@ -167,21 +154,48 b' def override_remove(orig, ui, repo, *pat' | |||||
167 | lfdirstate = lfutil.openlfdirstate(ui, repo) |
|
154 | lfdirstate = lfutil.openlfdirstate(ui, repo) | |
168 | for f in remove: |
|
155 | for f in remove: | |
169 | if not after: |
|
156 | if not after: | |
170 | os.unlink(repo.wjoin(f)) |
|
157 | # If this is being called by addremove, notify the user that we | |
|
158 | # are removing the file. | |||
|
159 | if getattr(repo, "_isaddremove", False): | |||
|
160 | ui.status(_('removing %s\n' % f)) | |||
|
161 | if os.path.exists(repo.wjoin(f)): | |||
|
162 | os.unlink(repo.wjoin(f)) | |||
171 | currentdir = os.path.split(f)[0] |
|
163 | currentdir = os.path.split(f)[0] | |
172 | while currentdir and not os.listdir(repo.wjoin(currentdir)): |
|
164 | while currentdir and not os.listdir(repo.wjoin(currentdir)): | |
173 | os.rmdir(repo.wjoin(currentdir)) |
|
165 | os.rmdir(repo.wjoin(currentdir)) | |
174 | currentdir = os.path.split(currentdir)[0] |
|
166 | currentdir = os.path.split(currentdir)[0] | |
175 | lfdirstate.remove(f) |
|
167 | lfdirstate.remove(f) | |
176 | lfdirstate.write() |
|
168 | lfdirstate.write() | |
177 |
|
||||
178 | forget = [lfutil.standin(f) for f in forget] |
|
169 | forget = [lfutil.standin(f) for f in forget] | |
179 | remove = [lfutil.standin(f) for f in remove] |
|
170 | remove = [lfutil.standin(f) for f in remove] | |
180 | lfutil.repo_forget(repo, forget) |
|
171 | lfutil.repo_forget(repo, forget) | |
181 | lfutil.repo_remove(repo, remove, unlink=True) |
|
172 | # If this is being called by addremove, let the original addremove | |
|
173 | # function handle this. | |||
|
174 | if not getattr(repo, "_isaddremove", False): | |||
|
175 | lfutil.repo_remove(repo, remove, unlink=True) | |||
182 | finally: |
|
176 | finally: | |
183 | wlock.release() |
|
177 | wlock.release() | |
184 |
|
178 | |||
|
179 | # -- Wrappers: modify existing commands -------------------------------- | |||
|
180 | ||||
|
181 | # Add works by going through the files that the user wanted to add and | |||
|
182 | # checking if they should be added as largefiles. Then it makes a new | |||
|
183 | # matcher which matches only the normal files and runs the original | |||
|
184 | # version of add. | |||
|
185 | def override_add(orig, ui, repo, *pats, **opts): | |||
|
186 | bad = add_largefiles(ui, repo, *pats, **opts) | |||
|
187 | installnormalfilesmatchfn(repo[None].manifest()) | |||
|
188 | result = orig(ui, repo, *pats, **opts) | |||
|
189 | restorematchfn() | |||
|
190 | ||||
|
191 | return (result == 1 or bad) and 1 or 0 | |||
|
192 | ||||
|
193 | def override_remove(orig, ui, repo, *pats, **opts): | |||
|
194 | installnormalfilesmatchfn(repo[None].manifest()) | |||
|
195 | orig(ui, repo, *pats, **opts) | |||
|
196 | restorematchfn() | |||
|
197 | remove_largefiles(ui, repo, *pats, **opts) | |||
|
198 | ||||
185 | def override_status(orig, ui, repo, *pats, **opts): |
|
199 | def override_status(orig, ui, repo, *pats, **opts): | |
186 | try: |
|
200 | try: | |
187 | repo.lfstatus = True |
|
201 | repo.lfstatus = True | |
@@ -851,26 +865,29 b' def override_summary(orig, ui, repo, *pa' | |||||
851 | ui.status(_('largefiles: %d to upload\n') % len(toupload)) |
|
865 | ui.status(_('largefiles: %d to upload\n') % len(toupload)) | |
852 |
|
866 | |||
853 | def override_addremove(orig, ui, repo, *pats, **opts): |
|
867 | def override_addremove(orig, ui, repo, *pats, **opts): | |
854 | # Check if the parent or child has largefiles; if so, disallow |
|
868 | # Get the list of missing largefiles so we can remove them | |
855 | # addremove. If there is a symlink in the manifest then getting |
|
869 | lfdirstate = lfutil.openlfdirstate(ui, repo) | |
856 | # the manifest throws an exception: catch it and let addremove |
|
870 | s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False, | |
857 | # deal with it. |
|
871 | False, False) | |
858 | try: |
|
872 | (unsure, modified, added, removed, missing, unknown, ignored, clean) = s | |
859 | manifesttip = set(repo['tip'].manifest()) |
|
|||
860 | except util.Abort: |
|
|||
861 | manifesttip = set() |
|
|||
862 | try: |
|
|||
863 | manifestworking = set(repo[None].manifest()) |
|
|||
864 | except util.Abort: |
|
|||
865 | manifestworking = set() |
|
|||
866 |
|
873 | |||
867 | # Manifests are only iterable so turn them into sets then union |
|
874 | # Call into the normal remove code, but the removing of the standin, we want | |
868 | for file in manifesttip.union(manifestworking): |
|
875 | # to have handled by original addremove. Monkey patching here makes sure | |
869 | if file.startswith(lfutil.shortname): |
|
876 | # we don't remove the standin in the largefiles code, preventing a very | |
870 | raise util.Abort( |
|
877 | # confused state later. | |
871 | _('addremove cannot be run on a repo with largefiles')) |
|
878 | repo._isaddremove = True | |
872 |
|
879 | remove_largefiles(ui, repo, *missing, **opts) | ||
873 | return orig(ui, repo, *pats, **opts) |
|
880 | repo._isaddremove = False | |
|
881 | # Call into the normal add code, and any files that *should* be added as | |||
|
882 | # largefiles will be | |||
|
883 | add_largefiles(ui, repo, *pats, **opts) | |||
|
884 | # Now that we've handled largefiles, hand off to the original addremove | |||
|
885 | # function to take care of the rest. Make sure it doesn't do anything with | |||
|
886 | # largefiles by installing a matcher that will ignore them. | |||
|
887 | installnormalfilesmatchfn(repo[None].manifest()) | |||
|
888 | result = orig(ui, repo, *pats, **opts) | |||
|
889 | restorematchfn() | |||
|
890 | return result | |||
874 |
|
891 | |||
875 | # Calling purge with --all will cause the largefiles to be deleted. |
|
892 | # Calling purge with --all will cause the largefiles to be deleted. | |
876 | # Override repo.status to prevent this from happening. |
|
893 | # Override repo.status to prevent this from happening. |
@@ -286,6 +286,20 b' dir after a purge.' | |||||
286 | $ cat sub2/large7 |
|
286 | $ cat sub2/large7 | |
287 | large7 |
|
287 | large7 | |
288 |
|
288 | |||
|
289 | Test addremove: verify that files that should be added as largfiles are added as | |||
|
290 | such and that already-existing largfiles are not added as normal files by | |||
|
291 | accident. | |||
|
292 | ||||
|
293 | $ rm normal3 | |||
|
294 | $ rm sub/large4 | |||
|
295 | $ echo "testing addremove with patterns" > testaddremove.dat | |||
|
296 | $ echo "normaladdremove" > normaladdremove | |||
|
297 | $ hg addremove | |||
|
298 | removing sub/large4 | |||
|
299 | adding testaddremove.dat as a largefile | |||
|
300 | removing normal3 | |||
|
301 | adding normaladdremove | |||
|
302 | ||||
289 | Clone a largefiles repo. |
|
303 | Clone a largefiles repo. | |
290 |
|
304 | |||
291 | $ hg clone . ../b |
|
305 | $ hg clone . ../b |
General Comments 0
You need to be logged in to leave comments.
Login now