Exemple #1
0
def do_cherry_pick(commit):
    cherry_options = config["cherry_options"]
    merge_commits = config["merge_commits"]

    if commit in merge_commits:
        cherry_options = cherry_options + ["-m", "1"]

    sys.stdout.write("Pick ")
    cmd = ['git', '--no-pager', 'log', '-1', '--pretty=format:%h %s\n', commit]
    git.call(cmd, stdout=sys.stdout)
    cmd = ["git", "cherry-pick", "-n"] + cherry_options + [commit]
    p = subprocess.Popen(cmd, stdout=sys.stdout, stderr=subprocess.PIPE)
    errmsg = p.stderr.read()
    rc = p.wait()
    if errmsg == 'Finished one cherry-pick.\n':
        return
    elif errmsg:
        resolved_file_lines = []
        for line in errmsg.splitlines(1):
            if line.startswith("Resolved ") or line.startswith("Staged "):
                resolved_file_lines.append(line)

        unmerged = unmerged_files()
        if unmerged or resolved_file_lines:
            if (resolved_file_lines):
                sys.stderr.writelines(resolved_file_lines)
            else:
                sys.stderr.write(unmerged)
            sys.stderr.write("Automatic cherry-pick failed.  ")
            output_resolve_msg_and_exit()

        sys.stderr.write(errmsg)

    if rc != 0:
        sys.exit(rc)
Exemple #2
0
def check_mv_headers(ids):
    no_mv_header_ids = []
    u = git.usage()

    for id in ids:
        commit = git.read_commit(id)
        h = commit.mv_header_dict
        if 'source' in h and 'mr' in h and 'type' in h and 'disposition' in h:
            continue
        no_mv_header_ids.append(id)

    if no_mv_header_ids:
        sys.stderr.write("The following commits have no MV header:\n")
        for id in no_mv_header_ids:
            cmd = ['git', '--no-pager', 'log', '-1', '--pretty=oneline', id]
            git.call(cmd, stdout=sys.stdout)
        sys.stderr.write("To cherry-pick commits without an MV header, "
                         "it is necessary to specify either\n"
                         "--edit or all of these options: \n"
                         "--source %s\n"
                         "--bugz, "
                         "--type %s\n"
                         "--disposition %s\n" %
                         (u.Source, u.Type, u.Disposition))
        sys.exit(1)
Exemple #3
0
def do_continue_or_skip():
    restore_state()
    merge_msg_filename = config["gitdir"] + "/MERGE_MSG"
    if os.path.isfile(merge_msg_filename):
        os.remove(merge_msg_filename)

    commits = config["commits"]
    commits_done = config["commits_done"]

    commit = commits[commits_done]
    cmd = ['git', '--no-pager', 'log', '-1', '--pretty=format:%h %s\n', commit]
    oneline = git.call(cmd).strip()
    if config["continue"]:
        sys.stdout.write("Continuing %s\n" % oneline)
        unmerged = unmerged_files()
        if unmerged:
            sys.stderr.write(unmerged)
            sys.stderr.write("Unmerged files.  ")
            output_resolve_msg_and_exit()
        do_commit(commit)
    else:
        cmd = ['git', 'reset', '--hard', 'HEAD^0']
        git.call(cmd, stdout=None)
        sys.stdout.write("Skipping %s\n" % oneline)
        config["skipped_commits"].append(commit)
    commits_done += 1
    config["commits_done"] = commits_done
    save_state()
Exemple #4
0
def signoff_limb():
    options = config["options"]
    limb1name = config["limb1"].rstrip("/")
    limb2name = config["limb2"].rstrip("/")

    if not limb2name:
        limb2name = git.current_limb().name

    limb1 = git.Limb.get(limb1name)
    if not limb1.exists():
        sys.stdout.write("%s: not found\n" % limb1name)
        sys.exit(1)

    limb2 = git.Limb.get(limb2name)
    if not limb2.exists():
        sys.stdout.write("%s: not found\n" % limb2name)
        sys.exit(1)

    limb1_subnames = git.subnames(limb1name)
    limb2_subnames = git.subnames(limb2name)

    signed_off_count = 0
    skipped_branchnames = []
    for subname in limb2_subnames:
        limb1_branchname = "%s/%s" % (limb1name, subname)
        limb2_branchname = "%s/%s" % (limb2name, subname)

        if subname.startswith("external."):
            continue

        if subname not in limb1_subnames:
            skipped_branchnames.append((limb1_branchname, limb2_branchname))
            continue

        limb1_branch = git.Branch.get(limb1_branchname)
        limb2_branch = git.Branch.get(limb2_branchname)
        if limb1_branch.id == limb2_branch.id:
            continue

        cmd = ['git', 'checkout', limb2_branchname]
        git.call(cmd, stdout=sys.stdout, verbose=True)

        cmd = ['git', 'signoff-mv'] + options + ['%s..' % limb1_branchname]

        # ignore the error return from git signoff-mv, until it's fixed
        git.call(cmd,
                 error=None,
                 stdout=sys.stdout,
                 stderr=sys.stderr,
                 verbose=True)

        signed_off_count += 1

    for limb1_branchname, limb2_branchname in skipped_branchnames:
        sys.stdout.write("%s not found, \n" % limb1_branchname)
        sys.stdout.write("  NOT signing off on commits in %s\n" %
                         limb2_branchname)
    else:
        if not signed_off_count:
            sys.stdout.write("No new commits to signoff.\n")
