def ensureLocalUpToDateWithRemote(repo='', branch='master'): utility.printMsg( "Ensuring local branch %s in %s is up to date with origin" % (branch, repo)) with utility.cd(repo): # attempt to fetch the requested branch try: git.fetch("origin", "%s:%s" % (branch, branch)) except: # the branch may not exist, but this is ok pass if git.currentBranch() == branch: return if not git.hasBranch(branch): # switch to corresponding public branch if the branch does not exist public = grapeConfig.workspaceConfig().getPublicBranchFor(branch) # figure out if this is a submodule relpath = os.path.relpath(repo, utility.workspaceDir()) relpath = relpath.replace('\\', "/") with utility.cd(utility.workspaceDir()): # if this is a submodule, get the appropriate public mapping if relpath in git.getAllSubmoduleURLMap().keys(): public = grapeConfig.workspaceConfig().getMapping( "workspace", "submodulepublicmappings")[public] utility.printMsg( "Branch %s does not exist in %s, switching to %s and detaching" % (branch, repo, public)) git.checkout(public) git.pull("origin %s" % (public)) git.checkout("--detach HEAD")
def ensureLocalUpToDateWithRemote(repo = '', branch = 'master'): utility.printMsg( "Ensuring local branch %s in %s is up to date with origin" % (branch, repo)) with utility.cd(repo): # attempt to fetch the requested branch try: git.fetch("origin", "%s:%s" % (branch, branch)) except: # the branch may not exist, but this is ok pass if git.currentBranch() == branch: return if not git.hasBranch(branch): # switch to corresponding public branch if the branch does not exist public = grapeConfig.workspaceConfig().getPublicBranchFor(branch) # figure out if this is a submodule relpath = os.path.relpath(repo, utility.workspaceDir()) relpath = relpath.replace('\\',"/") with utility.cd(utility.workspaceDir()): # if this is a submodule, get the appropriate public mapping if relpath in git.getAllSubmoduleURLMap().keys(): public = grapeConfig.workspaceConfig().getMapping("workspace", "submodulepublicmappings")[public] utility.printMsg("Branch %s does not exist in %s, switching to %s and detaching" % (branch, repo, public)) git.checkout(public) git.pull("origin %s" % (public)) git.checkout("--detach HEAD")
def unbundlecmd(repo='', branch='', args={}): mappings = args["--branchMappings"] mapTokens = mappings.split() with utility.cd(repo): bundleNames = glob.glob("*.bundle") for bundleName in bundleNames: mappings = "" for token in mapTokens: sourceDestPair = token.split(":") source = sourceDestPair[0] dest = sourceDestPair[1] bundleHeads = git.bundle("list-heads %s" % bundleName).split("\n") bundleBranches = [] for line in bundleHeads: if "refs/heads" in line: bundleBranches.append(line.split()[1].split("refs/heads/")[1]) if source.replace('/', '.') in bundleBranches: mappings += "%s:%s " % (source, dest) try: git.bundle("verify %s" % bundleName) except git.GrapeGitError as e: print e.gitCommand print e.cwd print e.gitOutput raise e git.fetch("--tags -u %s %s" % (bundleName, mappings)) return True
def getStatus(branch='', repo='', args=''): statusArgs = args[0] wsDir = args[1] toReturn = [] sub = repo if not sub.strip(): return "" try: with utility.cd(sub): subStatus = git.status("--porcelain -b %s" % statusArgs).split('\n') for line in subStatus: strippedL = line.strip() if strippedL: tokens = strippedL.split() tokens[0] = tokens[0].strip() if len(tokens[0]) == 1: tokens[0] = " %s " % tokens[0] if wsDir == sub: relPath = "" toReturn.append(' '.join([tokens[0], tokens[1]])) else: relPath = os.path.relpath(sub, wsDir) toReturn.append(' '.join( [tokens[0], '/'.join([relPath, tokens[1]])])) return toReturn except Exception as e: print e
def createNewBranches(repo='', branch='', args={}): project = repo checkoutargs = args["checkout"] with utility.cd(project): utility.printMsg("Creating new branch %s in %s." % (branch, project)) git.checkout(checkoutargs+" -b "+branch) git.push("-u origin %s" % branch) return True
def createNewBranches(repo='', branch='', args={}): project = repo checkoutargs = args["checkout"] with utility.cd(project): utility.printMsg("Creating new branch %s in %s." % (branch, project)) git.checkout(checkoutargs + " -b " + branch) git.push("-u origin %s" % branch) return True
def detachThenForceDeleteBranch(repo='', branch='master', args=None): with utility.cd(repo): utility.printMsg( "*** WARNING ***: Detaching in order to delete %s in %s. You will be in a headless state." % (branch, repo)) git.checkout("--detach HEAD") git.branch("-D %s" % branch) if "origin/%s" % branch in git.remoteBranches(): git.push("--delete origin %s" % branch, throwOnFail=False)
def deleteBranch(repo='', branch='master', args=None): force = args[0] forceStr = "-D" if force is True else "-d" with utility.cd(repo): utility.printMsg("deleting %s in %s..." % (branch, repo)) git.branch("%s %s" % (forceStr, branch)) if "origin/%s" % branch in git.branch("-r"): try: git.push("--delete origin %s" % branch, throwOnFail=True) except git.GrapeGitError as e: if "remote ref does not exist" in e.gitOutput: pass
def handledCheckout(repo='', branch='master', args=[]): checkoutargs = args[0] sync = args[1] with utility.cd(repo): if sync: # attempt to fetch the requested branch try: git.fetch("origin", "%s:%s" % (branch, branch)) except: # the branch may not exist, but ignore the exception # and allow the checkout to throw the exception. pass git.checkout(checkoutargs + ' ' + branch) utility.printMsg("Checked out %s in %s" % (branch, repo)) return True
def handledCheckout(repo = '', branch = 'master', args = []): checkoutargs = args[0] sync = args[1] with utility.cd(repo): if sync: # attempt to fetch the requested branch try: git.fetch("origin", "%s:%s" % (branch, branch)) except: # the branch may not exist, but ignore the exception # and allow the checkout to throw the exception. pass git.checkout(checkoutargs + ' ' + branch) utility.printMsg("Checked out %s in %s" % (branch, repo)) return True
def createBranch(repo="unknown", branch="master", args=[]): branchPoint = branch fullBranch = args with utility.cd(repo): utility.printMsg("creating and switching to %s in %s" % (fullBranch, repo)) try: git.checkout("-b %s %s " % (fullBranch, branchPoint)) except git.GrapeGitError as e: print "%s:%s" % (repo, e.gitOutput) utility.printMsg("WARNING: %s in %s will not be pushed." % (fullBranch, repo)) return utility.printMsg("pushing %s to origin in %s" % (fullBranch, repo)) try: git.push("-u origin %s" % fullBranch) except git.GrapeGitError as e: print "%s: %s" % (repo, e.gitOutput) return
def fetchLocal(repo='unknown', branch='master'): # branch is actually the list of branches branches = branch with utility.cd(repo): currentBranch = git.currentBranch() if len(branches) > 0: git.fetch("--prune --tags") allRemoteBranches = git.remoteBranches() fetchArgs = "origin " toFetch = [] for b in branches: if b != currentBranch: if "origin/%s" % b in allRemoteBranches: fetchArgs += "%s:%s " % (b, b) toFetch.append(b) else: try: utility.printMsg("Pulling current branch %s in %s" % (currentBranch, repo)) git.pull("origin %s" % currentBranch) except git.GrapeGitError: print( "GRAPE: Could not pull %s from origin. Maybe you haven't pushed it yet?" % currentBranch) try: if toFetch: utility.printMsg("updating %s in %s" % (','.join(toFetch), repo)) git.fetch(fetchArgs) except git.GrapeGitError as e: # let non-fast-forward fetches slide if "rejected" in e.gitOutput and "non-fast-forward" in e.gitOutput: print e.gitCommand print e.gitOutput print( "GRAPE: WARNING: one of your public branches %s in %s has local commits! " "Did you forget to create a topic branch?" % (",".join(branches), repo)) pass elif "Refusing to fetch into current branch" in e.gitOutput: print e.gitOutput else: raise e
def handleDeleteBranchMRE(mre, force=False): detachTuples = [] for e1, branch, repo in zip(mre.exceptions(), mre.branches(), mre.repos()): try: raise e1 except git.GrapeGitError as e: with utility.cd(repo): if "Cannot delete the branch" in e.gitOutput and \ "which you are currently on." in e.gitOutput: if force: detachTuples.append((repo, branch, None)) else: utility.printMsg( "call grape db -D %s to force deletion of branch you are currently on." % branch) elif "not deleting branch" in e.gitOutput and "even though it is merged to HEAD." in e.gitOutput: git.branch("-D %s" % branch) elif "error: branch" in e.gitOutput and "not found" in e.gitOutput: "%s not found in %s" % (branch, repo) pass elif "is not fully merged" in e.gitOutput: if force: utility.printMsg("**DELETING UNMERGED BRANCH %s" % branch) git.branch("-D %s" % branch) else: print "%s is not fully merged in %s. Run grape db -D %s to force the deletion" % ( branch, repo, branch) elif e.commError: utility.printMsg( "Could not connect to origin to delete remote references to your branch " "You may want to call grape db %s again once you've reconnected." % branch) else: utility.printMsg( "Deletion of %s failed for unhandled reason." % branch) print e.gitOutput raise e utility.MultiRepoCommandLauncher( detachThenForceDeleteBranch, listOfRepoBranchArgTuples=detachTuples).launchFromWorkspaceDir( handleMRE=handleDetachThenForceMRE)
def bundlecmd(repo='', branch='', args={}): branchlist = args["branchList"] tagsToBundle = args["tags"] tagprefix = args["prefix"] describePattern = args["describePattern"] with utility.cd(repo): reponame = os.path.split(repo)[1] for branch in branchlist: # ensure branch can be fast forwardable to origin/branch and do so if not git.safeForceBranchToOriginRef(branch): print("Branch %s in %s has diverged from or is ahead of origin, or does not exist. Sync branches before bundling." % (branch, repo)) continue tagname = "%s/%s" % (tagprefix, branch) try: previousLocation = git.describe("--always --match '%s' %s" % (describePattern, tagname)) except: # We should only get here if the tagname does not exist previousLocation = "unknown" try: currentLocation = git.describe("--always --match '%s' %s" % (describePattern, branch)) except: utility.printMsg("Unable to locate %s in %s! Something may be wrong..." % (branch, reponame)) currentLocation = branch if previousLocation.strip() != currentLocation.strip(): try: git.shortSHA(tagname) revlists = " %s..%s" % (tagname, branch) except: utility.printMsg("%s does not exist in %s, bundling entire branch %s" % (tagname, reponame, branch)) revlists = " %s" % (branch) bundlename = args["--outfile"] if not bundlename: bundlename = "%s.%s-%s-%s.bundle" % (reponame, branch.replace('/', '.'), previousLocation, currentLocation) utility.printMsg("creating bundle %s in %s" % (bundlename, reponame)) git.bundle("create %s %s --tags=%s " % (bundlename, revlists, tagsToBundle[branch])) return True
def execute(self, args): with utility.cd(utility.workspaceDir()): if not args["--checkWSOnly"]: self.printStatus(args) # Sanity check workspace layout publicBranchesExist = self.checkForLocalPublicBranches(args) # Check that submodule branching is consistent consistentBranchState = self.checkForConsistentWorkspaceBranches( args) retval = True if args["--failIfInconsistent"]: retval = retval and publicBranchesExist and consistentBranchState if args["--failIfMissingPublicBranches"]: retval = retval and publicBranchesExist if args["--failIfBranchesInconsistent"]: retval = retval and consistentBranchState return retval
def fetchLocal(repo='unknown', branch='master'): # branch is actually the list of branches branches = branch with utility.cd(repo): currentBranch = git.currentBranch() if len(branches) > 0: git.fetch("--prune --tags") allRemoteBranches = git.remoteBranches() fetchArgs = "origin " toFetch = [] for b in branches: if b != currentBranch: if "origin/%s" % b in allRemoteBranches: fetchArgs += "%s:%s " % (b, b) toFetch.append(b) else: try: utility.printMsg("Pulling current branch %s in %s" % (currentBranch, repo)) git.pull("origin %s" % currentBranch) except git.GrapeGitError: print("GRAPE: Could not pull %s from origin. Maybe you haven't pushed it yet?" % currentBranch) try: if toFetch: utility.printMsg("updating %s in %s" % (','.join(toFetch), repo)) git.fetch(fetchArgs) except git.GrapeGitError as e: # let non-fast-forward fetches slide if "rejected" in e.gitOutput and "non-fast-forward" in e.gitOutput: print e.gitCommand print e.gitOutput print("GRAPE: WARNING: one of your public branches %s in %s has local commits! " "Did you forget to create a topic branch?" % (",".join(branches), repo)) pass elif "Refusing to fetch into current branch" in e.gitOutput: print e.gitOutput else: raise e
def execute(self, args): """ A fair chunk of this stuff relies on stashy's wrapping of the STASH REST API, which is posted at https://developer.atlassian.com/static/rest/stash/2.12.1/stash-rest.html """ config = grapeConfig.grapeConfig() name = args["--user"] if not name: name = utility.getUserName() utility.printMsg("Logging onto %s" % args["--bitbucketURL"]) if args["--test"]: bitbucket = Atlassian.TestAtlassian(name) else: verify = True if args["--verifySSL"].lower() == "true" else False bitbucket = Atlassian.Atlassian(name, url=args["--bitbucketURL"], verify=verify) # default project (outer level project) project_name = args["--project"] # default repo (outer level repo) repo_name = args["--repo"] # determine source branch and target branch branch = args["--source"] if not branch: branch = git.currentBranch() # make sure we are in the outer level repo before we push wsDir = utility.workspaceDir() os.chdir(wsDir) #ensure branch is pushed utility.printMsg("Pushing %s to bitbucket..." % branch) git.push("origin %s" % branch) #target branch for outer level repo target_branch = args["--target"] if not target_branch: target_branch = config.getPublicBranchFor(branch) # load pull request from Bitbucket if it already exists wsRepo = bitbucket.project(project_name).repo(repo_name) existingOuterLevelRequest = getReposPullRequest(wsRepo, branch, target_branch, args) # determine pull request title title = args["--title"] if existingOuterLevelRequest is not None and not title: title = existingOuterLevelRequest.title() #determine pull request URL outerLevelURL = None if existingOuterLevelRequest: outerLevelURL = existingOuterLevelRequest.link() # determine pull request description descr = self.parseDescriptionArgs(args) if not descr and existingOuterLevelRequest: descr = existingOuterLevelRequest.description() # determine pull request reviewers reviewers = self.parseReviewerArgs(args) if reviewers is None and existingOuterLevelRequest is not None: reviewers = [r[0] for r in existingOuterLevelRequest.reviewers()] # if we're in append mode, only append what was asked for: if args["--append"] or args["--prepend"]: title = args["--title"] descr = self.parseDescriptionArgs(args) reviewers = self.parseReviewerArgs(args) ## Submodule Repos missing = utility.getModifiedInactiveSubmodules(target_branch, branch) if missing: utility.printMsg("The following submodules that you've modified are not currently present in your workspace.\n" "You should activate them using grape uv and then call grape review again. If you haven't modified " "these submodules, you may need to do a grape md to proceed.") utility.printMsg(','.join(missing)) return False pullRequestLinks = {} if not args["--norecurse"] and (args["--recurse"] or config.getboolean("workspace", "manageSubmodules")): modifiedSubmodules = git.getModifiedSubmodules(target_branch, branch) submoduleBranchMappings = config.getMapping("workspace", "submoduleTopicPrefixMappings") for submodule in modifiedSubmodules: if not submodule: continue # push branch os.chdir(submodule) utility.printMsg("Pushing %s to bitbucket..." % branch) git.push("origin %s" % branch) os.chdir(wsDir) repo = bitbucket.repoFromWorkspaceRepoPath(submodule, isSubmodule=True) # determine branch prefix prefix = branch.split('/')[0] sub_target_branch = submoduleBranchMappings[prefix] prevSubDescr = getReposPullRequestDescription(repo, branch, sub_target_branch, args) #amend the subproject pull request description with the link to the outer pull request subDescr = addLinkToDescription(descr, outerLevelURL, True) if args["--prepend"] or args["--append"]: subDescr = descr newRequest = postPullRequest(repo, title, branch, sub_target_branch, subDescr, reviewers, args) if newRequest: pullRequestLinks[newRequest.link()] = True else: # if a pull request could not be generated, just add a link to browse the branch pullRequestLinks["%s%s/browse?at=%s" % (bitbucket.rzbitbucketURL, repo.repo.url(), urllib.quote_plus("refs/heads/%s" % branch))] = False ## NESTED SUBPROJECT REPOS nestedProjects = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojects(target_branch) nestedProjectPrefixes = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojectPrefixes(target_branch) for proj, prefix in zip(nestedProjects, nestedProjectPrefixes): with utility.cd(prefix): git.push("origin %s" % branch) repo = bitbucket.repoFromWorkspaceRepoPath(proj, isSubmodule=False, isNested=True) newRequest = postPullRequest(repo, title, branch, target_branch,descr, reviewers, args) if newRequest: pullRequestLinks[newRequest.link()] = True else: # if a pull request could not be generated, just add a link to browse the branch pullRequestLinks["%s%s/browse?at=%s" % (bitbucket.rzbitbucketURL, repo.repo.url(), urllib.quote_plus("refs/heads/%s" % branch))] = False ## OUTER LEVEL REPO # load the repo level REST resource if not args["--subprojectsOnly"]: if not git.hasBranch(branch): utility.printMsg("Top level repository does not have a branch %s, not generating a Pull Request" % (branch)) return True if git.branchUpToDateWith(target_branch, branch): utility.printMsg("%s up to date with %s, not generating a Pull Request in Top Level repo" % (target_branch, branch)) return True repo_name = args["--repo"] repo = bitbucket.repoFromWorkspaceRepoPath(wsDir, topLevelRepo=repo_name, topLevelProject=project_name) utility.printMsg("Posting pull request to %s,%s" % (project_name, repo_name)) request = postPullRequest(repo, title, branch, target_branch, descr, reviewers, args) updatedDescription = request.description() for link in pullRequestLinks: updatedDescription = addLinkToDescription(updatedDescription, link, pullRequestLinks[link]) if updatedDescription != request.description(): request = postPullRequest(repo, title, branch, target_branch, updatedDescription, reviewers, args) utility.printMsg("Request generated/updated:\n\n%s" % request) return True
def push(repo='', branch='master'): with utility.cd(repo): utility.printMsg("Pushing %s in %s..." % (branch, repo)) git.push("-u origin %s" % branch, throwOnFail=True)
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)
def execute(self, args): """ A fair chunk of this stuff relies on stashy's wrapping of the STASH REST API, which is posted at https://developer.atlassian.com/static/rest/stash/2.12.1/stash-rest.html """ config = grapeConfig.grapeConfig() name = args["--user"] if not name: name = utility.getUserName() utility.printMsg("Logging onto %s" % args["--bitbucketURL"]) if args["--test"]: bitbucket = Atlassian.TestAtlassian(name) else: verify = True if args["--verifySSL"].lower() == "true" else False bitbucket = Atlassian.Atlassian(name, url=args["--bitbucketURL"], verify=verify) # default project (outer level project) project_name = args["--project"] # default repo (outer level repo) repo_name = args["--repo"] # determine source branch and target branch branch = args["--source"] if not branch: branch = git.currentBranch() # make sure we are in the outer level repo before we push wsDir = utility.workspaceDir() os.chdir(wsDir) #ensure branch is pushed utility.printMsg("Pushing %s to bitbucket..." % branch) git.push("origin %s" % branch) #target branch for outer level repo target_branch = args["--target"] if not target_branch: target_branch = config.getPublicBranchFor(branch) # load pull request from Bitbucket if it already exists wsRepo = bitbucket.project(project_name).repo(repo_name) existingOuterLevelRequest = getReposPullRequest( wsRepo, branch, target_branch, args) # determine pull request title title = args["--title"] if existingOuterLevelRequest is not None and not title: title = existingOuterLevelRequest.title() #determine pull request URL outerLevelURL = None if existingOuterLevelRequest: outerLevelURL = existingOuterLevelRequest.link() # determine pull request description descr = self.parseDescriptionArgs(args) if not descr and existingOuterLevelRequest: descr = existingOuterLevelRequest.description() # determine pull request reviewers reviewers = self.parseReviewerArgs(args) if reviewers is None and existingOuterLevelRequest is not None: reviewers = [r[0] for r in existingOuterLevelRequest.reviewers()] # if we're in append mode, only append what was asked for: if args["--append"] or args["--prepend"]: title = args["--title"] descr = self.parseDescriptionArgs(args) reviewers = self.parseReviewerArgs(args) ## Submodule Repos missing = utility.getModifiedInactiveSubmodules(target_branch, branch) if missing: utility.printMsg( "The following submodules that you've modified are not currently present in your workspace.\n" "You should activate them using grape uv and then call grape review again. If you haven't modified " "these submodules, you may need to do a grape md to proceed.") utility.printMsg(','.join(missing)) return False pullRequestLinks = {} if not args["--norecurse"] and (args["--recurse"] or config.getboolean( "workspace", "manageSubmodules")): modifiedSubmodules = git.getModifiedSubmodules( target_branch, branch) submoduleBranchMappings = config.getMapping( "workspace", "submoduleTopicPrefixMappings") for submodule in modifiedSubmodules: if not submodule: continue # push branch os.chdir(submodule) utility.printMsg("Pushing %s to bitbucket..." % branch) git.push("origin %s" % branch) os.chdir(wsDir) repo = bitbucket.repoFromWorkspaceRepoPath(submodule, isSubmodule=True) # determine branch prefix prefix = branch.split('/')[0] sub_target_branch = submoduleBranchMappings[prefix] prevSubDescr = getReposPullRequestDescription( repo, branch, sub_target_branch, args) #amend the subproject pull request description with the link to the outer pull request subDescr = addLinkToDescription(descr, outerLevelURL, True) if args["--prepend"] or args["--append"]: subDescr = descr newRequest = postPullRequest(repo, title, branch, sub_target_branch, subDescr, reviewers, args) if newRequest: pullRequestLinks[newRequest.link()] = True else: # if a pull request could not be generated, just add a link to browse the branch pullRequestLinks[ "%s%s/browse?at=%s" % (bitbucket.rzbitbucketURL, repo.repo.url(), urllib.quote_plus("refs/heads/%s" % branch))] = False ## NESTED SUBPROJECT REPOS nestedProjects = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojects( target_branch) nestedProjectPrefixes = grapeConfig.GrapeConfigParser.getAllModifiedNestedSubprojectPrefixes( target_branch) for proj, prefix in zip(nestedProjects, nestedProjectPrefixes): with utility.cd(prefix): git.push("origin %s" % branch) repo = bitbucket.repoFromWorkspaceRepoPath(proj, isSubmodule=False, isNested=True) newRequest = postPullRequest(repo, title, branch, target_branch, descr, reviewers, args) if newRequest: pullRequestLinks[newRequest.link()] = True else: # if a pull request could not be generated, just add a link to browse the branch pullRequestLinks["%s%s/browse?at=%s" % (bitbucket.rzbitbucketURL, repo.repo.url(), urllib.quote_plus( "refs/heads/%s" % branch))] = False ## OUTER LEVEL REPO # load the repo level REST resource if not args["--subprojectsOnly"]: if not git.hasBranch(branch): utility.printMsg( "Top level repository does not have a branch %s, not generating a Pull Request" % (branch)) return True if git.branchUpToDateWith(target_branch, branch): utility.printMsg( "%s up to date with %s, not generating a Pull Request in Top Level repo" % (target_branch, branch)) return True repo_name = args["--repo"] repo = bitbucket.repoFromWorkspaceRepoPath( wsDir, topLevelRepo=repo_name, topLevelProject=project_name) utility.printMsg("Posting pull request to %s,%s" % (project_name, repo_name)) request = postPullRequest(repo, title, branch, target_branch, descr, reviewers, args) updatedDescription = request.description() for link in pullRequestLinks: updatedDescription = addLinkToDescription( updatedDescription, link, pullRequestLinks[link]) if updatedDescription != request.description(): request = postPullRequest(repo, title, branch, target_branch, updatedDescription, reviewers, args) utility.printMsg("Request generated/updated:\n\n%s" % request) return True
def foreach(repo='', branch='', args={}): cmd = args["<cmd>"] with utility.cd(repo): utility.executeSubProcess(cmd, repo, verbose=-1) return True
def cleanupPush(repo='', branch='', args='none'): with utility.cd(repo): utility.printMsg("Attempting push of local %s in %s" % (branch, repo)) git.push("origin %s" % branch)
def foreach(repo='', branch='', args={}): cmd = args["<cmd>"] with utility.cd(repo): utility.executeSubProcess(cmd, repo, verbose = -1) return True
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)