mercurial/subrepo.py
changeset 21585 652e07debf10
parent 21401 2c364f7801c8
parent 21568 8dd17b19e722
child 21885 fe9db58b0b2d
equal deleted inserted replaced
21580:32601b0b74c0 21585:652e07debf10
   275 def reporelpath(repo):
   275 def reporelpath(repo):
   276     """return path to this (sub)repo as seen from outermost repo"""
   276     """return path to this (sub)repo as seen from outermost repo"""
   277     parent = repo
   277     parent = repo
   278     while util.safehasattr(parent, '_subparent'):
   278     while util.safehasattr(parent, '_subparent'):
   279         parent = parent._subparent
   279         parent = parent._subparent
   280     p = parent.root.rstrip(os.sep)
   280     return repo.root[len(pathutil.normasprefix(parent.root)):]
   281     return repo.root[len(p) + 1:]
       
   282 
   281 
   283 def subrelpath(sub):
   282 def subrelpath(sub):
   284     """return path to this subrepo as seen from outermost repo"""
   283     """return path to this subrepo as seen from outermost repo"""
   285     if util.safehasattr(sub, '_relpath'):
   284     if util.safehasattr(sub, '_relpath'):
   286         return sub._relpath
   285         return sub._relpath
   313             # chop off the .hg component to get the default path form
   312             # chop off the .hg component to get the default path form
   314             return os.path.dirname(repo.sharedpath)
   313             return os.path.dirname(repo.sharedpath)
   315     if abort:
   314     if abort:
   316         raise util.Abort(_("default path for subrepository not found"))
   315         raise util.Abort(_("default path for subrepository not found"))
   317 
   316 
   318 def _sanitize(ui, path):
   317 def _sanitize(ui, path, ignore):
   319     def v(arg, dirname, names):
   318     for dirname, dirs, names in os.walk(path):
       
   319         for i, d in enumerate(dirs):
       
   320             if d.lower() == ignore:
       
   321                 del dirs[i]
       
   322                 break
   320         if os.path.basename(dirname).lower() != '.hg':
   323         if os.path.basename(dirname).lower() != '.hg':
   321             return
   324             continue
   322         for f in names:
   325         for f in names:
   323             if f.lower() == 'hgrc':
   326             if f.lower() == 'hgrc':
   324                 ui.warn(
   327                 ui.warn(_("warning: removing potentially hostile 'hgrc' "
   325                     _("warning: removing potentially hostile .hg/hgrc in '%s'")
   328                           "in '%s'\n") % dirname)
   326                       % path)
       
   327                 os.unlink(os.path.join(dirname, f))
   329                 os.unlink(os.path.join(dirname, f))
   328     os.walk(path, v, None)
       
   329 
   330 
   330 def subrepo(ctx, path):
   331 def subrepo(ctx, path):
   331     """return instance of the right subrepo class for subrepo in path"""
   332     """return instance of the right subrepo class for subrepo in path"""
   332     # subrepo inherently violates our import layering rules
   333     # subrepo inherently violates our import layering rules
   333     # because it wants to make repo objects from deep inside the stack
   334     # because it wants to make repo objects from deep inside the stack
  1057             args.append('--force')
  1058             args.append('--force')
  1058         # The revision must be specified at the end of the URL to properly
  1059         # The revision must be specified at the end of the URL to properly
  1059         # update to a directory which has since been deleted and recreated.
  1060         # update to a directory which has since been deleted and recreated.
  1060         args.append('%s@%s' % (state[0], state[1]))
  1061         args.append('%s@%s' % (state[0], state[1]))
  1061         status, err = self._svncommand(args, failok=True)
  1062         status, err = self._svncommand(args, failok=True)
  1062         _sanitize(self._ui, self._path)
  1063         _sanitize(self._ui, self._ctx._repo.wjoin(self._path), '.svn')
  1063         if not re.search('Checked out revision [0-9]+.', status):
  1064         if not re.search('Checked out revision [0-9]+.', status):
  1064             if ('is already a working copy for a different URL' in err
  1065             if ('is already a working copy for a different URL' in err
  1065                 and (self._wcchanged()[:2] == (False, False))):
  1066                 and (self._wcchanged()[:2] == (False, False))):
  1066                 # obstructed but clean working copy, so just blow it away.
  1067                 # obstructed but clean working copy, so just blow it away.
  1067                 self.remove()
  1068                 self.remove()
  1350                 # the -f option will otherwise throw away files added for
  1351                 # the -f option will otherwise throw away files added for
  1351                 # commit, not just unmark them.
  1352                 # commit, not just unmark them.
  1352                 self._gitcommand(['reset', 'HEAD'])
  1353                 self._gitcommand(['reset', 'HEAD'])
  1353                 cmd.append('-f')
  1354                 cmd.append('-f')
  1354             self._gitcommand(cmd + args)
  1355             self._gitcommand(cmd + args)
  1355             _sanitize(self._ui, self._path)
  1356             _sanitize(self._ui, self._abspath, '.git')
  1356 
  1357 
  1357         def rawcheckout():
  1358         def rawcheckout():
  1358             # no branch to checkout, check it out with no branch
  1359             # no branch to checkout, check it out with no branch
  1359             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
  1360             self._ui.warn(_('checking out detached HEAD in subrepo %s\n') %
  1360                           self._relpath)
  1361                           self._relpath)
  1399             # Since we are only looking at branching at update, we need to
  1400             # Since we are only looking at branching at update, we need to
  1400             # detect this situation and perform this action lazily.
  1401             # detect this situation and perform this action lazily.
  1401             if tracking[remote] != self._gitcurrentbranch():
  1402             if tracking[remote] != self._gitcurrentbranch():
  1402                 checkout([tracking[remote]])
  1403                 checkout([tracking[remote]])
  1403             self._gitcommand(['merge', '--ff', remote])
  1404             self._gitcommand(['merge', '--ff', remote])
       
  1405             _sanitize(self._ui, self._abspath, '.git')
  1404         else:
  1406         else:
  1405             # a real merge would be required, just checkout the revision
  1407             # a real merge would be required, just checkout the revision
  1406             rawcheckout()
  1408             rawcheckout()
  1407 
  1409 
  1408     @annotatesubrepoerror
  1410     @annotatesubrepoerror
  1434         def mergefunc():
  1436         def mergefunc():
  1435             if base == revision:
  1437             if base == revision:
  1436                 self.get(state) # fast forward merge
  1438                 self.get(state) # fast forward merge
  1437             elif base != self._state[1]:
  1439             elif base != self._state[1]:
  1438                 self._gitcommand(['merge', '--no-commit', revision])
  1440                 self._gitcommand(['merge', '--no-commit', revision])
  1439             _sanitize(self._ui, self._path)
  1441             _sanitize(self._ui, self._abspath, '.git')
  1440 
  1442 
  1441         if self.dirty():
  1443         if self.dirty():
  1442             if self._gitstate() != revision:
  1444             if self._gitstate() != revision:
  1443                 dirty = self._gitstate() == self._state[1] or code != 0
  1445                 dirty = self._gitstate() == self._state[1] or code != 0
  1444                 if _updateprompt(self._ui, self, dirty,
  1446                 if _updateprompt(self._ui, self, dirty,