예제 #1
0
def _update_repo(repo, raises=False, verbose=1):
    name = product_name(repo)

    try:
        if verbose == 1:
            click.echo('Updating ' + name)

        branch = current_branch(repo)
        parent = parent_branch(branch)
        if parent:
            checkout_branch(parent, repo)

        update_repo(repo, quiet=verbose != 2)

        if parent:
            if verbose == 2:
                click.echo('Rebasing ' + branch)
            checkout_branch(branch, repo_path=repo)
            update_branch(repo=repo, parent=parent)

        return True
    except Exception as e:
        if raises:
            raise
        else:
            log.error('%s: %s', name, e)
            return False
예제 #2
0
def _update_repo(repo, raises=False, verbose=1):
    name = product_name(repo)

    try:
        if verbose == 1:
            click.echo('Updating ' + name)

        branch = current_branch(repo)
        parent = parent_branch(branch)
        if parent:
            checkout_branch(parent, repo)

        update_repo(repo, quiet=verbose != 2)

        if parent:
            if verbose == 2:
                click.echo('Rebasing ' + branch)
            checkout_branch(branch, repo_path=repo)
            update_branch(repo=repo, parent=parent)

        return True
    except Exception as e:
        if raises:
            raise
        else:
            log.error('%s: %s', name, e)
            return False
예제 #3
0
    def run(self):

        if not self.skip_style_check and self.commander.command(
                'test').supports_style_check():
            click.echo('Checking style')
            self.commander.run('test', env_or_file=['style'], silent=2)

        current = current_branch()

        if not self.branch:
            self.branch = current
        elif self.branch != current:
            checkout_branch(self.branch)

        if self.merge:
            parent = parent_branch(self.branch)

            if parent:
                checkout_branch(parent)
                click.echo('Merging {} into {}'.format(self.branch, parent))

            else:
                self.merge = False
                log.error('Can not merge as there is no parent branch')
                sys.exit(1)

        else:
            click.echo('Pushing ' + self.branch)

        if not self.force:
            self.commander.run('update', quiet=True)

        if self.merge:
            checkout_branch(self.branch)
            update_branch(
                parent=parent
            )  # Failed rebase can be continued easily than failed merge

            checkout_branch(parent)
            merge_branch(self.branch)

            click.echo('Pushing ' + parent)

        remotes = all_remotes() if self.all_remotes else [default_remote()]
        for remote in remotes:
            if len(remotes) > 1:
                click.echo('    ... to ' + remote)
            push_repo(force=self.force, remote=remote, branch=current_branch())

        if self.merge:
            remove_branch(self.branch, remote=True, force=True)
예제 #4
0
    def run(self):

        if not self.skip_style_check and self.commander.command('test').supports_style_check():
            click.echo('Checking style')
            self.commander.run('test', env_or_file=['style'], silent=2)

        current = current_branch()

        if not self.branch:
            self.branch = current
        elif self.branch != current:
            checkout_branch(self.branch)

        if self.merge:
            parent = parent_branch(self.branch)

            if parent:
                checkout_branch(parent)
                click.echo('Merging {} into {}'.format(self.branch, parent))

            else:
                self.merge = False
                log.error('Can not merge as there is no parent branch')
                sys.exit(1)

        else:
            click.echo('Pushing ' + self.branch)

        if not self.force:
            self.commander.run('update', quiet=True)

        if self.merge:
            checkout_branch(self.branch)
            update_branch(parent=parent)  # Failed rebase can be continued easily than failed merge

            checkout_branch(parent)
            merge_branch(self.branch)

            click.echo('Pushing ' + parent)

        remotes = all_remotes() if self.all_remotes else [default_remote()]
        for remote in remotes:
            if len(remotes) > 1:
                click.echo('    ... to ' + remote)
            push_repo(force=self.force, remote=remote, branch=current_branch())

        if self.merge:
            remove_branch(self.branch, remote=True, force=True)
