def postCheckout(args): updateSubmodule = args["--checkoutSubmodule"] if updateSubmodule and updateSubmodule.lower() == 'true': utility.printMsg("Post-Checkout Hook: Syncing submodule URLs...") git.submodule("--quiet sync") utility.printMsg("Post-Checkout Hook: Updating submodules...") git.submodule("--quiet update")
def postMerge(args): updateSubmodule = args["--mergeSubmodule"] if updateSubmodule and updateSubmodule.lower() == 'true': utility.printMsg("Post-Merge Hook: Syncing submodule URLs...") git.submodule("--quiet sync") utility.printMsg("Post-Merge Hook: Updating submodules...") git.submodule("--quiet update --merge")
def postRebase(args): updateSubmodule = args["--rebaseSubmodule"] if updateSubmodule and updateSubmodule.lower() == 'true': git.submodule("--quiet sync") git.submodule("update --rebase")
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
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
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
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
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
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