Exemple #5
0
def diff_limb():
    options = config["options"]
    limb1name = config["limb1"].rstrip("/")
    limb2name = config["limb2"].rstrip("/")
    paths = config["paths"]

    if not limb1name:
        limb1name = git.current_limb().name

    if not limb2name:
        limb2name = git.current_limb().name

    limb1 = git.Limb.get(limb1name)
    if not limb1.exists():
        sys.stdout.write("%s: not found\n" % limb1name)
        sys.exit(1)

    limb2 = git.Limb.get(limb2name)
    if not limb2.exists():
        sys.stdout.write("%s: not found\n" % limb2name)
        sys.exit(1)

    limb1_subnames = git.subnames(limb1name)
    limb2_subnames = git.subnames(limb2name)

    not_found = False
    diff_branches = []
    for subname in sorted(set(limb1_subnames + limb2_subnames)):
        branch1name = "%s/%s" % (limb1name, subname)
        branch2name = "%s/%s" % (limb2name, subname)
        if subname not in limb1_subnames:
            sys.stdout.write("WARNING, non-existent branch: %s\n" %
                             branch1name)
            not_found = True
            continue

        if subname not in limb2_subnames:
            sys.stdout.write("WARNING, non-existent branch: %s\n" %
                             branch2name)
            not_found = True
            continue

        branch1 = git.Branch.get(branch1name)
        branch2 = git.Branch.get(branch2name)
        if branch1.id == branch2.id:
            continue

        diff_branches.append([branch1name, branch2name])

    if not_found and diff_branches:
        sys.stdout.write("\n")

    for branch1name, branch2name in diff_branches:
        cmd = ['git', '--no-pager', 'diff'] + options
        cmd.append('%s..%s' % (branch1name, branch2name))
        cmd += paths

        git.call(cmd, stdout=sys.stdout, verbose=True)
Exemple #6
0
def move_commits_to_original_branch():
    branch = config["orig_branchname"]
    if branch != 'detached HEAD':
        cmd = ['git', 'rev-parse', 'HEAD^0']
        head = git.call(cmd).strip()
        message = "Cherry-pick finished"
        orig_head = config["orig_head"]
        cmd = ['git', 'update-ref', '-m', message, branch, head, orig_head]
        git.call(cmd)
Exemple #7
0
def git_list_dependencies():
    limbname = config["limb1"]
    if not limbname:
        limbname = git.current_limb().name

    branch_dep_ref = "%s/limb-info:MONTAVISTA/branch_dependencies" % limbname

    try:
        git.call(['git', 'show', branch_dep_ref], stdout=sys.stdout)
    except:
        sys.stderr.write("%s not found\n", branch_dep_ref)
        sys.exit(1)
Exemple #8
0
def do_abort():
    restore_state()

    merge_msg_filename = config["gitdir"] + "/MERGE_MSG"
    if os.path.isfile(merge_msg_filename):
        os.remove(merge_msg_filename)

    cleanup_state()
    checkout_original_branch()
    cmd = ['git', 'reset', '--hard']
    git.call(cmd, stdout=sys.stdout)

    sys.exit(0)
Exemple #9
0
def check_clean_state():
    cmd = ['git', 'update-index', '--refresh']
    try:
        git.call(cmd, stdout=sys.stdout)
    except:
        sys.exit(1)

    cmd = [
        'git', 'diff-index', '--cached', '--name-status', '-r', 'HEAD^0', '--'
    ]
    msg = git.call(cmd)
    if msg:
        sys.stdout.write("Your index is not up-to-date\n")
        sys.stdout.write(msg)
        sys.exit(1)
Exemple #10
0
def checkout_original_branch():
    if config["orig_branchname"] != 'detached HEAD':
        if not config["nocommit"]:
            cmd = ["git", "reset", "--hard"]
            git.call(cmd)
        prefix_len = len('refs/heads/')
        cmd = ["git", "checkout", config["orig_branchname"][prefix_len:]]
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE)
        errmsg = p.stderr.read()
        rc = p.wait()
        if 'Switched to branch ' not in errmsg:
            sys.stderr.write(errmsg)
        if rc != 0:
            sys.stdout.write('"git checkout %s" failed\n' %
                             config["orig_branchname"])
            sys.exit(1)
Exemple #11
0
def commit_mv():
    no_edit = opt["no-edit"]
    message_commit = opt["message-commit"]
    reset_author = opt["reset_author"]
    commit_options = opt["commit_options"]

    if message_commit and not reset_author:
        cmd = [
            'git', 'log', '-1', '--pretty=format:%an\n%ae\n%ai',
            message_commit.id
        ]
        a_name, a_email, a_date = git.call(cmd).splitlines()
        os.environ["GIT_AUTHOR_NAME"] = a_name
        os.environ["GIT_AUTHOR_EMAIL"] = a_email
        os.environ["GIT_AUTHOR_DATE"] = a_date

    if not no_edit:
        commit_options.append("-e")

    msg = commit_message()
    msgfile = tempfile.NamedTemporaryFile()
    msgfile.write(msg)
    msgfile.flush()

    commit_options += ["--file", msgfile.name]

    cmd = ['git', 'commit'] + commit_options
    commit = subprocess.Popen(cmd)
    rc = commit.wait()
    msgfile.close()

    if rc != 0:
        sys.exit(rc)

    validate_commit('HEAD^0')
