Exemplo n.º 1
0
def resolve_with(tool, repo, files):
    opts = {'tool': tool}
    paths = [repo.wjoin(f) for f in files]
    commands.resolve(repo.ui, repo, *paths, **opts)
    return True
Exemplo n.º 2
0
def resolve(parent, ui, repo, files):
    commands.resolve(ui, repo, *files)
    return True
Exemplo n.º 3
0
def resolve_with(tool, repo, files):
    opts = {'tool': tool}
    paths = [repo.wjoin(f) for f in files]
    commands.resolve(repo.ui, repo, *paths, **opts)
    return True
Exemplo n.º 4
0
def resolve(parent, ui, repo, files):
    commands.resolve(ui, repo, *files)
    return True
Exemplo n.º 5
0
def tclose(ui, repo, *args, **opts):
  """ close the current topic branch and push to the central repository """

  mustBeTopicRepo(repo)

  # Sanity check
  if not isClean(ui, repo):
    return 1

  if args:
    branches = args
  else:
    if not onTopicBranch(ui, repo):
      return 1
    branches = [repo.dirstate.branch()]

  if 'tmenu' in opts:
    if ui.prompt("Branch '%s': close it?" % branches[0]).upper() != 'Y':
      return 1
    opts = { 'nopull':False, 'nopush':False }

  pulled = False # only pull once

  for branch in branches:

    # Pull new changes from the central repo to avoid multiple-heads problem
    if not opts['nopull'] and not pulled:
      if tryCommand(ui, "pull", lambda:commands.pull(ui, repo, **opts) >= 2):
        return 1
      pulled = True

    # Can't close already closed branches, nor any of the special branches
    if not repo.branchheads(branch) or branch in repo.topicSpecialBranches:
      ui.warn("Error: %s is not an open topic branch\n" % branch)
      return 1

    # Now update to the head of the branch being closed
    if repo.dirstate.parents()[0] not in repo.branchheads(branch):
      if tryCommand(ui, "update %s" % quoteBranch(branch), lambda:commands.update(ui, repo, node=branch)):
        return 1

    # Unlike a normal hg commit, if no text is specified we supply a reasonable default.
    branch = repo.dirstate.branch()
    text = opts.get('message')
    if text is None:
      text = "Closing %s" % branch

    # Close it
    if tryCommand(ui, "commit --close-branch", lambda:repo.commit(text, extra = {'close':'True'}) is None):
      return 1

    # Aditionally, for this to not be considered a "head" it has to have a
    # child commit. So we have to merge into prod. First, update.
    #
    if tryCommand(ui, "update %s" % repo.topicProdBranch, lambda:commands.update(ui, repo, node=repo.topicProdBranch)):
      return 1

    # Now merge, ignoring all conflicts.
    mergeOpts = copy.deepcopy(opts)
    mergeOpts['tool'] = "internal:fail"
    mergeOpts['noninteractive'] = True
    # Ignore return value... ok if merge fails
    tryCommand(ui, "merge -r %s" % quoteBranch(branch), 
               lambda:commands.merge(ui, repo, node=branch, **mergeOpts),
               repo = repo)

    # Revert all files to prod (regardless of what happened on the branch)
    revertOpts = copy.deepcopy(opts)
    revertOpts['all'] = True
    revertOpts['rev'] = "."
    if tryCommand(ui, "revert -a -r .", lambda:commands.revert(ui, repo, **revertOpts), repo = repo):
      return 1

    # Were there any merge conflicts?
    resolveOpts = copy.deepcopy(opts)
    resolveOpts['list'] = True
    if tryCommand(ui, "resolve -l", lambda:commands.resolve(ui, repo, **resolveOpts), repo = repo):
      return 1

    # Anything that had a merge conflict, mark it resolved (by the revert)
    if ui.lastTryCommandOutput != '':
      resolveOpts = copy.deepcopy(opts)
      resolveOpts['all'] = True
      resolveOpts['mark'] = True
      if tryCommand(ui, "resolve -a -m", lambda:commands.resolve(ui, repo, **resolveOpts), repo = repo):
        return 1

    # Commit the merge
    if tryCommand(ui, "commit", lambda:repo.commit(text) is None):
      return 1

  # And push.
  if not opts['nopush']:
    pushOpts = copy.deepcopy(opts)
    if 'message' in pushOpts:
      del pushOpts['message']
    pushOpts['force'] = True
    nameSet = set()
    for name, path in ui.configitems("paths"):
      nameSet.add(name)
    if tryCommand(ui, "push -f -b %s -b %s default" % (quoteBranch(branch), repo.topicProdBranch), 
                  lambda:commands.push(ui, repo, branch=(branch,repo.topicProdBranch), **pushOpts), 
                  repo=repo) > 1:
      return 1
    if "dev" in nameSet:
      if tryCommand(ui, "push -f -b %s -b %s dev" % (quoteBranch(branch), repo.topicProdBranch), 
                    lambda:commands.push(ui, repo, branch=(branch,repo.topicProdBranch), dest="dev", **pushOpts), 
                    repo=repo) > 1:
        return 1
    if "stage" in nameSet:
      if tryCommand(ui, "push -f -b %s -b %s stage" % (quoteBranch(branch), repo.topicProdBranch), 
                    lambda:commands.push(ui, repo, branch=(branch,repo.topicProdBranch), dest="stage", **pushOpts), 
                    repo=repo) > 1:
        return 1
    if "prod" in nameSet:
      if tryCommand(ui, "push -f -b %s -b %s prod" % (quoteBranch(branch), repo.topicProdBranch), 
                    lambda:commands.push(ui, repo, branch=(branch,repo.topicProdBranch), dest="prod", **pushOpts), 
                    repo=repo) > 1:
        return 1

  ui.status("Done.\n")
