From patchwork Fri Jan 31 21:58:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11360609 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2EBCC13A4 for ; Fri, 31 Jan 2020 21:58:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0D1482082E for ; Fri, 31 Jan 2020 21:58:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SBUaaL+e" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726225AbgAaV6T (ORCPT ); Fri, 31 Jan 2020 16:58:19 -0500 Received: from mail-wm1-f50.google.com ([209.85.128.50]:40336 "EHLO mail-wm1-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726199AbgAaV6T (ORCPT ); Fri, 31 Jan 2020 16:58:19 -0500 Received: by mail-wm1-f50.google.com with SMTP id t14so10442406wmi.5 for ; Fri, 31 Jan 2020 13:58:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=39fy91fgGzKvFe/kdRqWd1b5A2SJFlQxpy83ONk/D2o=; b=SBUaaL+eXQyAJere8VPHpSP+gpq65ImN7y4E/aYIA/+dN/L0siB+uQVh5eW2OqzHdS 90QGsTG3+JYMIkvcXBoCjngt91G99sC2Ma+pJUk5Yatmd1O/VePhy/ScK8/WLNtYg2PN 4k5KsPjlGHd8B96BdOD7pGI2ZvVUeK8Ak0B1SZ33nqbyqN7QPVHxowhBeD5f7QD5dfzO sZvqTqDc6+ikkTmQydNr6QWfdfpotAXkdWIA9hcKOxxOt0+RuHub7PdCvMlPRXXQZPta 7OFjIqB0xRnPKwMUBjix3OqwIssGYBM7PrANrTn42K+HNYowu3BiRtB50jy0IFXHGwTh CjLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=39fy91fgGzKvFe/kdRqWd1b5A2SJFlQxpy83ONk/D2o=; b=CRDnXzx0QlbvB0v/gpMJoT2PPnOAelyVamjjBJJT47il1p03vyl4AiX5C3h2xXdPCZ 3rJ6kuw7aoytqW88YwnwfaPYfT+R1OFd58llc3R/aK2bAQv74PJ4bqjl7Y3M+eHzwWhN pl2x/tM6M/wgKId0BsGBOBQ0oNoPU+yi6p8ZiJ1BPZUqnclLjvtGT3QhLqQQcNBb9FFD eoZHI7fqGv0UppVRpEcEWoAdCGNZyDhZLLXAU91DtVKKupquBPQnr8JobjyT3MbBwIVz sl4ikP+F07Q7rzaTWBDTXSjUOeSeCJEGG/aHgyMJbOutkqqfrTDW1DMS4ku7fEzA3K+e kWGg== X-Gm-Message-State: APjAAAW3GdmNbktXktQJ0wHGlfBG7Clj78zY3NVGwL6finVy6boVXIEr S81XEhRz+GeLdvVdFgoojvBNOGqC X-Google-Smtp-Source: APXvYqz1WaKvT9dtSU7HCBelQznzqG7XN1Lo5LYSS/JqbQOxAo7KzxlpJaTcfWUW6beUD3DUZlzbFw== X-Received: by 2002:a05:600c:211:: with SMTP id 17mr13975867wmi.60.1580507897292; Fri, 31 Jan 2020 13:58:17 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t5sm13366473wrr.35.2020.01.31.13.58.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jan 2020 13:58:16 -0800 (PST) Message-Id: <585bdd51b258acbf438efe5a84924977778aff71.1580507895.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Ben Keene via GitGitGadget" Date: Fri, 31 Jan 2020 21:58:12 +0000 Subject: [PATCH v2 1/4] git-p4: rewrite prompt to be Windows compatible Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Ben Keene , Ben Keene Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ben Keene The existing function prompt(prompt_text) does not work correctly when run on Windows 10 bash terminal when launched from the sourcetree GUI application. The stdout is not flushed properly so the prompt text is not displayed to the user until the next flush of stdout, which is quite confusing. Change this method by: * Adding flush to stderr, stdout, and stdin * Use readline from sys.stdin instead of raw_input. The existing strip().lower() are retained. Signed-off-by: Ben Keene --- git-p4.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/git-p4.py b/git-p4.py index 40d9e7c594..7d8a5ee788 100755 --- a/git-p4.py +++ b/git-p4.py @@ -175,7 +175,11 @@ def prompt(prompt_text): """ choices = set(m.group(1) for m in re.finditer(r"\[(.)\]", prompt_text)) while True: - response = raw_input(prompt_text).strip().lower() + sys.stderr.flush() + sys.stdout.write(prompt_text) + sys.stdout.flush() + sys.stdin.flush() + response=sys.stdin.readline().strip().lower() if not response: continue response = response[0] From patchwork Fri Jan 31 21:58:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11360615 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9ED161398 for ; Fri, 31 Jan 2020 21:58:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7C14C20705 for ; Fri, 31 Jan 2020 21:58:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RNTyRTgg" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726262AbgAaV6V (ORCPT ); Fri, 31 Jan 2020 16:58:21 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:38978 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726180AbgAaV6U (ORCPT ); Fri, 31 Jan 2020 16:58:20 -0500 Received: by mail-wr1-f65.google.com with SMTP id y11so10386683wrt.6 for ; Fri, 31 Jan 2020 13:58:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=KmGtXPMlV8ymsmHIwAhdCuBuRoA9p/FklThI8KHVs9A=; b=RNTyRTgg/HUxYtjpbK7w0AwmOfTB/LpOgRmqqJnYN0V0DBIXdfbqY68o3ZSUqMRVLk w0mNiwoRi1HnGAMP76GF/mVZHj+q8FLpLqgXxt4tS1y8YY+AOcZA2i51iJm0KQaepNAN +JveUDAyUbM5gbiEf4ezEN5c9txe6iiA/sOuwqlXDDoYsR+HLCHBHeEYUS5+pmRSoBw6 RtjRkJ2Iqogg1R+hn7yOfREEwortjOuV0SgGb4Y2wPByz0VIPu4SSZ2PouniOeQU+xZZ 99PW/sxH1hbfy4icKwgzNp7aDaEg2K1WDzcaEmI14CNUR8IK8K61AxjDeugb6Fm3prRA kKTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=KmGtXPMlV8ymsmHIwAhdCuBuRoA9p/FklThI8KHVs9A=; b=JuYRkX8QVWSkLa770rNOHDgk06DFI36ADKlqfSbGrX4sgpN1jbGpZHX7fCrPe/m2HN UZmh+5gup+Itmi3aJUiomCEwCH/YOWIY7vblEISqdRhVx/P1JQH1X6W8FpYNR11kma1V AZoBZ21Xfv9NJQroCrVOYmFDmGOtvewkB/tMZz5sMImlp9CkAzgGLI4nAKp/pai5JH0g cU1WORUNFgZjMCHCsymJ3wGeGDYRAIuISKJAYtPvHazn6WRbEOy1PchIx4cBKuWvnVSi rU+ae90cp+3v43M23zTvr51fAb/iQe2vUDuOdWkInWNwIWwcTPHYO66+pBLQjlaAVA8J wnxQ== X-Gm-Message-State: APjAAAVEnGpwYSVNv7kbY1RwOOOgpeL3H1dPtms4pvi5yCRmMvA96ynz UmFnfbXan/GT8EIQ1Ww5ax6/O1rK X-Google-Smtp-Source: APXvYqwl9T2o9BfysldcPRXA2lqqNGkQpXJVMQwgZu6UtHh9TD5pVKa5RZRl0WCUmYb6yrDnOdp9XA== X-Received: by 2002:adf:f64b:: with SMTP id x11mr405473wrp.355.1580507898061; Fri, 31 Jan 2020 13:58:18 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x21sm11930849wmi.30.2020.01.31.13.58.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jan 2020 13:58:17 -0800 (PST) Message-Id: In-Reply-To: References: From: "Ben Keene via GitGitGadget" Date: Fri, 31 Jan 2020 21:58:13 +0000 Subject: [PATCH v2 2/4] git-p4: create new method gitRunHook Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Ben Keene , Ben Keene Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ben Keene This commit is in preparation of introducing new p4 submit hooks. The current code in the python script git-p4.py makes the assumption that the git hooks can be executed by subprocess.call() method. However, when git is run on Windows, this may not work as expected. The subprocess.call() does not execute SH.EXE implictly under Windows, so the scripts may fail. In other words, the hooks do not execute under windows because the shell interpreter is not automatically loaded. Add a new function, gitRunHook, that takes 2 parameters: * the filename of an optionally registered git hook * an optional list of parameters The gitRunHook function will honor the existing behavior seen in the current code for executing the p4-pre-submit hook: * Hooks are looked for in core.hooksPath directory. * If core.hooksPath is not set, then the current .git/hooks directory is checked. * If the hook does not exist, the function returns True. * If the hook file is not accessible, the function returns True. * If the hook returns a zero exit code when executed, the function return True. * If the hook returns a non-zero exit code, the function returns False. Add new conditional behavior for Windows: * Check for an evironment variable 'EXEPATH' which should be set by git when git-p4.py is envoked. * If EXEPATH is None - treat it as an empty string. * If EXEPATH is set, look for sh.exe in the bin/ directory located in EXEPATH. * If EXEPATH is not set, attempt to resolve against "bin/sh.exe" * Add a new test for Windows that checks to see of sh.exe can be located. If not, return True. Signed-off-by: Ben Keene --- git-p4.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/git-p4.py b/git-p4.py index 7d8a5ee788..4e481b3b55 100755 --- a/git-p4.py +++ b/git-p4.py @@ -4125,6 +4125,35 @@ def printUsage(commands): "unshelve" : P4Unshelve, } +def gitRunHook(cmd, param=[]): + """Execute a hook if the hook exists.""" + if verbose: + sys.stderr.write("Looking for hook: %s\n" % cmd) + sys.stderr.flush() + + hooks_path = gitConfig("core.hooksPath") + if len(hooks_path) <= 0: + hooks_path = os.path.join(os.environ.get("GIT_DIR", ".git"), "hooks") + + hook_file = os.path.join(hooks_path, cmd) + if isinstance(param,basestring): + param=[param] + + if platform.system() == 'Windows': + exepath = os.environ.get("EXEPATH") + if exepath is None: + exepath = "" + shexe = os.path.join(exepath, "bin", "sh.exe") + if os.path.isfile(shexe) \ + and os.path.isfile(hook_file) \ + and os.access(hook_file, os.X_OK) \ + and subprocess.call([shexe, hook_file] + param) != 0: + return False + + else: + if os.path.isfile(hook_file) and os.access(hook_file, os.X_OK) and subprocess.call([hook_file] + param) != 0: + return False + return True def main(): if len(sys.argv[1:]) == 0: From patchwork Fri Jan 31 21:58:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11360611 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4731913A4 for ; Fri, 31 Jan 2020 21:58:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 247D02082E for ; Fri, 31 Jan 2020 21:58:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Zpj5l+OX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726330AbgAaV6V (ORCPT ); Fri, 31 Jan 2020 16:58:21 -0500 Received: from mail-wm1-f65.google.com ([209.85.128.65]:56050 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726199AbgAaV6U (ORCPT ); Fri, 31 Jan 2020 16:58:20 -0500 Received: by mail-wm1-f65.google.com with SMTP id q9so9639566wmj.5 for ; Fri, 31 Jan 2020 13:58:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=dG7WSJ4uoNLxdjXeoy82EGkz/4mMq86QcJn2e1yuw/c=; b=Zpj5l+OXzxzyie/meop29i6UgdfNmsIvzdg6fk1Z8O0vrH89IF/c4CjEo/a0O+FCDf 0hRvn4IAZ1JX39CPawYX77f5c/cU5FXclay75BUCjJOdqZe4lJLA6NDV6GScqUA6xYWX unPrbU3QPcXH507hC28uarIqLx6BiQ0mqih+WSQPDKxzp1BoTieSbstj+WA6hhugREIM EsAgsbJ7k5KoYSSX/nm5ez8vWraCyZmDWajNVSvVyLELrg586HYwtnrPFXj+ywMKHPUY 7nb/t1m56s6Z/+Mig74VmWHqJ2DvsGtSJ94xuhvHIo5mYNH+njsLu9ChgPEqZ7LUgs/0 Y6uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=dG7WSJ4uoNLxdjXeoy82EGkz/4mMq86QcJn2e1yuw/c=; b=H+2ERJjJOCEKaczIi63P6zHJzRxvcldjJ5MkCxnwn2AbDuSshQZycKP+Ns2vb93C2p mn3AiAZp/eK9hraAs/5pAb75hF3EGDHmeFKrGhAQNpdjYYvMo7l74ZCa0K65J7AcCqZD Sv6g8MrJmH9Fkh+0ZL4X5mJtTg2ZSHNAqW+4NKO8jlnsbOz1yH9Ip6yDW1Cz4AJ/bp4+ mZdiaftU4XQYpbssoTlX0iijVo01/91FBmXiB8+rmQMFi8/6z5J7yzXmfBqiBZVYZyhH MXyHmi2JFX2GjjLZC6EIJc3S8UcYcC9yMP7y4t56w/LImPrA1sOeLiiXmG1ZwSatAU19 ZYQA== X-Gm-Message-State: APjAAAULBnNM7FLUMSuWCVu294ispVA214g2ESv3VQaBVKn6MjTGLL7K Vek8wvl+St9KKIYwAMy/Tcqqc6YP X-Google-Smtp-Source: APXvYqz7S0s2aYp/1Qd3HlD7HkjSt7SOjV6az6u3RvanldAkmiXGMwlve/Ie6mn9EErwxEcJ0W+10A== X-Received: by 2002:a1c:38c7:: with SMTP id f190mr13662641wma.94.1580507898754; Fri, 31 Jan 2020 13:58:18 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id z10sm11853355wmk.31.2020.01.31.13.58.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jan 2020 13:58:18 -0800 (PST) Message-Id: <1bdcdc4c18b9d8fa3cc5a9c846fb855182330d05.1580507895.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Ben Keene via GitGitGadget" Date: Fri, 31 Jan 2020 21:58:14 +0000 Subject: [PATCH v2 3/4] git-p4: add hook p4-pre-edit-changelist Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Ben Keene , Ben Keene Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ben Keene Add an additional hook to the git-p4 command to allow a hook to modify the text of the changelist prior to displaying the p4editor command. This hook will be called prior to checking for the flag "--prepare-p4-only". The hook is optional, if it does not exist, it will be skipped. The hook takes a single parameter, the filename of the temporary file that contains the P4 submit text. The hook should return a zero exit code on success or a non-zero exit code on failure. If the hook returns a non-zero exit code, git-p4 will revert the P4 edits by calling p4_revert(f) on each file that was flagged as edited and then it will return False so the calling method may continue as it does in existing failure cases. Signed-off-by: Ben Keene --- git-p4.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/git-p4.py b/git-p4.py index 4e481b3b55..61cfd1c1ae 100755 --- a/git-p4.py +++ b/git-p4.py @@ -2030,6 +2030,17 @@ def applyCommit(self, id): tmpFile.write(submitTemplate) tmpFile.close() + # Run the pre-edit hook to allow programmatic update to the changelist + hooks_path = gitConfig("core.hooksPath") + if len(hooks_path) <= 0: + hooks_path = os.path.join(os.environ.get("GIT_DIR", ".git"), "hooks") + + hook_file = os.path.join(hooks_path, "p4-pre-edit-changelist") + if os.path.isfile(hook_file) and os.access(hook_file, os.X_OK) and subprocess.call([hook_file, fileName]) != 0: + for f in editedFiles: + p4_revert(f) + return False + if self.prepare_p4_only: # # Leave the p4 tree prepared, and the submit template around From patchwork Fri Jan 31 21:58:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Arver via GitGitGadget X-Patchwork-Id: 11360617 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 34DEF1398 for ; Fri, 31 Jan 2020 21:58:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F28632082E for ; Fri, 31 Jan 2020 21:58:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="b9KFdqFn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726347AbgAaV6Y (ORCPT ); Fri, 31 Jan 2020 16:58:24 -0500 Received: from mail-wm1-f54.google.com ([209.85.128.54]:36657 "EHLO mail-wm1-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726174AbgAaV6X (ORCPT ); Fri, 31 Jan 2020 16:58:23 -0500 Received: by mail-wm1-f54.google.com with SMTP id p17so10468783wma.1 for ; Fri, 31 Jan 2020 13:58:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=EaWm5pCgfKAlsWAM1IG+K5SJlgQQMIeaaTAi1/FbsL4=; b=b9KFdqFniAAoPZ+QmFGpbDOD/hFnVoWfCJ+nhYHl0ILqxjUI92oEuJUbKA+SvDd8n4 /mhu1nprHCy369gVOgcqui+WfNE6/f4ybNItRQe1/iQUKCbUpsoT84og9V8LuuwqU9FA gRDL3tQl0oAoeZbdyzXOq4Q5Vnmi4WZZ1XK0TSuz+aIteh5zdO+O8AOnn7pg1AUaehm9 yJAjqcIXDr6rKxq7cEDRP21kdLyZWO4Xyn1xwcg0gfH7B0d2h+RzeHGDQihy+e/aGdNE J+nT9GPsQGJk6lCefM0ZlO5AE8kBGna2exaDsXiAEXvk+aqnqUxTiV8Ni/paHwcFtSAg 1jxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=EaWm5pCgfKAlsWAM1IG+K5SJlgQQMIeaaTAi1/FbsL4=; b=QWzua4PkxHNZopFRHSEmgQV0JL+mYt0TQdnhDF9EFUD/JSkMDCS6IV1QXApOuVFAXP yUik3LXd4gGESenz1UYftqKfws/tP3ckzBDMasElxRZ2f2bdUf9gso7EDD3zbhpmYbu9 aM488FlYP0cn1nyYhCl8buTwAB0C7L9e1T/P3usq/Gt2sXBy6QDW0Nz1uVMznjxgelTn +DxnaNIUK1zAa7+CL8CVs1idkZq/9GkCc3M6TlW6eckRfhTmSwtFwOsJwAkRwCBPN8tr BHAct6p2zvmzyVzRQPIfuecNM1YR8T3yKfyNpnayOyXvlUf3I8jTAPoCbp95rqfpEtJn 08AA== X-Gm-Message-State: APjAAAUlwV6sp/5aOWQsjrbdPjnqqFYaOL2MVP9KbsHzY39in305Abws kzCF4LrNK/gb0WpkAI9hAbcXAOsF X-Google-Smtp-Source: APXvYqz27xhwLYogtyoXckpHelhti95hLT2rDNd5NTq31UiVxzTGEJI9yxJJfK0gKQXMmfY78abY6Q== X-Received: by 2002:a7b:cd15:: with SMTP id f21mr13739796wmj.29.1580507899631; Fri, 31 Jan 2020 13:58:19 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id i3sm14169wrc.6.2020.01.31.13.58.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Jan 2020 13:58:19 -0800 (PST) Message-Id: <3d34dd042e47fce7bc49a63f676378172e15775e.1580507895.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Ben Keene via GitGitGadget" Date: Fri, 31 Jan 2020 21:58:15 +0000 Subject: [PATCH v2 4/4] git-p4: add p4 submit hooks Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: Ben Keene , Ben Keene Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Ben Keene The git command "commit" supports a number of hooks that support changing the behavior of the commit command. The git-p4.py program only has one existing hook, "p4-p4-pre-submit". This command occurs early in the process. There are no hooks in the process flow for modifying the P4 changelist text programmatically. Adds 3 new hooks and 1 new option to git-p4.py to the submit option. The new command line option --no-verify: Add a new command line option "--no-verify" to the Submit command of git-p4.py. This option will function in the spirit of the existing --no-verify command line option found in git commit. It will cause the P4 Submit function to ignore the existing p4-pre-submit and the new p4-changelist hooks. The new hooks are: * p4-prepare-changelist - Execute this hook after the changelist file has been created. The hook will be executed even if the --prepare-p4-only option is set. This hook ignores the --no-verify option in keeping with the existing behavior of git commit. * p4-changelist - Execute this hook after the user has edited the changelist. Do not execute this hook if the user has selected the --prepare-p4-only option. This hook will honor the --no-verify, following the conventions of git commit. * p4-post-changelist - Execute this hook after the P4 submission process has completed successfully. This hook takes no parameters and is executed regardless of the --no-verify option. It's return value will not be checked. Change the execution of the existing trigger p4-pre-submit to honor the --no-verify option. Before exiting on failure of this hook, display text to the user explaining which hook has failed and the impact of using the --no-verify option. Move all the code after creating the submitTemplate text into the try-finally block in the applyCommit() method. By restructuring the code, the P4 workspace is protected against otherwise unhandled exceptions and other early exits. The calls to the new hooks: p4-prepare-changelist, p4-changelist, and p4-post-changelist should all be called inside the try-finally block. Existing flow control can remain as defined - the if-block for prepare-p4-only sets the local variable "submitted" to True and exits the function. All other early exits, leave submitted set to False so the Finally block will undo changes to the P4 workspace. Make the small usability change of adding an empty string to the print statements displayed to the user when the prepare-p4-only option is selected. On Windows, the command print() may display a set of parentheses () to the user when the print() function is called with no parameters. By supplying an empty string, the intended blank line will print as expected. Fix a small bug when the submittedTemplate is edited by the user and all content in the file is removed. The existing code will throw an exception if the separateLine is not found in the file. Change this code to test for the separator line using a find() test first and only split on the separator if it is found. Additionally, add the new behavior that if the changelist file has been completely emptied that the Submit action for this changelist will be aborted. Signed-off-by: Ben Keene --- Documentation/git-p4.txt | 44 +++++++++- Documentation/githooks.txt | 46 ++++++++++ git-p4.py | 167 +++++++++++++++++++++++-------------- 3 files changed, 191 insertions(+), 66 deletions(-) diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index 3494a1db3e..f17c1d0561 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -374,14 +374,54 @@ These options can be used to modify 'git p4 submit' behavior. been submitted. Implies --disable-rebase. Can also be set with git-p4.disableP4Sync. Sync with origin/master still goes ahead if possible. -Hook for submit -~~~~~~~~~~~~~~~ +Hooks for submit +---------------- + +p4-pre-submit +~~~~~~~~~~~~~ + The `p4-pre-submit` hook is executed if it exists and is executable. The hook takes no parameters and nothing from standard input. Exiting with non-zero status from this script prevents `git-p4 submit` from launching. One usage scenario is to run unit tests in the hook. +p4-prepare-changelist +~~~~~~~~~~~~~~~~~~~~~ + +The `p4-prepare-changelist` hook is executed right after preparing +the default changelist message and before the editor is started. +It takes one parameter, the name of the file that contains the +changelist text. Exiting with a non-zero status from the script +will abort the process. + +The purpose of the hook is to edit the message file in place, +and it is not supressed by the `--no-verify` option. This hook +is called even if `--prepare-p4-only` is set. + +p4-changelist +~~~~~~~~~~~~~ + +The `p4-changelist` hook is executed after the changelist +message has been edited by the user. It can be bypassed with the +`--no-verify` option. It takes a single parameter, the name +of the file that holds the proposed changelist text. Exiting +with a non-zero status causes the command to abort. + +The hook is allowed to edit the changelist file and can be used +to normalize the text into some project standard format. It can +also be used to refuse the Submit after inspect the message file. + +p4-post-changelist +~~~~~~~~~~~~~~~~~~ + +The `p4-post-changelist` hook is invoked after the submit has +successfully occured in P4. It takes no parameters and is meant +primarily for notification and cannot affect the outcome of the +git p4 submit action. + + + Rebase options ~~~~~~~~~~~~~~ These options can be used to modify 'git p4 rebase' behavior. diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 50365f2914..67e78a8a05 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -515,6 +515,52 @@ The exit status determines whether git will use the data from the hook to limit its search. On error, it will fall back to verifying all files and folders. +p4-changelist +~~~~~~~~~~~~~ + +This hook is invoked by `git-p4 submit`. + +The `p4-changelist` hook is executed after the changelist +message has been edited by the user. It can be bypassed with the +`--no-verify` option. It takes a single parameter, the name +of the file that holds the proposed changelist text. Exiting +with a non-zero status causes the command to abort. + +The hook is allowed to edit the changelist file and can be used +to normalize the text into some project standard format. It can +also be used to refuse the Submit after inspect the message file. + +Run `git-p4 submit --help` for details. + +p4-prepare-changelist +~~~~~~~~~~~~~~~~~~~~~ + +This hook is invoked by `git-p4 submit`. + +The `p4-prepare-changelist` hook is executed right after preparing +the default changelist message and before the editor is started. +It takes one parameter, the name of the file that contains the +changelist text. Exiting with a non-zero status from the script +will abort the process. + +The purpose of the hook is to edit the message file in place, +and it is not supressed by the `--no-verify` option. This hook +is called even if `--prepare-p4-only` is set. + +Run `git-p4 submit --help` for details. + +p4-post-changelist +~~~~~~~~~~~~~~~~~~ + +This hook is invoked by `git-p4 submit`. + +The `p4-post-changelist` hook is invoked after the submit has +successfully occured in P4. It takes no parameters and is meant +primarily for notification and cannot affect the outcome of the +git p4 submit action. + +Run `git-p4 submit --help` for details. + p4-pre-submit ~~~~~~~~~~~~~ diff --git a/git-p4.py b/git-p4.py index 61cfd1c1ae..fe633acf84 100755 --- a/git-p4.py +++ b/git-p4.py @@ -1521,13 +1521,39 @@ def __init__(self): "work from a local git branch that is not master"), optparse.make_option("--disable-p4sync", dest="disable_p4sync", action="store_true", help="Skip Perforce sync of p4/master after submit or shelve"), + optparse.make_option("--no-verify", dest="no_verify", action="store_true", + help="Bypass p4-pre-submit and p4-changelist hooks"), ] self.description = """Submit changes from git to the perforce depot.\n - The `p4-pre-submit` hook is executed if it exists and is executable. - The hook takes no parameters and nothing from standard input. Exiting with - non-zero status from this script prevents `git-p4 submit` from launching. - - One usage scenario is to run unit tests in the hook.""" + The `p4-pre-submit` hook is executed if it exists and is executable. It + can be bypassed with the `--no-verify` command line option. The hook takes + no parameters and nothing from standard input. Exiting with a non-zero status + from this script prevents `git-p4 submit` from launching. + + One usage scenario is to run unit tests in the hook. + + The `p4-prepare-changelist` hook is executed right after preparing the default + changelist message and before the editor is started. It takes one parameter, + the name of the file that contains the changelist text. Exiting with a non-zero + status from the script will abort the process. + + The purpose of the hook is to edit the message file in place, and it is not + supressed by the `--no-verify` option. This hook is called even if + `--prepare-p4-only` is set. + + The `p4-changelist` hook is executed after the changelist message has been + edited by the user. It can be bypassed with the `--no-verify` option. It + takes a single parameter, the name of the file that holds the proposed + changelist text. Exiting with a non-zero status causes the command to abort. + + The hook is allowed to edit the changelist file and can be used to normalize + the text into some project standard format. It can also be used to refuse the + Submit after inspect the message file. + + The `p4-post-changelist` hook is invoked after the submit has successfully + occured in P4. It takes no parameters and is meant primarily for notification + and cannot affect the outcome of the git p4 submit action. + """ self.usage += " [name of git branch to submit into perforce depot]" self.origin = "" @@ -1545,6 +1571,7 @@ def __init__(self): self.exportLabels = False self.p4HasMoveCommand = p4_has_move_command() self.branch = None + self.no_verify = False if gitConfig('git-p4.largeFileSystem'): die("Large file system not supported for git-p4 submit command. Please remove it from config.") @@ -1931,6 +1958,9 @@ def applyCommit(self, id): applyPatchCmd = patchcmd + "--check --apply -" patch_succeeded = True + if verbose: + print("TryPatch: %s" % tryPatchCmd) + if os.system(tryPatchCmd) != 0: fixed_rcs_keywords = False patch_succeeded = False @@ -1970,6 +2000,7 @@ def applyCommit(self, id): print("Retrying the patch with RCS keywords cleaned up") if os.system(tryPatchCmd) == 0: patch_succeeded = True + print("Patch succeesed this time") if not patch_succeeded: for f in editedFiles: @@ -2030,66 +2061,73 @@ def applyCommit(self, id): tmpFile.write(submitTemplate) tmpFile.close() - # Run the pre-edit hook to allow programmatic update to the changelist - hooks_path = gitConfig("core.hooksPath") - if len(hooks_path) <= 0: - hooks_path = os.path.join(os.environ.get("GIT_DIR", ".git"), "hooks") - - hook_file = os.path.join(hooks_path, "p4-pre-edit-changelist") - if os.path.isfile(hook_file) and os.access(hook_file, os.X_OK) and subprocess.call([hook_file, fileName]) != 0: - for f in editedFiles: - p4_revert(f) - return False - - if self.prepare_p4_only: - # - # Leave the p4 tree prepared, and the submit template around - # and let the user decide what to do next - # - print() - print("P4 workspace prepared for submission.") - print("To submit or revert, go to client workspace") - print(" " + self.clientPath) - print() - print("To submit, use \"p4 submit\" to write a new description,") - print("or \"p4 submit -i <%s\" to use the one prepared by" \ - " \"git p4\"." % fileName) - print("You can delete the file \"%s\" when finished." % fileName) - - if self.preserveUser and p4User and not self.p4UserIsMe(p4User): - print("To preserve change ownership by user %s, you must\n" \ - "do \"p4 change -f \" after submitting and\n" \ - "edit the User field.") - if pureRenameCopy: - print("After submitting, renamed files must be re-synced.") - print("Invoke \"p4 sync -f\" on each of these files:") - for f in pureRenameCopy: - print(" " + f) - - print() - print("To revert the changes, use \"p4 revert ...\", and delete") - print("the submit template file \"%s\"" % fileName) - if filesToAdd: - print("Since the commit adds new files, they must be deleted:") - for f in filesToAdd: - print(" " + f) - print() - return True - - # - # Let the user edit the change description, then submit it. - # submitted = False try: + # Allow the hook to edit the changelist text before presenting it + # to the user. + if not gitRunHook("p4-prepare-changelist", [fileName]): + return False + + if self.prepare_p4_only: + # + # Leave the p4 tree prepared, and the submit template around + # and let the user decide what to do next + # + submitted = True + print("") + print("P4 workspace prepared for submission.") + print("To submit or revert, go to client workspace") + print(" " + self.clientPath) + print("") + print("To submit, use \"p4 submit\" to write a new description,") + print("or \"p4 submit -i <%s\" to use the one prepared by" \ + " \"git p4\"." % fileName) + print("You can delete the file \"%s\" when finished." % fileName) + + if self.preserveUser and p4User and not self.p4UserIsMe(p4User): + print("To preserve change ownership by user %s, you must\n" \ + "do \"p4 change -f \" after submitting and\n" \ + "edit the User field.") + if pureRenameCopy: + print("After submitting, renamed files must be re-synced.") + print("Invoke \"p4 sync -f\" on each of these files:") + for f in pureRenameCopy: + print(" " + f) + + print("") + print("To revert the changes, use \"p4 revert ...\", and delete") + print("the submit template file \"%s\"" % fileName) + if filesToAdd: + print("Since the commit adds new files, they must be deleted:") + for f in filesToAdd: + print(" " + f) + print("") + sys.stdout.flush() + return True + if self.edit_template(fileName): + if not self.no_verify: + if not gitRunHook("p4-changelist", [fileName]): + print("The p4-changelist hook failed.") + sys.stdout.flush() + return False + # read the edited message and submit tmpFile = open(fileName, "rb") message = tmpFile.read() tmpFile.close() if self.isWindows: message = message.replace("\r\n", "\n") - submitTemplate = message[:message.index(separatorLine)] + if message.find(separatorLine) <> -1: + submitTemplate = message[:message.index(separatorLine)] + else: + submitTemplate = message + + if len(submitTemplate.strip()) == 0: + print("Changelist is empty, aborting this changelist.") + sys.stdout.flush() + return False if update_shelve: p4_write_pipe(['shelve', '-r', '-i'], submitTemplate) @@ -2112,20 +2150,22 @@ def applyCommit(self, id): submitted = True + gitRunHook("p4-post-changelist") finally: - # skip this patch + # Revert changes if we skip this patch if not submitted or self.shelve: if self.shelve: print ("Reverting shelved files.") else: print ("Submission cancelled, undoing p4 changes.") + sys.stdout.flush() for f in editedFiles | filesToDelete: p4_revert(f) for f in filesToAdd: p4_revert(f) os.remove(f) - os.remove(fileName) + os.remove(fileName) return submitted # Export git tags as p4 labels. Create a p4 label and then tag @@ -2349,13 +2389,12 @@ def run(self, args): sys.exit("number of commits (%d) must match number of shelved changelist (%d)" % (len(commits), num_shelves)) - hooks_path = gitConfig("core.hooksPath") - if len(hooks_path) <= 0: - hooks_path = os.path.join(os.environ.get("GIT_DIR", ".git"), "hooks") - - hook_file = os.path.join(hooks_path, "p4-pre-submit") - if os.path.isfile(hook_file) and os.access(hook_file, os.X_OK) and subprocess.call([hook_file]) != 0: - sys.exit(1) + if not self.no_verify: + if not gitRunHook("p4-pre-submit"): + print("\nThe p4-pre-submit hook failed, aborting the submit.\n\nYou can skip " \ + "this pre-submission check by adding\nthe command line option '--no-verify', " \ + "however,\nthis will also skip the p4-changelist hook as well.") + sys.exit(1) # # Apply the commits, one at a time. On failure, ask if should