Exemple #12
0
def move_to_detached_head():
    cmd = ['git', 'rev-parse', 'HEAD^0']
    orig_head = git.call(cmd).strip()
    config['orig_head'] = orig_head

    cmd = ['git', 'symbolic-ref', 'HEAD']
    orig_branchname = git.call(cmd, stderr=None, error=None).strip()
    if not orig_branchname:
        orig_branchname = 'detached HEAD'
    else:
        cmd = ['git', 'checkout', orig_head]
        try:
            git.call(cmd, stdout=None, stderr=None)
        except:
            sys.stderr.write("could not detach HEAD\n")
            sys.exit(1)
    config['orig_branchname'] = orig_branchname
Exemple #13
0
def git_pending_commits():
    left = config["left"]
    right = config["right"]
    with_rejects = config["with_rejects"]

    if right:
	right = git.Branch(right)
    else:
	right = git.current_branch()
    if left:
	left = git.Branch(left)

    if not left.id:
	sys.stderr.write("Invalid branch: %s\n" % left.name)
	sys.exit(1)

    if not right.id:
	sys.stderr.write("Invalid branch: %s\n" % right.name)
	sys.exit(1)

    left_base = left.upstream_version

    if not left_base:
	sys.stderr.write("Invalid upstream_version for %s\n" % left.name)
	sys.exit(1)

    commits = git.changeid_diff(left, right, with_rejects=with_rejects)

    if (not left.has_branch_merge_base() and commits
        and not commits[0].contains(left_base)):
	sys.stderr.write("Error: upstream version: %s\n"
	    "       is not a first-parent ancestor of:\n"
	    "       %s\n" % (left_base, left.name))
	sys.exit(1)

    if config["verbose"]:
	cmd = ["git", "--no-pager", "log", "-1", "--pretty=format:%h %s\n"]
	for commit in commits:
	    git.call(cmd + [commit.id], stdout=sys.stdout)
    else:
	for commit in commits:
	    sys.stdout.write("%s\n" % commit.id)
Exemple #14
0
def git_move_limb():
    force = config["force"]
    recursive = config["recursive"]

    if config["limb2"]:
        oldlimbname = config["limb1"]
        newlimbname = config["limb2"]
    else:
        oldlimbname = git.current_limb().name
        newlimbname = config["limb1"]

    oldlimb = git.Limb.get(oldlimbname)
    if not oldlimb.exists():
        if not oldlimbname:
            oldlimbname = '""'
        sys.stderr.write("%s: not found\n" % oldlimbname)
        sys.exit(1)

    newlimb = git.Limb.get(newlimbname)
    if newlimb.exists():
        if force:

            cmd = ['git', 'branch', '-D']
            cmd += git.branchnames(newlimbname, recursive=recursive)
            git.call(cmd, stdout=sys.stdout)
        else:
            sys.stderr.write("%s: already exists.  Use -M to overwrite.\n" %
                             newlimbname)
            sys.exit(1)

    if force:
        m_opt = "M"
    else:
        m_opt = "m"

    branchnames = git.branchnames(oldlimbname, recursive=recursive)
    subnames = [x[(len(oldlimbname) + 1):] for x in branchnames]
    for subname in subnames:
        old_name = "%s/%s" % (oldlimbname, subname)
        new_name = "%s/%s" % (newlimbname, subname)
        cmd = ['git', 'branch', '-%s' % m_opt, old_name, new_name]
        git.call(cmd, stdout=sys.stdout, verbose=True)
Exemple #15
0
def select_merge_commits(commits):
    merge_commits = {}

    cmd = ["git", "rev-list", "--no-walk", "--parents"] + commits
    parentlines = git.call(cmd, stderr=None).splitlines()
    for parentline in parentlines:
        ids = parentline.split()
        if len(ids) > 2:
            merge_commits[ids[0]] = True

    return merge_commits
Exemple #16
0
def git_delete_limb():
    limbname = config["limb1"]
    recursive = config["recursive"]

    limb = git.Limb.get(limbname)
    if not limb.exists():
        if not limbname:
            limbname = '""'
        sys.stderr.write("%s: not found\n" % limbname)
        sys.exit(1)

    limb_branches = git.branchnames(limbname, recursive=recursive)
    try:
        current_name = git.current_branch().name
        if current_name and current_name in limb_branches:
            sys.stderr.write("Cannot delete current branch: %s.\n" %
                             current_name)
            sys.exit(1)
    except git.GitError:
        pass

    cmd = ['git', 'branch', '-D'] + limb_branches
    git.call(cmd, stdout=sys.stdout, verbose=True)
Exemple #17
0
    def get_config(var, array=False, required=False):
        '''
	Return the value of the given git config variable
	'''
        try:
            val = git.call(['git', 'config', var]).strip()
            if array:
                val = [x.strip() for x in val.split(',')]
        except:
            if required:
                error('"Server missing config variable %s"\n' % var)
            if array:
                val = []
            else:
                val = ''

        return val
