Example #1
0
def commit(options, debug, info):
    path = getcwd()
    git = Git(path)

    debug(git.commit('-m', message(options['m'], 'commit')))

    info('Committed with message "{message}".'.format(message=options['m']))
Example #2
0
    def gitPush(self, path, comment=None):
            # Announce changes to git
            cmd = Git(path)
            changed = False
            for line in cmd.status("--porcelain").splitlines():
                changed = True
                line = line.lstrip()
                self.log.info("staging changes for %s" % line.split(" ", 1)[1:])

                mode, file_path = line.split(" ", 1)
                file_path = os.path.join(*file_path.split("/")[0:])

                # Remove data?
                if mode == "D":
                    cmd.rm("-r", file_path)

                # Add data...
                else:
                    cmd.add(file_path)

            # No need to deal...
            if not changed:
                return False

            # Commit changes
            if not comment:
                comment = "Change made with no comment"

            self.log.info("committing changes for module %s" % path)
            cmd.commit("-m", comment)
            cmd.push("origin")

            return True
Example #3
0
    def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs):
        """Initialize a git repository at the given path if specified

        :param path:
            is the full path to the repo (traditionally ends with /<name>.git)
            or None in which case the repository will be created in the current
            working directory

        :parm mkdir:
            if specified will create the repository directory if it doesn't
            already exists. Creates the directory with a mode=0755.
            Only effective if a path is explicitly given

        :param odbt:
            Object DataBase type - a type which is constructed by providing
            the directory containing the database objects, i.e. .git/objects.
            It will be used to access all object data

        :parm kwargs:
            keyword arguments serving as additional options to the git-init command

        :return: ``git.Repo`` (the newly created repo)"""
        if path:
            path = _expand_path(path)
        if mkdir and path and not os.path.exists(path):
            os.makedirs(path, 0o755)

        # git command automatically chdir into the directory
        git = Git(path)
        git.init(**kwargs)
        return cls(path, odbt=odbt)
Example #4
0
def get_days_since_last_update(path):
    """
    :return: The days since the last update of any of the files in path. If the
             path points to a filename, the last update of that filename is
             returned.
    """
    git = Git(".")
    cmd_str = "git log -1 --format=%%cd %s" % path
    cmd = shlex.split(cmd_str)

    try:
        date_str = git.execute(command=cmd, with_extended_output=False)
    except GitCommandError:
        raise ValueError('"%s" is not in tracked by this repository.' % path)

    # The date_str is in the following format: Sat Jun 21 10:20:31 2014 -0300
    # We need to parse it, and then do some date math to return the result
    #
    # We ignore the UTC offset because it was "hard to parse" and we don't care
    last_commit_time = datetime.strptime(date_str[:-6], "%a %b %d %H:%M:%S %Y")
    last_commit_date = last_commit_time.date()

    today_date = date.today()

    time_delta = today_date - last_commit_date

    return time_delta.days
Example #5
0
	def init(cls, path=None, mkdir=True, **kwargs):
		"""Initialize a git repository at the given path if specified

		:param path:
			is the full path to the repo (traditionally ends with /<name>.git)
			or None in which case the repository will be created in the current 
			working directory

		:parm mkdir:
			if specified will create the repository directory if it doesn't
			already exists. Creates the directory with a mode=0755. 
			Only effective if a path is explicitly given

		:parm kwargs:
			keyword arguments serving as additional options to the git-init command

		:return: ``git.Repo`` (the newly created repo)"""

		if mkdir and path and not os.path.exists(path):
			os.makedirs(path, 0755)

		# git command automatically chdir into the directory
		git = Git(path)
		output = git.init(**kwargs)
		return Repo(path)
Example #6
0
    def fork(self, new_body):
        git_path = mkdtemp(prefix=settings.GIT_ROOT_PATH)
        git = Git(git_path)
        git.clone(os.path.abspath(self.git_path), git_path)

        new_fork = Fork.objects.create(body=new_body, parent=self, git_path=git_path)
        return new_fork
Example #7
0
    def removeItem(self, release, path, comment=None):
        result = None
        session = None
        try:
            session = self._manager.getSession()
            item = self._get_item(release, path)
            item = session.merge(item)
            target_path, target_name = self.__get_target(release, path)
            module = self._supportedItems[item.item_type]['module'](target_path, target_name)
            module.delete()

            # Commit changes
            if not comment:
                comment = "Change made with no comment"

            self.log.info("commiting changes for module %s" % target_name)
            cmd = Git(target_path)
            try:
                cmd.commit("-a", "-m", comment)
                cmd.push("origin")
            except GitCommandError as e:
                self.log.debug("no commit for %s: %s" % (target_name, str(e)))
            session.commit()
            result = True
        except:
            session.rollback()
            raise
        finally:
            session.close()
        result &= super(PuppetInstallMethod, self).removeItem(release, path)
        return result
Example #8
0
def init_remotes():
    path = getcwd()
    git = Git(path)

    has_upstream = raw_input('Is this a fork? (y/N) ')
    if has_upstream.lower() == 'y':
        upstream = raw_input('What is the url of the upstream project? ')
        git.remote('add', 'upstream', upstream)
Example #9
0
 def merge(self, remoteref, wd=None, **kwargs):
     if wd is None:
         git = self.git
     else:
         git = Git(wd)
         git.extra = dict(self.git.extra)
         git.extra["env"]["GIT_WORK_TREE"] = wd
     git.merge(remoteref)
Example #10
0
    def command(self, command):
        """
        Runs the Git command in self.repo
        """
        args = split(command)

        cmd = Git(self.repodir)

        cmd.execute(args)
Example #11
0
 def merge_index(self, *args, **kwargs):
     wd = kwargs.get("work_tree")
     if wd is None:
         git = self.git
     else:
         git = Git(wd)
         git.extra = dict(self.git.extra)
         git.extra["env"]["GIT_WORK_TREE"] = wd
     return git.merge_index(*args, **kwargs)
