예제 #1
0
 def get_branch(self):
     headpath = self.repository._repo.refs.refpath('HEAD')
     try:
         content = open(headpath).read()
         match = re.match(r'^ref: refs/heads/(?P<branch>.+)\n$', content)
         if match:
             return match.groupdict()['branch']
         else:
             raise RepositoryError("Couldn't compute workdir's branch")
     except IOError:
         # Try naive way...
         raise RepositoryError("Couldn't compute workdir's branch")
예제 #2
0
파일: changeset.py 프로젝트: mqshen/MyGit
    def __init__(self, repository, revision):
        self._stat_modes = {}
        self.repository = repository

        try:
            commit = self.repository._repo.get_object(revision)
            if isinstance(commit, objects.Tag):
                revision = commit.object[1]
                commit = self.repository._repo.get_object(commit.object[1])
        except KeyError:
            raise RepositoryError("Cannot get object with id %s" % revision)
        self.raw_id = revision
        self.id = self.raw_id
        self.short_id = self.raw_id[:12]
        self._commit = commit

        self._tree_id = commit.tree
        self._committer_property = 'committer'
        self._author_property = 'author'
        self._date_property = 'commit_time'
        self._date_tz_property = 'commit_timezone'
        self.revision = repository.revisions.index(revision)

        self.message = commit.message.decode("utf-8")

        self.nodes = {}
        self._paths = {}
예제 #3
0
 def get_tree_for_dir(tree, dirname):
     for name, mode, id in tree.iteritems():
         if name == dirname:
             obj = self.repository._repo[id]
             if isinstance(obj, objects.Tree):
                 return obj
             else:
                 raise RepositoryError(
                     "Cannot create directory %s "
                     "at tree %s as path is occupied and is not a "
                     "Tree" % (dirname, tree))
     return None
예제 #4
0
파일: repository.py 프로젝트: mqshen/MyGit
    def _run_git_command(cls, cmd, **opts):
        """
        Runs given ``cmd`` as git command and returns tuple
        (stdout, stderr).

        :param cmd: git command to be executed
        :param opts: env options to pass into Subprocess command
        """

        if '_bare' in opts:
            _copts = []
            del opts['_bare']
        else:
            _copts = ['-c', 'core.quotepath=false', ]
        safe_call = False
        if '_safe' in opts:
            #no exc on failure
            del opts['_safe']
            safe_call = True

        _str_cmd = False
        if isinstance(cmd, str):
            cmd = [cmd]
            _str_cmd = True

        gitenv = os.environ
        # need to clean fix GIT_DIR !
        if 'GIT_DIR' in gitenv:
            del gitenv['GIT_DIR']
        gitenv['GIT_CONFIG_NOGLOBAL'] = '1'

        _git_path = options.git_path
        cmd = [_git_path] + _copts + cmd
        if _str_cmd:
            cmd = ' '.join(cmd)
        try:
            _opts = dict(
                env=gitenv,
                shell=False,
            )
            _opts.update(opts)
            p = subprocessio.SubprocessIOChunker(cmd, **_opts)
        except (EnvironmentError, OSError) as err:
            tb_err = ("Couldn't run git command (%s).\n"
                      "Original error was:%s\n" % (cmd, err))
            log.error(tb_err)
            if safe_call:
                return '', err
            else:
                raise RepositoryError(tb_err)

        return (b''.join(p.output)).decode('utf-8'), (b''.join(p.error)).decode('utf-8')
예제 #5
0
파일: repository.py 프로젝트: mqshen/MyGit
 def _get_repo(self, create, src_url=None, update_after_clone=False,
               bare=False):
     if create and os.path.exists(self.path):
         raise RepositoryError("Location already exist")
     if src_url and not create:
         raise RepositoryError("Create should be set to True if src_url is "
                               "given (clone operation creates repository)")
     try:
         if create and src_url:
             GitRepository._check_url(src_url)
             self.clone(src_url, update_after_clone, bare)
             return Repo(self.path)
         elif create:
             os.mkdir(self.path)
             if bare:
                 return Repo.init_bare(self.path)
             else:
                 return Repo.init(self.path)
         else:
             return self._repo
     except (NotGitRepository, OSError) as err:
         raise RepositoryError(err)