Exemple #18
0
def set_global_constants():
    '''
    Initialize several global contants used by this program
    '''

    global git_dir
    global progname

    progname, ext = os.path.splitext(os.path.basename(sys.argv[0]))

    if 'GIT_DIR' in os.environ:
        git_dir = os.path.abspath(os.environ['GIT_DIR'])
    else:
        cmd = ['git', 'rev-parse', '--git-dir']
        git_dir = git.call(cmd, error=None, stderr=None)
        if not git_dir:
            error('No git repository found\n')
Exemple #19
0
def cherry_pick_mv():
    set_gitdir()

    if config["abort"]:
        do_abort()

    if config["continue"] or config["skip"]:
        do_continue_or_skip()
    else:
        initialize_commits()

    commits = config["commits"]
    commits_done = config["commits_done"]

    for commit in commits[commits_done:]:
        do_cherry_pick(commit)

        do_commit(commit)

        commits_done += 1
        config["commits_done"] = commits_done

        save_state()

    if len(commits) > 1:
        if config["skipped_commits"]:
            count = len(config["skipped_commits"])
            if count == 1:
                str = "commit was"
            else:
                str = "%d commits were" % count
            sys.stderr.write("The following %s skipped:\n" % str)
            for commit in config["skipped_commits"]:
                cmd = [
                    'git', '--no-pager', 'log', '-1',
                    '--pretty=format:%h %s\n', commit
                ]
                oneline = git.call(cmd).rstrip()
                sys.stderr.write("    %s\n" % oneline)

    move_commits_to_original_branch()
    checkout_original_branch()
    cleanup_state()
Exemple #20
0
def set_global_constants():
    '''
    Initialize several global contants used by this program
    '''
    def get_config(var, array=False, required=False):
        '''
	Return the value of the given git config variable
	'''
        try:
            val = git.call(['git', 'config', var]).strip()
            if array:
                val = [x.strip() for x in val.split(',')]
        except:
            if required:
                error('"Server missing config variable %s"\n' % var)
            if array:
                val = []
            else:
                val = ''

        return val

    global git_dir
    global progname
    global debug_flag
    global gatekeeper_groups
    global gatekeepers
    global gitadmin_groups
    global gitadmins
    global email_recipients
    global user
    global project_desc
    global project_url
    global commit_url_fmt
    global bugz_url_fmt

    progname, ext = os.path.splitext(os.path.basename(sys.argv[0]))

    if 'GIT_DIR' in os.environ:
        git_dir = os.path.abspath(os.environ['GIT_DIR'])
        if git_dir.startswith(git_base_dir):
            rel_dir = git_dir[(len(git_base_dir) + 1):]
        else:
            rel_dir = git_dir
    else:
        usage()

    notice('\n')

    debug_flag = get_config('mvista.debug')

    if debug_flag != '0' and debug_flag != 'False' and debug_flag != 'off':
        debug_flag = True
        notice('%s\n' % progname)
    else:
        debug_flag = False

    gatekeeper_groups = get_config('mvista.gatekeeper-groups', array=True)
    gatekeepers = get_config('mvista.gatekeepers', array=True)
    gitadmin_groups = get_config('mvista.gitadmin-groups', array=True)
    gitadmins = get_config('mvista.gitadmins', array=True)
    email_recipients = get_config('mvista.dev.push-recipients',
                                  array=True,
                                  required=True)

    cmd = ['head', '-1', os.path.join(git_dir, "description")]
    project_desc = git.call(cmd, error=False).strip()

    if not project_desc or project_desc.startswith('Unnamed repository; edit'):
        notice('Warning: project description file not set on server\n')

    project_url = 'http://%s/?p=%s;a=summary' % (git_server, rel_dir)
    commit_url_fmt = 'http://%s/?p=%s;a=commitdiff;h=%%s' % \
   (git_server, rel_dir)
    bugz_url_fmt = 'http://%s/show_bug.cgi?id=%%s' % bugz_server

    user = git.User()

    check_errors()