Example #12
0
def init_branches(options, error, info, debug):
    path = getcwd()
    git = Git(path)
    create = options.release_tool_settings['branches']

    for branch in create:
        debug('creating branch "%s"...' % branch)
        debug(git.branch(branch))

    info('Created branches ' + ', '.join(create))
Example #13
0
 def __init__(self, options, build_type='job'):
     self.options = options
     repository, project, version = self.parse_repository()
     self.repository = repository
     self.project = project
     self.version = version
     self.cache_dir = Workspace().get_vcs_space('git')
     self.build_type = build_type
     self.workspace = self.cwd
     self.git = Git(working_dir=self.cwd)
     self.refs = None
     self.logger = get_logger('console')
Example #14
0
 def is_cached(self):
     try:
         cache_path = self.cache_dir + '/' + self.project
         is_dir = os.path.isdir(cache_path)
         if is_dir:
             result = Git(cache_path).execute(
                 ['git', 'rev-parse', '--git-dir'], )
             if result.startswith('.'):
                 return True
             return False
     except Exception:
         return False
Example #15
0
    def get_contibutors(self) -> list[str]:
        """Return list of Git contributors for given path using `git shortlog`

        :path: Path of which to get contributors
        :flags: Additional flags passed to `git shortlog`
        """
        docfile_path = Path(self.get_source_info()[0]).resolve()
        docfile_name = docfile_path.name
        docdir_path = docfile_path.parent
        min_commits = self.optn_over_conf("min_commits",
                                          "scm_contribs_min_commits")

        limit_authors = self.optn_over_conf("limit_authors",
                                            "scm_contribs_limit_authors")
        if limit_authors is not None and limit_authors < 1:
            logger.warning(
                "List of contributors limited to less than one entry. "
                "Check '(scm_contribs_)limit_authors' option/config value")

        flags: list[str] = []

        contribs_email = directives.choice(
            self.optn_over_conf("email", "scm_contribs_email"),
            ("true", "false"),
        )
        flags += ["-e"] if contribs_email == "true" else []

        contribs_sort = directives.choice(
            self.optn_over_conf("sort", "scm_contribs_sort"),
            ("name", "num"),
        )
        flags += ["-n"] if contribs_sort == "num" else []

        contribs_type = directives.choice(
            self.optn_over_conf("type", "scm_contribs_type"),
            ("author", "committer"),
        )
        flags += ["-c"] if contribs_type == "committer" else []

        git_shortlog_options = ["-s", *flags, "--", docfile_name]

        contributors = []
        git_shortlog = Git(docdir_path).shortlog(*git_shortlog_options)
        git_shortlog_items = git_shortlog.split("\n")
        for item in git_shortlog_items:
            if not item:
                continue
            num, contributor = item.split("\t")
            if int(num) < min_commits:
                continue
            contributors += [contributor]

        return contributors[:limit_authors]
Example #16
0
    def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
        if progress is not None:
            progress = to_progress_instance(progress)

        odbt = kwargs.pop('odbt', odb_default_type)

        ## A bug win cygwin's Git, when `--bare` or `--separate-git-dir`
        #  it prepends the cwd or(?) the `url` into the `path, so::
        #        git clone --bare  /cygwin/d/foo.git  C:\\Work
        #  becomes::
        #        git clone --bare  /cygwin/d/foo.git  /cygwin/d/C:\\Work
        #
        clone_path = (Git.polish_url(path)
                      if Git.is_cygwin() and 'bare' in kwargs else path)
        sep_dir = kwargs.get('separate_git_dir')
        if sep_dir:
            kwargs['separate_git_dir'] = Git.polish_url(sep_dir)
        proc = git.clone(Git.polish_url(url),
                         clone_path,
                         with_extended_output=True,
                         as_process=True,
                         v=True,
                         **add_progress(kwargs, git, progress))
        if progress:
            handle_process_output(proc, None, progress.new_message_handler(),
                                  finalize_process)
        else:
            (stdout, stderr) = proc.communicate()
            log.debug("Cmd(%s)'s unused stdout: %s", getattr(proc, 'args', ''),
                      stdout)
            finalize_process(proc, stderr=stderr)

        # our git command could have a different working dir than our actual
        # environment, hence we prepend its working dir if required
        if not osp.isabs(path) and git.working_dir:
            path = osp.join(git._working_dir, path)

        repo = cls(path, odbt=odbt)

        # retain env values that were passed to _clone()
        repo.git.update_environment(**git.environment())

        # adjust remotes - there may be operating systems which use backslashes,
        # These might be given as initial paths, but when handling the config file
        # that contains the remote from which we were clones, git stops liking it
        # as it will escape the backslashes. Hence we undo the escaping just to be
        # sure
        if repo.remotes:
            with repo.remotes[0].config_writer as writer:
                writer.set_value('url', Git.polish_url(repo.remotes[0].url))
        # END handle remote repo
        return repo
Example #17
0
def pull(repo_dir: str):
    """
    Pull all the new files in the master in specified directory.
    Directory should contain path where .git file is located.

    Arguments:
        :param repo_dir directory where .git file is located
    """
    git = Git(repo_dir)
    git.pull()
    repo = Repo(repo_dir)
    for submodule in repo.submodules:
        submodule.update(recursive=True, init=True)
Example #18
0
    def clone_from(cls, url, to_path, progress=None, env=None, **kwargs):
        """Create a clone from the given URL

        :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS
        :param to_path: Path to which the repository should be cloned to
        :param progress: See 'git.remote.Remote.push'.
        :param env: Optional dictionary containing the desired environment variables.
        :param kwargs: see the ``clone`` method
        :return: Repo instance pointing to the cloned directory"""
        git = Git(os.getcwd())
        if env is not None:
            git.update_environment(**env)
        return cls._clone(git, url, to_path, GitCmdObjectDB, progress, **kwargs)
