Esempio n. 1
0
    def execute(self, args):
        try:
            clonePath = git.baseDir()
            if clonePath == "":
                return False
        except git.GrapeGitError:
            pass
        
        clonePath = args["--source"]
        if not clonePath: 
            clonePath = utility.userInput("Enter path to original clone", clonePath)

        newTree = args["--dest"]
        if not newTree:
            newTree = utility.userInput("Enter name of new working tree")

        newTreePath = args["--destPath"]
        if not newTreePath:
            newTreePath = utility.userInput("Enter desired location of new working tree (must exist)",
                                            os.path.realpath(os.path.join(clonePath, "../")))

        newRepo = os.path.join(newTreePath, newTree)
        #TODO: When grape is installed to PUBLIC, the first argument here should be the
        # publically available git-new-workdir, instead of the version in the local repo.
        p = utility.executeSubProcess(os.path.join(os.path.dirname(__file__), "..", "git-new-workdir")
                                      + " " + clonePath + " " + newRepo, workingDirectory=os.getcwd())
        p.wait()
        os.chdir(newRepo)
        if not args["--noSparse"]:
            print "created new working tree %s in %s. Calling grape uv from new workspace now." % (newTree, newTreePath)
            menu = grapeMenu.menu()
            return menu.applyMenuChoice('uv', ["uv"] + args["<uvargs>"])
        else:
            git.checkout("HEAD")
            return True
Esempio n. 2
0
File: commit.py Progetto: LLNL/GRAPE
    def execute(self, args):
        commitargs = ""
        if args['-a']:
            commitargs = commitargs + " -a"
        elif args["<filetree>"]:
            commitargs = commitargs + " %s" % args["<filetree>"]
        if not args['-m']:
            args["-m"] = utility.userInput("Please enter commit message:")
        commitargs += " -m \"%s\"" % args["-m"]

        wsDir = utility.workspaceDir()
        os.chdir(wsDir)

        submodules = [(True, x) for x in git.getModifiedSubmodules()]
        subprojects = [(False, x) for x in grapeConfig.GrapeConfigParser.
                       getAllActiveNestedSubprojectPrefixes()]
        for stage, sub in submodules + subprojects:
            os.chdir(os.path.join(wsDir, sub))
            subStatus = git.status("--porcelain -uno")
            if subStatus:
                utility.printMsg("Committing in %s..." % sub)
                if self.commit(commitargs, sub) and stage:
                    os.chdir(wsDir)
                    utility.printMsg("Staging committed change in %s..." % sub)
                    git.add(sub)

        os.chdir(wsDir)
        if submodules or git.status("--porcelain"):
            utility.printMsg("Performing commit in outer level project...")
            self.commit(commitargs, wsDir)
        return True
Esempio n. 3
0
File: commit.py Progetto: LLNL/GRAPE
    def execute(self, args):
        commitargs = ""
        if args['-a']: 
            commitargs = commitargs +  " -a"
        elif args["<filetree>"]:
            commitargs = commitargs + " %s"% args["<filetree>"]
        if not args['-m']:
            args["-m"] = utility.userInput("Please enter commit message:")
        commitargs += " -m \"%s\"" % args["-m"]
         
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)

        submodules = [(True, x ) for x in git.getModifiedSubmodules()]
        subprojects = [(False, x) for x in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()]
        for stage,sub in submodules +  subprojects:
            os.chdir(os.path.join(wsDir,sub))
            subStatus = git.status("--porcelain -uno")
            if subStatus:
                utility.printMsg("Committing in %s..." % sub)
                if self.commit(commitargs, sub) and stage: 
                    os.chdir(wsDir)
                    utility.printMsg("Staging committed change in %s..." % sub)
                    git.add(sub)
        
        os.chdir(wsDir)
        if submodules or git.status("--porcelain"): 
            utility.printMsg("Performing commit in outer level project...")
            self.commit(commitargs, wsDir)
        return True
Esempio n. 4
0
def handleEnsureLocalUpToDateMRE(mre):
    _pushBranch = False
    _skipPush = False
    cleanupPushArgs = []
    for e1, repo, branch in zip(mre.exceptions(), mre.repos(), mre.branches()):
        try:
            raise e1
        except git.GrapeGitError as e:
            if ("[rejected]" in e.gitOutput
                    and "(non-fast-forward)" in e.gitOutput
                ) or "Couldn't find remote ref" in e.gitOutput:
                if "Couldn't find remote ref" in e.gitOutput:
                    if not _pushBranch:
                        utility.printMsg(
                            "No remote reference to %s in %s's origin. You may want to push this branch."
                            % (branch, repo))
                else:
                    utility.printMsg(
                        "Fetch of %s rejected as non-fast-forward in repo %s" %
                        (branch, repo))
                pushBranch = _pushBranch
                if _skipPush:
                    pushBranch = False
                elif not pushBranch:
                    pushBranch = utility.userInput(
                        "Would you like to push your local branch? \n"
                        "(select 'a' to say yes for (a)ll subprojects, 's' to (s)kip push for all subprojects)"
                        "\n(y,n,a,s)", 'y')

                if str(pushBranch).lower()[0] == 'a':
                    _pushBranch = True
                    pushBranch = True
                if str(pushBranch).lower()[0] == 's':
                    _skipPush = True
                    pushBranch = False
                if pushBranch:

                    cleanupPushArgs.append((repo, branch, None))
                else:
                    utility.printMsg("Skipping push of local %s in %s" %
                                     (branch, repo))

            elif e.commError:
                utility.printMsg(
                    "Could not update %s from origin due to a connectivity issue. Checking out most recent\n"
                    "local version. " % branch)
            else:
                raise (e)

    # do another MRC launch to do any follow up pushes that were requested.
    utility.MultiRepoCommandLauncher(
        cleanupPush,
        listOfRepoBranchArgTuples=cleanupPushArgs).launchFromWorkspaceDir(
            handleMRE=handleCleanupPushMRE)
    return
Esempio n. 5
0
    def execute(self, args):
        start = args["--start"]
        if not start:
            start = self._public

        # decide whether to recurse
        recurse = grapeConfig.grapeConfig().get('workspace',
                                                'manageSubmodules')
        if args["--recurse"]:
            recurse = True
        if args["--noRecurse"]:
            recurse = False

        if not args["<descr>"]:
            args["<descr>"] = utility.userInput(
                "Enter one word description for branch:")

        if not args["--user"]:
            args["--user"] = utility.getUserName()

        branchName = self._key + "/" + args["--user"] + "/" + args["<descr>"]

        launcher = utility.MultiRepoCommandLauncher(createBranch,
                                                    runInSubmodules=recurse,
                                                    runInSubprojects=recurse,
                                                    runInOuter=True,
                                                    branch=start,
                                                    globalArgs=branchName)

        launcher.initializeCommands()
        utility.printMsg("About to create the following branches:")
        for repo, branch in zip(launcher.repos, launcher.branches):
            utility.printMsg("\t%s off of %s in %s" %
                             (branchName, branch, repo))
        proceed = utility.userInput("Proceed? [y/n]", default="y")
        if proceed:
            grapeMenu.menu().applyMenuChoice(
                'up', ['up', '--public=%s' % start])
            launcher.launchFromWorkspaceDir()
        else:
            utility.printMsg("branches not created")
Esempio n. 6
0
    def execute(self, args):
        branch = args["<branch>"]
        force = args["-D"]
        if not branch:
            branch = utility.userInput("Enter name of branch to delete")

        if args["--verify"]:
            proceed = utility.userInput(
                "Would you like to delete the branch %s" % branch, 'y')
            if not proceed:
                return True

        launcher = utility.MultiRepoCommandLauncher(deleteBranch,
                                                    branch=branch,
                                                    globalArgs=[force])
        try:
            launcher.launchFromWorkspaceDir()
        except utility.MultiRepoException as e:
            handleDeleteBranchMRE(e, force)

        return True
Esempio n. 7
0
    def execute(self, args):
        start = args["--start"]
        if not start: 
            start = self._public
            
        
        # decide whether to recurse
        recurse = grapeConfig.grapeConfig().get('workspace', 'manageSubmodules')
        if args["--recurse"]:
            recurse = True
        if args["--noRecurse"]:
            recurse = False

        
        if not args["<descr>"]:
            args["<descr>"] =  utility.userInput("Enter one word description for branch:")
            
        if not args["--user"]:
            args["--user"] = utility.getUserName()
            
        branchName = self._key + "/" + args["--user"] + "/" + args["<descr>"]

            
        launcher = utility.MultiRepoCommandLauncher(createBranch, 
                                                   runInSubmodules=recurse, 
                                                   runInSubprojects=recurse, 
                                                   runInOuter=True, 
                                                   branch=start, 
                                                   globalArgs=branchName)
        
        launcher.initializeCommands()
        utility.printMsg("About to create the following branches:")
        for repo, branch in zip(launcher.repos, launcher.branches):
            utility.printMsg("\t%s off of %s in %s" % (branchName, branch, repo))
        proceed = utility.userInput("Proceed? [y/n]", default="y")
        if proceed:
            grapeMenu.menu().applyMenuChoice('up', ['up', '--public=%s' % start])
            launcher.launchFromWorkspaceDir()
        else:
            utility.printMsg("branches not created")