Exemple #21
0
def push_limb():
    re_parent = re.compile(r'(.*)/bugfixes/\d+[^/]*')

    options = config["options"]
    repo = config["repo"]
    localname = config["local"].rstrip("/")
    remotename = config["remote"].rstrip("/")
    nofetch = config["nofetch"]

    if not remotename:
        if not localname:
            localname = git.current_limb().name
        remotename = localname

    if not localname or not nofetch:
        git.call(['git', 'fetch', repo], stdout=sys.stdout, verbose=True)
        git.call(['git', 'remote', 'prune', repo],
                 stdout=sys.stdout,
                 verbose=True)

    if not localname:
        remote_branchnames = git.branchnames("%s/%s" % (repo, remotename))
        if not remote_branchnames:
            sys.stdout.write("remote limb %s not found\n" % remotename)
            sys.exit(1)

        del_prefix_len = len(repo) + 1
        cmd = ['git', 'push'] + options + [repo]
        cmd += [":%s" % x[del_prefix_len:] for x in remote_branchnames]
        git.call(cmd, stdout=sys.stdout, verbose=True)
        return

    local = git.Limb.get(localname)
    if not local.exists():
        sys.stdout.write("local limb %s not found\n" % localname)
        sys.exit(1)

    if not nofetch:
        # call "git analyze-changes" before pushing
        cmd = ['git', 'analyze-changes', '-r', repo]
        if local != git.current_limb():
            cmd.append(localname)
        try:
            git.call(cmd, stdout=sys.stdout, verbose=True)
        except:
            sys.stderr.write(
                "git analyze-changes failed.  No branches pushed.\n")
            sys.exit(1)
        time.sleep(5)

    local_subnames = git.subnames(localname)

    nff_names = []
    rebased_names = []
    branchnames = []
    for subname in local_subnames:
        branchname = "%s/%s" % (localname, subname)
        repo_branchname = "%s/%s/%s" % (repo, remotename, subname)

        repo_branch = git.Branch.get(repo_branchname)
        branch = git.Branch.get(branchname)

        if repo_branch.id and repo_branch.id == branch.id:
            continue

        rebased = False
        match = re_parent.match(remotename)
        if match:
            parentname = match.group(1)
            parent_branchname = "%s/%s/%s" % (repo, parentname, subname)
            parent_branch = git.Branch.get(parent_branchname)
            rebased = parent_branch.id and not branch.contains(parent_branch)

        if rebased:
            rebased_names.append(branchname)
        elif repo_branch.id and not branch.contains(repo_branch):
            nff_names.append(branchname)

        if localname != remotename:
            branchname = "%s:%s" % (branchname, "%s/%s" %
                                    (remotename, subname))

        branchnames.append(branchname)

    force = "-f" in options or "--force" in options
    if rebased_names and not force:
        parentname = "%s/%s" % (repo, parentname)
        sys.stdout.write("\nNon-fast-forward when compared to %s:\n" %
                         parentname)
        for branchname in rebased_names:
            sys.stdout.write("    %s\n" % branchname)
        sys.stdout.write('\nPlease do "git rebase-limb %s".\n' % parentname)
        sys.stdout.write("Or if this is what you want, "
                         "re-push the limb using --force.\n")
        sys.stdout.write("\nNo branches pushed.\n")
        return

    if nff_names and not force:
        sys.stdout.write("\nNon-fast-forward:\n")
        for branchname in nff_names:
            sys.stdout.write("    %s\n" % branchname)
        sys.stdout.write("\nIf this is what you want, "
                         "re-push the limb using --force.\n")
        sys.stdout.write("\nNo branches pushed.\n")
        return

    if not branchnames:
        sys.stdout.write("No updated or new branches to push.\n")
        return

    cmd = ['git', 'push'] + options + [repo] + branchnames
    git.call(cmd, stdout=sys.stdout, verbose=True)
Exemple #22
0
def provenance():
    branchname = config["branchname"]
    limitIDs = config["limitIDs"]
    abbrev = config["abbrev"]
    terse = config["terse"]
    extraterse = config["extraterse"]
    verbose = config["verbose"]
    includes = config["includes"]
    excludes = config["excludes"]
    upstream_branchnames = config["upstream_branchnames"]

    if branchname and branchname != 'HEAD':
        branch = git.Branch(branchname)
    else:
        branch = git.current_branch()

    if not branch.id or not branch.exists():
        if branchname:
            sys.stderr.write('Branch "%s" not found\n' % branchname)
        else:
            sys.stderr.write('No current branch\n')
        sys.exit(1)

    if upstream_branchnames:
        if not branch.limb:
            sys.stderr.write('Branch "%s" is not part of a limb.\n' %
                             branch.name)
            sys.exit(1)

        upstream_branches = []
        for ub_name in upstream_branchnames:
            ub = git.Branch.get(ub_name)
            if not ub.exists():
                rub = ub.remote_branch
                if not rub.exists():
                    sys.stderr.write("upstream-branch '%s' not found\n" %
                                     ub_name)
                    sys.exit(1)
                ub = rub
            upstream_branches.append(ub)

        branch.limb.upstream_branches = upstream_branches

    ids = []
    for id in limitIDs:
        cmd = ['git', 'rev-parse', id]
        nid = git.call(cmd, error=None, stderr=None).rstrip() or id
        ids.append(nid)
    limitIDs = ids

    for commit, change in branch.provenance():
        commitid = commit.id
        changeid = commit.changeid
        if limitIDs:
            for id in limitIDs:
                if commitid.startswith(id) or changeid.startswith(id):
                    break
            else:
                continue

        if change == 'cherry-picked' and (includes or excludes):
            from_branchnames = [x.name for x in commit.from_branches]
            if includes:
                for s in includes:
                    for name in from_branchnames:
                        if s in name:
                            break
                    else:
                        continue
                    break
                else:
                    continue

            if excludes:
                skip = False
                for s in excludes:
                    for name in from_branchnames:
                        if s in name:
                            skip = True
                            break
                    else:
                        continue
                    break
                if skip:
                    continue

        elif includes:
            continue

        if abbrev:
            commitid = commit.abbrev_id()

        sys.stdout.write(commitid)

        if verbose:
            sys.stdout.write(" %s" % ' '.join(commit.subject))

        if change == 'cherry-picked':
            if extraterse:
                sys.stdout.write("\n")
                continue
            elif terse:
                fmt = " %s %s"
            else:
                if abbrev:
                    fmt = "\n %9s %s"
                else:
                    fmt = "\n  %s %s"
            for i in reversed(range(len(commit.from_commits))):
                if abbrev:
                    commitid = commit.from_commits[i].abbrev_id()
                else:
                    commitid = commit.from_commits[i].id
                branchname = commit.from_branches[i].name
                sys.stdout.write(fmt % (commitid, branchname))

        if terse:
            sys.stdout.write("\n")
        else:
            sys.stdout.write("\n\n")