Example #19
0
    def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
        if progress is not None:
            progress = to_progress_instance(progress)

        odbt = kwargs.pop('odbt', odb_default_type)

        # when pathlib.Path or other classbased path is passed
        if not isinstance(path, str):
            path = str(path)

        ## A bug win cygwin's Git, when `--bare` or `--separate-git-dir`
        #  it prepends the cwd or(?) the `url` into the `path, so::
        #        git clone --bare  /cygwin/d/foo.git  C:\\Work
        #  becomes::
        #        git clone --bare  /cygwin/d/foo.git  /cygwin/d/C:\\Work
        #
        clone_path = (Git.polish_url(path)
                      if Git.is_cygwin() and 'bare' in kwargs
                      else path)
        sep_dir = kwargs.get('separate_git_dir')
        if sep_dir:
            kwargs['separate_git_dir'] = Git.polish_url(sep_dir)
        proc = git.clone(Git.polish_url(url), clone_path, with_extended_output=True, as_process=True,
                         v=True, universal_newlines=True, **add_progress(kwargs, git, progress))
        if progress:
            handle_process_output(proc, None, progress.new_message_handler(), finalize_process, decode_streams=False)
        else:
            (stdout, stderr) = proc.communicate()
            log.debug("Cmd(%s)'s unused stdout: %s", getattr(proc, 'args', ''), stdout)
            finalize_process(proc, stderr=stderr)

        # our git command could have a different working dir than our actual
        # environment, hence we prepend its working dir if required
        if not osp.isabs(path) and git.working_dir:
            path = osp.join(git._working_dir, path)

        repo = cls(path, odbt=odbt)

        # retain env values that were passed to _clone()
        repo.git.update_environment(**git.environment())

        # adjust remotes - there may be operating systems which use backslashes,
        # These might be given as initial paths, but when handling the config file
        # that contains the remote from which we were clones, git stops liking it
        # as it will escape the backslashes. Hence we undo the escaping just to be
        # sure
        if repo.remotes:
            with repo.remotes[0].config_writer as writer:
                writer.set_value('url', Git.polish_url(repo.remotes[0].url))
        # END handle remote repo
        return repo
Example #20
0
    def __init__(self, *args, **kwargs):
        if not kwargs.get('parent', None):
            # Initialize a new repo
            git_path = mkdtemp(prefix=settings.GIT_ROOT_PATH)
            git = Git(git_path)
            git.init()

            body_path = os.path.join(git_path, 'BODY')

            self.message = "created new"

            kwargs['git_path'] = git_path

        super(Fork, self).__init__(*args, **kwargs)
Example #21
0
    def checkout(self, wd=None, **kwargs):
        if wd is None:
            git = self.git
            wd = self.repo.wd
        else:
            git = Git(wd)
            git.extra = dict(self.git.extra)
            git.extra["env"]["GIT_WORK_TREE"] = wd

        try:
            makedirs(wd)
        except OSError, exc:
            if exc.errno != EEXIST:
                raise
Example #22
0
    def save(self, *args, **kwargs):
        message = kwargs.pop('message', self._next_message() or 'update')

        super(Fork, self).save(*args, **kwargs)
        with open(os.path.join(self.git_path, "BODY"), 'w') as f:
            f.write(self.body)
        git = Git(self.git_path)
        git.add('BODY')

        try:
            git.commit(message=message)
        except GitCommandError, e:
            if e.status != 1:
                raise
Example #23
0
def checkout(c, name=None):
    _platform = __platform()
    _c_name, _c_platform = f'[hl]{name}[/hl]', f'[hl]{_platform}[/hl]'
    _h_name, _h_platform = f'<b>{name}</b>', f'<b>{_platform}</b>'
    _msg = f'Checkout of :{cfg.icon.component}: %s %s completed @ :{cfg.icon.platform}: %s.'
    try:
        _git = Git(cfg.git.get(name))
        _git.checkout()
        log.success(_msg % (_c_name, '[ok]correctly[/ok]', _c_platform))
        telegrot.success(_msg % (_h_name, '<u>correctly</u>', _h_platform))
        exit(0)
    except Exception:
        log.error(_msg % (_c_name, '[err]not[/err]', _c_platform))
        telegrot.error(_msg % (_h_name, '<u>not</u>', _h_platform))
        exit(1)
Example #24
0
    def test_diff_with_staged_file(self, rw_dir):
        # SETUP INDEX WITH MULTIPLE STAGES
        r = Repo.init(rw_dir)
        fp = osp.join(rw_dir, 'hello.txt')
        with open(fp, 'w') as fs:
            fs.write("hello world")
        r.git.add(Git.polish_url(fp))
        r.git.commit(message="init")

        with open(fp, 'w') as fs:
            fs.write("Hola Mundo")
        r.git.commit(all=True, message="change on master")

        r.git.checkout('HEAD~1', b='topic')
        with open(fp, 'w') as fs:
            fs.write("Hallo Welt")
        r.git.commit(all=True, message="change on topic branch")

        # there must be a merge-conflict
        self.failUnlessRaises(GitCommandError, r.git.cherry_pick, 'master')

        # Now do the actual testing - this should just work
        self.assertEqual(len(r.index.diff(None)), 2)

        self.assertEqual(len(r.index.diff(None, create_patch=True)), 0,
                         "This should work, but doesn't right now ... it's OK")
Example #25
0
    def __init__(self,
                 options,
                 title=None,
                 default_index=0,
                 options_map_func=None):
        self.KEYS_ENTER = (curses.KEY_ENTER, ord('\n'), ord('\r'))
        self.KEYS_UP = (curses.KEY_UP, ord('k'))
        self.KEYS_DOWN = (curses.KEY_DOWN, ord('j'))
        self.KEYS_SELECT = (curses.KEY_RIGHT, ord(' '))
        self.options = options
        self.title = title
        self.indicator = "=>"
        self.options_map_func = options_map_func
        self.commit_type = [
            "feat", "fix", "docs", "style", "refactor", "test", "chore", "exit"
        ]
        self.git = Git(os.getcwd())
        self.emojis = {
            "feat": "sparkles",
            "fix": "bug",
            "docs": "memo",
            "style": "art",
            "refactor": "recycle",
            "test": "white_check_mark",
            "chore": "building_construction",
        }

        if default_index >= len(options):
            raise ValueError(
                'default_index should be less than the length of options')

        self.index = default_index