예제 #5
0
    def run(self):
        if is_repo():
            if len(self.target) == 1:
                if self.target[0] in all_branches():
                    checkout_branch(self.target[0])
                    click.echo('Switched to branch ' + self.target[0])
                    return

                else:
                    possible_remotes = {upstream_remote()}
                    if '/' in self.target[0]:
                        possible_remotes.add(self.target[0].split('/')[0])

                    for pull_tags in [False, True]:
                        if pull_tags:
                            for remote in possible_remotes & set(
                                    all_remotes()):
                                update_tags(remote)

                        if '/' in self.target[0] and 'remotes/{}'.format(
                                self.target[0]) in all_branches(remotes=True):
                            checkout_branch(self.target[0])
                            click.echo('Switched to branch ' +
                                       self.target[0].split('/')[-1])
                            return

                        if 'remotes/{}/{}'.format(
                                upstream_remote(),
                                self.target[0]) in all_branches(remotes=True):
                            checkout_branch("{}/{}".format(
                                upstream_remote(), self.target[0]))
                            click.echo('Switched to branch ' + self.target[0])
                            return

            checkout_files(self.target)
            return

        product_urls = expand_product_groups(self.target)

        for product_url in product_urls:
            product_url = product_url.strip('/')

            product_path = product_checkout_path(product_url)

            if os.path.exists(product_path):
                click.echo('Updating ' + product_name(product_path))
            else:
                click.echo('Checking out ' + product_url)

            checkout_product(product_url, product_path)
예제 #6
0
    def run(self):
        if is_repo():
            if len(self.target) == 1:
                if self.target[0] in all_branches():
                    checkout_branch(self.target[0])
                    click.echo('Switched to branch ' + self.target[0])
                    return

                else:
                    possible_remotes = {upstream_remote()}
                    if '/' in self.target[0]:
                        possible_remotes.add(self.target[0].split('/')[0])

                    for pull_tags in [False, True]:
                        if pull_tags:
                            for remote in possible_remotes & set(all_remotes()):
                                update_tags(remote)

                        if '/' in self.target[0] and 'remotes/{}'.format(self.target[0]) in all_branches(remotes=True):
                            checkout_branch(self.target[0])
                            click.echo('Switched to branch ' + self.target[0].split('/')[-1])
                            return

                        if 'remotes/{}/{}'.format(upstream_remote(), self.target[0]) in all_branches(remotes=True):
                            checkout_branch("{}/{}".format(upstream_remote(), self.target[0]))
                            click.echo('Switched to branch ' + self.target[0])
                            return

            checkout_files(self.target)
            return

        product_urls = expand_product_groups(self.target)

        for product_url in product_urls:
            product_url = product_url.strip('/')

            product_path = product_checkout_path(product_url)

            if os.path.exists(product_path):
                click.echo('Updating ' + product_name(product_path))
            else:
                click.echo('Checking out ' + product_url)

            checkout_product(product_url, product_path)