def git_call_with_err(cmd, errstart):
    try:
        strout = git.call(cmd)
    except git.GitError, e:
        sys.stderr.write(errstart + ": " + e.msg + "\n")
        sys.exit(1)
Exemple #24
0
            config['addsignoff'] = False
        elif option in ('-f', '--force'):
            config["force"] = True

    if len(args) == 0:
        usage()

    config["revlist"] = args

    if name and email:
        if email[0] != '<':
            email = "<%s>" % email
        committer = "%s %s" % (name, email)
    else:
        cmd = ['git', 'var', 'GIT_COMMITTER_IDENT']
        ident = git.call(cmd)
        committer = ident[0:(ident.rindex('>') + 1)]

        if name:
            email = committer[committer.index('<'):]
            if email[0] != '<':
                email = "<%s>" % email
            committer = "%s %s" % (name, email)
        elif email:
            name = committer[0:(committer.index('<') - 1)]
            committer = "%s %s" % (name, email)

    config['committer'] = committer


def signoff_mv():
Exemple #25
0
def rebase_limb():
    options = config["options"]
    upstreamname = config["upstream"]
    limbname = config["limb"]

    if limbname:
        common_branch = "%s/common" % limbname.rstrip("/")
        cmd = ['git', 'checkout', common_branch]
        git.call(cmd, stdout=sys.stdout, verbose=True)

    original_branch = git.current_branch()
    limb = git.current_limb()
    limbname = limb.name

    upstreamname = upstreamname.rstrip("/")
    upstream = git.Limb.get(upstreamname)

    if not limb.exists():
        sys.stdout.write("%s: not found\n" % limbname)
        sys.exit(1)

    if not upstream.exists():
        sys.stdout.write("%s: not found\n" % upstreamname)
        sys.exit(1)

    upstream_subnames = git.subnames(upstreamname)
    limb_subnames = git.subnames(limbname)

    not_rebased = []
    for subname in limb_subnames:
        limb_branchname = "%s/%s" % (limbname, subname)
        upstream_branchname = "%s/%s" % (upstreamname, subname)

        if subname not in upstream_subnames:
            not_rebased.append((limb_branchname, upstream_branchname))
            continue

        limb_branch = git.Branch.get(limb_branchname)
        upstream_branch = git.Branch.get(upstream_branchname)
        if limb_branch.contains(upstream_branch):
            continue

        cmd = ['git', 'checkout', limb_branchname]
        git.call(cmd, stdout=sys.stdout, verbose=True)

        cmd = ['git', 'rebase'] + options + [upstream_branchname]
        git.call(cmd, stdout=sys.stdout, verbose=True)

    for subname in upstream_subnames:
        if subname in limb_subnames:
            continue

        limb_branchname = "%s/%s" % (limbname, subname)
        upstream_branchname = "%s/%s" % (upstreamname, subname)

        cmd = ['git', 'branch', limb_branchname, upstream_branchname]
        git.call(cmd, stdout=sys.stdout, verbose=True)

    # restore original branch
    if git.current_branch() != original_branch:
        cmd = ['git', 'checkout', original_branch.name]
        git.call(cmd, stdout=sys.stdout, verbose=True)

    if not_rebased:
        sys.stderr.write("\n")
        for limb_branchname, upstream_branchname in not_rebased:
            sys.stderr.write("NOT rebasing %s, no %s\n" %
                             (limb_branchname, upstream_branchname))
Exemple #26
0
def file_lines(branch, path):
    ref = '%s:%s' % (branch.name, path)
    cmd = ['git', 'show', ref]
    return git.call(cmd, stderr=None).splitlines()