Example #26
0
 async def pull(self, ctx):
     """Update the bot from github"""
     g = Git()
     try:
         await ctx.send(f"Probably pulled.\n```\n{g.pull()}```")
     except git.exc.GitCommandError as e:
         await ctx.send(f"An error has occured when pulling```\n{e}```")
Example #27
0
    def __set_path(config: Config, attr: str):
        msg = {
            'root_path': "path of the repository to work on",
        }
        while True:
            if not hasattr(config, attr) or not getattr(config, attr):
                path = prompt_enter_value(msg[attr])
            else:
                path = getattr(config, attr)  # set by script param

            if not __check_path(path):
                setattr(config, attr, "")
                continue

            if (attr == "root_path") & (os.path.realpath(__file__).startswith(
                    os.path.abspath(path))):
                log_error(
                    "Please copy and run the create release script in another place outside of the repository and execute again."
                )
                sys.exit()

            try:
                Git(path)
            except InvalidGitRepositoryError:
                log_error("Path is not a git repository.")

            setattr(config, attr, path)

            info = {
                "root_path": "Executing release in path '",
            }
            log_info(info[attr] + str(getattr(config, attr)) + "'")
            break
Example #28
0
    def test_git_submodules_and_add_sm_with_new_commit(self, rwdir):
        parent = git.Repo.init(osp.join(rwdir, 'parent'))
        parent.git.submodule('add', self._small_repo_url(), 'module')
        parent.index.commit("added submodule")

        assert len(parent.submodules) == 1
        sm = parent.submodules[0]

        assert sm.exists() and sm.module_exists()

        clone = git.Repo.clone_from(
            self._small_repo_url(),
            osp.join(parent.working_tree_dir, 'existing-subrepository'))
        sm2 = parent.create_submodule('nongit-file-submodule',
                                      clone.working_tree_dir)
        assert len(parent.submodules) == 2

        for _ in range(2):
            for init in (False, True):
                sm.update(init=init)
                sm2.update(init=init)
            # end for each init state
        # end for each iteration

        sm.move(sm.path + '_moved')
        sm2.move(sm2.path + '_moved')

        parent.index.commit("moved submodules")

        with sm.config_writer() as writer:
            writer.set_value('user.email', '*****@*****.**')
            writer.set_value('user.name', 'me')
        smm = sm.module()
        fp = osp.join(smm.working_tree_dir, 'empty-file')
        with open(fp, 'w'):
            pass
        smm.git.add(Git.polish_url(fp))
        smm.git.commit(m="new file added")

        # submodules are retrieved from the current commit's tree, therefore we can't really get a new submodule
        # object pointing to the new submodule commit
        sm_too = parent.submodules['module_moved']
        assert parent.head.commit.tree[sm.path].binsha == sm.binsha
        assert sm_too.binsha == sm.binsha, "cached submodule should point to the same commit as updated one"

        added_bies = parent.index.add([sm])  # addded base-index-entries
        assert len(added_bies) == 1
        parent.index.commit("add same submodule entry")
        commit_sm = parent.head.commit.tree[sm.path]
        assert commit_sm.binsha == added_bies[0].binsha
        assert commit_sm.binsha == sm.binsha

        sm_too.binsha = sm_too.module().head.commit.binsha
        added_bies = parent.index.add([sm_too])
        assert len(added_bies) == 1
        parent.index.commit("add new submodule entry")
        commit_sm = parent.head.commit.tree[sm.path]
        assert commit_sm.binsha == added_bies[0].binsha
        assert commit_sm.binsha == sm_too.binsha
        assert sm_too.binsha != sm.binsha
Example #29
0
 def urls(self):
     """:return: Iterator yielding all configured URL targets on a remote as strings"""
     try:
         remote_details = self.repo.git.remote("get-url", "--all", self.name)
         for line in remote_details.split('\n'):
             yield line
     except GitCommandError as ex:
         ## We are on git < 2.7 (i.e TravisCI as of Oct-2016),
         #  so `get-utl` command does not exist yet!
         #    see: https://github.com/gitpython-developers/GitPython/pull/528#issuecomment-252976319
         #    and: http://stackoverflow.com/a/32991784/548792
         #
         if 'Unknown subcommand: get-url' in str(ex):
             try:
                 remote_details = self.repo.git.remote("show", self.name)
                 for line in remote_details.split('\n'):
                     if '  Push  URL:' in line:
                         yield line.split(': ')[-1]
             except GitCommandError as ex:
                 if any([msg in str(ex) for msg in ['correct access rights',
                                                    'cannot run ssh']]):
                     # If ssh is not setup to access this repository, see issue 694
                     result = Git().execute(['git', 'config', '--get',
                                             'remote.%s.url' % self.name])
                     yield result
                 else:
                     raise ex
         else:
             raise ex
Example #30
0
    def test_diff_with_staged_file(self, rw_dir):
        # SETUP INDEX WITH MULTIPLE STAGES
        r = Repo.init(rw_dir)
        fp = osp.join(rw_dir, 'hello.txt')
        with open(fp, 'w') as fs:
            fs.write("hello world")
        r.git.add(Git.polish_url(fp))
        r.git.commit(message="init")

        with open(fp, 'w') as fs:
            fs.write("Hola Mundo")
        r.git.commit(all=True, message="change on master")

        r.git.checkout('HEAD~1', b='topic')
        with open(fp, 'w') as fs:
            fs.write("Hallo Welt")
        r.git.commit(all=True, message="change on topic branch")

        # there must be a merge-conflict
        self.failUnlessRaises(GitCommandError, r.git.cherry_pick, 'master')

        # Now do the actual testing - this should just work
        self.assertEqual(len(r.index.diff(None)), 2)

        self.assertEqual(
            len(r.index.diff(None, create_patch=True)), 0,
            "This should work, but doesn't right now ... it's OK")