Esempio n. 8
0
    def execute(self,args):
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = "mr"
        otherBranch = args['<branch>']
        if not otherBranch:
            # list remote branches that are available
            print git.branch('-r')
            otherBranch = utility.userInput("Enter name of branch you would like to merge into this branch (without the origin/ prefix)")

        # make sure remote references are up to date
        utility.printMsg("Fetching remote references in all projects...")
        try:
            utility.MultiRepoCommandLauncher(fetchHelper).launchFromWorkspaceDir()
        except utility.MultiRepoException as mre:
            commError = False
            commErrorRepos = []
            for e, r in zip(mre.exceptions(), mre.repos()):
                if e.commError:
                    commErrorRepos.append(r)
                    commError = True
                
            if commError:
                utility.printMsg("ERROR: can't communicate with remotes for %s. Halting remote merge." % commErrorRepos)
                return False
            
            
        
        
        # update our local reference to the remote branch so long as it's fast-forwardable or we don't have it yet..)
        hasRemote = ("origin/%s" % otherBranch) in git.remoteBranches()
        hasBranch = git.hasBranch(otherBranch)
        currentBranch = git.currentBranch()
        remoteUpToDateWithLocal = git.branchUpToDateWith("remotes/origin/%s" % otherBranch, otherBranch)
        updateLocal =  hasRemote and  (remoteUpToDateWithLocal or not hasBranch) and currentBranch != otherBranch
        if  updateLocal:
            utility.printMsg("updating local branch %s from %s" % (otherBranch, "origin/%s" % otherBranch))
            utility.MultiRepoCommandLauncher(updateBranchHelper, branch=otherBranch).launchFromWorkspaceDir(handleMRE=updateBranchHandleMRE)
        
        args["<branch>"] = otherBranch if updateLocal else "origin/%s" % otherBranch
        # we've handled the update, we don't want m or md to update the local branch. 
        args["--noUpdate"] = True
        # if mr is called by the user, need to initialize the --continue argument. 
        # if it is called by md, it will be set already. 
        if not "--continue" in args:
            args["--continue"] = False        
        
        return grapeMenu.menu().getOption('m').execute(args)
Esempio n. 9
0
def handleEnsureLocalUpToDateMRE(mre):
    _pushBranch = False
    _skipPush = False
    cleanupPushArgs = []
    for e1, repo, branch in zip(mre.exceptions(), mre.repos(), mre.branches()):
        try: 
            raise e1
        except git.GrapeGitError as e:
            if ("[rejected]" in e.gitOutput and "(non-fast-forward)" in e.gitOutput) or "Couldn't find remote ref" in e.gitOutput:
                if "Couldn't find remote ref" in e.gitOutput:
                    if not _pushBranch:
                        utility.printMsg("No remote reference to %s in %s's origin. You may want to push this branch." % (branch, repo))
                else:
                    utility.printMsg("Fetch of %s rejected as non-fast-forward in repo %s" % (branch, repo))
                pushBranch = _pushBranch
                if _skipPush:
                    pushBranch = False
                elif not pushBranch:
                    pushBranch =  utility.userInput("Would you like to push your local branch? \n"
                                                    "(select 'a' to say yes for (a)ll subprojects, 's' to (s)kip push for all subprojects)"
                                                    "\n(y,n,a,s)", 'y')
                    
                if str(pushBranch).lower()[0] == 'a':
                    _pushBranch = True
                    pushBranch = True
                if str(pushBranch).lower()[0] == 's':
                    _skipPush = True
                    pushBranch = False
                if pushBranch:
                    
                    cleanupPushArgs.append((repo, branch, None))
                else:
                    utility.printMsg("Skipping push of local %s in %s" % (branch, repo))
                    
            elif e.commError:
                utility.printMsg("Could not update %s from origin due to a connectivity issue. Checking out most recent\n"
                                 "local version. " % branch)
            else:    
                raise(e)
   
    # do another MRC launch to do any follow up pushes that were requested. 
    utility.MultiRepoCommandLauncher(cleanupPush, listOfRepoBranchArgTuples=cleanupPushArgs).launchFromWorkspaceDir(handleMRE=handleCleanupPushMRE)
    return
Esempio n. 10
0
File: merge.py Progetto: LLNL/GRAPE
    def execute(self, args):
        # this is necessary due to the unholy relationships between mr, m, and md. 
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = 'm'
        otherBranch = args["<branch>"] if args["<branch>"] else utility.userInput("Enter name of branch you would like"
                                                                                  " to merge into this branch")
        args["<branch>"] = otherBranch
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        toks = otherBranch.split("origin/")
        if toks[-1] in publicBranches:
            public = toks[-1]
            publicMapping = config.getMapping("workspace", "submodulePublicMappings")
            subpublic = publicMapping[public]
            toks[-1] = subpublic
            subpublic = 'origin/'.join(toks)
        else:
            subpublic = otherBranch
            
        

        mdArgs = {}
        mdArgs["--am"] = args["--am"]
        mdArgs["--as"] = args["--as"]
        mdArgs["--at"] = args["--at"]
        mdArgs["--aT"] = args["--aT"]
        mdArgs["--ay"] = args["--ay"]
        mdArgs["--aY"] = args["--aY"]
        mdArgs["--askAll"] = args["--askAll"]
        mdArgs["--public"] = args["<branch>"]
        mdArgs["--subpublic"] = subpublic
        mdArgs["--recurse"] = not args["--noRecurse"]
        mdArgs["--noRecurse"] = args["--noRecurse"]
        mdArgs["--continue"] = args["--continue"]
        mdArgs["<<cmd>>"] = args["<<cmd>>"]
        mdArgs["--noUpdate"] = args["--noUpdate"]
        mdArgs["--squash"] = args["--squash"]
        
        
        return grapeMenu.menu().getOption("md").execute(mdArgs)
Esempio n. 11
0
    def execute(self, args):
        # this is necessary due to the unholy relationships between mr, m, and md.
        if not "<<cmd>>" in args:
            args["<<cmd>>"] = 'm'
        otherBranch = args["<branch>"] if args[
            "<branch>"] else utility.userInput(
                "Enter name of branch you would like"
                " to merge into this branch")
        args["<branch>"] = otherBranch
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        toks = otherBranch.split("origin/")
        if toks[-1] in publicBranches:
            public = toks[-1]
            publicMapping = config.getMapping("workspace",
                                              "submodulePublicMappings")
            subpublic = publicMapping[public]
            toks[-1] = subpublic
            subpublic = 'origin/'.join(toks)
        else:
            subpublic = otherBranch

        mdArgs = {}
        mdArgs["--am"] = args["--am"]
        mdArgs["--as"] = args["--as"]
        mdArgs["--at"] = args["--at"]
        mdArgs["--aT"] = args["--aT"]
        mdArgs["--ay"] = args["--ay"]
        mdArgs["--aY"] = args["--aY"]
        mdArgs["--askAll"] = args["--askAll"]
        mdArgs["--public"] = args["<branch>"]
        mdArgs["--subpublic"] = subpublic
        mdArgs["--recurse"] = not args["--noRecurse"]
        mdArgs["--noRecurse"] = args["--noRecurse"]
        mdArgs["--continue"] = args["--continue"]
        mdArgs["<<cmd>>"] = args["<<cmd>>"]
        mdArgs["--noUpdate"] = args["--noUpdate"]
        mdArgs["--squash"] = args["--squash"]

        return grapeMenu.menu().getOption("md").execute(mdArgs)
Esempio n. 12
0
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        checkoutargs = ''
        branch = args["<branch>"]
        if args['-b']: 
            checkoutargs += " -b"

        workspaceDir = utility.workspaceDir()
        os.chdir(workspaceDir)
        currentSHA = git.shortSHA("HEAD")

        utility.printMsg("Performing checkout of %s in outer level project." % branch)
        launcher = utility.MultiRepoCommandLauncher(handledCheckout, listOfRepoBranchArgTuples=[(workspaceDir, branch, [checkoutargs, sync])])
       
        if not launcher.launchFromWorkspaceDir(handleMRE=handleCheckoutMRE)[0]:
            return False
        previousSHA = currentSHA

        submoduleListDidChange = ".gitmodules" in git.diff("--name-only %s %s" % (previousSHA, branch))
        addedModules = []
        removedModules = []
        uvArgs = []
        submodulesDidChange = False
        if submoduleListDidChange and grapeConfig.grapeConfig().getboolean("workspace", "manageSubmodules"):

            self.parseGitModulesDiffOutput(git.diff("%s %s --no-ext-diff -- .gitmodules" % (previousSHA, branch)), addedModules,
                                           removedModules)
            if not addedModules and not removedModules:
                pass
            else:
                submodulesDidChange = True

                if removedModules:
                    for sub in removedModules:
                        try:
                            os.chdir(os.path.join(workspaceDir, sub))
                            if git.isWorkingDirectoryClean():
                                cleanBehaviorSet = args["--noUpdateView"] or args["--updateView"]
                                if not cleanBehaviorSet:
                                    clean = utility.userInput("Would you like to remove the submodule %s ?" % sub, 'n')
                                elif args["--noUpdateView"]:
                                    clean = False
                                elif args["--updateView"]:
                                    clean = True
                                if clean:
                                    utility.printMsg("Removing clean submodule %s." % sub)
                                    os.chdir(workspaceDir)
                                    shutil.rmtree(os.path.join(workspaceDir, sub))
                            else:
                                utility.printMsg("Unstaged / committed changes in %s, not removing." % sub)
                                os.chdir(workspaceDir)
                        except OSError:
                            pass


        # check to see if nested project list changed
        addedProjects = []
        removedProjects = []
        removedProjectPrefices = {}
        nestedProjectListDidChange = False
        os.chdir(workspaceDir)
        if ".grapeconfig" in git.diff("--name-only %s %s" % (previousSHA, branch)): 
            configDiff = git.diff("--no-ext-diff %s %s -- %s" % (previousSHA, branch, ".grapeconfig"))
            nestedProjectListDidChange = "[nestedprojects]" in configDiff.lower()
            self.parseGrapeConfigNestedProjectDiffOutput(configDiff, addedProjects, removedProjects, removedProjectPrefices)
            
            if removedProjects: 
                config = grapeConfig.grapeConfig()
                for proj in removedProjects:
                    projPrefix = removedProjectPrefices[proj]
                    try:
                        os.chdir(os.path.join(workspaceDir, proj))
                    except OSError as e:
                        if e.errno == 2:
                            # directory doesn't exist, that's OK since we're thinking about removing it
                            # anyways at this point...
                            continue
                    if git.isWorkingDirectoryClean():
                        removeBehaviorSet = args["--noUpdateView"] or args["--updateView"]
                        if not removeBehaviorSet:
                            remove = utility.userInput("Would you like to remove the nested subproject %s? \n"
                                                       "All work that has not been pushed will be lost. " % projPrefix, 'n'  )
                        elif args["--noUpdateView"]:
                            remove = False
                        elif args["--updateView"]:
                            remove = True
                        if remove:
                            remove = utility.userInput("Are you sure you want to remove %s? When you switch back to the previous branch, you will have to\n"
                                                       "reclone %s." % (projPrefix, projPrefix), 'n')
                        if remove:
                            os.chdir(workspaceDir)
                            shutil.rmtree(os.path.join(workspaceDir,projPrefix))
                    else:
                        utility.printMsg("Unstaged / committed changes in %s, not removing. \n"
                                         "Note this project is NOT active in %s. " % (projPrefix, branch))
                        os.chdir(workspaceDir)                          
                        
        if not submodulesDidChange and not nestedProjectListDidChange:
            uvArgs.append("--checkSubprojects")
        else:
            updateViewSet = args["--noUpdateView"] or args["--updateView"]
            if not updateViewSet:
                updateView = utility.userInput("Submodules or subprojects were added/removed as a result of this checkout. \n" + 
                                               "%s" % ("Added Projects: %s\n" % ','.join(addedProjects) if addedProjects else "") + 
                                               "%s" % ("Added Submodules: %s\n"% ','.join(addedModules) if addedModules else "") +
                                               "%s" % ("Removed Projects: %s\n" % ','.join(removedProjects) if removedProjects else "") +
                                               "%s" % ("Removed Submodules: %s\n" % ','.join(removedModules) if removedModules else "") +
                                               "Would you like to update your workspace view? [y/n]", 'n')
            elif args["--noUpdateView"]:
                updateView = False
            elif args["--updateView"]:
                updateView = True
            if not updateView:
                uvArgs.append("--checkSubprojects")
            
        if args["-b"]: 
            uvArgs.append("-b")
        if sync:
            uvArgs.append("--sync=True")
        else:
            uvArgs.append("--sync=False")

        # in case the user switches to a branch without corresponding branches in the submodules, make sure active submodules
        # are at the right commit before possibly creating new branches at the current HEAD. 
        git.submodule("update")
        utility.printMsg("Calling grape uv %s to ensure branches are consistent across all active subprojects and submodules." % ' '.join(uvArgs))
        grapeConfig.read()
        grapeMenu.menu().applyMenuChoice('uv', uvArgs)

        os.chdir(workspaceDir)
        
        if sync:
            utility.printMsg("Switched to %s. Updating from remote...\n\t (use --sync=False or .grapeconfig.post-checkout.syncWithOrigin to change behavior.)" % branch)            
            if args["-b"]:
                grapeMenu.menu().applyMenuChoice("push")
            else:
                grapeMenu.menu().applyMenuChoice("pull")
        else:
            utility.printMsg("Switched to %s." % branch)
            
        global _skipBranchCreation
        global _createNewBranch
        _skipBranchCreation = False
        _createNewBranch = False        
        return True