Exemple #27
0
def log_limbs():
    options = config["options"]
    separator = config["separator"]
    limb1name = config["limb1"].rstrip("/")
    limb2name = config["limb2"].rstrip("/")
    paths = config["paths"]

    if not limb1name:
        limb1name = git.current_limb().name

    if not separator:
        for option in options:
            if option.startswith("--max-count"):
                break
        else:
            options.append("--max-count=1")

        been_here = False
        limb1 = git.branchnames(limb1name)
        for branchname in git.branchnames(limb1name):
            cmd = ['git', '--no-pager', 'log'] + options
            cmd.append(branchname)
            cmd += paths

            if been_here:
                sys.stdout.write("\n")
            else:
                been_here = True

            git.call(cmd, stdout=sys.stdout, verbose=True)

        sys.exit(0)

    if not limb2name:
        limb2name = git.current_limb().name

    limb1 = git.Limb.get(limb1name)
    if not limb1.exists():
        sys.stdout.write("%s: not found\n" % limb1name)
        sys.exit(1)

    limb2 = git.Limb.get(limb2name)
    if not limb2.exists():
        sys.stdout.write("%s: not found\n" % limb2name)
        sys.exit(1)

    limb1_subnames = git.subnames(limb1name)
    limb2_subnames = git.subnames(limb2name)

    not_found = False
    log_branches = []
    for subname in sorted(set(limb1_subnames + limb2_subnames)):
        branch1name = "%s/%s" % (limb1name, subname)
        branch2name = "%s/%s" % (limb2name, subname)
        if subname not in limb1_subnames:
            sys.stdout.write("WARNING, non-existent branch: %s\n" %
                             branch1name)
            not_found = True
            continue

        if subname not in limb2_subnames:
            sys.stdout.write("WARNING, non-existent branch  %s\n" %
                             branch2name)
            not_found = True
            continue

        branch1 = git.Branch.get(branch1name)
        branch2 = git.Branch.get(branch2name)
        if branch1.id == branch2.id:
            continue

        log_branches.append([branch1name, branch2name])

    if not_found and log_branches:
        sys.stdout.write("\n")

    been_here = False
    for branch1name, branch2name in log_branches:
        range = "%s%s%s" % (branch1name, separator, branch2name)

        cmd = ['git', 'rev-list'] + [range] + paths
        if not bool(git.call(cmd)):
            continue

        if been_here:
            sys.stdout.write("\n")
        else:
            been_here = True

        cmd = ['git', '--no-pager', 'log'] + options + [range] + paths
        git.call(cmd, stdout=sys.stdout, verbose=True)
Exemple #28
0
def git_create_limb():
    limb1name = config["limb1"]
    limb2name = config["limb2"]
    force = config["force"]
    recursive = config["recursive"]
    checkout = config["checkout"]
    checkout_name = None

    if checkout:
        check_clean_state()

    branch = git.Branch.get(limb1name)
    if branch.exists():
        sys.stdout.write("%s is an existing branch, need a limb name\n" %
                         limb1name)
        sys.exit(1)

    remote = git.remote_alias()
    if limb1name.startswith(remote + '/'):
        sys.stdout.write('%s: Cannot create a limb beginning with "%s"\n' %
                         (limb1name, remote))
        sys.exit(1)

    if limb2name:
        branch = git.Branch.get(limb2name)
        if branch.exists():
            sys.stdout.write("%s is an existing branch, need a limb\n" %
                             limb2name)
            sys.exit(1)
        limb2 = git.Limb.get(limb2name)
    else:
        limb2 = git.current_limb()
        limb2name = limb2.name

    if not limb2.exists():
        if not limb2name:
            limb2name = '""'
        sys.stdout.write("%s: not found\n" % limb2name)
        sys.exit(1)

    if limb1name == limb2name:
        sys.stdout.write("%s and %s are identical.\n" % (limb1name, limb2name))
        return

    limb1_branchnames = git.branchnames(limb1name, recursive=recursive)

    if limb1_branchnames and not force:
        sys.stderr.write("%s exists.  Use -f to force overwrite.\n" %
                         limb1name)
        sys.exit(1)

    limb2_subnames = git.subnames(limb2name, recursive=recursive)

    try:
        current = git.current_branch()
        current_name = current.name
    except:
        current_name = None

    if current_name and current_name in limb1_branchnames:
        if not checkout:
            check_clean_state()
        git.call(['git', 'checkout', current.id], stdout=None, stderr=None)
        checkout = True
        if current.subname in limb2_subnames:
            checkout_name = current_name

    limb1_subnames = git.subnames(limb1name, limb1_branchnames)

    for subname in limb2_subnames:
        destname = "%s/%s" % (limb1name, subname)
        sourcename = "%s/%s" % (limb2name, subname)

        dest = git.Branch.get(destname)
        source = git.Branch.get(sourcename)
        if dest.id != source.id:
            cmd = ['git', 'branch', '-f', destname, sourcename]
            git.call(cmd, stdout=sys.stdout, verbose=True)

        if not checkout_name:
            checkout_name = destname

    for subname in limb1_subnames:
        if subname in limb2_subnames:
            continue

        del_name = "%s/%s" % (limb1name, subname)
        cmd = ['git', 'branch', '-D', del_name]
        git.call(cmd, stdout=sys.stdout, verbose=True)

    if checkout:
        if not checkout_name:
            sys.stderr.write("No branch in %s to checkout.\n" % limb2name)
            sys.exit(1)

        cmd = ['git', 'checkout', checkout_name]
        if current_name and checkout_name == current.name:
            git.call(cmd, stdout=None, stderr=None)
        else:
            git.call(cmd, stdout=sys.stdout, verbose=True)