Example #31
0
    def clone(self, url):
        """Clones a dotfile repository.

        Args:
            url: The URL of the repository to clone.
        """
        print('Cloning {} into {}'.format(url, self.path))
        _exec_raw(lambda: Git().clone(url, self.path))
    def clone_from(cls, url, to_path, **kwargs):
        """Create a clone from the given URL
		:param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS
		:param to_path: Path to which the repository should be cloned to
		:param **kwargs: see the ``clone`` method
		:return: Repo instance pointing to the cloned directory"""
        return cls._clone(Git(os.getcwd()), url, to_path, GitCmdObjectDB,
                          **kwargs)
Example #33
0
    def graph(self):
        """
        Prints a graph of the git log.

        This is used for testing and debugging only.
        """
        sys.stdout.write(
            Git(self.repodir).execute(["git", "log", "--graph", "--oneline"]))
Example #34
0
 def sync_mirror(self):
     dirname = self.cache_dir + '/' + self.project
     if not self.is_cached():
         Workspace.mkdir(dirname)
         git = Git(dirname)
         git.execute(['git', 'clone', '--mirror', self.repository, dirname])
         command = ['git', 'remote', 'add', 'eclogue', self.repository]
         git.execute(command)
         self.logger.info(' '.join(command))
         command = [
             'git', 'remote', 'set-url', '--push', 'origin', self.repository
         ]
         git.execute(command)
         self.logger.info(' '.join(command))
         command = ['git', 'remote', 'update', '--prune', 'origin']
         git.execute(command)
         self.logger.info(' '.join(command))
Example #35
0
    def graph(self):
        """
        Prints a graph of the git log.

        This is used for testing and debugging only.
        """
        sys.stdout.write(
            Git(self.repodir).execute(['git', 'log', '--graph', '--oneline']))
    def test_git_submodules_and_add_sm_with_new_commit(self, rwdir):
        parent = git.Repo.init(osp.join(rwdir, 'parent'))
        parent.git.submodule('add', self._small_repo_url(), 'module')
        parent.index.commit("added submodule")

        assert len(parent.submodules) == 1
        sm = parent.submodules[0]

        assert sm.exists() and sm.module_exists()

        clone = git.Repo.clone_from(self._small_repo_url(),
                                    osp.join(parent.working_tree_dir, 'existing-subrepository'))
        sm2 = parent.create_submodule('nongit-file-submodule', clone.working_tree_dir)
        assert len(parent.submodules) == 2

        for _ in range(2):
            for init in (False, True):
                sm.update(init=init)
                sm2.update(init=init)
            # end for each init state
        # end for each iteration

        sm.move(sm.path + '_moved')
        sm2.move(sm2.path + '_moved')

        parent.index.commit("moved submodules")

        with sm.config_writer() as writer:
            writer.set_value('user.email', '*****@*****.**')
            writer.set_value('user.name', 'me')
        smm = sm.module()
        fp = osp.join(smm.working_tree_dir, 'empty-file')
        with open(fp, 'w'):
            pass
        smm.git.add(Git.polish_url(fp))
        smm.git.commit(m="new file added")

        # submodules are retrieved from the current commit's tree, therefore we can't really get a new submodule
        # object pointing to the new submodule commit
        sm_too = parent.submodules['module_moved']
        assert parent.head.commit.tree[sm.path].binsha == sm.binsha
        assert sm_too.binsha == sm.binsha, "cached submodule should point to the same commit as updated one"

        added_bies = parent.index.add([sm])  # addded base-index-entries
        assert len(added_bies) == 1
        parent.index.commit("add same submodule entry")
        commit_sm = parent.head.commit.tree[sm.path]
        assert commit_sm.binsha == added_bies[0].binsha
        assert commit_sm.binsha == sm.binsha

        sm_too.binsha = sm_too.module().head.commit.binsha
        added_bies = parent.index.add([sm_too])
        assert len(added_bies) == 1
        parent.index.commit("add new submodule entry")
        commit_sm = parent.head.commit.tree[sm.path]
        assert commit_sm.binsha == added_bies[0].binsha
        assert commit_sm.binsha == sm_too.binsha
        assert sm_too.binsha != sm.binsha
Example #37
0
    def removeRelease(self, name, recursive=False):
        super(PuppetInstallMethod, self).removeRelease(name, recursive)

        with puppet_lock:
            # Move to concrete directory name
            name = name.replace("/", "@")

            # Sort by length and remove relevant releases
            for fname in [f for f in sorted(
                os.listdir(self.__work_path), lambda a, b: cmp(b, a), len)
                if (recursive and f.startswith(name)) or (not recursive and f == name)]:

                current_dir = os.path.join(self.__work_path, fname)
                cmd = Git(current_dir)
                cmd.push("origin", ":" + fname)
                shutil.rmtree(current_dir)

        return True
Example #38
0
def get_repo(repo_url: str, repo_path: Path):
    if repo_path.exists():
        repo = Repo(repo_path)
        heads = Git().ls_remote(repo_url)
        git_hash_length = 40
        remote_last_commit = heads.split("\n")[0][:git_hash_length]
        if remote_last_commit != repo.head.commit.hexsha:
            update_repo = questionary.confirm(
                "The remote repository has been updated."
                "Do you want to update it?"
            ).ask()
            if update_repo:
                repo.remotes.origin.pull()
    else:
        # pyright: reportUnknownMemberType=false
        repo = Repo.clone_from(repo_url, repo_path)

    return repo