Esempio n. 13
0
    def execute(self, args):
        name = args["--name"]
        prefix = args["--prefix"]
        url = args["--url"]
        fullurl = utility.parseSubprojectRemoteURL(url)
        branch = args["--branch"]
        config = grapeConfig.grapeConfig()
        projectType = self.parseSubprojectType(config, args)
        proceed = args["--noverify"]
        if projectType == "subtree":
            #  whether or not to squash
            squash = args["--squash"] or config.get("subtrees", "mergePolicy").strip().lower() == "squash"
            squash = squash and not args["--nosquash"]
            squash_arg = "--squash" if squash else ""
            # expand the URL
            if not proceed:
                proceed = utility.userInput("About to create a subtree called %s at path %s,\n"
                                            "cloned from %s at %s " % (name, prefix, fullurl, branch) +
                                            ("using a squash merge." if squash else "") + "\nProceed? [y/n]", "y")

            if proceed:
                os.chdir(utility.workspaceDir())
                git.subtree("add %s --prefix=%s %s %s" % (squash_arg, prefix, fullurl, branch))

                #update the configuration file
                current_cfg_names = config.get("subtrees", "names").split()
                if not current_cfg_names or current_cfg_names[0].lower() == "none":
                    config.set("subtrees", "names", name)
                else:
                    current_cfg_names.append(name)
                    config.set("subtrees", "names", ' '.join(current_cfg_names))

                section = "subtree-%s" % name
                config.add_section(section)
                config.set(section, "prefix", prefix)
                config.set(section, "remote", url)
                config.set(section, "topicPrefixMappings", "?:%s" % branch)
                with open(os.path.join(utility.workspaceDir(), ".grapeconfig"), "w") as f:
                    config.write(f)
                utility.printMsg("Successfully added subtree branch. \n"
                      "Updated .grapeconfig file. Review changes and then commit. ")
        elif projectType == "submodule":
            if not proceed:
                proceed = utility.userInput("about to add %s as a submodule at path %s,\n"
                                            "cloned from %s at branch %s.\nproceed? [y/n]" %
                                            (name, prefix, url, branch), "y")
            if proceed:
                git.submodule("add --name %s --branch %s %s %s" % (name, branch, url, prefix))
                print("Successfully added submodule %s at %s. Please review changes and commit." % (name, prefix))
        elif projectType == "nested":
            if not proceed:
                proceed = utility.userInput(" about to clone %s as a nested git repo at path %s,\n"
                                            "cloned from %s at branch %s.\nProceed? [y/n]" %
                                            (name, prefix, url, branch), 'y')
            if proceed:
                git.clone("%s %s" % (fullurl, prefix))
                ignorePath = os.path.join(git.baseDir(), ".gitignore")
                with open(ignorePath, 'a') as ignore:
                    ignore.writelines([prefix+'\n'])
                git.add(ignorePath)
                wsConfig = grapeConfig.workspaceConfig()
                currentSubprojects = wsConfig.getList("nestedProjects", "names")
                currentSubprojects.append(name)
                wsConfig.set("nestedProjects", "names", ' '.join(currentSubprojects))
                newSection = "nested-%s" % name
                wsConfig.ensureSection(newSection)
                wsConfig.set(newSection, "prefix", prefix)
                wsConfig.set(newSection, "url", url)
                configFileName = os.path.join(utility.workspaceDir(), ".grapeconfig")
                with open(os.path.join(configFileName), 'w') as f:
                    wsConfig.write(f)
                git.add(configFileName)
                git.commit("%s %s -m \"GRAPE: Added nested subproject %s\"" % (ignorePath, configFileName, prefix))
                # update the runtime config with the new workspace .grapeconfig's settings.
                grapeConfig.read()

                userConfig = grapeConfig.grapeUserConfig()
                userConfig.ensureSection(newSection)
                userConfig.set(newSection, "active", "True")
                grapeConfig.writeConfig(userConfig, os.path.join(utility.workspaceDir(), ".git", ".grapeuserconfig"))

        return True
Esempio n. 14
0
def handleCheckoutMRE(mre):
    global _skipBranchCreation
    global _createNewBranch
    newBranchReposArgTuples = []
    newBranches = []

    for e1, branch, project, checkoutargs in zip(mre.exceptions(),
                                                 mre.branches(), mre.repos(),
                                                 mre.args()):
        try:
            raise e1
        except git.GrapeGitError as e:
            with utility.cd(project):
                if "pathspec" in e.gitOutput:
                    createNewBranch = _createNewBranch
                    if _skipBranchCreation:
                        utility.printMsg("Skipping checkout of %s in %s" %
                                         (branch, project))
                        createNewBranch = False

                    elif not createNewBranch:
                        createNewBranch = utility.userInput(
                            "Branch not found locally or remotely. Would you like to create a "
                            "new branch called %s in %s? \n"
                            "(select 'a' to say yes for (a)ll, 's' to (s)kip creation for branches that don't exist )"
                            "\n(y,n,a,s)" % (branch, project), 'y')

                    if str(createNewBranch).lower()[0] == 'a':
                        _createNewBranch = True
                        createNewBranch = True
                    if str(createNewBranch).lower()[0] == 's':
                        _skipBranchCreation = True
                        createNewBranch = False
                    if createNewBranch:
                        newBranchReposArgTuples.append((project, branch, {
                            "checkout":
                            checkoutargs[0]
                        }))
                    else:
                        continue

                elif "already exists" in e.gitOutput:
                    utility.printMsg("Branch %s already exists in %s." %
                                     (branch, project))
                    branchDescription = git.commitDescription(branch)
                    headDescription = git.commitDescription("HEAD")
                    if branchDescription == headDescription:
                        utility.printMsg(
                            "Branch %s and HEAD are the same. Switching to %s."
                            % (branch, branch))
                        action = "k"
                    else:
                        utility.printMsg(
                            "Branch %s and HEAD are not the same." % branch)
                        action = ''
                        valid = False
                        while not valid:
                            action = utility.userInput(
                                "Would you like to \n (k)eep it as is at: %s \n"
                                " or \n (f)orce it to: %s? \n(k,f)" %
                                (branchDescription, headDescription), 'k')
                            valid = (action == 'k') or (action == 'f')
                            if not valid:
                                utility.printMsg(
                                    "Invalid input. Enter k or f. ")
                    if action == 'k':
                        git.checkout(branch)
                    elif action == 'f':
                        git.checkout("-B %s" % branch)
                elif "conflict" in e.gitOutput.lower():
                    utility.printMsg(
                        "CONFLICT occurred when pulling %s from origin." %
                        branch)
                elif "does not appear to be a git repository" in e.gitOutput.lower(
                ):
                    utility.printMsg(
                        "Remote 'origin' does not exist. "
                        "This branch was not updated from a remote repository."
                    )
                elif "Couldn't find remote ref" in e.gitOutput:
                    utility.printMsg(
                        "Remote of %s does not have reference to %s. You may want to push this branch. "
                        % (project, branch))
                else:
                    raise e

    if len(newBranchReposArgTuples) > 0:
        utility.MultiRepoCommandLauncher(
            createNewBranches,
            listOfRepoBranchArgTuples=newBranchReposArgTuples
        ).launchFromWorkspaceDir(handleMRE=createNewBranchesMREHandler)
