Esempio n. 1
0
 def log(self, opts):
     """[<repo>]
        Display GitLab log for a repository"""
     repo = self.repository(opts)
     if not repo:
         return
     now = datetime.datetime.now()
     for event in reversed(repo.Event()):
         ts = datetime.datetime.strptime(event.created_at,
                                         '%Y-%m-%dT%H:%M:%S.%fZ')
         event.data = event.data or {}
         if ts.year == now.year:
             if (ts.month, ts.day) == (now.month, now.day):
                 ts = wrap(ts.strftime("%H:%M"), attr.faint)
             else:
                 ts = wrap(ts.strftime("%m/%d %H:%M"), attr.faint)
         else:
             ts = wrap(ts.strftime("%Y/%m/%d %H:%M"), attr.faint)
         if event.action_name == 'joined':
             print('%s %s joined' % (ts, event.author_username))
         elif event.target_type == 'Issue':
             issue = glapi.ProjectIssue(self.gl,
                                        event.target_id,
                                        project_id=event.project_id)
             print('%s %s %s issue %s (%s)' %
                   (ts, event.author_username, event.action_name, issue.iid,
                    issue.title))
         elif event.target_type == 'MergeRequest':
             issue = glapi.ProjectMergeRequest(self.gl,
                                               event.target_id,
                                               project_id=event.project_id)
             print('%s %s %s merge request %s (%s)' %
                   (ts, event.author_username, event.action_name, issue.iid,
                    issue.title))
         elif event.target_type == 'Note':
             print('%s %s created a comment' % (ts, event.author_username))
         elif 'total_commits_count' in event.data:
             if event.data['total_commits_count'] == 0:
                 print('%s %s deleted branch %s' %
                       (ts, event.author_username, event.data['ref'][11:]))
             else:
                 print('%s %s pushed %s commits to %s' %
                       (ts, event.author_username,
                        event.data['total_commits_count'],
                        event.data['ref'][11:]))
         elif 'ref' in event.data:
             print('%s %s created tag %s' %
                   (ts, event.author_username, event.data['ref'][10:]))
         else:
             print(
                 wrap(
                     "Cannot display event. Please file a bug at github.com/seveas/git-spindle\nincluding the following output:",
                     attr.bright))
             pprint(event.json())
Esempio n. 2
0
    def merge_request(self, opts):
        """[--yes] [<yours:theirs>]
           Opens a merge request to merge your branch to an upstream branch"""
        repo = self.repository(opts)
        parent = self.parent_repo(repo) or repo
        # Which branch?
        src = opts['<yours:theirs>'] or ''
        dst = None
        if ':' in src:
            src, dst = src.split(':', 1)
        if not src:
            src = self.gitm('rev-parse', '--abbrev-ref', 'HEAD').stdout.strip()
        if not dst:
            dst = parent.default_branch

        if src == dst and parent == repo:
            err("Cannot file a merge request on the same branch")

        # Try to get the local commit
        commit = self.gitm('show-ref', 'refs/heads/%s' % src).stdout.split()[0]
        # Do they exist on GitLab?
        try:
            srcb = repo.Branch(src)
        except glapi.GitlabGetError:
            srcb = None
            if self.question(
                    "Branch %s does not exist in your GitLab repo, shall I push?"
                    % src):
                self.gitm('push', repo.remote, src, redirect=False)
            else:
                err("Aborting")
        if srcb and srcb.commit.id != commit:
            # Have we diverged? Then there are commits that are reachable from the GitLab branch but not local
            diverged = self.gitm('rev-list', srcb.commit.id, '^' + commit)
            if diverged.stderr or diverged.stdout:
                if self.question(
                        "Branch %s has diverged from GitLab, shall I push and overwrite?"
                        % src,
                        default=False):
                    self.gitm('push',
                              '--force',
                              repo.remote,
                              src,
                              redirect=False)
                else:
                    err("Aborting")
            else:
                if self.question(
                        "Branch %s not up to date on GitLab, but can be fast forwarded, shall I push?"
                        % src):
                    self.gitm('push', repo.remote, src, redirect=False)
                else:
                    err("Aborting")

        dstb = parent.Branch(dst)
        if not dstb:
            err("Branch %s does not exist in %s/%s" %
                (dst, parent.namespace.path, parent.path))

        # Do we have the dst locally?
        for remote in self.gitm('remote').stdout.strip().split("\n"):
            url = self.gitm('config', 'remote.%s.url' % remote).stdout.strip()
            if url in [parent.ssh_url_to_repo, parent.http_url_to_repo]:
                if not parent.public and url != parent.ssh_url_to_repo:
                    err("You should configure %s/%s to fetch via ssh, it is a private repo"
                        % (parent.namespace.path, parent.path))
                self.gitm('fetch', remote, redirect=False)
                break
        else:
            err("You don't have %s/%s configured as a remote repository" %
                (parent.namespace.path, parent.path))

        # How many commits?
        accept_empty_body = False
        commits = try_decode(
            self.gitm('log', '--pretty=%H', '%s/%s..%s' %
                      (remote, dst, src)).stdout).strip().split()
        commits.reverse()
        if not commits:
            err("Your branch has no commits yet")

        # 1 commit: title/body from commit
        if len(commits) == 1:
            title, body = self.gitm(
                'log', '--pretty=%s\n%b',
                '%s^..%s' % (commits[0], commits[0])).stdout.split('\n', 1)
            title = title.strip()
            body = body.strip()
            accept_empty_body = not bool(body)

        # More commits: title from branchname (titlecased, s/-/ /g), body comments from shortlog
        else:
            title = src
            if '/' in title:
                title = title[title.rfind('/') + 1:]
            title = title.title().replace('-', ' ')
            body = ""

        body += """
# Requesting a merge from %s/%s into %s/%s
#
# Please enter a message to accompany your merge request. Lines starting
# with '#' will be ignored, and an empty message aborts the request.
#""" % (repo.namespace.path, src, parent.namespace.path, dst)
        body += "\n# " + try_decode(
            self.gitm('shortlog', '%s/%s..%s' %
                      (remote, dst, src)).stdout).strip().replace(
                          '\n', '\n# ')
        body += "\n#\n# " + try_decode(
            self.gitm('diff', '--stat', '%s^..%s' %
                      (commits[0], commits[-1])).stdout).strip().replace(
                          '\n', '\n#')
        title, body = self.edit_msg("%s\n\n%s" % (title, body),
                                    'MERGE_REQUEST_EDIT_MSG')
        if not body and not accept_empty_body:
            err("No merge request message specified")

        try:
            merge = glapi.ProjectMergeRequest(
                self.gl, {
                    'project_id': repo.id,
                    'target_project_id': parent.id,
                    'source_branch': src,
                    'target_branch': dst,
                    'title': title,
                    'description': body
                })
            merge.save()
            print("merge request %d created %s" %
                  (merge.iid, self.merge_url(merge)))
        except:
            filename = self.backup_message(title, body,
                                           'merge-request-message-')
            err("Failed to create a merge request, the merge request text has been saved in %s"
                % filename)