From ca89a89cf1c17bce101e76515c84a8eb433a2344 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 10:12:46 +0200 Subject: [PATCH 01/16] Print stdout on git commit error --- scc/git.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scc/git.py b/scc/git.py index d13c110c..ab376cd4 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1850,7 +1850,7 @@ def summary_commit(self, merge_msg, commit_id="merge", top_message=None, updated = self.has_local_changes() if updated: - self.call("git", "commit", "-a", "-n", "-m", commit_message) + self.communicate("git", "commit", "-a", "-n", "-m", commit_message) elif allow_empty: self.call("git", "commit", "--allow-empty", '-a', "-n", "-m", commit_message) From 25bcd11e52ae0d74873f36339beb8bc5f8e90873 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 10:27:43 +0200 Subject: [PATCH 02/16] Temporary debugging commits --- scc/git.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scc/git.py b/scc/git.py index ab376cd4..9940ce8d 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1284,7 +1284,8 @@ def has_local_changes(self): self.call("git", "diff-index", "--quiet", "HEAD") self.dbg("%s has no local changes", self) return False - except Exception: + except Exception, e: + print "EXCEPTION", e self.dbg("%s has local changes", self) return True @@ -1850,6 +1851,7 @@ def summary_commit(self, merge_msg, commit_id="merge", top_message=None, updated = self.has_local_changes() if updated: + print self.communicate("git", "status") self.communicate("git", "commit", "-a", "-n", "-m", commit_message) elif allow_empty: self.call("git", "commit", "--allow-empty", '-a', "-n", "-m", From b1c44428f50e1efa50ef23828cb5af746b513fb9 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 10:48:38 +0200 Subject: [PATCH 03/16] Print diff-index quiet and non-quiet --- scc/git.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scc/git.py b/scc/git.py index 9940ce8d..ab376cd4 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1284,8 +1284,7 @@ def has_local_changes(self): self.call("git", "diff-index", "--quiet", "HEAD") self.dbg("%s has no local changes", self) return False - except Exception, e: - print "EXCEPTION", e + except Exception: self.dbg("%s has local changes", self) return True @@ -1851,7 +1850,6 @@ def summary_commit(self, merge_msg, commit_id="merge", top_message=None, updated = self.has_local_changes() if updated: - print self.communicate("git", "status") self.communicate("git", "commit", "-a", "-n", "-m", commit_message) elif allow_empty: self.call("git", "commit", "--allow-empty", '-a', "-n", "-m", From 79237fcba53876e0ae8c3186ada0bd7024d91266 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 14:58:06 +0200 Subject: [PATCH 04/16] Turn self.cd into a contextmanager see: * https://github.com/openmicroscopy/snoopycrimecop/pull/115 * https://github.com/openmicroscopy/snoopycrimecop/commit/85e1c5e65638377249d79c7629f0ff6597bf1cf9 --- scc/git.py | 91 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/scc/git.py b/scc/git.py index ab376cd4..8aca1b9f 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1064,9 +1064,21 @@ def register_submodules(self): self.cd(self.path) def cd(self, directory): + class DirectoryChanger(object): + + def __init__(self): + self.original = os.getcwd() + + def __enter__(self): + pass + + def __exit__(self, *args): + os.chdir(self.original) + if not os.path.abspath(os.getcwd()) == os.path.abspath(directory): self.dbg("cd %s", directory) os.chdir(directory) + return DirectoryChanger() def communicate(self, *command, **kwargs): return_stderr = kwargs.pop('return_stderr', False) @@ -1118,32 +1130,32 @@ def wrap_call(self, logWrap, *command, **kwargs): except Exception: no_wait = False - self.cd(self.path) - self.dbg("Calling '%s'" % " ".join(command)) - p = subprocess.Popen(command, **kwargs) - if not no_wait: - rc = p.wait() - if rc: - raise Exception("rc=%s" % rc) - return p + with self.cd(self.path): + self.dbg("Calling '%s'" % " ".join(command)) + p = subprocess.Popen(command, **kwargs) + if not no_wait: + rc = p.wait() + if rc: + raise Exception("rc=%s" % rc) + return p def write_directories(self): """Write directories in candidate PRs comments to a txt file""" - self.cd(self.path) - directories_log = None - - for pr in self.origin.candidate_pulls: - directories = pr.parse_comments("test") - if directories: - if directories_log is None: - directories_log = open('directories.txt', 'w') - for directory in directories: - directories_log.write(directory) - directories_log.write("\n") - # Cleanup - if directories_log: - directories_log.close() + with self.cd(self.path): + directories_log = None + + for pr in self.origin.candidate_pulls: + directories = pr.parse_comments("test") + if directories: + if directories_log is None: + directories_log = open('directories.txt', 'w') + for directory in directories: + directories_log.write(directory) + directories_log.write("\n") + # Cleanup + if directories_log: + directories_log.close() # # General git commands @@ -1369,8 +1381,8 @@ def list_remotes(self): def get_remote_url(self, remote_name="origin"): """Return the URL of the remote""" - self.cd(self.path) - return git_config("remote.%s.url" % remote_name) + with self.cd(self.path): + return git_config("remote.%s.url" % remote_name) # # Higher level git commands @@ -1763,8 +1775,7 @@ def rmerge(self, filters, info=False, comment=False, commit_id="merge", if info: merge_msg += self.origin.merge_info() else: - self.cd(self.path) - self.write_directories() + self.write_directories() # Handles own chdir presha1 = self.get_current_sha1() if self.has_remote_branch(filters["base"], self.remote): ff_msg, ff_log = self.fast_forward(filters["base"], @@ -1792,15 +1803,12 @@ def rmerge(self, filters, info=False, comment=False, commit_id="merge", # Do not copy top-level PRs for ftype in ["include", "exclude"]: sub_filters[ftype].pop("pr", None) - try: - submodule_updated, submodule_msg = submodule_repo.rmerge( - sub_filters, info, comment, commit_id=commit_id, - update_gitmodules=update_gitmodules, - set_commit_status=set_commit_status, - allow_empty=allow_empty, is_submodule=True) - merge_msg += "\n" + submodule_msg - finally: - self.cd(self.path) + submodule_updated, submodule_msg = submodule_repo.rmerge( + sub_filters, info, comment, commit_id=commit_id, + update_gitmodules=update_gitmodules, + set_commit_status=set_commit_status, + allow_empty=allow_empty, is_submodule=True) + merge_msg += "\n" + submodule_msg if not info: summary_update = self.summary_commit( @@ -3171,12 +3179,13 @@ def merge(self, args, main_repo): if args.check_commit_status: commit_args.append("-S%s" % args.check_commit_status) - updated, merge_msg = main_repo.rmerge( - self.filters, args.info, - args.comment, commit_id=" ".join(commit_args), - top_message=args.message, - update_gitmodules=args.update_gitmodules, - set_commit_status=args.set_commit_status) + with main_repo.cd(main_repo.path): + updated, merge_msg = main_repo.rmerge( + self.filters, args.info, + args.comment, commit_id=" ".join(commit_args), + top_message=args.message, + update_gitmodules=args.update_gitmodules, + set_commit_status=args.set_commit_status) for line in merge_msg.split("\n"): self.log.info(line) From 27fec38e101bd67958aa0ec9b85ee0e72e70e8e4 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 15:15:44 +0200 Subject: [PATCH 05/16] Move some 'with self.cd' uses to pass Popen(cwd) --- scc/git.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scc/git.py b/scc/git.py index 8aca1b9f..b42b83f1 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1066,7 +1066,8 @@ def register_submodules(self): def cd(self, directory): class DirectoryChanger(object): - def __init__(self): + def __init__(self, dbg): + self.dbg = dbg self.original = os.getcwd() def __enter__(self): @@ -1074,11 +1075,12 @@ def __enter__(self): def __exit__(self, *args): os.chdir(self.original) + self.dbg("< cd %s", directory) if not os.path.abspath(os.getcwd()) == os.path.abspath(directory): - self.dbg("cd %s", directory) + self.dbg("> cd %s", directory) os.chdir(directory) - return DirectoryChanger() + return DirectoryChanger(self.dbg) def communicate(self, *command, **kwargs): return_stderr = kwargs.pop('return_stderr', False) @@ -1130,14 +1132,13 @@ def wrap_call(self, logWrap, *command, **kwargs): except Exception: no_wait = False - with self.cd(self.path): - self.dbg("Calling '%s'" % " ".join(command)) - p = subprocess.Popen(command, **kwargs) - if not no_wait: - rc = p.wait() - if rc: - raise Exception("rc=%s" % rc) - return p + self.dbg("Calling '%s'" % " ".join(command)) + p = subprocess.Popen(command, cwd=self.path, **kwargs) + if not no_wait: + rc = p.wait() + if rc: + raise Exception("rc=%s" % rc) + return p def write_directories(self): """Write directories in candidate PRs comments to a txt file""" From 6c662dec35c7a7acddd4193887d0d7b02fe95e70 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 15:36:29 +0200 Subject: [PATCH 06/16] Minor logging fixes --- scc/git.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scc/git.py b/scc/git.py index b42b83f1..d14baaf0 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1045,6 +1045,9 @@ def __init__(self, gh, path, remote="origin", push_branch=None, if gh: self.origin = gh.gh_repo(repo_name, user_name) + def __str__(self): + return "GitRepo(%s)" % self.path + def register_submodules(self): if len(self.submodules) == 0: for directory in self.get_submodule_paths(): @@ -1174,7 +1177,7 @@ def get_current_head(self): def get_sha1(self, branch): """Return the sha1 for the specified branch""" - self.dbg("Get sha1 of %s") + self.dbg("Get sha1 of %s" % branch) o = self.communicate("git", "rev-parse", branch) return o.strip() From 072d98f6f27b1139629042cc76665def322a241e Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 16:15:13 +0200 Subject: [PATCH 07/16] More chdir cleanups --- scc/git.py | 58 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/scc/git.py b/scc/git.py index d14baaf0..e3140a38 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1057,14 +1057,13 @@ def register_submodules(self): directory in self.repository_config["submodules"]: repository_config = \ self.repository_config["submodules"][directory] - try: + # TODO: Unclear if this is needed + with self.cd(self.path): submodule_repo = \ self.gh.git_repo(directory, repository_config=repository_config) self.submodules.append(submodule_repo) submodule_repo.register_submodules() - finally: - self.cd(self.path) def cd(self, directory): class DirectoryChanger(object): @@ -1080,9 +1079,8 @@ def __exit__(self, *args): os.chdir(self.original) self.dbg("< cd %s", directory) - if not os.path.abspath(os.getcwd()) == os.path.abspath(directory): - self.dbg("> cd %s", directory) - os.chdir(directory) + self.dbg("> cd %s", directory) + os.chdir(directory) return DirectoryChanger(self.dbg) def communicate(self, *command, **kwargs): @@ -1146,6 +1144,7 @@ def wrap_call(self, logWrap, *command, **kwargs): def write_directories(self): """Write directories in candidate PRs comments to a txt file""" + # Doesn't use (wrap_)call so changing with self.cd(self.path): directories_log = None @@ -1385,6 +1384,7 @@ def list_remotes(self): def get_remote_url(self, remote_name="origin"): """Return the URL of the remote""" + # Protect git_config with self.cd(self.path): return git_config("remote.%s.url" % remote_name) @@ -1840,25 +1840,27 @@ def summary_commit(self, merge_msg, commit_id="merge", top_message=None, % (top_message, merge_msg + merge_msg_footer) if update_gitmodules: - submodule_paths = self.get_submodule_paths() - for path in submodule_paths: - # Read submodule URL registered in .gitmodules - config_url = "submodule.%s.url" % path - submodule_url = git_config(config_url, - config_file=".gitmodules") - - # Substitute submodule URL using connection login - user = self.gh.get_login() - pattern = '(.*github.com[:/]).*(/.*.git)' - new_url = re.sub(pattern, r'\1%s\2' % user, submodule_url) - git_config(config_url, config_file=".gitmodules", - value=new_url) - - # Substitute submodule branch - if self.push_branch is not None: - config_branch = "submodule.%s.branch" % path - git_config(config_branch, config_file=".gitmodules", - value=self.push_branch_name) + # Protect calls to git_config with self.cd + with self.cd(self.path): + submodule_paths = self.get_submodule_paths() + for path in submodule_paths: + # Read submodule URL registered in .gitmodules + config_url = "submodule.%s.url" % path + submodule_url = git_config(config_url, + config_file=".gitmodules") + + # Substitute submodule URL using connection login + user = self.gh.get_login() + pattern = '(.*github.com[:/]).*(/.*.git)' + new_url = re.sub(pattern, r'\1%s\2' % user, submodule_url) + git_config(config_url, config_file=".gitmodules", + value=new_url) + + # Substitute submodule branch + if self.push_branch is not None: + config_branch = "submodule.%s.branch" % path + git_config(config_branch, config_file=".gitmodules", + value=self.push_branch_name) updated = self.has_local_changes() if updated: @@ -1952,7 +1954,6 @@ def rcleanup(self): submodule_repo.rcleanup() except Exception: self.dbg("Failed to clean repository %s" % self.path) - self.cd(self.path) def cleanup(self): """Remove remote branches created for merging.""" @@ -1974,10 +1975,9 @@ def rpush(self, branch_name, remote, force=False): self.dbg("Pushed %s to %s" % (branch_name, full_remote)) for submodule_repo in self.submodules: - try: + # TODO: Unclear if needed + with self.cd(self.path): submodule_repo.rpush(branch_name, remote, force=force) - finally: - self.cd(self.path) def __del__(self): # We need to make sure our logging wrappers are closed when this From 025936db597a77d4babeeb38cf42df9d3dcc6351 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 16:27:56 +0200 Subject: [PATCH 08/16] Better cd logging --- scc/git.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scc/git.py b/scc/git.py index e3140a38..ff137a4e 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1077,9 +1077,9 @@ def __enter__(self): def __exit__(self, *args): os.chdir(self.original) - self.dbg("< cd %s", directory) + self.dbg(" %s", os.getcwd(), self.original) - self.dbg("> cd %s", directory) + self.dbg(">cd: %s --> %s", os.getcwd(), directory) os.chdir(directory) return DirectoryChanger(self.dbg) From 5e8f22b6d6e55f94d864f1a665c3b4d10a62688b Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 17:10:10 +0200 Subject: [PATCH 09/16] And _more_ debugging --- scc/git.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/scc/git.py b/scc/git.py index ff137a4e..9382f817 100755 --- a/scc/git.py +++ b/scc/git.py @@ -735,7 +735,7 @@ def is_merged(self): class GitHubRepository(object): def __init__(self, gh, user_name, repo_name): - self.log = logging.getLogger("scc.repo") + self.log = logging.getLogger("scc.repo.%s.%s" % (repo_name, user_name)) self.dbg = self.log.debug self.gh = gh self.user_name = user_name @@ -1007,6 +1007,13 @@ def find_candidate_branches(self, filters, class GitRepository(object): + def __initlog__(self, name): + self.log = logging.getLogger(name) + self.dbg = self.log.debug + self.info = self.log.info + self.debugWrap = LoggerWrapper(self.log, logging.DEBUG) + self.infoWrap = LoggerWrapper(self.log, logging.INFO) + def __init__(self, gh, path, remote="origin", push_branch=None, repository_config=None): """ @@ -1014,16 +1021,12 @@ def __init__(self, gh, path, remote="origin", push_branch=None, register the GitHub origin remote. """ - self.log = logging.getLogger("scc.git") - self.dbg = self.log.debug - self.info = self.log.info - self.debugWrap = LoggerWrapper(self.log, logging.DEBUG) - self.infoWrap = LoggerWrapper(self.log, logging.INFO) - + self.__initlog__("scc.git") self.gh = gh self.path = path root_path = self.communicate("git", "rev-parse", "--show-toplevel") self.path = os.path.abspath(root_path.strip()) + self.__initlog__("scc.git.%s" % os.path.basename(self.path)) self.get_status() @@ -1077,9 +1080,9 @@ def __enter__(self): def __exit__(self, *args): os.chdir(self.original) - self.dbg(" %s", os.getcwd(), self.original) + self.dbg(" < cd: %s" % self.original) - self.dbg(">cd: %s --> %s", os.getcwd(), directory) + self.dbg(" > cd: %s" % directory) os.chdir(directory) return DirectoryChanger(self.dbg) From a694e431decf8c05316d42a3c67a4127a0424fae Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 17:34:54 +0200 Subject: [PATCH 10/16] Simplify unneeded paths --- scc/git.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/scc/git.py b/scc/git.py index 9382f817..01483e59 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1060,13 +1060,12 @@ def register_submodules(self): directory in self.repository_config["submodules"]: repository_config = \ self.repository_config["submodules"][directory] - # TODO: Unclear if this is needed - with self.cd(self.path): - submodule_repo = \ - self.gh.git_repo(directory, - repository_config=repository_config) - self.submodules.append(submodule_repo) - submodule_repo.register_submodules() + + submodule_repo = \ + self.gh.git_repo(directory, + repository_config=repository_config) + self.submodules.append(submodule_repo) + submodule_repo.register_submodules() def cd(self, directory): class DirectoryChanger(object): @@ -1978,9 +1977,7 @@ def rpush(self, branch_name, remote, force=False): self.dbg("Pushed %s to %s" % (branch_name, full_remote)) for submodule_repo in self.submodules: - # TODO: Unclear if needed - with self.cd(self.path): - submodule_repo.rpush(branch_name, remote, force=force) + submodule_repo.rpush(branch_name, remote, force=force) def __del__(self): # We need to make sure our logging wrappers are closed when this From 740529d85fffc6016470824e48f3f6d78afaeb2e Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 18:02:04 +0200 Subject: [PATCH 11/16] Oops. It is needed --- scc/git.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/scc/git.py b/scc/git.py index 01483e59..1bc0979e 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1022,7 +1022,7 @@ def __init__(self, gh, path, remote="origin", push_branch=None, """ self.__initlog__("scc.git") - self.gh = gh + self.gh = gh # TODO: Possibly needs a cd wrapper self.path = path root_path = self.communicate("git", "rev-parse", "--show-toplevel") self.path = os.path.abspath(root_path.strip()) @@ -1052,20 +1052,21 @@ def __str__(self): return "GitRepo(%s)" % self.path def register_submodules(self): - if len(self.submodules) == 0: - for directory in self.get_submodule_paths(): - repository_config = None - if self.repository_config is not None and \ - "submodules" in self.repository_config and \ - directory in self.repository_config["submodules"]: - repository_config = \ - self.repository_config["submodules"][directory] - - submodule_repo = \ - self.gh.git_repo(directory, - repository_config=repository_config) - self.submodules.append(submodule_repo) - submodule_repo.register_submodules() + with self.cd(self.path): + if len(self.submodules) == 0: + for directory in self.get_submodule_paths(): + repository_config = None + if self.repository_config is not None and \ + "submodules" in self.repository_config and \ + directory in self.repository_config["submodules"]: + repository_config = \ + self.repository_config["submodules"][directory] + + submodule_repo = \ + self.gh.git_repo(directory, + repository_config=repository_config) + self.submodules.append(submodule_repo) + submodule_repo.register_submodules() def cd(self, directory): class DirectoryChanger(object): From 3f43efbc398d8722b3b1eb892f7f0faf10b73197 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 18:07:05 +0200 Subject: [PATCH 12/16] Wrap rev-parse --- scc/git.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scc/git.py b/scc/git.py index 1bc0979e..ad90230e 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1023,8 +1023,8 @@ def __init__(self, gh, path, remote="origin", push_branch=None, self.__initlog__("scc.git") self.gh = gh # TODO: Possibly needs a cd wrapper - self.path = path - root_path = self.communicate("git", "rev-parse", "--show-toplevel") + with self.cd(path): + root_path = self.communicate("git", "rev-parse", "--show-toplevel") self.path = os.path.abspath(root_path.strip()) self.__initlog__("scc.git.%s" % os.path.basename(self.path)) From 4ba69702e1dc061700065ffcfc4ac6d3439d0bdc Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 18:22:58 +0200 Subject: [PATCH 13/16] Use absolute subdirectory path --- scc/git.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scc/git.py b/scc/git.py index ad90230e..0d81357f 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1023,8 +1023,8 @@ def __init__(self, gh, path, remote="origin", push_branch=None, self.__initlog__("scc.git") self.gh = gh # TODO: Possibly needs a cd wrapper - with self.cd(path): - root_path = self.communicate("git", "rev-parse", "--show-toplevel") + self.path = path + root_path = self.communicate("git", "rev-parse", "--show-toplevel") self.path = os.path.abspath(root_path.strip()) self.__initlog__("scc.git.%s" % os.path.basename(self.path)) @@ -1063,7 +1063,7 @@ def register_submodules(self): self.repository_config["submodules"][directory] submodule_repo = \ - self.gh.git_repo(directory, + self.gh.git_repo(os.path.join(self.path, directory), repository_config=repository_config) self.submodules.append(submodule_repo) submodule_repo.register_submodules() From c3d8f548b85c1c7f49cd801a54ea286f451842c8 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 20:21:27 +0200 Subject: [PATCH 14/16] Add decorator for chdir --- scc/git.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/scc/git.py b/scc/git.py index 0d81357f..ad272536 100755 --- a/scc/git.py +++ b/scc/git.py @@ -34,6 +34,8 @@ import socket import yaml import six +import functools + from ssl import SSLError from yaclifw.framework import Command, Stop @@ -211,6 +213,17 @@ def get_github(login_or_token=None, password=None, **kwargs): """ return GHManager(login_or_token, password, **kwargs) + +class CD(object): + + def __call__(self, f): + @functools.wraps(f) + def wrapper(*args, **kw): + this = args[0] + with this.cd(this.path): + return f(*args, **kw) + return wrapper + # # Management classes. These allow for proper mocking in tests. # @@ -1760,6 +1773,7 @@ def get_fork_filter(self, is_submodule=False): return lambda x: ( '/' in x and not x.endswith(repo_names)) + @CD() def rmerge(self, filters, info=False, comment=False, commit_id="merge", top_message=None, update_gitmodules=False, set_commit_status=False, allow_empty=True, is_submodule=False): From 788cfac0a37375bdc23932057e45dd3ad26f8bb6 Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 20:26:02 +0200 Subject: [PATCH 15/16] Log rmerge --- scc/git.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scc/git.py b/scc/git.py index ad272536..3379a6b3 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1779,6 +1779,7 @@ def rmerge(self, filters, info=False, comment=False, commit_id="merge", set_commit_status=False, allow_empty=True, is_submodule=False): """Recursively merge PRs for each submodule.""" + self.dbg("rmerge: %s" % filters) if self.repository_config is not None and \ "base-branch" in self.repository_config and \ filters["base"] != self.repository_config["base-branch"]: From 0625c134ae7254449f9001ce26d9d1f891d09aea Mon Sep 17 00:00:00 2001 From: jmoore Date: Wed, 29 Aug 2018 20:34:06 +0200 Subject: [PATCH 16/16] Use `git status --porcelain` No output from status --porcelain more exactly matches the semantics of whether or not allow-empty is needed. --- scc/git.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scc/git.py b/scc/git.py index 3379a6b3..53c29561 100755 --- a/scc/git.py +++ b/scc/git.py @@ -1112,7 +1112,8 @@ def communicate(self, *command, **kwargs): rc: %s stdout: %s stderr: %s""" % (" ".join(command), p.returncode, o, e) - raise Exception(msg) + self.log.error(msg) + raise Stop("failed command") if return_stderr: return o, e @@ -1311,13 +1312,13 @@ def get_rev_list(self, commit): def has_local_changes(self): """Check for local changes in the Git repository""" - try: - self.call("git", "diff-index", "--quiet", "HEAD") - self.dbg("%s has no local changes", self) - return False - except Exception: + out = self.communicate("git", "status", "--porcelain").strip() + if out: self.dbg("%s has local changes", self) return True + else: + self.dbg("%s has no local changes", self) + return False def has_ref(self, ref): """Check for reference existence in the local Git repository"""