Esempio n. 15
0
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        checkoutargs = ''
        branch = args["<branch>"]
        if args['-b']:
            checkoutargs += " -b"

        workspaceDir = utility.workspaceDir()
        os.chdir(workspaceDir)
        currentSHA = git.shortSHA("HEAD")

        utility.printMsg("Performing checkout of %s in outer level project." %
                         branch)
        launcher = utility.MultiRepoCommandLauncher(handledCheckout,
                                                    listOfRepoBranchArgTuples=[
                                                        (workspaceDir, branch,
                                                         [checkoutargs, sync])
                                                    ])

        if not launcher.launchFromWorkspaceDir(handleMRE=handleCheckoutMRE)[0]:
            return False
        previousSHA = currentSHA

        submoduleListDidChange = ".gitmodules" in git.diff(
            "--name-only %s %s" % (previousSHA, branch))
        addedModules = []
        removedModules = []
        uvArgs = []
        submodulesDidChange = False
        if submoduleListDidChange and grapeConfig.grapeConfig().getboolean(
                "workspace", "manageSubmodules"):

            self.parseGitModulesDiffOutput(
                git.diff("%s %s --no-ext-diff -- .gitmodules" %
                         (previousSHA, branch)), addedModules, removedModules)
            if not addedModules and not removedModules:
                pass
            else:
                submodulesDidChange = True

                if removedModules:
                    for sub in removedModules:
                        try:
                            os.chdir(os.path.join(workspaceDir, sub))
                            if git.isWorkingDirectoryClean():
                                cleanBehaviorSet = args[
                                    "--noUpdateView"] or args["--updateView"]
                                if not cleanBehaviorSet:
                                    clean = utility.userInput(
                                        "Would you like to remove the submodule %s ?"
                                        % sub, 'n')
                                elif args["--noUpdateView"]:
                                    clean = False
                                elif args["--updateView"]:
                                    clean = True
                                if clean:
                                    utility.printMsg(
                                        "Removing clean submodule %s." % sub)
                                    os.chdir(workspaceDir)
                                    shutil.rmtree(
                                        os.path.join(workspaceDir, sub))
                            else:
                                utility.printMsg(
                                    "Unstaged / committed changes in %s, not removing."
                                    % sub)
                                os.chdir(workspaceDir)
                        except OSError:
                            pass

        # check to see if nested project list changed
        addedProjects = []
        removedProjects = []
        removedProjectPrefices = {}
        nestedProjectListDidChange = False
        os.chdir(workspaceDir)
        if ".grapeconfig" in git.diff("--name-only %s %s" %
                                      (previousSHA, branch)):
            configDiff = git.diff("--no-ext-diff %s %s -- %s" %
                                  (previousSHA, branch, ".grapeconfig"))
            nestedProjectListDidChange = "[nestedprojects]" in configDiff.lower(
            )
            self.parseGrapeConfigNestedProjectDiffOutput(
                configDiff, addedProjects, removedProjects,
                removedProjectPrefices)

            if removedProjects:
                config = grapeConfig.grapeConfig()
                for proj in removedProjects:
                    projPrefix = removedProjectPrefices[proj]
                    try:
                        os.chdir(os.path.join(workspaceDir, proj))
                    except OSError as e:
                        if e.errno == 2:
                            # directory doesn't exist, that's OK since we're thinking about removing it
                            # anyways at this point...
                            continue
                    if git.isWorkingDirectoryClean():
                        removeBehaviorSet = args["--noUpdateView"] or args[
                            "--updateView"]
                        if not removeBehaviorSet:
                            remove = utility.userInput(
                                "Would you like to remove the nested subproject %s? \n"
                                "All work that has not been pushed will be lost. "
                                % projPrefix, 'n')
                        elif args["--noUpdateView"]:
                            remove = False
                        elif args["--updateView"]:
                            remove = True
                        if remove:
                            remove = utility.userInput(
                                "Are you sure you want to remove %s? When you switch back to the previous branch, you will have to\n"
                                "reclone %s." % (projPrefix, projPrefix), 'n')
                        if remove:
                            os.chdir(workspaceDir)
                            shutil.rmtree(
                                os.path.join(workspaceDir, projPrefix))
                    else:
                        utility.printMsg(
                            "Unstaged / committed changes in %s, not removing. \n"
                            "Note this project is NOT active in %s. " %
                            (projPrefix, branch))
                        os.chdir(workspaceDir)

        if not submodulesDidChange and not nestedProjectListDidChange:
            uvArgs.append("--checkSubprojects")
        else:
            updateViewSet = args["--noUpdateView"] or args["--updateView"]
            if not updateViewSet:
                updateView = utility.userInput(
                    "Submodules or subprojects were added/removed as a result of this checkout. \n"
                    + "%s" %
                    ("Added Projects: %s\n" %
                     ','.join(addedProjects) if addedProjects else "") + "%s" %
                    ("Added Submodules: %s\n" %
                     ','.join(addedModules) if addedModules else "") + "%s" %
                    ("Removed Projects: %s\n" %
                     ','.join(removedProjects) if removedProjects else "") +
                    "%s" %
                    ("Removed Submodules: %s\n" %
                     ','.join(removedModules) if removedModules else "") +
                    "Would you like to update your workspace view? [y/n]", 'n')
            elif args["--noUpdateView"]:
                updateView = False
            elif args["--updateView"]:
                updateView = True
            if not updateView:
                uvArgs.append("--checkSubprojects")

        if args["-b"]:
            uvArgs.append("-b")
        if sync:
            uvArgs.append("--sync=True")
        else:
            uvArgs.append("--sync=False")

        # in case the user switches to a branch without corresponding branches in the submodules, make sure active submodules
        # are at the right commit before possibly creating new branches at the current HEAD.
        git.submodule("update")
        utility.printMsg(
            "Calling grape uv %s to ensure branches are consistent across all active subprojects and submodules."
            % ' '.join(uvArgs))
        grapeConfig.read()
        grapeMenu.menu().applyMenuChoice('uv', uvArgs)

        os.chdir(workspaceDir)

        if sync:
            utility.printMsg(
                "Switched to %s. Updating from remote...\n\t (use --sync=False or .grapeconfig.post-checkout.syncWithOrigin to change behavior.)"
                % branch)
            if args["-b"]:
                grapeMenu.menu().applyMenuChoice("push")
            else:
                grapeMenu.menu().applyMenuChoice("pull")
        else:
            utility.printMsg("Switched to %s." % branch)

        global _skipBranchCreation
        global _createNewBranch
        _skipBranchCreation = False
        _createNewBranch = False
        return True
Esempio n. 16
0
 def mergeIntoCurrent(self, branchName, args, projectName):
     choice = False
     strategy = None
     if args["--continue"]:
         if self.continueLocalMerge(args):
             return True
     if args['--am']:
         strategy = 'am'
     elif args['--as']: 
         strategy = 'as' 
     elif args['--at']: 
         strategy = 'at'
     elif args['--aT']: 
         strategy = 'aT'
     elif args['--ay']: 
         strategy = 'ay'
     elif args['--aY']: 
         strategy = 'aY'
 
     if not strategy or args['--askAll']:
         repoSpec = " in %s" % projectName if args['--askAll'] else ""
         strategy = utility.userInput("How do you want to resolve changes%s? [am / as / at / aT / ay / aY] \n" % repoSpec +
                                      "am: Auto Merge (default) \n" +
                                      "as: Safe Merge - issues conflicts if both branches touch same file.\n" +
                                      "at: Accept Theirs - accept changes in %s if both branches touch same file\n" % branchName +
                                      "aT: Accept Theirs (if conflicted) - resolves conflicts by accepting changes in %s\n" % branchName +
                                      "ay: Accept Yours - accept changes in current branch if both branches touch same file\n" +
                                      "aY: Accept Yours (if conflicted) - resolves conflicts by using changes in current branch.",
                                      "am")
 
     if strategy == 'am':
         args["--am"] = True
         utility.printMsg("Merging using git's default strategy...")
         choice = self.merge(branchName, "", args)
     elif strategy == 'as' or strategy == 'at' or strategy == 'ay':
         if strategy == 'as':
             args["--as"] = True
             # this employs using the custom low-level merge driver "verify" and
             # appending a "* merge=verify" to the .gitattributes file.
             #
             # see
             # http://stackoverflow.com/questions/5074452/git-how-to-force-merge-conflict-and-manual-merge-on-selected-file
             # for details.
             utility.printMsg("Merging forcing conflicts whenever both branches edited the same file...")
         elif strategy == 'at':
             args["--at"] = True
         elif strategy == 'ay':
             args["--ay"] = True
         base = git.gitDir()
         if base == "":
             return False
         attributes = os.path.join(base, ".gitattributes")
         tmpattributes = None
         if os.path.exists(attributes): 
             tmpattributes = os.path.join(base, ".gitattributes.tmp")
             # save original attributes file
             shutil.copyfile(attributes, tmpattributes)
             #append merge driver strategy to the attributes file
             with open(attributes, 'a') as f:
                 f.write("* merge=verify")
         else: 
             with open(attributes, 'w') as f:
                 f.write("* merge=verify")
 
         # perform the merge
         choice = self.merge(branchName, "", args)
 
         # restore original attributes file
         if tmpattributes:
             shutil.copyfile(tmpattributes, attributes)
             os.remove(tmpattributes)
         else:
             os.remove(attributes)
     elif strategy == 'aT':
         args["--aT"] = True
         utility.printMsg("Merging using recursive strategy, resolving conflicts cleanly with changes in %s..." % branchName)
         choice = self.merge(branchName, "-Xtheirs", args)
     elif strategy == 'aY':
         args["--aY"] = True
         utility.printMsg("Merging using recursive strategy, resolving conflicts cleanly with current branch's changes...")
         choice = self.merge(branchName, "-Xours", args)
 
     return choice