Example #39
0
 def get_remote_url(self, remote='origin'):
     r = self.get_remote(remote)
     try:
         url = list(r.urls)[0]
     except GitCommandError as ex:
         if 'correct access rights' in str(ex):
             # If ssh is not setup to access this repository
             cmd = ['git', 'config', '--get', 'remote.%s.url' % r.name]
             url = Git().execute(cmd)
         else:
             raise ex
     except AttributeError:
         url = None
     if url is not None and url.startswith('git@'):
         domain = url.split('@')[1].split(':')[0]
         path = url.split(':')[1]
         url = "http://%s/%s" % (domain, path)
     return url
Example #40
0
 def get_remote_url(self, remote='origin'):
     r = self.get_remote(remote)
     try:
         url = list(r.urls)[0]
     except GitCommandError as ex:
         if 'correct access rights' in str(ex):
             # If ssh is not setup to access this repository 
             cmd = ['git','config','--get','remote.%s.url' % r.name]                                                                                           
             url = Git().execute(cmd)
         else:
             raise ex
     except AttributeError:
         url = None
     if url is not None and url.startswith('git@'):
         domain = url.split('@')[1].split(':')[0]
         path = url.split(':')[1]
         url = "http://%s/%s" % (domain,path)
     return url
Example #41
0
def init_logging(gn_env: GNEnvironment) -> None:
    if len(gn_env.config) == 0 or gn_env.config.get(ConfigKeys.TESTING, False):
        # assume we're testing
        return

    logging_type = gn_env.config.get(
        ConfigKeys.TYPE, domain=ConfigKeys.LOGGING, default="logger"
    )
    if (
        logging_type is None
        or len(logging_type.strip()) == 0
        or logging_type in ["logger", "default", "mock"]
    ):
        return

    if logging_type != "sentry":
        raise RuntimeError(f"unknown logging type {logging_type}")

    dsn = gn_env.config.get(ConfigKeys.DSN, domain=ConfigKeys.LOGGING, default="")
    if dsn is None or len(dsn.strip()) == 0:
        logger.warning(
            "sentry logging selected but no DSN supplied, not configuring sentry"
        )
        return

    import socket
    from git.cmd import Git

    home_dir = os.environ.get("DINO_HOME", default=None)
    if home_dir is None:
        home_dir = "."
    tag_name = Git(home_dir).describe()

    import sentry_sdk
    from sentry_sdk import capture_exception as sentry_capture_exception
    from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

    sentry_sdk.init(
        dsn=dsn,
        environment=os.getenv("ENVIRONMENT"),  # TODO: fix DINO_ENVIRONMENT / ENVIRONMENT discrepancy
        server_name=socket.gethostname(),
        release=tag_name,
        integrations=[
            SqlalchemyIntegration(),
            RedisIntegration()
        ],
    )

    def capture_wrapper(e_info) -> None:
        try:
            sentry_capture_exception(e_info)
        except Exception as e2:
            logger.exception(e_info)
            logger.error(f"could not capture exception with sentry: {str(e2)}")

    gn_env.capture_exception = capture_wrapper
Example #42
0
def init_releaserc(debug, info):
    path = getcwd()
    git = Git(path)
    another_env = 'y'
    n_th = 'first'
    branches = []
    secrets = {}
    commands = {
        "test": "/usr/bin/true"
    }

    # get branch names and passwords
    info('\nLet\'s setup your roll process.')
    info('-------------------------------')
    while another_env.lower() == 'y' or another_env.lower() == '':
        env_name = raw_input('What\'s the name of the ' + n_th + ' environment? ')
        branches.append(env_name)
        password_required = raw_input('Should a password be required to roll here? (y/N) ')
        password = None

        if password_required.lower() == 'y':
            password = sha.new(getpass()).hexdigest()

        secrets[env_name] = password
        another_env = raw_input('Is there another environment? (Y/n) ')

        n_th = 'next'
        info('')

    info('Your roll process is:\nmaster -> ' + ' -> '.join(branches))
    info('')
    info('')

    fd = open('.releaserc', 'w')

    json.dump({
        "branches": branches,
        "commands": commands,
        "secrets": secrets
    }, fd, indent=4, separators=(',', ': '))

    debug('adding .releaserc...')
    debug(git.add('.releaserc'))
Example #43
0
def init(error, info, debug):
    path = getcwd()
    git = Git(path)

    debug('running git init...')
    debug(git.init())

    welcome_package()
    init_releaserc()

    call_task('commit', options={
        'm': 'Intializing repository'
    })

    init_branches()

    debug('')

    info('Git repository created successfully.')
Example #44
0
    def clone_from(cls, url, to_path, progress=None, env=None, multi_options=None, **kwargs):
        """Create a clone from the given URL

        :param url: valid git url, see http://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS
        :param to_path: Path to which the repository should be cloned to
        :param progress: See 'git.remote.Remote.push'.
        :param env: Optional dictionary containing the desired environment variables.
            Note: Provided variables will be used to update the execution
            environment for `git`. If some variable is not specified in `env`
            and is defined in `os.environ`, value from `os.environ` will be used.
            If you want to unset some variable, consider providing empty string
            as its value.
        :param multi_options: See ``clone`` method
        :param kwargs: see the ``clone`` method
        :return: Repo instance pointing to the cloned directory"""
        git = Git(os.getcwd())
        if env is not None:
            git.update_environment(**env)
        return cls._clone(git, url, to_path, GitCmdObjectDB, progress, multi_options, **kwargs)
def refresh(path=None):
    """Convenience method for setting the git executable path."""
    global GIT_OK
    GIT_OK = False

    if not Git.refresh(path=path):
        return
    if not FetchInfo.refresh():
        return

    GIT_OK = True
Example #46
0
def refresh(path=None):
    """Convenience method for setting the git executable path."""
    global GIT_OK
    GIT_OK = False

    if not Git.refresh(path=path):
        return
    if not FetchInfo.refresh():
        return

    GIT_OK = True
