merge with i18n stable
authorMatt Mackall <mpm@selenic.com>
Thu, 27 Sep 2012 15:50:14 -0500
branchstable
changeset 17660 f36f11f2bfce
parent 17659 ae57920ac188 (diff)
parent 17657 e480df0911a2 (current diff)
child 17661 67deea9c1c42
child 17678 07d577dae285
child 17684 e4ed5638bc55
merge with i18n
--- 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):
--- 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
 
--- 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',
--- 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('<hhBl',
+                               0x5455,     # block type: "extended-timestamp"
+                               1 + 4,      # size of this block
+                               1,          # "modification time is present"
+                               self.mtime) # time of last modification (UTC)
         self.z.writestr(i, data)
 
     def done(self):
--- a/tests/test-archive.t	Tue Sep 25 16:01:08 2012 +0400
+++ b/tests/test-archive.t	Thu Sep 27 15:50:14 2012 -0500
@@ -270,3 +270,31 @@
   \s*147\s+2 files (re)
 
   $ cd ..
+
+issue3600: check whether "hg archive" can create archive files which
+are extracted with expected timestamp, even though TZ is not
+configured as GMT.
+
+  $ mkdir issue3600
+  $ cd issue3600
+
+  $ hg init repo
+  $ echo a > repo/a
+  $ hg -R repo add repo/a
+  $ hg -R repo commit -m '#0' -d '456789012 21600'
+  $ cat > show_mtime.py <<EOF
+  > 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 ..
--- 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 ..