Esempio n. 17
0
    def defineActiveSubmodules(projectType="submodule"):
        """
        Queries the user for the submodules (projectType == "submodule") or nested subprojects
        (projectType == "nested subproject") they would like to activate.

        """
        if projectType == "submodule":
            allSubprojects = git.getAllSubmodules()
            activeSubprojects = git.getActiveSubmodules()

        if projectType == "nested subproject":
            config = grapeConfig.grapeConfig()
            allSubprojectNames = config.getAllNestedSubprojects()
            allSubprojects = []
            for project in allSubprojectNames:
                allSubprojects.append(
                    config.get("nested-%s" % project, "prefix"))
            activeSubprojects = grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes(
            )

        toplevelDirs = {}
        toplevelActiveDirs = {}
        toplevelSubs = []
        for sub in allSubprojects:
            # we are taking advantage of the fact that branchPrefixes are the same as directory prefixes for local
            # top-level dirs.
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix] = []
                toplevelActiveDirs[prefix] = []
        for sub in allSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix].append(sub)
            else:
                toplevelSubs.append(sub)
        for sub in activeSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelActiveDirs[prefix].append(sub)

        included = {}
        for directory, subprojects in toplevelDirs.items():

            activeDir = toplevelActiveDirs[directory]
            if len(activeDir) == 0:
                defaultValue = "none"
            elif set(activeDir) == set(subprojects):
                defaultValue = "all"
            else:
                defaultValue = "some"

            opt = utility.userInput(
                "Would you like all, some, or none of the %ss in %s?" %
                (projectType, directory),
                default=defaultValue)
            if opt.lower()[0] == "a":
                for subproject in subprojects:
                    included[subproject] = True

            if opt.lower()[0] == "n":
                for subproject in subprojects:
                    included[subproject] = False
            if opt.lower()[0] == "s":
                for subproject in subprojects:
                    included[subproject] = utility.userInput(
                        "Would you like %s %s? [y/n]" %
                        (projectType, subproject), 'y' if
                        (subproject in activeSubprojects) else 'n')
        for subproject in toplevelSubs:
            included[subproject] = utility.userInput(
                "Would you like %s %s? [y/n]" % (projectType, subproject),
                'y' if (subproject in activeSubprojects) else 'n')
        return included
Esempio n. 18
0
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        config = grapeConfig.grapeConfig()
        origwd = os.getcwd()
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)
        base = git.baseDir()
        if base == "":
            return False
        hasSubmodules = len(git.getAllSubmodules()) > 0 and not args["--skipSubmodules"]
        includedSubmodules = {}
        includedNestedSubprojectPrefixes = {}

        allSubmodules = git.getAllSubmodules()
        allNestedSubprojects = config.getAllNestedSubprojects()
        
        addedSubmodules = [] 
        addedNestedSubprojects = [] 
        addedProjects = args["--add"]
        notFound = []
       
        for proj in addedProjects:
            if proj in allSubmodules:
                addedSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                addedNestedSubprojects.append(proj)
            else:
                notFound.append(proj)
        
        rmSubmodules = []
        rmNestedSubprojects = []
        rmProjects = args["--rm"]
        
        for proj in rmProjects:
            if proj in allSubmodules:
                rmSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                rmNestedSubprojects.append(proj)
            else:
                notFound.append(proj)

        if notFound:
            utility.printMsg("\"%s\" not found in submodules %s \nor\n nested subprojects %s" % (",".join(notFound),",".join(allSubmodules),",".join(allNestedSubprojects)))
            return False
                
       
        if not args["--checkSubprojects"]:
            # get submodules to update
            if hasSubmodules:
                if args["--allSubmodules"]: 
                    includedSubmodules = {sub:True for sub in allSubmodules}
                elif args["--add"] or args["--rm"]:
                    includedSubmodules = {sub:True for sub in git.getActiveSubmodules()}
                    includedSubmodules.update({sub:True for sub in addedSubmodules})
                    includedSubmodules.update({sub:False for sub in rmSubmodules})
                else:
                    includedSubmodules = self.defineActiveSubmodules()

            # get subprojects to update
            if not args["--skipNestedSubprojects"]: 
                
                nestedPrefixLookup = lambda x : config.get("nested-%s" % x, "prefix")
                if args["--allNestedSubprojects"]: 
                    includedNestedSubprojectPrefixes = {nestedPrefixLookup(sub):True for sub in allNestedSubprojects}
                elif args["--add"] or args["--rm"]:
                    includedNestedSubprojectPrefixes = {sub:True for sub in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()}
                    includedNestedSubprojectPrefixes.update({nestedPrefixLookup(sub):True for sub in addedNestedSubprojects})
                    includedNestedSubprojectPrefixes.update({nestedPrefixLookup(sub):False for sub in rmNestedSubprojects})
                else:
                    includedNestedSubprojectPrefixes = self.defineActiveNestedSubprojects()                    
            
            if hasSubmodules:
                initStr = ""
                deinitStr = ""
                rmCachedStr = ""
                resetStr = ""
                for submodule, nowActive in includedSubmodules.items():
                    if nowActive:
                        initStr += ' %s' % submodule
                    else:
                        deinitStr += ' %s' % submodule
                        rmCachedStr += ' %s' % submodule
                        resetStr += ' %s' % submodule
                if args["-f"] and deinitStr:
                    deinitStr = "-f"+deinitStr

                utility.printMsg("Configuring submodules...")
                utility.printMsg("Initializing submodules...")
                git.submodule("init %s" % initStr.strip())
                if deinitStr:
                    utility.printMsg("Deiniting submodules that were not requested... (%s)" % deinitStr)
                    done = False
                    while not done:
                        try:
                            git.submodule("deinit %s" % deinitStr.strip())
                            done = True
                        except git.GrapeGitError as e:
                            if "the following file has local modifications" in e.gitOutput:
                                print e.gitOutput
                                utility.printMsg("A submodule that you wanted to remove has local modifications. "
                                                 "Use grape uv -f to force removal.")
                                return False
                            
                            elif "use 'rm -rf' if you really want to remove it including all of its history" in e.gitOutput:
                                if not args["-f"]:
                                    raise e
                                # it is safe to move the .git of the submodule to the .git/modules area of the workspace...
                                module = None
                                for l in e.gitOutput.split('\n'):
                                    if "Submodule work tree" in l and "contains a .git directory" in l:
                                        module = l.split("'")[1]
                                        break
                                if module:
                                    src = os.path.join(module, ".git")
                                    dest =  os.path.join(wsDir, ".git", "modules", module)
                                    utility.printMsg("Moving %s to %s"%(src, dest))
                                    shutil.move(src, dest )
                                else:
                                    raise e
                            else:
                                raise e
                    git.rm("--cached %s" % rmCachedStr)
                    git.reset(" %s" % resetStr)

                if initStr:
                    utility.printMsg("Updating active submodules...(%s)" % initStr)
                    git.submodule("update")

            # handle nested subprojects
            if not args["--skipNestedSubprojects"]: 
                reverseLookupByPrefix = {nestedPrefixLookup(sub) : sub for sub in allNestedSubprojects} 
                userConfig = grapeConfig.grapeUserConfig()
                updatedActiveList = []
                for subproject, nowActive in includedNestedSubprojectPrefixes.items():
                    subprojectName = reverseLookupByPrefix[subproject]
                    section = "nested-%s" % reverseLookupByPrefix[subproject]
                    userConfig.ensureSection(section)
                    previouslyActive = userConfig.getboolean(section, "active")
                    previouslyActive = previouslyActive and os.path.exists(os.path.join(base, subproject, ".git"))
                    userConfig.set(section, "active", "True" if previouslyActive else "False")
                    if nowActive and previouslyActive:
                        updatedActiveList.append(subprojectName)
    
                    if nowActive and not previouslyActive:
                        utility.printMsg("Activating Nested Subproject %s" % subproject)
                        if not addSubproject.AddSubproject.activateNestedSubproject(subprojectName, userConfig):
                            utility.printMsg("Can't activate %s. Exiting..." % subprojectName)
                            return False
                        
                        updatedActiveList.append(subprojectName)
    
                    if not nowActive and not previouslyActive:
                        pass
                    if not nowActive and previouslyActive:
                        #remove the subproject
                        subprojectdir = os.path.join(base, utility.makePathPortable(subproject))
                        proceed = args["-f"] or \
                                  utility.userInput("About to delete all contents in %s. Any uncommitted changes, committed changes "
                                                    "that have not been pushed, or ignored files will be lost.  Proceed?" %
                                                    subproject, 'n')
                        if proceed:
                            shutil.rmtree(subprojectdir)
                userConfig.setActiveNestedSubprojects(updatedActiveList)
                grapeConfig.writeConfig(userConfig, os.path.join(utility.workspaceDir(), ".git", ".grapeuserconfig"))

        checkoutArgs = "-b" if args["-b"] else ""

        safeSwitchWorkspaceToBranch( git.currentBranch(), checkoutArgs, sync)

        os.chdir(origwd)

        return True
