def format_commit_lines(web_url, repo, base, tip):
    # type: (str, repo, int, int) -> str
    """
    Format the per-commit information for the message, including the one-line
    commit summary and a link to the diff if a web URL has been configured:
    """
    if web_url:
        rev_base_url = web_url.rstrip("/") + "/rev/"

    commit_summaries = []
    for rev in range(base, tip):
        rev_node = repo.changelog.node(rev)
        rev_ctx = repo.changectx(rev_node)
        one_liner = rev_ctx.description().split("\n")[0]

        if web_url:
            summary_url = rev_base_url + str(rev_ctx)
            summary = "* [{summary}]({url})".format(summary=one_liner,
                                                    url=summary_url)
        else:
            summary = "* {summary}".format(summary=one_liner)

        commit_summaries.append(summary)

    return "\n".join(summary for summary in commit_summaries)
예제 #2
0
def format_commit_lines(web_url, repo, base, tip):
    # type: (str, repo, int, int) -> str
    """
    Format the per-commit information for the message, including the one-line
    commit summary and a link to the diff if a web URL has been configured:
    """
    if web_url:
        rev_base_url = web_url.rstrip("/") + "/rev/"

    commit_summaries = []
    for rev in range(base, tip):
        rev_node = repo.changelog.node(rev)
        rev_ctx = repo.changectx(rev_node)
        one_liner = rev_ctx.description().split("\n")[0]

        if web_url:
            summary_url = rev_base_url + str(rev_ctx)
            summary = "* [{summary}]({url})".format(
                summary=one_liner, url=summary_url)
        else:
            summary = "* {summary}".format(summary=one_liner)

        commit_summaries.append(summary)

    return "\n".join(summary for summary in commit_summaries)
예제 #3
0
def get_filechanges(repo,revision,parents,mleft):
  """Given some repository and revision, find all changed/deleted files."""
  l,c,r=[],[],[]
  for p in parents:
    if p<0: continue
    mright=repo.changectx(p).manifest()
    l,c,r=split_dict(mleft,mright,l,c,r)
  l.sort()
  c.sort()
  r.sort()
  return l,c,r
예제 #4
0
파일: hg2git.py 프로젝트: andreif/hg2git
def get_filechanges(repo,revision,parents,mleft):
  """Given some repository and revision, find all changed/deleted files."""
  l,c,r=[],[],[]
  for p in parents:
    if p<0: continue
    mright=repo.changectx(p).manifest()
    dleft=mleft.keys()
    dleft.sort()
    dright=mright.keys()
    dright.sort()
    l,c,r=outer_set(mleft,mright,l,c,r)
  return l,c,r
예제 #5
0
def get_filechanges(repo, revision, parents, mleft):
    """Given some repository and revision, find all changed/deleted files."""
    l, c, r = [], [], []
    for p in parents:
        if p < 0: continue
        mright = repo.changectx(p).manifest()
        dleft = mleft.keys()
        dleft.sort()
        dright = mright.keys()
        dright.sort()
        l, c, r = outer_set(mleft, mright, l, c, r)
    return l, c, r
예제 #6
0
    def get_property_pages(self, vfs_files):
        if len(vfs_files) != 1:
            return
        file = vfs_files[0]
        path = self.get_path_for_vfs_file(file)
        if path is None or file.is_directory():
            return
        repo = self.get_repo_for_path(path)
        if repo is None:
            return

        localpath = path[len(repo.root) + 1 :]
        emblem, status = self._get_file_status(repo, localpath)

        # Get the information from Mercurial
        ctx = repo.workingctx().parents()[0]
        try:
            fctx = ctx.filectx(localpath)
            rev = fctx.filelog().linkrev(fctx.filenode())
        except:
            rev = ctx.rev()
        ctx = repo.changectx(rev)
        node = short(ctx.node())
        date = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(ctx.date()[0]))
        parents = "\n".join([short(p.node()) for p in ctx.parents()])
        description = ctx.description()
        user = ctx.user()
        user = gobject.markup_escape_text(user)
        tags = ", ".join(ctx.tags())
        branch = ctx.branch()

        self.property_label = gtk.Label("Mercurial")

        table = gtk.Table(7, 2, False)
        table.set_border_width(5)
        table.set_row_spacings(5)
        table.set_col_spacings(5)

        self.__add_row(table, 0, "<b>Status</b>:", status)
        self.__add_row(table, 1, "<b>Last-Commit-Revision</b>:", str(rev))
        self.__add_row(table, 2, "<b>Last-Commit-Description</b>:", description)
        self.__add_row(table, 3, "<b>Last-Commit-Date</b>:", date)
        self.__add_row(table, 4, "<b>Last-Commit-User</b>:", user)
        if tags:
            self.__add_row(table, 5, "<b>Tags</b>:", tags)
        if branch != "default":
            self.__add_row(table, 6, "<b>Branch</b>:", branch)

        table.show()

        return (nautilus.PropertyPage("MercurialPropertyPage::status", self.property_label, table),)
