def main(): """Run a git pre-commit lint-check.""" # If we're a merge, don't try to do a lint-check. git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir']) if os.path.exists(os.path.join(git_root.strip(), 'MERGE_HEAD')): print "Skipping lint on merge..." return 0 commit_message = open(sys.argv[1]).read() # Get rid of the comment lines, and leading and trailing whitespace. commit_message = _normalized_commit_message(commit_message) # If the commit message is empty or unchanged from the template, abort. if not commit_message: print "Aborting commit, empty commit message" return 1 try: with open(os.path.join(git_root.strip(), 'commit_template')) as f: template = f.read() except (IOError, OSError): # user doesn't have a commit template pass else: if commit_message == _normalized_commit_message(template): print "Aborting commit, commit message unchanged" return 1 # Go through all modified or added files. try: subprocess.check_output(['git', 'rev-parse', '--verify', 'HEAD'], stderr=subprocess.STDOUT) parent = 'HEAD' except subprocess.CalledProcessError: parent = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' # empty repo # Look at Added, Modified, and Renamed files. files = subprocess.check_output([ 'git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z', parent ]) files_to_lint = files.strip('\0').split('\0') # that's what -z is for if not files_to_lint or files_to_lint == ['']: return 0 num_errors = hook_lib.lint_files(files_to_lint) # Lint the commit message itself! # For the phabricator workflow, some people always have the git # commit message be 'WIP', and put in the actual message at 'arc # diff' time. We don't require a 'real' commit message in that # case. if not commit_message.lower().startswith('wip'): num_errors += hook_lib.lint_commit_message(commit_message) # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.git', 'commit.save'))
def main(): """Run a git pre-commit lint-check.""" # If we're a merge, don't try to do a lint-check. git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir']) if os.path.exists(os.path.join(git_root.strip(), 'MERGE_HEAD')): print "Skipping lint on merge..." return 0 commit_message = open(sys.argv[1]).read() # Get rid of the comment lines, and leading and trailing whitespace. commit_message = _normalized_commit_message(commit_message) # If the commit message is empty or unchanged from the template, abort. if not commit_message: print "Aborting commit, empty commit message" return 1 try: with open(os.path.join(git_root.strip(), 'commit_template')) as f: template = f.read() except (IOError, OSError): # user doesn't have a commit template pass else: if commit_message == _normalized_commit_message(template): print "Aborting commit, commit message unchanged" return 1 # Go through all modified or added files. try: subprocess.check_output(['git', 'rev-parse', '--verify', 'HEAD'], stderr=subprocess.STDOUT) parent = 'HEAD' except subprocess.CalledProcessError: parent = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' # empty repo # Look at Added, Modified, and Renamed files. files = subprocess.check_output(['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z', parent]) files_to_lint = files.strip('\0').split('\0') # that's what -z is for if not files_to_lint or files_to_lint == ['']: return 0 num_errors = hook_lib.lint_files(files_to_lint) # Lint the commit message itself! # For the phabricator workflow, some people always have the git # commit message be 'WIP', and put in the actual message at 'arc # diff' time. We don't require a 'real' commit message in that # case. if not commit_message.lower().startswith('wip'): num_errors += hook_lib.lint_commit_message(commit_message) # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.git', 'commit.save'))
def commit_msg_hook(commit_message_file): """Run a git pre-commit lint-check.""" git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir']).decode('utf-8') # read the commit message contents from the file specified commit_message = open(commit_message_file).read() # Get rid of the comment lines, and leading and trailing whitespace. commit_message = _normalized_commit_message(commit_message) # If the commit message is empty or unchanged from the template, abort. if not commit_message: six.print_("Aborting commit, empty commit message") return 1 try: with open(os.path.join(git_root.strip(), 'commit_template')) as f: template = f.read() except (IOError, OSError): # user doesn't have a commit template pass else: if commit_message == _normalized_commit_message(template): six.print_("Aborting commit, commit message unchanged") return 1 # If we're a merge, don't try to do a lint-check. is_merge_commit = os.path.exists( os.path.join(git_root.strip(), 'MERGE_HEAD')) # Lint the commit message itself! # For the phabricator workflow, some people always have the git # commit message be 'WIP', and put in the actual message at 'arc # diff' time. We don't require a 'real' commit message in that # case. num_errors = 0 if not is_merge_commit and not commit_message.lower().startswith('wip'): num_errors += hook_lib.lint_commit_message(commit_message) # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.git', 'commit.save'))
def main(commit_message_file): """Run a git pre-commit lint-check.""" # If we're a merge, don't try to do a lint-check. git_root = subprocess.check_output(['git', 'rev-parse', '--git-dir']) # read the commit message contents from the file specified commit_message = open(commit_message_file).read() # Get rid of the comment lines, and leading and trailing whitespace. commit_message = _normalized_commit_message(commit_message) # If the commit message is empty or unchanged from the template, abort. if not commit_message: print "Aborting commit, empty commit message" return 1 try: with open(os.path.join(git_root.strip(), 'commit_template')) as f: template = f.read() except (IOError, OSError): # user doesn't have a commit template pass else: if commit_message == _normalized_commit_message(template): print "Aborting commit, commit message unchanged" return 1 is_merge_commit = os.path.exists(os.path.join(git_root.strip(), 'MERGE_HEAD')) # Go through all modified or added files. We handle the case # separately if we're a merge or a 'normal' commit. If we're a # merge, the pre-commit hook will only trigger if the merge had # conflicts; in this case we only care about linting the files # that were edited to resolve the conflict. For a normal commit, # we of course care about linting *all* the changes files. if is_merge_commit: # I used to run # git diff-tree -r --cc --name-only --diff-filter=AMR -z HEAD # but this wouldn't catch changes made to resolve conflicts, so # I try this other approach instead. It doesn't properly ignore # files that have changed in both branches but the system was # able to do an automatic merge though, sadly. a_files = subprocess.check_output(['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z', 'ORIG_HEAD']) b_files = subprocess.check_output(['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z', 'MERGE_HEAD']) a_files = frozenset(a_files.strip('\0').split('\0')) b_files = frozenset(b_files.strip('\0').split('\0')) files_to_lint = list(a_files & b_files) else: # Look at Added, Modified, and Renamed files. # When no commit is specified, it defaults to HEAD which is # what we want. files = subprocess.check_output(['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z']) files_to_lint = files.strip('\0').split('\0') # that's what -z is for if not files_to_lint or files_to_lint == ['']: return 0 lint_errors = hook_lib.lint_files(files_to_lint) # Lint the commit message itself! # For the phabricator workflow, some people always have the git # commit message be 'WIP', and put in the actual message at 'arc # diff' time. We don't require a 'real' commit message in that # case. msg_errors = 0 if not is_merge_commit and not commit_message.lower().startswith('wip'): msg_errors += hook_lib.lint_commit_message(commit_message) num_errors = lint_errors + msg_errors if lint_errors: recommendation = ('Running `arc lint` may help to autofix the errors.' '\nUse "git recommit -a" when the errors' ' are fixed, to re-use this commit message.') elif msg_errors: recommendation = ('Use "git commit -a --template .git/commit.save"' ' to commit with a fixed message.') else: recommendation = None # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.git', 'commit.save'), recommendation=recommendation)
def main(commit_message_file): """Run a git pre-commit lint-check.""" # If we're a merge, don't try to do a lint-check. git_root = subprocess.check_output( ['git', 'rev-parse', '--git-dir']).decode('utf-8') # read the commit message contents from the file specified commit_message = open(commit_message_file).read() # Get rid of the comment lines, and leading and trailing whitespace. commit_message = _normalized_commit_message(commit_message) # If the commit message is empty or unchanged from the template, abort. if not commit_message: six.print_("Aborting commit, empty commit message") return 1 try: with open(os.path.join(git_root.strip(), 'commit_template')) as f: template = f.read() except (IOError, OSError): # user doesn't have a commit template pass else: if commit_message == _normalized_commit_message(template): six.print_("Aborting commit, commit message unchanged") return 1 is_merge_commit = os.path.exists(os.path.join( git_root.strip(), 'MERGE_HEAD')) # Go through all modified or added files. We handle the case # separately if we're a merge or a 'normal' commit. If we're a # merge, the pre-commit hook will only trigger if the merge had # conflicts; in this case we only care about linting the files # that were edited to resolve the conflict. For a normal commit, # we of course care about linting *all* the changes files. if is_merge_commit: # I used to run # git diff-tree -r --cc --name-only --diff-filter=AMR -z HEAD # but this wouldn't catch changes made to resolve conflicts, so # I try this other approach instead. It doesn't properly ignore # files that have changed in both branches but the system was # able to do an automatic merge though, sadly. a_files = subprocess.check_output( ['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z', 'ORIG_HEAD']).decode('utf-8') b_files = subprocess.check_output( ['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z', 'MERGE_HEAD']).decode('utf-8') a_files = frozenset(a_files.strip('\0').split('\0')) b_files = frozenset(b_files.strip('\0').split('\0')) files_to_lint = list(a_files & b_files) else: # Look at Added, Modified, and Renamed files. # When no commit is specified, it defaults to HEAD which is # what we want. files = subprocess.check_output( ['git', 'diff', '--cached', '--name-only', '--diff-filter=AMR', '-z']).decode('utf-8') files_to_lint = files.strip('\0').split('\0') # that's what -z is for if not files_to_lint or files_to_lint == ['']: return 0 lint_errors = hook_lib.lint_files(files_to_lint) # Lint the commit message itself! # For the phabricator workflow, some people always have the git # commit message be 'WIP', and put in the actual message at 'arc # diff' time. We don't require a 'real' commit message in that # case. msg_errors = 0 if not is_merge_commit and not commit_message.lower().startswith('wip'): msg_errors += hook_lib.lint_commit_message(commit_message) num_errors = lint_errors + msg_errors if lint_errors: recommendation = ('Running `arc lint` may help to autofix the errors.' '\nUse "git recommit -a" when the errors' ' are fixed, to re-use this commit message.') elif msg_errors: recommendation = ('Use "git commit -a --template .git/commit.save"' ' to commit with a fixed message.') else: recommendation = None # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.git', 'commit.save'), recommendation=recommendation)
try: status_output = subprocess.check_output(['hg', 'status', '-a', '-m', '--change', 'tip']) except subprocess.CalledProcessError, e: print >> sys.stderr, "Error calling 'hg status':", e return 1 files_to_lint = [] if status_output: for line in status_output.strip().split('\n'): # each line has the format "M path/to/filename.js" status, filename = line.split(' ', 1) files_to_lint.append(filename) num_errors = hook_lib.lint_files(files_to_lint) # Lint the commit message itself! commit_message = subprocess.check_output(['hg', 'tip', '--template', '{desc}']) num_errors += hook_lib.lint_commit_message(commit_message) # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.hg', 'commit.save')) if __name__ == '__main__': suppress_lint = os.getenv('FORCE_COMMIT', '') if suppress_lint.lower() not in ('1', 'true'): sys.exit(main())
try: status_output = subprocess.check_output( ['hg', 'status', '-a', '-m', '--change', 'tip']) except subprocess.CalledProcessError, e: print >> sys.stderr, "Error calling 'hg status':", e return 1 files_to_lint = [] if status_output: for line in status_output.strip().split('\n'): # each line has the format "M path/to/filename.js" status, filename = line.split(' ', 1) files_to_lint.append(filename) num_errors = hook_lib.lint_files(files_to_lint) # Lint the commit message itself! commit_message = subprocess.check_output( ['hg', 'tip', '--template', '{desc}']) num_errors += hook_lib.lint_commit_message(commit_message) # Report what we found, and exit with the proper status code. hook_lib.report_errors_and_exit(num_errors, commit_message, os.path.join('.hg', 'commit.save')) if __name__ == '__main__': suppress_lint = os.getenv('FORCE_COMMIT', '') if suppress_lint.lower() not in ('1', 'true'): sys.exit(main())