Esempio n. 19
0
    def execute(self, args):
        sync = args["--sync"].lower().strip()
        sync = sync == "true" or sync == "yes"
        args["--sync"] = sync
        config = grapeConfig.grapeConfig()
        origwd = os.getcwd()
        wsDir = utility.workspaceDir()
        os.chdir(wsDir)
        base = git.baseDir()
        if base == "":
            return False
        hasSubmodules = len(
            git.getAllSubmodules()) > 0 and not args["--skipSubmodules"]
        includedSubmodules = {}
        includedNestedSubprojectPrefixes = {}

        allSubmodules = git.getAllSubmodules()
        allNestedSubprojects = config.getAllNestedSubprojects()

        addedSubmodules = []
        addedNestedSubprojects = []
        addedProjects = args["--add"]
        notFound = []

        for proj in addedProjects:
            if proj in allSubmodules:
                addedSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                addedNestedSubprojects.append(proj)
            else:
                notFound.append(proj)

        rmSubmodules = []
        rmNestedSubprojects = []
        rmProjects = args["--rm"]

        for proj in rmProjects:
            if proj in allSubmodules:
                rmSubmodules.append(proj)
            elif proj in allNestedSubprojects:
                rmNestedSubprojects.append(proj)
            else:
                notFound.append(proj)

        if notFound:
            utility.printMsg(
                "\"%s\" not found in submodules %s \nor\n nested subprojects %s"
                % (",".join(notFound), ",".join(allSubmodules),
                   ",".join(allNestedSubprojects)))
            return False

        if not args["--checkSubprojects"]:
            # get submodules to update
            if hasSubmodules:
                if args["--allSubmodules"]:
                    includedSubmodules = {sub: True for sub in allSubmodules}
                elif args["--add"] or args["--rm"]:
                    includedSubmodules = {
                        sub: True
                        for sub in git.getActiveSubmodules()
                    }
                    includedSubmodules.update(
                        {sub: True
                         for sub in addedSubmodules})
                    includedSubmodules.update(
                        {sub: False
                         for sub in rmSubmodules})
                else:
                    includedSubmodules = self.defineActiveSubmodules()

            # get subprojects to update
            if not args["--skipNestedSubprojects"]:

                nestedPrefixLookup = lambda x: config.get(
                    "nested-%s" % x, "prefix")
                if args["--allNestedSubprojects"]:
                    includedNestedSubprojectPrefixes = {
                        nestedPrefixLookup(sub): True
                        for sub in allNestedSubprojects
                    }
                elif args["--add"] or args["--rm"]:
                    includedNestedSubprojectPrefixes = {
                        sub: True
                        for sub in grapeConfig.GrapeConfigParser.
                        getAllActiveNestedSubprojectPrefixes()
                    }
                    includedNestedSubprojectPrefixes.update({
                        nestedPrefixLookup(sub): True
                        for sub in addedNestedSubprojects
                    })
                    includedNestedSubprojectPrefixes.update({
                        nestedPrefixLookup(sub): False
                        for sub in rmNestedSubprojects
                    })
                else:
                    includedNestedSubprojectPrefixes = self.defineActiveNestedSubprojects(
                    )

            if hasSubmodules:
                initStr = ""
                deinitStr = ""
                rmCachedStr = ""
                resetStr = ""
                for submodule, nowActive in includedSubmodules.items():
                    if nowActive:
                        initStr += ' %s' % submodule
                    else:
                        deinitStr += ' %s' % submodule
                        rmCachedStr += ' %s' % submodule
                        resetStr += ' %s' % submodule
                if args["-f"] and deinitStr:
                    deinitStr = "-f" + deinitStr

                utility.printMsg("Configuring submodules...")
                utility.printMsg("Initializing submodules...")
                git.submodule("init %s" % initStr.strip())
                if deinitStr:
                    utility.printMsg(
                        "Deiniting submodules that were not requested... (%s)"
                        % deinitStr)
                    done = False
                    while not done:
                        try:
                            git.submodule("deinit %s" % deinitStr.strip())
                            done = True
                        except git.GrapeGitError as e:
                            if "the following file has local modifications" in e.gitOutput:
                                print e.gitOutput
                                utility.printMsg(
                                    "A submodule that you wanted to remove has local modifications. "
                                    "Use grape uv -f to force removal.")
                                return False

                            elif "use 'rm -rf' if you really want to remove it including all of its history" in e.gitOutput:
                                if not args["-f"]:
                                    raise e
                                # it is safe to move the .git of the submodule to the .git/modules area of the workspace...
                                module = None
                                for l in e.gitOutput.split('\n'):
                                    if "Submodule work tree" in l and "contains a .git directory" in l:
                                        module = l.split("'")[1]
                                        break
                                if module:
                                    src = os.path.join(module, ".git")
                                    dest = os.path.join(
                                        wsDir, ".git", "modules", module)
                                    utility.printMsg("Moving %s to %s" %
                                                     (src, dest))
                                    shutil.move(src, dest)
                                else:
                                    raise e
                            else:
                                raise e
                    git.rm("--cached %s" % rmCachedStr)
                    git.reset(" %s" % resetStr)

                if initStr:
                    utility.printMsg("Updating active submodules...(%s)" %
                                     initStr)
                    git.submodule("update")

            # handle nested subprojects
            if not args["--skipNestedSubprojects"]:
                reverseLookupByPrefix = {
                    nestedPrefixLookup(sub): sub
                    for sub in allNestedSubprojects
                }
                userConfig = grapeConfig.grapeUserConfig()
                updatedActiveList = []
                for subproject, nowActive in includedNestedSubprojectPrefixes.items(
                ):
                    subprojectName = reverseLookupByPrefix[subproject]
                    section = "nested-%s" % reverseLookupByPrefix[subproject]
                    userConfig.ensureSection(section)
                    previouslyActive = userConfig.getboolean(section, "active")
                    previouslyActive = previouslyActive and os.path.exists(
                        os.path.join(base, subproject, ".git"))
                    userConfig.set(section, "active",
                                   "True" if previouslyActive else "False")
                    if nowActive and previouslyActive:
                        updatedActiveList.append(subprojectName)

                    if nowActive and not previouslyActive:
                        utility.printMsg("Activating Nested Subproject %s" %
                                         subproject)
                        if not addSubproject.AddSubproject.activateNestedSubproject(
                                subprojectName, userConfig):
                            utility.printMsg("Can't activate %s. Exiting..." %
                                             subprojectName)
                            return False

                        updatedActiveList.append(subprojectName)

                    if not nowActive and not previouslyActive:
                        pass
                    if not nowActive and previouslyActive:
                        #remove the subproject
                        subprojectdir = os.path.join(
                            base, utility.makePathPortable(subproject))
                        proceed = args["-f"] or \
                                  utility.userInput("About to delete all contents in %s. Any uncommitted changes, committed changes "
                                                    "that have not been pushed, or ignored files will be lost.  Proceed?" %
                                                    subproject, 'n')
                        if proceed:
                            shutil.rmtree(subprojectdir)
                userConfig.setActiveNestedSubprojects(updatedActiveList)
                grapeConfig.writeConfig(
                    userConfig,
                    os.path.join(utility.workspaceDir(), ".git",
                                 ".grapeuserconfig"))

        checkoutArgs = "-b" if args["-b"] else ""

        safeSwitchWorkspaceToBranch(git.currentBranch(), checkoutArgs, sync)

        os.chdir(origwd)

        return True
Esempio n. 20
0
    def execute(self, args):
        name = args["--name"]
        prefix = args["--prefix"]
        url = args["--url"]
        fullurl = utility.parseSubprojectRemoteURL(url)
        branch = args["--branch"]
        config = grapeConfig.grapeConfig()
        projectType = self.parseSubprojectType(config, args)
        proceed = args["--noverify"]
        if projectType == "subtree":
            #  whether or not to squash
            squash = args["--squash"] or config.get(
                "subtrees", "mergePolicy").strip().lower() == "squash"
            squash = squash and not args["--nosquash"]
            squash_arg = "--squash" if squash else ""
            # expand the URL
            if not proceed:
                proceed = utility.userInput(
                    "About to create a subtree called %s at path %s,\n"
                    "cloned from %s at %s " % (name, prefix, fullurl, branch) +
                    ("using a squash merge." if squash else "") +
                    "\nProceed? [y/n]", "y")

            if proceed:
                os.chdir(utility.workspaceDir())
                git.subtree("add %s --prefix=%s %s %s" %
                            (squash_arg, prefix, fullurl, branch))

                #update the configuration file
                current_cfg_names = config.get("subtrees", "names").split()
                if not current_cfg_names or current_cfg_names[0].lower(
                ) == "none":
                    config.set("subtrees", "names", name)
                else:
                    current_cfg_names.append(name)
                    config.set("subtrees", "names",
                               ' '.join(current_cfg_names))

                section = "subtree-%s" % name
                config.add_section(section)
                config.set(section, "prefix", prefix)
                config.set(section, "remote", url)
                config.set(section, "topicPrefixMappings", "?:%s" % branch)
                with open(os.path.join(utility.workspaceDir(), ".grapeconfig"),
                          "w") as f:
                    config.write(f)
                utility.printMsg(
                    "Successfully added subtree branch. \n"
                    "Updated .grapeconfig file. Review changes and then commit. "
                )
        elif projectType == "submodule":
            if not proceed:
                proceed = utility.userInput(
                    "about to add %s as a submodule at path %s,\n"
                    "cloned from %s at branch %s.\nproceed? [y/n]" %
                    (name, prefix, url, branch), "y")
            if proceed:
                git.submodule("add --name %s --branch %s %s %s" %
                              (name, branch, url, prefix))
                print(
                    "Successfully added submodule %s at %s. Please review changes and commit."
                    % (name, prefix))
        elif projectType == "nested":
            if not proceed:
                proceed = utility.userInput(
                    " about to clone %s as a nested git repo at path %s,\n"
                    "cloned from %s at branch %s.\nProceed? [y/n]" %
                    (name, prefix, url, branch), 'y')
            if proceed:
                git.clone("%s %s" % (fullurl, prefix))
                ignorePath = os.path.join(git.baseDir(), ".gitignore")
                with open(ignorePath, 'a') as ignore:
                    ignore.writelines([prefix + '\n'])
                git.add(ignorePath)
                wsConfig = grapeConfig.workspaceConfig()
                currentSubprojects = wsConfig.getList("nestedProjects",
                                                      "names")
                currentSubprojects.append(name)
                wsConfig.set("nestedProjects", "names",
                             ' '.join(currentSubprojects))
                newSection = "nested-%s" % name
                wsConfig.ensureSection(newSection)
                wsConfig.set(newSection, "prefix", prefix)
                wsConfig.set(newSection, "url", url)
                configFileName = os.path.join(utility.workspaceDir(),
                                              ".grapeconfig")
                with open(os.path.join(configFileName), 'w') as f:
                    wsConfig.write(f)
                git.add(configFileName)
                git.commit("%s %s -m \"GRAPE: Added nested subproject %s\"" %
                           (ignorePath, configFileName, prefix))
                # update the runtime config with the new workspace .grapeconfig's settings.
                grapeConfig.read()

                userConfig = grapeConfig.grapeUserConfig()
                userConfig.ensureSection(newSection)
                userConfig.set(newSection, "active", "True")
                grapeConfig.writeConfig(
                    userConfig,
                    os.path.join(utility.workspaceDir(), ".git",
                                 ".grapeuserconfig"))

        return True