예제 #7
0
def export_commit(ui,repo,revision,old_marks,max,count,authors,sob,brmap):
  def get_branchname(name):
    if brmap.has_key(name):
      return brmap[name]
    n=sanitize_name(name)
    brmap[name]=n
    return n

  (revnode,_,user,(time,timezone),files,desc,branch,_)=get_changeset(ui,repo,revision,authors)

  branch=get_branchname(branch)

  parents = [p for p in repo.changelog.parentrevs(revision) if p >= 0]

  if len(parents)==0 and revision != 0:
    wr('reset refs/heads/%s' % branch)

  wr('commit refs/heads/%s' % branch)
  wr('mark :%d' % (revision+1))
  if sob:
    wr('author %s %d %s' % (get_author(desc,user,authors),time,timezone))
  wr('committer %s %d %s' % (user,time,timezone))
  wr('data %d' % (len(desc)+1)) # wtf?
  wr(desc)
  wr()


  # Sort the parents based on revision ids so that we always get the
  # same resulting git repo, no matter how the revisions were
  # numbered.
  parents.sort(key=repo.changelog.node, reverse=True)

  ctx=repo.changectx(str(revision))
  man=ctx.manifest()
  added,changed,removed,type=[],[],[],''

  if len(parents) == 0:
    # first revision: feed in full manifest
    added=man.keys()
    added.sort()
    type='full'
  else:
    wr('from %s' % revnum_to_revref(parents[0], old_marks))
    if len(parents) == 1:
      # later non-merge revision: feed in changed manifest
      # if we have exactly one parent, just take the changes from the
      # manifest without expensively comparing checksums
      f=repo.status(repo.lookup(parents[0]),revnode)[:3]
      added,changed,removed=f[1],f[0],f[2]
      type='simple delta'
    else: # a merge with two parents
      wr('merge %s' % revnum_to_revref(parents[1], old_marks))
      # later merge revision: feed in changed manifest
      # for many files comparing checksums is expensive so only do it for
      # merges where we really need it due to hg's revlog logic
      added,changed,removed=get_filechanges(repo,revision,parents,man)
      type='thorough delta'

  sys.stderr.write('%s: Exporting %s revision %d/%d with %d/%d/%d added/changed/removed files\n' %
      (branch,type,revision+1,max,len(added),len(changed),len(removed)))

  map(lambda r: wr('D %s' % r),removed)
  export_file_contents(ctx,man,added)
  export_file_contents(ctx,man,changed)
  wr()

  return checkpoint(count)
def hook(ui, repo, **kwargs):
    # type: (ui, repo, **Text) -> None
    """
    Invoked by configuring a [hook] entry in .hg/hgrc.
    """
    hooktype = kwargs["hooktype"]
    node = kwargs["node"]

    ui.debug("Zulip: received {hooktype} event\n".format(hooktype=hooktype))

    if hooktype != "changegroup":
        ui.warn("Zulip: {hooktype} not supported\n".format(hooktype=hooktype))
        sys.exit(1)

    ctx = repo.changectx(node)
    branch = ctx.branch()

    # If `branches` isn't specified, notify on all branches.
    branch_whitelist = get_config(ui, "branches")
    branch_blacklist = get_config(ui, "ignore_branches")

    if branch_whitelist:
        # Only send notifications on branches we are watching.
        watched_branches = [
            b.lower().strip() for b in branch_whitelist.split(",")
        ]
        if branch.lower() not in watched_branches:
            ui.debug(
                "Zulip: ignoring event for {branch}\n".format(branch=branch))
            sys.exit(0)

    if branch_blacklist:
        # Don't send notifications for branches we've ignored.
        ignored_branches = [
            b.lower().strip() for b in branch_blacklist.split(",")
        ]
        if branch.lower() in ignored_branches:
            ui.debug(
                "Zulip: ignoring event for {branch}\n".format(branch=branch))
            sys.exit(0)

    # The first and final commits in the changeset.
    base = repo[node].rev()
    tip = len(repo)

    email = get_config(ui, "email")
    api_key = get_config(ui, "api_key")
    site = get_config(ui, "site")

    if not (email and api_key):
        ui.warn("Zulip: missing email or api_key configurations\n")
        ui.warn("in the [zulip] section of your .hg/hgrc.\n")
        sys.exit(1)

    stream = get_config(ui, "stream")
    # Give a default stream if one isn't provided.
    if not stream:
        stream = "commits"

    web_url = get_config(ui, "web_url")
    user = ctx.user()
    content = format_summary_line(web_url, user, base, tip, branch, node)
    content += format_commit_lines(web_url, repo, base, tip)

    subject = branch

    ui.debug("Sending to Zulip:\n")
    ui.debug(content + "\n")

    send_zulip(email, api_key, site, stream, subject, content)