Example #47
0
def refresh(path='C:\Program Files\Git\bin'):
    """Convenience method for setting the git executable path."""
    global GIT_OK
    GIT_OK = False

    if not Git.refresh(path=path):
        return
    if not FetchInfo.refresh():
        return

    GIT_OK = True
Example #48
0
def update_repo(project, mirror_dir, gerrit_url):
    """Utility function to mirror git repo

    Arguments:
        :arg str project: Git project to mirror
        :arg str mirror_dir: Path to directory containing repos.
        :arg str gerrit_url: URL to the Gerrit server. Used for cloning repos.
    """
    log.debug("Updating repo for {0}".format(project))
    project_dir = os.path.join(mirror_dir, '{0}.git'.format(project))

    if os.path.exists(project_dir):
        args = ['git', 'fetch']
    else:
        os.makedirs(project_dir)
        args = ['git', 'clone', '--mirror',
                '{0}/{1}'.format(gerrit_url, project), '.']

    project_repo = Git(project_dir)
    project_repo.execute(args)
Example #49
0
class Index(object):
    def __init__(self, repo, path=None):
        if path is None:
            path = join(repo.path, "index")
            self.git = repo.git
        else:
            self.git = Git(repo.wd)
            env = {
                "GIT_INDEX_FILE": path,
            }
            if not repo.bare:
                env["GIT_WORK_TREE"] = repo.wd
            self.git.extra["env"] = env

        self.path = path
        self.repo = repo

    def data_update(self, path, data, mode="0644", **kwargs):
        path = str(path)
        if isabs(path):
            path = path[1:]

        hash = self.repo.git.hash_object(stdin=True, t="blob", w=True,
                                         input=data, path=path)
        self.git.update_index("--cacheinfo", mode, hash, path, **kwargs)

    def checkout(self, wd=None, **kwargs):
        if wd is None:
            git = self.git
            wd = self.repo.wd
        else:
            git = Git(wd)
            git.extra = dict(self.git.extra)
            git.extra["env"]["GIT_WORK_TREE"] = wd

        try:
            makedirs(wd)
        except OSError, exc:
            if exc.errno != EEXIST:
                raise
        return git.checkout_index(**kwargs)
Example #50
0
    def init(cls,
             path=None,
             mkdir=True,
             odbt=DefaultDBType,
             expand_vars=True,
             **kwargs):
        """Initialize a git repository at the given path if specified

        :param path:
            is the full path to the repo (traditionally ends with /<name>.git)
            or None in which case the repository will be created in the current
            working directory

        :parm mkdir:
            if specified will create the repository directory if it doesn't
            already exists. Creates the directory with a mode=0755.
            Only effective if a path is explicitly given

        :param odbt:
            Object DataBase type - a type which is constructed by providing
            the directory containing the database objects, i.e. .git/objects.
            It will be used to access all object data

        :param expand_vars:
            if specified, environment variables will not be escaped. This
            can lead to information disclosure, allowing attackers to
            access the contents of environment variables

        :parm kwargs:
            keyword arguments serving as additional options to the git-init command

        :return: ``git.Repo`` (the newly created repo)"""
        if path:
            path = expand_path(path, expand_vars)
        if mkdir and path and not osp.exists(path):
            os.makedirs(path, 0o755)

        # git command automatically chdir into the directory
        git = Git(path)
        git.init(**kwargs)
        return cls(path, odbt=odbt)
Example #51
0
    def __init__(
        self,
        root=None,
        folders=None,
        name=None,
        url=None,
    ):
        self.DEFAULT_BRANCH = 'master'

        if root is None:
            self.root = tempfile.mkdtemp(prefix="bugle_" + name + "_")
            self.is_root_tmp = True
        else:
            self.root = root
            self.is_root_tmp = False

        if name is None:
            self.name = os.path.basename(root)
        else:
            self.name = name

        self.url = url
        # Make sure folder is a git repo
        if self.is_root_tmp and self.url is None:
            raise Exception("New folder with no repo URL")
        self.git = Git(self.root)
        self.git_clone()

        self.repo = Repo(self.root)

        if folders is None:
            self.folders = ['.']
        else:
            self.folders = folders

        self.files = {}
        self.branches = {}
        self.total_count = {}
        self.branch_count = {}
        print "creating repo %s under %s, folders %s" % (name, self.root,
                                                         self.folders)
Example #52
0
    def install_or_update(
        self, parent_repo, address, target_dir, select=[], fname=None
    ):
        from git.cmd import Git

        if not self.is_in_root():
            raise DvcException(
                "This command can be run only from a repository root"
            )

        if not os.path.exists(self.MODULES_DIR):
            logger.debug("Creating modules dir {}".format(self.MODULES_DIR))
            os.makedirs(self.MODULES_DIR)
            parent_repo.scm.ignore(os.path.abspath(self.MODULES_DIR))

        module_name = Git.polish_url(address).strip("/").split("/")[-1]
        if not module_name:
            raise DvcException(
                "Package address error: unable to extract package name"
            )

        with TempGitRepo(
            address, module_name, Package.MODULES_DIR
        ) as tmp_repo:
            outputs_to_copy = tmp_repo.outs
            if select:
                outputs_to_copy = list(
                    filter(lambda out: out.dvc_path in select, outputs_to_copy)
                )

            fetched_stage_files = set(
                map(lambda o: o.stage.path, outputs_to_copy)
            )
            tmp_repo.fetch(fetched_stage_files)

            module_dir = self.create_module_dir(module_name)
            tmp_repo.persist_to(module_dir, parent_repo)

            dvc_file = self.get_dvc_file_name(fname, target_dir, module_name)
            try:
                self.persist_stage_and_scm_state(
                    parent_repo, outputs_to_copy, target_dir, dvc_file
                )
            except Exception as ex:
                raise DvcException(
                    "Package '{}' was installed "
                    "but stage file '{}' "
                    "was not created properly: {}".format(
                        address, dvc_file, ex
                    )
                )

        parent_repo.checkout(dvc_file)