def checkconflict(ui, repo, source=None, **opts):
    """Print there will be a conflict after merge or not."""

    check_uncommited_changes(repo)

    cur_dir = repo.root
    local_clone_dir = cur_dir + '-local'
    remote_clone_dir = cur_dir + '-remote'

    # if the source is not specified,
    # we take the default one from the repo configuration.
    # otherwise we take source

    if source is None:
        clone_source = check_config(repo, 'default')
    else:
        is_URL = bool(urlparse.urlparse(source).netloc)
        if os.path.isdir(source) or is_URL:
            clone_source = source
        else:
            clone_source = check_config(repo, str(source))

    # path to the cache list
    cache_dir = os.path.expanduser('~\\.hg.cache')
    cache_list = os.path.join(cache_dir, 'cache_list.json')

    # if the source is local, then just clone

    if hg.islocal(clone_source):
        clone(repo, clone_source, remote_clone_dir)

    # otherwise, open the cache list and see
    # if it contains path information to the cache
    # of the specified resource for the current working repo

    else:
        cache_source = None

        # clear the cache list if this option is set, or
        # if the cache list does not exist, create it

        if not os.path.exists(cache_list) or opts.get('clear_cache_list'):
            if not os.path.exists(cache_dir):
                make_dir(cache_dir)
            create_cache_list(cache_list)
        else:
            data = read_cache_list(cache_list)
            cache_source = find_cache_src(data, cur_dir, clone_source)

        # if the cache resource is found but this path does not exist or the path exists,
        # but it is not a repo, or set_cache_repo option,
        # we delete information about this cache repo from the cache list
        was_cached = cache_source is not None
        if was_cached:
            cache_source = cache_source.encode('cp1251')
            if not is_repo(repo, cache_source) or opts.get('set_cache_repo'):
                cache_data = read_cache_list(cache_list)
                new_cache_data = find_cache_src(cache_data, cur_dir, clone_source, for_remove=True)

                write_cache_list(cache_list, new_cache_data)

                repo.ui.write('\nThe last path to the cache repository is broken.\n')
                cache_source = None

        # if the cache resource is not found
        # suggest to choose the path to the cash repo
        # if the paths exists and empty -> clone,
        # if the path exists and repo -> checkupdate
        # else: select empty folder

        if cache_source is None:
            cache_source = str(raw_input('Specify the path for the cache-repository,\n'
                                         'or if no path it will be use /user/.hg.cache path.\n')).replace('\r', '')
            if not cache_source:
                cache_source = default_cache_src(cur_dir, cache_dir)
            if os.path.exists(cache_source):
                if not os.listdir(cache_source):
                    clone(repo, clone_source, cache_source)  # clone from the resource to the cache
                elif is_repo(repo, cache_source):
                    clone_root = commands.identify(repo.ui, repo, rev=0)
                    repo = hg.repository(repo.ui, cache_source)
                    cache_root = commands.identify(repo.ui, repo, rev=0)
                    if clone_root == cache_root:
                        check_update(repo, clone_source)
                        repo = hg.repository(repo.ui, cur_dir)
                    else:
                        repo = hg.repository(repo.ui, cur_dir)
                        repo.ui.write('\nCache-repo and remote-repo do not match.\n')
                        sys.exit()
                else:
                    repo.ui.write('\nYou must select an empty folder or an existing repo folder.\n')
                    sys.exit()
            else:
                make_dir(cache_source)
                clone(repo, clone_source, cache_source)

            note = gen_note(cur_dir, clone_source, cache_source)
            write_cache_list(cache_list, note, add=True)

        # if the cache resource is found,
        # check if new changes can be pulled.
        # if yes, pull and update

        else:
            repo = hg.repository(repo.ui, cache_source)
            check_update(repo, clone_source)
            repo = hg.repository(repo.ui, cur_dir)

        # finally clone from cache to remote
        clone(repo, cache_source, remote_clone_dir)

    # create a local repo clone
    clone(repo, cur_dir, local_clone_dir)

    repo = hg.repository(repo.ui, remote_clone_dir)  # go to remote repo clone
    commands.pull(repo.ui, repo, local_clone_dir)  # pull changes from a local repo clone to it
    commands.update(repo.ui, repo)  # update

    repo.ui.pushbuffer()
    conflict = do_merge(repo)
    deleted_str = repo.ui.popbuffer()
    deleted_list = re.findall('\'(.*)\'', deleted_str)

    # if there is a conflict,
    # we look at the list of files with conflicts
    # and display them, because merge3 will mark conflicting lines with special tags

    if conflict:
        repo.ui.pushbuffer()
        commands.resolve(repo.ui, repo, list=True)
        u_files_str = repo.ui.popbuffer()
        u_files_list = re.findall('U (.*)\n', u_files_str)

        if opts.get('check_file'):
            file = opts.get('check_file')
            if file in deleted_list:
                repo.ui.write(
                    '\nfile ' + file + ' was deleted in other [merge rev] but was modified in local [working '
                                       'copy].\n')
            elif file in u_files_list:
                show_file_merge(repo, remote_clone_dir, file)
            else:
                repo.ui.write('\nFile ' + str(file) + ' does not cause conflict.\n'
                                                      'The conflict occurs in the following files:\n')
                show_all_conflicts(repo, u_files_list, deleted_list)

        else:
            show_all_conflicts(repo, u_files_list, deleted_list)

        repo.ui.write('\nYes, here is a conflict\n')

    # if there is no conflict, say it
    else:
        repo.ui.write('\nNo, everything cool\n')

    # go back to our work repo
    repo = hg.repository(repo.ui, cur_dir)

    # delete clones
    remove_clones(local_clone_dir, remote_clone_dir)

    sys.exit()