예제 #9
0
def export_commit(ui,repo,revision,marks,mapping,heads,last,max,count,authors,sob,brmap):
  def get_branchname(name):
    if brmap.has_key(name):
      return brmap[name]
    n=sanitize_name(name)
    brmap[name]=n
    return n

  (revnode,_,user,(time,timezone),files,desc,branch,_)=get_changeset(ui,repo,revision,authors)
  parents=repo.changelog.parentrevs(revision)

  branch=get_branchname(branch)

  wr('commit refs/heads/%s' % branch)
  wr('mark :%d' % (revision+1))
  if sob:
    wr('author %s %d %s' % (get_author(desc,user,authors),time,timezone))
  wr('committer %s %d %s' % (user,time,timezone))
  wr('data %d' % (len(desc)+1)) # wtf?
  wr(desc)
  wr()

  pidx1, pidx2 = 0, 1
  if parents[0] < parents[1]:
    pidx1, pidx2 = 1, 0

  src=heads.get(branch,'')
  link=''
  if src!='':
    # if we have a cached head, this is an incremental import: initialize it
    # and kill reference so we won't init it again
    wr('from %s' % src)
    heads[branch]=''
    sys.stderr.write('%s: Initializing to parent [%s]\n' %
        (branch,src))
    link=src # avoid making a merge commit for incremental import
  elif link=='' and not heads.has_key(branch) and revision>0:
    # newly created branch and not the first one: connect to parent
    tmp=get_parent_mark(parents[0],marks)
    wr('from %s' % tmp)
    sys.stderr.write('%s: Link new branch to parent [%s]\n' %
        (branch,tmp))
    link=tmp # avoid making a merge commit for branch fork
  elif last.get(branch,revision) != parents[pidx1] and parents[pidx1] > 0 and revision > 0:
    pm=get_parent_mark(parents[pidx1],marks)
    sys.stderr.write('%s: Placing commit [r%d] in branch [%s] on top of [r%d]\n' %
        (branch,revision,branch,parents[pidx1]));
    wr('from %s' % pm)

  if parents[pidx2] > 0:
    pm=get_parent_mark(parents[pidx2],marks)
    sys.stderr.write('%s: Merging with parent [%s] from [r%d]\n' %
        (branch,pm,parents[pidx2]))
    wr('merge %s' % pm)

  last[branch]=revision
  heads[branch]=''
  # we need this later to write out tags
  marks[str(revision)]=':%d'%(revision+1)

  ctx=repo.changectx(str(revision))
  man=ctx.manifest()
  added,changed,removed,type=[],[],[],''

  if revision==0:
    # first revision: feed in full manifest
    added=man.keys()
    added.sort()
    type='full'
  elif is_merge(parents):
    # later merge revision: feed in changed manifest
    # for many files comparing checksums is expensive so only do it for
    # merges where we really need it due to hg's revlog logic
    added,changed,removed=get_filechanges(repo,revision,parents,man)
    type='thorough delta'
  else:
    # later non-merge revision: feed in changed manifest
    # if we have exactly one parent, just take the changes from the
    # manifest without expensively comparing checksums
    f=repo.status(repo.lookup(parents[0]),revnode)[:3]
    added,changed,removed=f[1],f[0],f[2]
    type='simple delta'

  sys.stderr.write('%s: Exporting %s revision %d/%d with %d/%d/%d added/changed/removed files\n' %
      (branch,type,revision+1,max,len(added),len(changed),len(removed)))

  map(lambda r: wr('D %s' % r),removed)
  export_file_contents(ctx,man,added)
  export_file_contents(ctx,man,changed)
  wr()

  return checkpoint(count)