Example #53
0
 def create(cls, repo, name, url, **kwargs):
     """Create a new remote to the given repository
     :param repo: Repository instance that is to receive the new remote
     :param name: Desired name of the remote
     :param url: URL which corresponds to the remote's name
     :param kwargs: Additional arguments to be passed to the git-remote add command
     :return: New Remote instance
     :raise GitCommandError: in case an origin with that name already exists"""
     scmd = 'add'
     kwargs['insert_kwargs_after'] = scmd
     repo.git.remote(scmd, name, Git.polish_url(url), **kwargs)
     return cls(repo, name)
Example #54
0
 def create(cls, repo, name, url, **kwargs):
     """Create a new remote to the given repository
     :param repo: Repository instance that is to receive the new remote
     :param name: Desired name of the remote
     :param url: URL which corresponds to the remote's name
     :param kwargs: Additional arguments to be passed to the git-remote add command
     :return: New Remote instance
     :raise GitCommandError: in case an origin with that name already exists"""
     scmd = 'add'
     kwargs['insert_kwargs_after'] = scmd
     repo.git.remote(scmd, name, Git.polish_url(url), **kwargs)
     return cls(repo, name)
Example #55
0
def get():
    parser = reqparse.RequestParser()
    parser.add_argument('repo', location='args', required=True)
    parser.add_argument('port', location='args', required=True)
    data = parser.parse_args()
    repo = data['repo']
    port = data['port']
    try:
        response = requests.get(repo)
        if response.status_code != 200:
            return jsonify({
                'status': 401,
                'error': '{} is not a valid URL'.format(repo)
            })
    except:
        return jsonify({
            'status': 401,
            'error': '{} is not a valid URL'.format(repo)
        })
    gitcmd = Git('.')
    gitcmd.init()
    name = repo.split('/')
    repo_name = name[-1]
    repo_name = repo_name.replace('.git', '')
    gitcmd.clone(repo, 'repos/' + repo_name)
    subprocess.Popen(
        '.flaskapp/bin/uwsgi --http :%s --file repos/{}/wsgi.py --callable app'
        .format(port, repo_name))
    return jsonify({
        'status':
        200,
        'message':
        'Deployed to Raspberry Pi! {} is now running!'.format(repo_name)
    })
Example #56
0
def update_repo(project, mirror_dir, gerrit_url):
    """Utility function to mirror git repo

    Arguments:
        :arg str project: Git project to mirror
        :arg str mirror_dir: Path to directory containing repos.
        :arg str gerrit_url: URL to the Gerrit server. Used for cloning repos.
    """
    log.debug("Updating repo for {0}".format(project))
    project_dir = os.path.join(mirror_dir, '{0}.git'.format(project))

    if os.path.exists(project_dir):
        args = ['git', 'fetch']
    else:
        os.makedirs(project_dir)
        args = [
            'git', 'clone', '--mirror', '{0}/{1}'.format(gerrit_url, project),
            '.'
        ]

    project_repo = Git(project_dir)
    project_repo.execute(args)
Example #57
0
 def get_remote_url(self, remote='origin', cached=True):
     """Get a git remote URL for this instance."""
     if hasattr(self.__class__, '_remote_url') and cached:
         url = self.__class__._remote_url
     else:
         r = self.get_remote(remote)
         try:
             url = list(r.urls)[0]
         except GitCommandError as ex:
             if 'correct access rights' in str(ex):
                 # If ssh is not setup to access this repository
                 cmd = ['git', 'config', '--get', 'remote.%s.url' % r.name]
                 url = Git().execute(cmd)
             else:
                 raise ex
         except AttributeError:
             url = None
         if url is not None and url.startswith('git@'):
             domain = url.split('@')[1].split(':')[0]
             path = url.split(':')[1]
             url = "http://%s/%s" % (domain, path)
     self.__class__._remote_url = url
     return url
Example #58
0
def roll(options, debug, info, error):
    to_arg = options.args.index('to')
    path = getcwd()
    git = Git(path)
    repo = Repo(path)

    dest = None
    source = None
    active = repo.active_branch
    settings = options.release_tool_settings

    if to_arg == 0:
        source = active
        dest = options.args[1]

        #update()
    elif to_arg == 1:
        source = options.args[0]
        dest = options.args[2]
    else:
        return

    secret = settings['secrets'][str(dest)]

    if secret:
        info('Special permission is required to roll to this branch.')

    if not secret or has_permission(if_matches=secret):
        debug('rebasing {source} onto {dest}...'.format(
            source=source,
            dest=dest
        ))

        if secret:
            debug(git.rebase(source, dest))
            git.tag('-m', message('Roll from {source} to {dest} with special \
permission by {name} <{email}>.'.format(
                    source=source,
                    dest=dest,
                    name=Actor.author().name,
                    email=Actor.author().email
                ), 'tag'),
                '-s',
                'roll-from-' +
                    source + '-to-' +
                    dest + '-' +
                    datetime.utcnow().isoformat().replace(':', '.'),
                output_stream=stdout)
        else:
            debug(git.rebase(source, dest))

        debug('checking out {source}...'.format(source=source))
        debug(git.checkout(active))

        info('Rolled {source} to {dest}.'.format(source=source, dest=dest))
    else:
        error('You do not have permission to roll to this branch')
Example #59
0
def welcome_package(debug, info):
    path = getcwd()
    git = Git(path)

    fd = open('welcome.txt', 'w')

    fd.write('''
Welcome to {tool_name}
=======================

This tool is a helper to be used along side git.

    $ {tool_command} init # you just ran this!

    $ {tool_command} update

    $ {tool_command} roll to dev
    $ {tool_command} roll qa to prod
'''.format(tool_name=tool_name, tool_command=tool_command))

    debug('adding welcome.txt...')
    debug(git.add('welcome.txt'))

    info('Welcome to {tool_name}'.format(tool_name=tool_name))