Esempio n. 21
0
File: config.py Progetto: LLNL/GRAPE
    def execute(self, args):
        base = git.baseDir()
        if base == "":
            return False
        dotGit = git.gitDir()

        utility.printMsg("Optimizing git performance on slow file systems...")
        #runs file system intensive tasks such as git status and git commit
        # in parallel (important for NFS systems such as LC)
        git.config("core.preloadindex", "true")

        #have git automatically do some garbage collection / optimization
        utility.printMsg("Setting up automatic git garbage collection...")
        git.config("gc.auto", "1")

        #prevents false conflict detection due to differences in filesystem
        # time stamps
        utility.printMsg("Optimizing cross platform portability...")
        git.config("core.trustctime", "false")

        # stores login info for 12 hrs (max allowed by RZBitbucket)

        if not args["--nocredcache"]:
            cache = args["--credcache"]
            if not cache:
                cache = utility.userInput(
                    "Would you like to enable git-managed credential caching?",
                    'y')
            if cache:
                utility.printMsg(
                    "Enabling 12 hr caching of https credentials...")
                if os.name == "nt":
                    git.config("--global credential.helper", "wincred")
                else:
                    git.config("--global credential.helper",
                               "cache --timeout=43200")

        # enables 'as' option for merge strategies -forces a conflict if two branches
        # modify the same file
        mergeVerifyPath = os.path.join(os.path.dirname(__file__), "..",
                                       "merge-and-verify-driver")

        if os.path.exists(mergeVerifyPath):
            utility.printMsg(
                "Enabling safe merges (triggers conflicts any time same file is modified),\n\t see 'as' option for grape m and grape md..."
            )
            git.config("merge.verify.name", "merge and verify driver")
            git.config("merge.verify.driver",
                       "%s/merge-and-verify-driver %A %O %B")
        else:
            utility.printMsg(
                "WARNING: merge and verify script not detected, safe merges ('as' option to grape m / md) will not work!"
            )
        # enables lg as an alias to print a pretty-font summary of
        # key junctions in the history for this branch.
        utility.printMsg("Setting lg as an alias for a pretty log call...")
        git.config(
            "alias.lg",
            "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative --simplify-by-decoration"
        )

        # perform an update of the active subprojects if asked.
        ask = not args["--nouv"]
        updateView = ask and (args["--uv"] or utility.userInput(
            "Do you want to edit your active subprojects?"
            " (you can do this later using grape uv) [y/n]", "n"))
        if updateView:
            grapeMenu.menu().applyMenuChoice("uv", args["--uvArg"])

        # configure git to use p4merge for conflict resolution
        # and diffing

        useP4Merge = not args["--nop4merge"] and (
            args["--p4merge"] or utility.userInput(
                "Would you like to use p4merge as your merge tool? [y/n]",
                "y"))
        # note that this relies on p4merge being in your path somewhere
        if (useP4Merge):
            git.config("merge.keepBackup", "false")
            git.config("merge.tool", "p4merge")
            git.config("mergetool.keepBackup", "false")
            git.config(
                "mergetool.p4merge.cmd",
                'p4merge \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" \"\$MERGED\"')
            git.config("mergetool.p4merge.keepTemporaries", "false")
            git.config("mergetool.p4merge.trustExitCode", "false")
            git.config("mergetool.p4merge.keepBackup", "false")
            utility.printMsg(
                "Configured repo to use p4merge for conflict resolution")
        else:
            git.config("merge.tool", "tkdiff")

        useP4Diff = not args["--nop4diff"] and (
            args["--p4diff"] or utility.userInput(
                "Would you like to use p4merge as your diff tool? [y/n]", "y"))
        # this relies on p4diff being defined as a custom bash script, with the following one-liner:
        # [ $# -eq 7 ] && p4merge "$2" "$5"
        if (useP4Diff):
            p4diffScript = os.path.join(os.path.dirname(__file__), "..",
                                        "p4diff")
            if os.path.exists(p4diffScript):
                git.config("diff.external", p4diffScript)
                utility.printMsg(
                    "Configured repo to use p4merge for diff calls - p4merge must be in your path"
                )
            else:
                utility.printMsg("Could not find p4diff script at %s" %
                                 p4diffScript)
        useGitP4 = args["--git-p4"]
        if (useGitP4):
            git.config("git-p4.useclientspec", "true")
            # create p4 references to enable imports from p4
            p4remotes = os.path.join(dotGit, "refs", "remotes", "p4", "")
            utility.ensure_dir(p4remotes)
            commit = utility.userInput(
                "Please enter a descriptor (e.g. SHA, branch if tip, tag name) of the current git commit that mirrors the p4 repo",
                "master")
            sha = git.SHA(commit)
            with open(os.path.join(p4remotes, "HEAD"), 'w') as f:
                f.write(sha)
            with open(os.path.join(p4remotes, "master"), 'w') as f:
                f.write(sha)

            # to enable exports to p4, a maindev client needs to be set up
            haveCopied = False
            while (not haveCopied):
                p4settings = utility.userInput(
                    "Enter a path to a .p4settings file describing the maindev client you'd like to use for p4 updates",
                    ".p4settings")
                try:
                    shutil.copyfile(p4settings,
                                    os.path.join(base, ".p4settings"))
                    haveCopied = True
                except:
                    print(
                        "could not find p4settings file, please check your path and try again"
                    )
                    return False

        # install hooks here and in all submodules
        utility.printMsg("Installing hooks in all repos...")
        cwd = git.baseDir()
        grapeMenu.menu().applyMenuChoice("installHooks")

        #  ensure all public branches are available in all repos
        submodules = git.getActiveSubmodules()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        submodulePublicBranches = set(
            config.getMapping('workspace',
                              'submoduleTopicPrefixMappings').values())
        for sub in submodules:
            self.ensurePublicBranchesExist(grapeConfig.grapeRepoConfig(sub),
                                           sub, submodulePublicBranches)

        # reset config to the workspace grapeconfig, use that one for all nested projects' public branches.
        wsDir = utility.workspaceDir()
        config = grapeConfig.grapeRepoConfig(wsDir)
        for proj in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes(
        ):
            self.ensurePublicBranchesExist(config, os.path.join(wsDir, proj),
                                           publicBranches)

        self.ensurePublicBranchesExist(config, wsDir, publicBranches)

        return True
Esempio n. 22
0
    def mergeIntoCurrent(self, branchName, args, projectName):
        choice = False
        strategy = None
        if args["--continue"]:
            if self.continueLocalMerge(args):
                return True
        if args['--am']:
            strategy = 'am'
        elif args['--as']:
            strategy = 'as'
        elif args['--at']:
            strategy = 'at'
        elif args['--aT']:
            strategy = 'aT'
        elif args['--ay']:
            strategy = 'ay'
        elif args['--aY']:
            strategy = 'aY'

        if not strategy or args['--askAll']:
            repoSpec = " in %s" % projectName if args['--askAll'] else ""
            strategy = utility.userInput(
                "How do you want to resolve changes%s? [am / as / at / aT / ay / aY] \n"
                % repoSpec + "am: Auto Merge (default) \n" +
                "as: Safe Merge - issues conflicts if both branches touch same file.\n"
                +
                "at: Accept Theirs - accept changes in %s if both branches touch same file\n"
                % branchName +
                "aT: Accept Theirs (if conflicted) - resolves conflicts by accepting changes in %s\n"
                % branchName +
                "ay: Accept Yours - accept changes in current branch if both branches touch same file\n"
                +
                "aY: Accept Yours (if conflicted) - resolves conflicts by using changes in current branch.",
                "am")

        if strategy == 'am':
            args["--am"] = True
            utility.printMsg("Merging using git's default strategy...")
            choice = self.merge(branchName, "", args)
        elif strategy == 'as' or strategy == 'at' or strategy == 'ay':
            if strategy == 'as':
                args["--as"] = True
                # this employs using the custom low-level merge driver "verify" and
                # appending a "* merge=verify" to the .gitattributes file.
                #
                # see
                # http://stackoverflow.com/questions/5074452/git-how-to-force-merge-conflict-and-manual-merge-on-selected-file
                # for details.
                utility.printMsg(
                    "Merging forcing conflicts whenever both branches edited the same file..."
                )
            elif strategy == 'at':
                args["--at"] = True
            elif strategy == 'ay':
                args["--ay"] = True
            base = git.gitDir()
            if base == "":
                return False
            attributes = os.path.join(base, ".gitattributes")
            tmpattributes = None
            if os.path.exists(attributes):
                tmpattributes = os.path.join(base, ".gitattributes.tmp")
                # save original attributes file
                shutil.copyfile(attributes, tmpattributes)
                #append merge driver strategy to the attributes file
                with open(attributes, 'a') as f:
                    f.write("* merge=verify")
            else:
                with open(attributes, 'w') as f:
                    f.write("* merge=verify")

            # perform the merge
            choice = self.merge(branchName, "", args)

            # restore original attributes file
            if tmpattributes:
                shutil.copyfile(tmpattributes, attributes)
                os.remove(tmpattributes)
            else:
                os.remove(attributes)
        elif strategy == 'aT':
            args["--aT"] = True
            utility.printMsg(
                "Merging using recursive strategy, resolving conflicts cleanly with changes in %s..."
                % branchName)
            choice = self.merge(branchName, "-Xtheirs", args)
        elif strategy == 'aY':
            args["--aY"] = True
            utility.printMsg(
                "Merging using recursive strategy, resolving conflicts cleanly with current branch's changes..."
            )
            choice = self.merge(branchName, "-Xours", args)

        return choice
Esempio n. 23
0
    def defineActiveSubmodules(projectType="submodule"):
        """
        Queries the user for the submodules (projectType == "submodule") or nested subprojects
        (projectType == "nested subproject") they would like to activate.

        """
        if projectType == "submodule":
            allSubprojects = git.getAllSubmodules()
            activeSubprojects = git.getActiveSubmodules()

        if projectType == "nested subproject":
            config = grapeConfig.grapeConfig()
            allSubprojectNames = config.getAllNestedSubprojects()
            allSubprojects = []
            for project in allSubprojectNames:
                allSubprojects.append(config.get("nested-%s" % project, "prefix"))
            activeSubprojects = grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes()

        toplevelDirs = {}
        toplevelActiveDirs = {}
        toplevelSubs = []
        for sub in allSubprojects:
            # we are taking advantage of the fact that branchPrefixes are the same as directory prefixes for local
            # top-level dirs.
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix] = []
                toplevelActiveDirs[prefix] = []
        for sub in allSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelDirs[prefix].append(sub)
            else:
                toplevelSubs.append(sub)
        for sub in activeSubprojects:
            prefix = git.branchPrefix(sub)
            if sub != prefix:
                toplevelActiveDirs[prefix].append(sub)

        included = {}
        for directory, subprojects in toplevelDirs.items():

            activeDir = toplevelActiveDirs[directory]
            if len(activeDir) == 0:
                defaultValue = "none"
            elif set(activeDir) == set(subprojects):
                defaultValue = "all"
            else:
                defaultValue = "some"

            opt = utility.userInput("Would you like all, some, or none of the %ss in %s?" % (projectType,directory),
                                    default=defaultValue)
            if opt.lower()[0] == "a":
                for subproject in subprojects:
                    included[subproject] = True
                        
            if opt.lower()[0] == "n":
                for subproject in subprojects:
                    included[subproject] = False
            if opt.lower()[0] == "s":
                for subproject in subprojects: 
                    included[subproject] = utility.userInput("Would you like %s %s? [y/n]" % (projectType, subproject),
                                                             'y' if (subproject in activeSubprojects) else 'n')
        for subproject in toplevelSubs:
            included[subproject] = utility.userInput("Would you like %s %s? [y/n]" % (projectType, subproject),
                                                     'y' if (subproject in activeSubprojects) else 'n')
        return included