예제 #6
0
파일: repository.py 프로젝트: mqshen/MyGit
    def remove_tag(self, name, user, message=None, date=None):
        """
        Removes tag with the given ``name``.

        :param name: name of the tag to be removed
        :param user: full username, i.e.: "Joe Doe <*****@*****.**>"
        :param message: message of the tag's removal commit
        :param date: date of tag's removal commit

        :raises TagDoesNotExistError: if tag with given name does not exists
        """
        if name not in self.tags:
            raise TagDoesNotExistError("Tag %s does not exist" % name)
        tagpath = posixpath.join(self._repo.refs.path, 'refs', 'tags', name)
        try:
            os.remove(tagpath)
            self._parsed_refs = self._get_parsed_refs()
            self.tags = self._get_tags()
        except OSError as e:
            raise RepositoryError(e.strerror)
예제 #7
0
파일: repository.py 프로젝트: mqshen/MyGit
    def get_changesets(self, start=None, end=None, start_date=None,
           end_date=None, branch_name=None, reverse=False):
        """
        Returns iterator of ``GitChangeset`` objects from start to end (both
        are inclusive), in ascending date order (unless ``reverse`` is set).

        :param start: changeset ID, as str; first returned changeset
        :param end: changeset ID, as str; last returned changeset
        :param start_date: if specified, changesets with commit date less than
          ``start_date`` would be filtered out from returned set
        :param end_date: if specified, changesets with commit date greater than
          ``end_date`` would be filtered out from returned set
        :param branch_name: if specified, changesets not reachable from given
          branch would be filtered out from returned set
        :param reverse: if ``True``, returned generator would be reversed
          (meaning that returned changesets would have descending date order)

        :raise BranchDoesNotExistError: If given ``branch_name`` does not
            exist.
        :raise ChangesetDoesNotExistError: If changeset for given ``start`` or
          ``end`` could not be found.

        """
        if branch_name and branch_name not in self.branches:
            raise BranchDoesNotExistError("Branch '%s' not found" \
                                          % branch_name)
        # %H at format means (full) commit hash, initial hashes are retrieved
        # in ascending date order
        cmd_template = 'log --date-order --reverse --pretty=format:"%H"'
        cmd_params = {}
        if start_date:
            cmd_template += ' --since "$since"'
            cmd_params['since'] = start_date.strftime('%m/%d/%y %H:%M:%S')
        if end_date:
            cmd_template += ' --until "$until"'
            cmd_params['until'] = end_date.strftime('%m/%d/%y %H:%M:%S')
        if branch_name:
            cmd_template += ' $branch_name'
            cmd_params['branch_name'] = branch_name
        else:
            rev_filter = _git_path = options.git_rev_filter.strip()
            cmd_template += ' %s' % (rev_filter)

        cmd = Template(cmd_template).safe_substitute(**cmd_params)
        revs = self.run_git_command(cmd)[0].splitlines()
        start_pos = 0
        end_pos = len(revs)
        if start:
            _start = self._get_revision(start)
            try:
                start_pos = revs.index(_start)
            except ValueError:
                pass

        if end is not None:
            _end = self._get_revision(end)
            try:
                end_pos = revs.index(_end)
            except ValueError:
                pass

        if None not in [start, end] and start_pos > end_pos:
            raise RepositoryError('start cannot be after end')

        if end_pos is not None:
            end_pos += 1

        revs = revs[start_pos:end_pos]
        if reverse:
            revs = reversed(revs)
        for rev in revs:
            yield self.get_changeset(rev)