예제 #7
0
    def run(self):
        current = current_branch()
        repo = git.Repo(path=repo_path())

        if self.branch and self.downstreams:
            log.error('Branch and --downstreams are mutually exclusive. Please use one or the other.')
            sys.exit(1)

        if repo.is_dirty(untracked_files=True):
            log.error(
                'Your repo has untracked or modified files in working dir or in staging index. Please cleanup before doing merge')
            sys.exit(1)

        if not self.skip_update:
            self.commander.run('update', quiet=True)

        if self.branch:
            click.echo('Merging {} into {}'.format(self.branch, current))

            if not self.skip_update:
                checkout_branch(self.branch)
                self.commander.run('update', quiet=True)
                checkout_branch(current)

            all_commits = self.get_unmerged_commits(repo, self.branch, current)
            self.merge_commits(self.branch, all_commits, self.skip_commits)

        elif self.downstreams:
            if not self.merge_branches:
                self.merge_branches = config.merge.branches

            if not self.merge_branches:
                log.error('Config merge.branches must be configured with a list of branches to merge to, or '
                          'use --merge-branches to provide a list')
                sys.exit(1)

            branches = self.merge_branches.split()

            if current not in branches:
                log.error('Current branch %s not found in config merge.branches (%s)', current, self.merge_branches)
                sys.exit(1)

            last = current
            downstream_branches = branches[branches.index(last) + 1:]

            if not downstream_branches:
                click.echo('You are currently on the last branch, so no downstream branches to merge.')
                click.echo('Switch to the branch that you want to merge from first, and then re-run')
                sys.exit(0)

            for branch in downstream_branches:
                checkout_branch(branch)

                commits = self._unmerged_commits(repo, last, branch)

                if self.quiet and not commits:
                    last = branch
                    continue

                click.echo('Merging {} into {}'.format(last, branch))

                if not self.skip_update:
                    self.commander.run('update', quiet=True)

                if self.dry_run:
                    self.get_unmerged_commits(repo, last, branch)

                else:
                    if self.allow_commits:
                        if commits:
                            for commit in commits.split('\n'):
                                # Not performant / ok as # of allow_commits should be low
                                allowed_commit = (' Merge branch ' in commit
                                                  or ' Merge pull request ' in commit
                                                  or any(allow_commit in commit for allow_commit in self.allow_commits))
                                if not allowed_commit:
                                    click.echo('Found a commit that was not allowed to be merged:'.format(last))
                                    click.echo('  {}'.format(commit))
                                    raise NotAllowedCommit(commit)

                    self.merge_commits(last, commits, self.skip_commits)

                    if self.validation:
                        process_run(self.validation)

                    if self.validation:
                      process_run(self.validation)

                    self.commander.run('push', all_remotes=True, skip_style_check=True)

                last = branch

        else:
            log.error(
                'Please specify either a branch to merge from or --downstreams to merge to all downstream branches')
            sys.exit(1)
예제 #8
0
    def run(self):
        current = current_branch()
        repo = git.Repo(path=repo_path())

        if self.branch and self.downstreams:
            log.error('Branch and --downstreams are mutually exclusive. Please use one or the other.')
            sys.exit(1)

        if repo.is_dirty(untracked_files=True):
            log.error('Your repo has untracked or modified files in working dir or in staging index. Please cleanup before doing merge')
            sys.exit(1)

        if not self.skip_update:
          self.commander.run('update', quiet=True)

        if self.branch:
            click.echo('Merging {} into {}'.format(self.branch, current))

            if self.dry_run:
                self.show_unmerged_commits(repo, self.branch, current)
            else:
                if not self.skip_update:
                    checkout_branch(self.branch)
                    self.commander.run('update', quiet=True)
                    checkout_branch(current)
                merge_branch(self.branch, strategy=self.strategy)

        elif self.downstreams:
            if not self.merge_branches:
                self.merge_branches = config.merge.branches

            if not self.merge_branches:
                log.error('Config merge.branches must be configured with a list of branches to merge to, or '
                          'use --merge-branches to provide a list')
                sys.exit(1)

            branches = self.merge_branches.split()
            if current not in branches:
                log.error('Current branch %s not found in config merge.branches (%s)', current, self.merge_branches)
                sys.exit(1)

            last = current
            downstream_branches = branches[branches.index(last)+1:]

            if not downstream_branches:
                click.echo('You are currently on the last branch, so no downstream branches to merge.')
                click.echo('Switch to the branch that you want to merge from first, and then re-run')
                sys.exit(0)

            for branch in downstream_branches:
                checkout_branch(branch)

                commits = self._unmerged_commits(repo, last, branch)

                if self.quiet and not commits:
                    last = branch
                    continue

                click.echo('Merging {} into {}'.format(last, branch))

                if not self.skip_update:
                    self.commander.run('update', quiet=True)

                if self.dry_run:
                    self.show_unmerged_commits(repo, last, branch)

                else:
                    if self.allow_commits:
                        if commits:
                            for commit in commits.split('\n'):
                                # Not performant / ok as # of allow_commits should be low
                                allowed_commit = (' Merge branch ' in commit
                                                  or ' Merge pull request ' in commit
                                                  or any(allow_commit in commit for allow_commit in self.allow_commits))
                                if not allowed_commit:
                                    click.echo('Found a commit that was not allowed to be merged:'.format(last))
                                    click.echo('  {}'.format(commit))
                                    raise NotAllowedCommit(commit)

                    merge_branch(last, strategy=self.strategy)

                    if self.validation:
                      process_run(self.validation)

                    self.commander.run('push', all_remotes=True, skip_style_check=True)

                last = branch

        else:
            log.error('Please specify either a branch to merge from or --downstreams to merge to all downstream branches')
            sys.exit(1)
