mercurial/hg.py
changeset 4915 97b734fb9c6f
parent 4853 bf10a03a6b24
child 4917 126f527b3ba3
equal deleted inserted replaced
4914:9a2a73ea6135 4915:97b734fb9c6f
   128             self.dir_ = None
   128             self.dir_ = None
   129         def __del__(self):
   129         def __del__(self):
   130             if self.dir_:
   130             if self.dir_:
   131                 self.rmtree(self.dir_, True)
   131                 self.rmtree(self.dir_, True)
   132 
   132 
   133     dir_cleanup = None
   133     src_lock = dest_lock = dir_cleanup = None
   134     if islocal(dest):
   134     try:
   135         dir_cleanup = DirCleanup(dest)
   135         if islocal(dest):
   136 
   136             dir_cleanup = DirCleanup(dest)
   137     abspath = origsource
   137 
   138     copy = False
   138         abspath = origsource
   139     if src_repo.local() and islocal(dest):
   139         copy = False
   140         abspath = os.path.abspath(origsource)
   140         if src_repo.local() and islocal(dest):
   141         copy = not pull and not rev
   141             abspath = os.path.abspath(origsource)
   142 
   142             copy = not pull and not rev
   143     src_lock, dest_lock = None, None
   143 
   144     if copy:
   144         if copy:
   145         try:
       
   146             # we use a lock here because if we race with commit, we
       
   147             # can end up with extra data in the cloned revlogs that's
       
   148             # not pointed to by changesets, thus causing verify to
       
   149             # fail
       
   150             src_lock = src_repo.lock()
       
   151         except lock.LockException:
       
   152             copy = False
       
   153 
       
   154     if copy:
       
   155         def force_copy(src, dst):
       
   156             try:
   145             try:
   157                 util.copyfiles(src, dst)
   146                 # we use a lock here because if we race with commit, we
   158             except OSError, inst:
   147                 # can end up with extra data in the cloned revlogs that's
   159                 if inst.errno != errno.ENOENT:
   148                 # not pointed to by changesets, thus causing verify to
   160                     raise
   149                 # fail
   161 
   150                 src_lock = src_repo.lock()
   162         src_store = os.path.realpath(src_repo.spath)
   151             except lock.LockException:
   163         if not os.path.exists(dest):
   152                 copy = False
   164             os.mkdir(dest)
   153 
   165         dest_path = os.path.realpath(os.path.join(dest, ".hg"))
   154         if copy:
   166         os.mkdir(dest_path)
   155             def force_copy(src, dst):
   167         if src_repo.spath != src_repo.path:
   156                 try:
   168             dest_store = os.path.join(dest_path, "store")
   157                     util.copyfiles(src, dst)
   169             os.mkdir(dest_store)
   158                 except OSError, inst:
       
   159                     if inst.errno != errno.ENOENT:
       
   160                         raise
       
   161 
       
   162             src_store = os.path.realpath(src_repo.spath)
       
   163             if not os.path.exists(dest):
       
   164                 os.mkdir(dest)
       
   165             dest_path = os.path.realpath(os.path.join(dest, ".hg"))
       
   166             os.mkdir(dest_path)
       
   167             if src_repo.spath != src_repo.path:
       
   168                 dest_store = os.path.join(dest_path, "store")
       
   169                 os.mkdir(dest_store)
       
   170             else:
       
   171                 dest_store = dest_path
       
   172             # copy the requires file
       
   173             force_copy(src_repo.join("requires"),
       
   174                        os.path.join(dest_path, "requires"))
       
   175             # we lock here to avoid premature writing to the target
       
   176             dest_lock = lock.lock(os.path.join(dest_store, "lock"))
       
   177 
       
   178             files = ("data",
       
   179                      "00manifest.d", "00manifest.i",
       
   180                      "00changelog.d", "00changelog.i")
       
   181             for f in files:
       
   182                 src = os.path.join(src_store, f)
       
   183                 dst = os.path.join(dest_store, f)
       
   184                 force_copy(src, dst)
       
   185 
       
   186             # we need to re-init the repo after manually copying the data
       
   187             # into it
       
   188             dest_repo = repository(ui, dest)
       
   189 
   170         else:
   190         else:
   171             dest_store = dest_path
   191             dest_repo = repository(ui, dest, create=True)
   172         # copy the requires file
   192 
   173         force_copy(src_repo.join("requires"),
   193             revs = None
   174                    os.path.join(dest_path, "requires"))
   194             if rev:
   175         # we lock here to avoid premature writing to the target
   195                 if 'lookup' not in src_repo.capabilities:
   176         dest_lock = lock.lock(os.path.join(dest_store, "lock"))
   196                     raise util.Abort(_("src repository does not support revision "
   177 
   197                                        "lookup and so doesn't support clone by "
   178         files = ("data",
   198                                        "revision"))
   179                  "00manifest.d", "00manifest.i",
   199                 revs = [src_repo.lookup(r) for r in rev]
   180                  "00changelog.d", "00changelog.i")
   200 
   181         for f in files:
   201             if dest_repo.local():
   182             src = os.path.join(src_store, f)
   202                 dest_repo.clone(src_repo, heads=revs, stream=stream)
   183             dst = os.path.join(dest_store, f)
   203             elif src_repo.local():
   184             force_copy(src, dst)
   204                 src_repo.push(dest_repo, revs=revs)
   185 
   205             else:
   186         # we need to re-init the repo after manually copying the data
   206                 raise util.Abort(_("clone from remote to remote not supported"))
   187         # into it
       
   188         dest_repo = repository(ui, dest)
       
   189 
       
   190     else:
       
   191         dest_repo = repository(ui, dest, create=True)
       
   192 
       
   193         revs = None
       
   194         if rev:
       
   195             if 'lookup' not in src_repo.capabilities:
       
   196                 raise util.Abort(_("src repository does not support revision "
       
   197                                    "lookup and so doesn't support clone by "
       
   198                                    "revision"))
       
   199             revs = [src_repo.lookup(r) for r in rev]
       
   200 
   207 
   201         if dest_repo.local():
   208         if dest_repo.local():
   202             dest_repo.clone(src_repo, heads=revs, stream=stream)
   209             fp = dest_repo.opener("hgrc", "w", text=True)
   203         elif src_repo.local():
   210             fp.write("[paths]\n")
   204             src_repo.push(dest_repo, revs=revs)
   211             fp.write("default = %s\n" % abspath)
   205         else:
   212             fp.close()
   206             raise util.Abort(_("clone from remote to remote not supported"))
   213 
   207 
   214             if update:
   208     if src_lock:
   215                 try:
   209         src_lock.release()
   216                     checkout = dest_repo.lookup("default")
   210 
   217                 except:
   211     if dest_repo.local():
   218                     checkout = dest_repo.changelog.tip()
   212         fp = dest_repo.opener("hgrc", "w", text=True)
   219                 _update(dest_repo, checkout)
   213         fp.write("[paths]\n")
   220         if dir_cleanup:
   214         fp.write("default = %s\n" % abspath)
   221             dir_cleanup.close()
   215         fp.close()
   222 
   216 
   223         return src_repo, dest_repo
   217         if dest_lock:
   224     finally:
   218             dest_lock.release()
   225         del src_lock, dest_lock, dir_cleanup
   219 
       
   220         if update:
       
   221             try:
       
   222                 checkout = dest_repo.lookup("default")
       
   223             except:
       
   224                 checkout = dest_repo.changelog.tip()
       
   225             _update(dest_repo, checkout)
       
   226     if dir_cleanup:
       
   227         dir_cleanup.close()
       
   228 
       
   229     return src_repo, dest_repo
       
   230 
   226 
   231 def _showstats(repo, stats):
   227 def _showstats(repo, stats):
   232     stats = ((stats[0], _("updated")),
   228     stats = ((stats[0], _("updated")),
   233              (stats[1], _("merged")),
   229              (stats[1], _("merged")),
   234              (stats[2], _("removed")),
   230              (stats[2], _("removed")),