예제 #10
0
파일: hg2git.py 프로젝트: andreif/hg2git
def export_commit(ui,repo,revision,marks,heads,last,max,count,authors,sob):
  (revnode,_,user,(time,timezone),files,desc,branch,_)=get_changeset(ui,repo,revision,authors)
  parents=repo.changelog.parentrevs(revision)

  wr('commit refs/heads/%s' % branch)
  wr('mark :%d' % (revision+1))
  if sob:
    wr('author %s %d %s' % (get_author(desc,user,authors),time,timezone))
  wr('committer %s %d %s' % (user,time,timezone))
  wr('data %d' % (len(desc)+1)) # wtf?
  wr(desc)
  wr()

  src=heads.get(branch,'')
  link=''
  if src!='':
    # if we have a cached head, this is an incremental import: initialize it
    # and kill reference so we won't init it again
    wr('from %s' % src)
    heads[branch]=''
    sys.stderr.write('Initializing branch [%s] to parent [%s]\n' %
        (branch,src))
    link=src # avoid making a merge commit for incremental import
  elif link=='' and not heads.has_key(branch) and revision>0:
    # newly created branch and not the first one: connect to parent
    tmp=get_parent_mark(parents[0],marks)
    wr('from %s' % tmp)
    sys.stderr.write('Link new branch [%s] to parent [%s]\n' %
        (branch,tmp))
    link=tmp # avoid making a merge commit for branch fork

  if parents:
    l=last.get(branch,revision)
    for p in parents:
      # 1) as this commit implicitely is the child of the most recent
      #    commit of this branch, ignore this parent
      # 2) ignore nonexistent parents
      # 3) merge otherwise
      if p==l or p==revision or p<0:
        continue
      tmp=get_parent_mark(p,marks)
      # if we fork off a branch, don't merge with our parent via 'merge'
      # as we have 'from' already above
      if tmp==link:
        continue
      sys.stderr.write('Merging branch [%s] with parent [%s] from [r%d]\n' %
          (branch,tmp,p))
      wr('merge %s' % tmp)

  last[branch]=revision
  heads[branch]=''
  # we need this later to write out tags
  marks[str(revision)]=':%d'%(revision+1)

  ctx=repo.changectx(str(revision))
  man=ctx.manifest()
  added,changed,removed,type=[],[],[],''

  if revision==0:
    # first revision: feed in full manifest
    added=man.keys()
    type='full'
  elif is_merge(parents):
    # later merge revision: feed in changed manifest
    # for many files comparing checksums is expensive so only do it for
    # merges where we really need it due to hg's revlog logic
    added,changed,removed=get_filechanges(repo,revision,parents,man)
    type='thorough delta'
  else:
    # later non-merge revision: feed in changed manifest
    # if we have exactly one parent, just take the changes from the
    # manifest without expensively comparing checksums
    f=repo.status(repo.lookup(parents[0]),revnode)[:3]
    added,changed,removed=f[1],f[0],f[2]
    type='simple delta'

  sys.stderr.write('Exporting %s revision %d/%d with %d/%d/%d added/changed/removed files\n' %
      (type,revision+1,max,len(added),len(changed),len(removed)))

  map(lambda r: wr('D %s' % r),removed)
  export_file_contents(ctx,man,added+changed)
  wr()

  return checkpoint(count)