예제 #9
0
    def run(self):
        if self.discard or self.move:
            if not self.branch:
                if self.discard:
                    self.branch = current_branch()
                else:
                    self.branch = self.move[0]

            is_child_branch = base_branch = parent_branch(self.branch)

            if self.discard:
                changes = commit_logs(self.discard) if not is_child_branch else diff_branch(self.branch,
                                                                                            left_branch=base_branch)
            else:
                changes = commit_logs(1)
            changes = [_f for _f in changes.split('commit ') if _f]

            if self.discard and len(changes) <= self.discard and is_child_branch:
                checkout_branch(base_branch)
                remove_branch(self.branch, raises=True, force=True)

            else:
                match = re.match('([a-f0-9]+)(?: \(.*\))\n', changes[0])

                if match:
                    last_commit = match.group(1)

                    if self.move:
                        cur_branch = current_branch()
                        create_branch(self.branch)
                        checkout_branch(cur_branch)
                        click.echo('Moved {} to {}'.format(last_commit[:7], self.branch))
                        hard_reset(last_commit + '~1')

                    else:
                        checkout_branch(self.branch)
                        hard_reset(last_commit + '~' + str(self.discard))

                else:
                    log.error('Odd. No commit hash found in: %s', changes[0])

        else:
            if not self.skip_style_check and (self.test or self.push) and self.commander.command('test').supports_style_check():
                click.echo('Checking style')
                self.commander.run('test', env_or_file=['style'], silent=2)

            test_output = None

            if not (self.msg or self.amend):
                self.msg = prompt_with_editor('Please provide a commit message. Empty message will cancel the commit.')
                if not self.msg:
                    sys.exit()

            if not self.amend and self.test:
                click.echo('Running tests')
                test_output = self.commander.run('test', return_output=False, test_dependents=self.test > 1)

            branches = all_branches()
            cur_branch = branches and branches[0]

            if (not (self.push or self.amend) and config.commit.commit_branch_indicator not in cur_branch and
                    not self.branch and self.msg and config.commit.auto_branch_from_commit_words):
                self.branch = self._branch_for_msg(self.msg,
                                                   words=config.commit.auto_branch_from_commit_words,
                                                   branches=branches)
                if cur_branch:
                    self.branch = '{}@{}'.format(self.branch, cur_branch)

            if self.branch:
                if branches:
                    if self.branch in branches:
                        if self.branch != cur_branch:
                            checkout_branch(self.branch)

                    else:
                        create_branch(self.branch, cur_branch)

                else:  # Empty repo without a commit has no branches
                    create_branch(self.branch)

            add_files(files=self.files)
            local_commit(self.msg, self.amend)

            if self.amend and self.test:
                if self.commander.command('test').supports_style_check():
                    click.echo('Running style check')
                    self.commander.run('test', env_or_file=['style'], silent=2)

                click.echo('Running tests')
                test_output = self.commander.run('test', return_output=False, test_dependents=self.test > 1)

            if self.push:
                self.commander.run('push', branch=self.branch, force=self.amend, skip_style_check=True, all_remotes=int(self.push) > 1)

            return test_output