| 1 | # -*- mode: python; coding: utf-8 -*- |
|---|
| 2 | # :Progetto: vcpx -- Mercurial native backend |
|---|
| 3 | # :Creato: dom 11 set 2005 22:58:38 CEST |
|---|
| 4 | # :Autore: Lele Gaifax <lele@nautilus.homeip.net> |
|---|
| 5 | # :Licenza: GNU General Public License |
|---|
| 6 | # |
|---|
| 7 | |
|---|
| 8 | """ |
|---|
| 9 | This module implements the backends for Mercurial, using its native API |
|---|
| 10 | instead of thru the command line. |
|---|
| 11 | """ |
|---|
| 12 | |
|---|
| 13 | __docformat__ = 'reStructuredText' |
|---|
| 14 | |
|---|
| 15 | from target import SyncronizableTargetWorkingDir, TargetInitializationFailure |
|---|
| 16 | from mercurial import ui, hg, commands |
|---|
| 17 | |
|---|
| 18 | class HglibWorkingDir(SyncronizableTargetWorkingDir): |
|---|
| 19 | def _addPathnames(self, names): |
|---|
| 20 | from os.path import join, isdir |
|---|
| 21 | |
|---|
| 22 | notdirs = [n for n in names if not isdir(join(self.basedir, n))] |
|---|
| 23 | if notdirs: |
|---|
| 24 | self._hg.add(notdirs) |
|---|
| 25 | |
|---|
| 26 | def _commit(self, date, author, patchname, changelog=None, names=None): |
|---|
| 27 | from time import mktime |
|---|
| 28 | |
|---|
| 29 | encoding = self.repository.encoding |
|---|
| 30 | |
|---|
| 31 | logmessage = [] |
|---|
| 32 | if patchname: |
|---|
| 33 | logmessage.append(patchname.encode(encoding)) |
|---|
| 34 | if changelog: |
|---|
| 35 | logmessage.append(changelog.encode(encoding)) |
|---|
| 36 | self._hg.commit(names and [n.encode(encoding) for n in names] or [], |
|---|
| 37 | '\n'.join(logmessage), |
|---|
| 38 | author.encode(encoding), |
|---|
| 39 | "%d 0" % mktime(date.timetuple())) |
|---|
| 40 | |
|---|
| 41 | def _removePathnames(self, names): |
|---|
| 42 | """Remove a sequence of entries""" |
|---|
| 43 | |
|---|
| 44 | from os.path import join, isdir |
|---|
| 45 | |
|---|
| 46 | notdirs = [n for n in names if not isdir(join(self.basedir, n))] |
|---|
| 47 | if notdirs: |
|---|
| 48 | self._hg.remove(notdirs) |
|---|
| 49 | |
|---|
| 50 | def _renamePathname(self, oldname, newname): |
|---|
| 51 | """Rename an entry""" |
|---|
| 52 | |
|---|
| 53 | from os.path import join, isdir |
|---|
| 54 | from os import walk |
|---|
| 55 | from dualwd import IGNORED_METADIRS |
|---|
| 56 | |
|---|
| 57 | if isdir(join(self.basedir, newname)): |
|---|
| 58 | # Given lack of support for directories in current HG, |
|---|
| 59 | # loop over all files under the new directory and |
|---|
| 60 | # do a copy on them. |
|---|
| 61 | skip = len(self.basedir)+len(newname)+2 |
|---|
| 62 | for dir, subdirs, files in walk(join(self.basedir, newname)): |
|---|
| 63 | prefix = dir[skip:] |
|---|
| 64 | |
|---|
| 65 | for excd in IGNORED_METADIRS: |
|---|
| 66 | if excd in subdirs: |
|---|
| 67 | subdirs.remove(excd) |
|---|
| 68 | |
|---|
| 69 | for f in files: |
|---|
| 70 | self._hg.copy(join(oldname, prefix, f), |
|---|
| 71 | join(newname, prefix, f)) |
|---|
| 72 | self._hg.remove([join(oldname, prefix, f)]) |
|---|
| 73 | else: |
|---|
| 74 | self._hg.copy(oldname, newname) |
|---|
| 75 | self._hg.remove(oldname) |
|---|
| 76 | |
|---|
| 77 | def _prepareTargetRepository(self): |
|---|
| 78 | """ |
|---|
| 79 | Create the base directory if it doesn't exist, and the |
|---|
| 80 | repository as well in the new working directory. |
|---|
| 81 | """ |
|---|
| 82 | |
|---|
| 83 | from os.path import join, exists |
|---|
| 84 | |
|---|
| 85 | project = self.repository.project |
|---|
| 86 | self._ui = ui.ui(project.verbose, |
|---|
| 87 | project.config.get(self.repository.name, |
|---|
| 88 | 'debug', False), |
|---|
| 89 | project.verbose, False) |
|---|
| 90 | |
|---|
| 91 | if exists(join(self.basedir, self.repository.METADIR)): |
|---|
| 92 | create = 0 |
|---|
| 93 | else: |
|---|
| 94 | create = 1 |
|---|
| 95 | self._hg = hg.repository(ui=self._ui, path=self.basedir, create=create) |
|---|
| 96 | |
|---|
| 97 | def _prepareWorkingDirectory(self, source_repo): |
|---|
| 98 | """ |
|---|
| 99 | Create the .hgignore. |
|---|
| 100 | """ |
|---|
| 101 | |
|---|
| 102 | from os.path import join |
|---|
| 103 | from re import escape |
|---|
| 104 | from dualwd import IGNORED_METADIRS |
|---|
| 105 | |
|---|
| 106 | # Create the .hgignore file, that contains a regexp per line |
|---|
| 107 | # with all known VCs metadirs to be skipped. |
|---|
| 108 | ignore = open(join(self.basedir, '.hgignore'), 'w') |
|---|
| 109 | ignore.write('\n'.join(['(^|/)%s($|/)' % escape(md) |
|---|
| 110 | for md in IGNORED_METADIRS])) |
|---|
| 111 | ignore.write('\n') |
|---|
| 112 | if self.logfile.startswith(self.basedir): |
|---|
| 113 | ignore.write('^') |
|---|
| 114 | ignore.write(self.logfile[len(self.basedir)+1:]) |
|---|
| 115 | ignore.write('$\n') |
|---|
| 116 | if self.state_file.filename.startswith(self.basedir): |
|---|
| 117 | sfrelname = self.state_file.filename[len(self.basedir)+1:] |
|---|
| 118 | ignore.write('^') |
|---|
| 119 | ignore.write(sfrelname) |
|---|
| 120 | ignore.write('$\n') |
|---|
| 121 | ignore.write('^') |
|---|
| 122 | ignore.write(sfrelname+'.journal') |
|---|
| 123 | ignore.write('$\n') |
|---|
| 124 | ignore.close() |
|---|
| 125 | |
|---|
| 126 | def _initializeWorkingDir(self): |
|---|
| 127 | commands.add(self._ui, self._hg, self.basedir) |
|---|