예제 #11
0
def hook(ui, repo, **kwargs):
    # type: (ui, repo, Optional[Text]) -> None
    """
    Invoked by configuring a [hook] entry in .hg/hgrc.
    """
    hooktype = kwargs["hooktype"]
    node = kwargs["node"]

    ui.debug("Zulip: received {hooktype} event\n".format(hooktype=hooktype))

    if hooktype != "changegroup":
        ui.warn("Zulip: {hooktype} not supported\n".format(hooktype=hooktype))
        exit(1)

    ctx = repo.changectx(node)
    branch = ctx.branch()

    # If `branches` isn't specified, notify on all branches.
    branch_whitelist = get_config(ui, "branches")
    branch_blacklist = get_config(ui, "ignore_branches")

    if branch_whitelist:
        # Only send notifications on branches we are watching.
        watched_branches = [b.lower().strip() for b in branch_whitelist.split(",")]
        if branch.lower() not in watched_branches:
            ui.debug("Zulip: ignoring event for {branch}\n".format(branch=branch))
            exit(0)

    if branch_blacklist:
        # Don't send notifications for branches we've ignored.
        ignored_branches = [b.lower().strip() for b in branch_blacklist.split(",")]
        if branch.lower() in ignored_branches:
            ui.debug("Zulip: ignoring event for {branch}\n".format(branch=branch))
            exit(0)

    # The first and final commits in the changeset.
    base = repo[node].rev()
    tip = len(repo)

    email = get_config(ui, "email")
    api_key = get_config(ui, "api_key")
    site = get_config(ui, "site")

    if not (email and api_key):
        ui.warn("Zulip: missing email or api_key configurations\n")
        ui.warn("in the [zulip] section of your .hg/hgrc.\n")
        exit(1)

    stream = get_config(ui, "stream")
    # Give a default stream if one isn't provided.
    if not stream:
        stream = "commits"

    web_url = get_config(ui, "web_url")
    user = ctx.user()
    content = format_summary_line(web_url, user, base, tip, branch, node)
    content += format_commit_lines(web_url, repo, base, tip)

    subject = branch

    ui.debug("Sending to Zulip:\n")
    ui.debug(content + "\n")

    send_zulip(email, api_key, site, stream, subject, content)
예제 #12
0
def export_commit(ui, repo, revision, marks, heads, last, max, count, authors,
                  sob):
    (revnode, _, user, (time, timezone), files, desc, branch,
     _) = get_changeset(ui, repo, revision, authors)
    parents = repo.changelog.parentrevs(revision)

    wr('commit refs/heads/%s' % branch)
    wr('mark :%d' % (revision + 1))
    if sob:
        wr('author %s %d %s' %
           (get_author(desc, user, authors), time, timezone))
    wr('committer %s %d %s' % (user, time, timezone))
    wr('data %d' % (len(desc) + 1))  # wtf?
    wr(desc)
    wr()

    src = heads.get(branch, '')
    link = ''
    if src != '':
        # if we have a cached head, this is an incremental import: initialize it
        # and kill reference so we won't init it again
        wr('from %s' % src)
        heads[branch] = ''
        sys.stderr.write('Initializing branch [%s] to parent [%s]\n' %
                         (branch, src))
        link = src  # avoid making a merge commit for incremental import
    elif link == '' and not heads.has_key(branch) and revision > 0:
        # newly created branch and not the first one: connect to parent
        tmp = get_parent_mark(parents[0], marks)
        wr('from %s' % tmp)
        sys.stderr.write('Link new branch [%s] to parent [%s]\n' %
                         (branch, tmp))
        link = tmp  # avoid making a merge commit for branch fork

    if parents:
        l = last.get(branch, revision)
        for p in parents:
            # 1) as this commit implicitely is the child of the most recent
            #    commit of this branch, ignore this parent
            # 2) ignore nonexistent parents
            # 3) merge otherwise
            if p == l or p == revision or p < 0:
                continue
            tmp = get_parent_mark(p, marks)
            # if we fork off a branch, don't merge with our parent via 'merge'
            # as we have 'from' already above
            if tmp == link:
                continue
            sys.stderr.write(
                'Merging branch [%s] with parent [%s] from [r%d]\n' %
                (branch, tmp, p))
            wr('merge %s' % tmp)

    last[branch] = revision
    heads[branch] = ''
    # we need this later to write out tags
    marks[str(revision)] = ':%d' % (revision + 1)

    ctx = repo.changectx(str(revision))
    man = ctx.manifest()
    added, changed, removed, type = [], [], [], ''

    if revision == 0:
        # first revision: feed in full manifest
        added = man.keys()
        type = 'full'
    elif is_merge(parents):
        # later merge revision: feed in changed manifest
        # for many files comparing checksums is expensive so only do it for
        # merges where we really need it due to hg's revlog logic
        added, changed, removed = get_filechanges(repo, revision, parents, man)
        type = 'thorough delta'
    else:
        # later non-merge revision: feed in changed manifest
        # if we have exactly one parent, just take the changes from the
        # manifest without expensively comparing checksums
        f = repo.status(repo.lookup(parents[0]), revnode)[:3]
        added, changed, removed = f[1], f[0], f[2]
        type = 'simple delta'

    sys.stderr.write(
        'Exporting %s revision %d/%d with %d/%d/%d added/changed/removed files\n'
        % (type, revision + 1, max, len(added), len(changed), len(removed)))

    map(lambda r: wr('D %s' % r), removed)
    export_file_contents(ctx, man, added + changed)
    wr()

    return checkpoint(count)