Esempio n. 24
0
def handleCheckoutMRE(mre):
    global _skipBranchCreation
    global _createNewBranch
    newBranchReposArgTuples = []
    newBranches = []
    
    for e1, branch, project, checkoutargs in zip(mre.exceptions(), mre.branches(), mre.repos(), mre.args()):
        try:
            raise e1
        except git.GrapeGitError as e:
            with utility.cd(project):
                if "pathspec" in e.gitOutput:
                    createNewBranch = _createNewBranch
                    if _skipBranchCreation:
                        utility.printMsg("Skipping checkout of %s in %s" % (branch, project))
                        createNewBranch = False
                        
                    elif not createNewBranch:
                        createNewBranch =  utility.userInput("Branch not found locally or remotely. Would you like to create a "
                                                            "new branch called %s in %s? \n"
                                                        "(select 'a' to say yes for (a)ll, 's' to (s)kip creation for branches that don't exist )"
                                                            "\n(y,n,a,s)" % (branch, project), 'y')
                            
                    if str(createNewBranch).lower()[0] == 'a':
                        _createNewBranch = True
                        createNewBranch = True
                    if str(createNewBranch).lower()[0] == 's':
                        _skipBranchCreation = True
                        createNewBranch = False
                    if createNewBranch:
                        newBranchReposArgTuples.append((project, branch, {"checkout": checkoutargs[0]}))                        
                    else:
                            continue
    
                elif "already exists" in e.gitOutput:
                    utility.printMsg("Branch %s already exists in %s." % (branch, project))
                    branchDescription = git.commitDescription(branch)
                    headDescription = git.commitDescription("HEAD")
                    if branchDescription == headDescription:
                        utility.printMsg("Branch %s and HEAD are the same. Switching to %s." % (branch, branch))
                        action = "k"
                    else:
                        utility.printMsg("Branch %s and HEAD are not the same." % branch)
                        action = ''
                        valid = False
                        while not valid:
                            action = utility.userInput("Would you like to \n (k)eep it as is at: %s \n"
                                                       " or \n (f)orce it to: %s? \n(k,f)" %
                                                       (branchDescription, headDescription), 'k')
                            valid = (action == 'k') or (action == 'f')
                            if not valid:
                                utility.printMsg("Invalid input. Enter k or f. ")
                    if action == 'k':
                        git.checkout(branch)
                    elif action == 'f':
                        git.checkout("-B %s" % branch)
                elif "conflict" in e.gitOutput.lower(): 
                    utility.printMsg("CONFLICT occurred when pulling %s from origin." % branch)
                elif "does not appear to be a git repository" in e.gitOutput.lower():
                    utility.printMsg("Remote 'origin' does not exist. "
                                     "This branch was not updated from a remote repository.")
                elif "Couldn't find remote ref" in e.gitOutput:
                    utility.printMsg("Remote of %s does not have reference to %s. You may want to push this branch. " %(project, branch))
                else:
                    raise e
            
    if len(newBranchReposArgTuples) > 0:
        utility.MultiRepoCommandLauncher(createNewBranches, listOfRepoBranchArgTuples=newBranchReposArgTuples).launchFromWorkspaceDir(handleMRE=createNewBranchesMREHandler)
Esempio n. 25
0
File: config.py Progetto: LLNL/GRAPE
    def execute(self,args):
        base = git.baseDir()
        if base == "":
            return False
        dotGit = git.gitDir()
         
        utility.printMsg("Optimizing git performance on slow file systems...")
        #runs file system intensive tasks such as git status and git commit
        # in parallel (important for NFS systems such as LC)
        git.config("core.preloadindex","true")

        #have git automatically do some garbage collection / optimization
        utility.printMsg("Setting up automatic git garbage collection...")
        git.config("gc.auto","1")

        #prevents false conflict detection due to differences in filesystem
        # time stamps
        utility.printMsg("Optimizing cross platform portability...")
        git.config("core.trustctime","false")

        # stores login info for 12 hrs (max allowed by RZBitbucket)

        if not args["--nocredcache"]:
            cache = args["--credcache"]
            if not cache:
                cache = utility.userInput("Would you like to enable git-managed credential caching?", 'y')
            if cache:
                utility.printMsg("Enabling 12 hr caching of https credentials...")
                if os.name == "nt":
                    git.config("--global credential.helper", "wincred")
                else :
                    git.config("--global credential.helper", "cache --timeout=43200")

        # enables 'as' option for merge strategies -forces a conflict if two branches
        # modify the same file
        mergeVerifyPath = os.path.join(os.path.dirname(__file__),"..","merge-and-verify-driver")
        
        if os.path.exists(mergeVerifyPath): 
            utility.printMsg("Enabling safe merges (triggers conflicts any time same file is modified),\n\t see 'as' option for grape m and grape md...")
            git.config("merge.verify.name","merge and verify driver")
            git.config("merge.verify.driver","%s/merge-and-verify-driver %A %O %B")
        else:
            utility.printMsg("WARNING: merge and verify script not detected, safe merges ('as' option to grape m / md) will not work!")
        # enables lg as an alias to print a pretty-font summary of
        # key junctions in the history for this branch.
        utility.printMsg("Setting lg as an alias for a pretty log call...")
        git.config("alias.lg","log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative --simplify-by-decoration")
        
        # perform an update of the active subprojects if asked.
        ask = not args["--nouv"]
        updateView = ask and (args["--uv"] or utility.userInput("Do you want to edit your active subprojects?"
                                                                " (you can do this later using grape uv) [y/n]", "n"))
        if updateView:
            grapeMenu.menu().applyMenuChoice("uv", args["--uvArg"])

        # configure git to use p4merge for conflict resolution
        # and diffing

        useP4Merge = not args["--nop4merge"] and (args["--p4merge"] or utility.userInput("Would you like to use p4merge as your merge tool? [y/n]","y"))
        # note that this relies on p4merge being in your path somewhere
        if (useP4Merge):
            git.config("merge.keepBackup","false")
            git.config("merge.tool","p4merge")
            git.config("mergetool.keepBackup","false")
            git.config("mergetool.p4merge.cmd",'p4merge \"\$BASE\" \"\$LOCAL\" \"\$REMOTE\" \"\$MERGED\"')
            git.config("mergetool.p4merge.keepTemporaries","false")
            git.config("mergetool.p4merge.trustExitCode","false")
            git.config("mergetool.p4merge.keepBackup","false")
            utility.printMsg("Configured repo to use p4merge for conflict resolution")
        else:
            git.config("merge.tool","tkdiff")

        useP4Diff = not args["--nop4diff"] and (args["--p4diff"] or utility.userInput("Would you like to use p4merge as your diff tool? [y/n]","y"))
        # this relies on p4diff being defined as a custom bash script, with the following one-liner:
        # [ $# -eq 7 ] && p4merge "$2" "$5"
        if (useP4Diff):
            p4diffScript = os.path.join(os.path.dirname(__file__),"..","p4diff")
            if os.path.exists(p4diffScript): 
                git.config("diff.external",p4diffScript)
                utility.printMsg("Configured repo to use p4merge for diff calls - p4merge must be in your path")
            else: 
                utility.printMsg("Could not find p4diff script at %s" % p4diffScript)
        useGitP4 = args["--git-p4"]
        if (useGitP4 ):
            git.config("git-p4.useclientspec","true")
            # create p4 references to enable imports from p4
            p4remotes = os.path.join(dotGit,"refs","remotes","p4","")
            utility.ensure_dir(p4remotes)
            commit = utility.userInput("Please enter a descriptor (e.g. SHA, branch if tip, tag name) of the current git commit that mirrors the p4 repo","master")
            sha = git.SHA(commit)
            with open(os.path.join(p4remotes,"HEAD"),'w') as f:
                f.write(sha)
            with open(os.path.join(p4remotes,"master"),'w') as f:
                f.write(sha)

            # to enable exports to p4, a maindev client needs to be set up
            haveCopied = False
            while (not haveCopied):
                p4settings = utility.userInput("Enter a path to a .p4settings file describing the maindev client you'd like to use for p4 updates",".p4settings")
                try:
                    shutil.copyfile(p4settings,os.path.join(base,".p4settings"))
                    haveCopied = True
                except:
                    print("could not find p4settings file, please check your path and try again")
                    return False

        # install hooks here and in all submodules
        utility.printMsg("Installing hooks in all repos...")
        cwd = git.baseDir()
        grapeMenu.menu().applyMenuChoice("installHooks")
        
        #  ensure all public branches are available in all repos
        submodules = git.getActiveSubmodules()
        config = grapeConfig.grapeConfig()
        publicBranches = config.getPublicBranchList()
        submodulePublicBranches = set(config.getMapping('workspace', 'submoduleTopicPrefixMappings').values())
        for sub in submodules:
            self.ensurePublicBranchesExist(grapeConfig.grapeRepoConfig(sub),sub, submodulePublicBranches)
        
        # reset config to the workspace grapeconfig, use that one for all nested projects' public branches.
        wsDir = utility.workspaceDir()
        config = grapeConfig.grapeRepoConfig(wsDir)    
        for proj in grapeConfig.GrapeConfigParser.getAllActiveNestedSubprojectPrefixes():
            self.ensurePublicBranchesExist(config, os.path.join(wsDir,proj), publicBranches)
        
        self.ensurePublicBranchesExist(config, wsDir, publicBranches)
            
        return True