# HG changeset patch # User Matt Mackall # Date 1348779014 18000 # Node ID f36f11f2bfce0c5fb1581e0074eba2ef88f359e7 # Parent ae57920ac188e08ffb9eade8c00af491c4f61647# Parent e480df0911a2681254d4bd1be120c0226f6c45c6 merge with i18n diff -r e480df0911a2 -r f36f11f2bfce hgext/largefiles/lfutil.py --- a/hgext/largefiles/lfutil.py Tue Sep 25 16:01:08 2012 +0400 +++ b/hgext/largefiles/lfutil.py Thu Sep 27 15:50:14 2012 -0500 @@ -141,7 +141,7 @@ def normallookup(self, f): return super(largefilesdirstate, self).normallookup(unixpath(f)) -def openlfdirstate(ui, repo): +def openlfdirstate(ui, repo, create=True): ''' Return a dirstate object that tracks largefiles: i.e. its root is the repo root, but it is saved in .hg/largefiles/dirstate. @@ -154,7 +154,7 @@ # If the largefiles dirstate does not exist, populate and create # it. This ensures that we create it on the first meaningful # largefiles operation in a new clone. - if not os.path.exists(os.path.join(admin, 'dirstate')): + if create and not os.path.exists(os.path.join(admin, 'dirstate')): util.makedirs(admin) matcher = getstandinmatcher(repo) for standin in dirstatewalk(repo.dirstate, matcher): @@ -435,8 +435,11 @@ return util.pconvert(os.path.normpath(path)) def islfilesrepo(repo): - return ('largefiles' in repo.requirements and - util.any(shortname + '/' in f[0] for f in repo.store.datafiles())) + if ('largefiles' in repo.requirements and + util.any(shortname + '/' in f[0] for f in repo.store.datafiles())): + return True + + return util.any(openlfdirstate(repo.ui, repo, False)) class storeprotonotcapable(Exception): def __init__(self, storetypes): diff -r e480df0911a2 -r f36f11f2bfce hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Tue Sep 25 16:01:08 2012 +0400 +++ b/hgext/largefiles/overrides.py Thu Sep 27 15:50:14 2012 -0500 @@ -1018,11 +1018,12 @@ else: ui.status(_('largefiles: %d to upload\n') % len(toupload)) -def overrideaddremove(orig, ui, repo, *pats, **opts): +def scmutiladdremove(orig, repo, pats=[], opts={}, dry_run=None, + similarity=None): if not lfutil.islfilesrepo(repo): - return orig(ui, repo, *pats, **opts) + return orig(repo, pats, opts, dry_run, similarity) # Get the list of missing largefiles so we can remove them - lfdirstate = lfutil.openlfdirstate(ui, repo) + lfdirstate = lfutil.openlfdirstate(repo.ui, repo) s = lfdirstate.status(match_.always(repo.root, repo.getcwd()), [], False, False, False) (unsure, modified, added, removed, missing, unknown, ignored, clean) = s @@ -1034,16 +1035,16 @@ if missing: m = [repo.wjoin(f) for f in missing] repo._isaddremove = True - removelargefiles(ui, repo, *m, **opts) + removelargefiles(repo.ui, repo, *m, **opts) repo._isaddremove = False # Call into the normal add code, and any files that *should* be added as # largefiles will be - addlargefiles(ui, repo, *pats, **opts) + addlargefiles(repo.ui, repo, *pats, **opts) # Now that we've handled largefiles, hand off to the original addremove # function to take care of the rest. Make sure it doesn't do anything with # largefiles by installing a matcher that will ignore them. installnormalfilesmatchfn(repo[None].manifest()) - result = orig(ui, repo, *pats, **opts) + result = orig(repo, pats, opts, dry_run, similarity) restorematchfn() return result diff -r e480df0911a2 -r f36f11f2bfce hgext/largefiles/uisetup.py --- a/hgext/largefiles/uisetup.py Tue Sep 25 16:01:08 2012 +0400 +++ b/hgext/largefiles/uisetup.py Thu Sep 27 15:50:14 2012 -0500 @@ -9,7 +9,7 @@ '''setup for largefiles extension: uisetup''' from mercurial import archival, cmdutil, commands, extensions, filemerge, hg, \ - httppeer, localrepo, merge, sshpeer, sshserver, wireproto + httppeer, localrepo, merge, scmutil, sshpeer, sshserver, wireproto from mercurial.i18n import _ from mercurial.hgweb import hgweb_mod, protocol, webcommands from mercurial.subrepo import hgsubrepo @@ -30,8 +30,10 @@ '(default: 10)'))] entry[1].extend(addopt) - entry = extensions.wrapcommand(commands.table, 'addremove', - overrides.overrideaddremove) + # The scmutil function is called both by the (trivial) addremove command, + # and in the process of handling commit -A (issue3542) + entry = extensions.wrapfunction(scmutil, 'addremove', + overrides.scmutiladdremove) entry = extensions.wrapcommand(commands.table, 'remove', overrides.overrideremove) entry = extensions.wrapcommand(commands.table, 'forget', diff -r e480df0911a2 -r f36f11f2bfce mercurial/archival.py --- a/mercurial/archival.py Tue Sep 25 16:01:08 2012 +0400 +++ b/mercurial/archival.py Thu Sep 27 15:50:14 2012 -0500 @@ -12,6 +12,7 @@ import scmutil, util, encoding import cStringIO, os, tarfile, time, zipfile import zlib, gzip +import struct def tidyprefix(dest, kind, prefix): '''choose prefix to use for names in archive. make sure prefix is @@ -165,6 +166,7 @@ if mtime < epoch: mtime = epoch + self.mtime = mtime self.date_time = time.gmtime(mtime)[:6] def addfile(self, name, mode, islink, data): @@ -178,6 +180,14 @@ mode = 0777 ftype = 0xa000 # UNX_IFLNK in unzip source code i.external_attr = (mode | ftype) << 16L + # add "extended-timestamp" extra block, because zip archives + # without this will be extracted with unexpected timestamp, + # if TZ is not configured as GMT + i.extra += struct.pack(' repo/a + $ hg -R repo add repo/a + $ hg -R repo commit -m '#0' -d '456789012 21600' + $ cat > show_mtime.py < import sys, os + > print int(os.stat(sys.argv[1]).st_mtime) + > EOF + + $ hg -R repo archive --prefix tar-extracted archive.tar + $ (TZ=UTC-3; export TZ; tar xf archive.tar) + $ python show_mtime.py tar-extracted/a + 456789012 + + $ hg -R repo archive --prefix zip-extracted archive.zip + $ (TZ=UTC-3; export TZ; unzip -q archive.zip) + $ python show_mtime.py zip-extracted/a + 456789012 + + $ cd .. diff -r e480df0911a2 -r f36f11f2bfce tests/test-largefiles.t --- a/tests/test-largefiles.t Tue Sep 25 16:01:08 2012 +0400 +++ b/tests/test-largefiles.t Thu Sep 27 15:50:14 2012 -0500 @@ -543,6 +543,33 @@ C sub2/large6 C sub2/large7 +Test commit -A (issue 3542) + $ echo large8 > large8 + $ hg add --large large8 + $ hg ci -Am 'this used to add large8 as normal and commit both' + Invoking status precommit hook + A large8 + Invoking status postcommit hook + C large8 + C normal + C normal3 + C sub/large4 + C sub/normal4 + C sub2/large6 + C sub2/large7 + $ rm large8 + $ hg ci -Am 'this used to not notice the rm' + removing large8 + Invoking status precommit hook + R large8 + Invoking status postcommit hook + C normal + C normal3 + C sub/large4 + C sub/normal4 + C sub2/large6 + C sub2/large7 + Test that a standin can't be added as a large file $ touch large @@ -588,8 +615,19 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: removed large + changeset: 13:0a3e75774479 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: this used to add large8 as normal and commit both + + changeset: 14:84f3d378175c + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: this used to not notice the rm + searching for changes largefiles to upload: + large8 large foo @@ -1545,3 +1583,40 @@ lf_subrepo_archive/subrepo/normal.txt $ cd .. + +Test that addremove picks up largefiles prior to the initial commit (issue3541) + + $ hg init addrm2 + $ cd addrm2 + $ touch large.dat + $ touch large2.dat + $ touch normal + $ hg add --large large.dat + $ hg addremove -v + adding large2.dat as a largefile + adding normal + +Test that forgetting all largefiles reverts to islfilesrepo() == False +(addremove will add *.dat as normal files now) + $ hg forget large.dat + $ hg forget large2.dat + $ hg addremove -v + adding large.dat + adding large2.dat + +Test commit's addremove option prior to the first commit + $ hg forget large.dat + $ hg forget large2.dat + $ hg add --large large.dat + $ hg ci -Am "commit" + adding large2.dat as a largefile + Invoking status precommit hook + A large.dat + A large2.dat + A normal + $ find .hglf/ | sort + .hglf/ + .hglf/large.dat + .hglf/large2.dat + + $ cd ..