Exemple #29
0
def merge_limb():
    options = config["options"]
    remotename = config["remote"]
    limbname = config["limb"]

    if limbname:
        limbname = limbname.rstrip('/')
        limb = git.Limb.get(limbname)
        branch = limb.repository_branches()[0]
        git.call(['git', 'checkout', branch], stdout=sys.stdout, verbose=True)
    else:
        limb = git.current_limb()
        limbname = limb.name

    remote = git.Limb.get(remotename)
    remotename = remote.name.rstrip("/")

    if not limb.exists():
        sys.stdout.write("%s: not found\n" % limbname)
        sys.exit(1)

    if not remote.exists():
        sys.stdout.write("%s: not found\n" % remotename)
        sys.exit(1)

    limb_subnames = git.subnames(limbname)
    remote_subnames = git.subnames(remotename)

    for subname in remote_subnames:
        if subname not in limb_subnames:
            limb_branchname = "%s/%s" % (limbname, subname)
            remote_branchname = "%s/%s" % (remotename, subname)
            cmd = ['git', 'branch', limb_branchname, remote_branchname]
            git.call(cmd, stdout=sys.stdout, verbose=True)

    for subname in limb_subnames:
        if subname not in remote_subnames:
            continue
        limb_branchname = "%s/%s" % (limbname, subname)
        remote_branchname = "%s/%s" % (remotename, subname)

        limb_branch = git.Branch.get(limb_branchname)
        remote_branch = git.Branch.get(remote_branchname)
        if limb_branch.contains(remote_branch):
            sys.stdout.write("%s is up-to-date.\n" % limb_branchname)
            continue

        try:
            cmd = ['git', 'checkout', limb_branchname]
            git.call(cmd, stdout=sys.stdout, verbose=True)
            cmd = ['git', 'merge', remote_branchname]
            git.call(cmd, stdout=sys.stdout, verbose=True)

        except git.GitError:
            cmdline = ' '.join([re.sub(".*/", "", sys.argv[0])] + sys.argv[1:])
            sys.stdout.write("\n")
            sys.stdout.write("After resolving this issue, you may continue\n")
            sys.stdout.write("the merge by re-running the command:\n")
            sys.stdout.write("  %s\n" % cmdline)

            if config["debug"]:
                sys.stdout.write("\n")
                raise

            sys.exit(1)
Exemple #30
0
def commit_message():
    message_commit = opt["message-commit"]
    addsignoff = opt["addsignoff"]

    subject = ("Oneline summary of change, less then 60 characters\n"
               "# *** Leave above line blank for clean log formatting ***")
    source = "MontaVista Software, LLC | Cavium Networks, Inc | URL | Some Guy <email@addr>"
    bugz = "Bugzilla bug number"
    type = "Defect Fix | Security Fix | Enhancement | Integration"
    disposition = ("Submitted to | Needs submitting to | Merged from |"
                   " Accepted by | Rejected by | Backport from | Local")
    changeid = None
    body = []

    if message_commit:
        subject = '\n'.join(message_commit.subject)
        body = message_commit.body
        mv_header_lines = message_commit.mv_header_lines
        mv_header_dict = message_commit.mv_header_dict
        body = body[len(mv_header_lines):]
        if opt['add-picked-message']:
            body.append("(cherry picked from commit %s)" % message_commit.id)

    # override defaults with what is in mv style header
        if 'mr' in mv_header_dict:
            bugz = mv_header_dict['mr']
        if 'source' in mv_header_dict:
            source = mv_header_dict['source']
        if 'type' in mv_header_dict:
            type = mv_header_dict['type']
        if 'disposition' in mv_header_dict:
            disposition = mv_header_dict['disposition']
        if 'changeid' in mv_header_dict:
            changeid = mv_header_dict['changeid']

        # Use NCD source and dispostion.
        # Save NCD bugz #
        if opt.get('ncd', ""):
            if 'changeid' in mv_header_dict:
                body.append("(cherry picked from ncd %s)" % message_commit.id)

            if bugz.startswith('Bugzilla'):
                bugz = opt["bugz"]
            else:
                body.append("NCD Bug#: %s" % bugz)
                bugz = opt["bugz"]

        if not opt.get('ncd', ""):
            if opt["source"]:
                source = opt["source"]
            if opt["disposition"]:
                disposition = opt["disposition"]
        else:
            if 'source' not in mv_header_dict:
                source = opt["source"]
            if 'disposition' not in mv_header_dict:
                disposition = opt["disposition"]

    if opt["bugz"]:
        if bugz.startswith('Bugzilla'):
            bugz = opt["bugz"]
        else:
            if opt.get('reset_bugz'):
                bugz = opt["bugz"]

            if not opt.get('ncd', '') or not opt.get('reset_bugz'):
                bugz = bugz.split(',', 2)[0].strip()
                if bugz != opt["bugz"]:
                    bugz += ", " + opt["bugz"]
    if opt["type"]:
        type = opt["type"]

    if addsignoff:
        cmd = ['git', 'var', 'GIT_COMMITTER_IDENT']
        ident = git.call(cmd)
        ident = ident[0:(ident.rindex('>') + 1)]
        signoff_line = "Signed-off-by: " + ident
        if signoff_line not in body:
            if not body or ("-by: " not in body[-1]
                            and not body[-1].lower().startswith('cc:')):
                body.append("")
            body.append(signoff_line)

    header = """%s

Source: %s
MR: %s
Type: %s
Disposition: %s
""" % (subject, source, bugz, type, disposition)

    body = '\n'.join(body) + '\n'

    if opt["delete_changeid"]:
        changeid = None
    else:
        if opt["changeid"]:
            changeid = opt["changeid"]
        elif not changeid:
            changeid = generate_changeid(header, body)

    if changeid:
        header += "ChangeID: %s\n" % changeid

    if not body.startswith("Description:\n"):
        header += "Description:\n\n"

    return header + body