From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Sean Whitton Newsgroups: gmane.emacs.bugs Subject: bug#64055: Implementation of modifying VC change comments for Git Date: Fri, 18 Oct 2024 17:26:28 +0800 Message-ID: <874j59wym3.fsf@melete.silentflame.com> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="26322"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: Morgan Smith , Dmitry Gutov To: 64055@debbugs.gnu.org, Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Oct 18 11:27:50 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t1jGu-0006cE-EK for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 18 Oct 2024 11:27:48 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t1jGo-0007oL-KL; Fri, 18 Oct 2024 05:27:42 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t1jGn-0007o7-0r for bug-gnu-emacs@gnu.org; Fri, 18 Oct 2024 05:27:41 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t1jGm-0008K9-Ob for bug-gnu-emacs@gnu.org; Fri, 18 Oct 2024 05:27:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=MIME-Version:Date:From:To:In-Reply-To:References:Subject; bh=7DH5T/G0XWVU6CSQdh08eELG2xnBG1zkrhKCKcfkpyg=; b=gDMlVzL7rKDXV/rFgoEDRdF+NjWS4vbDOWj2gdml9a05vt8pVn16+1z3G4aJauriOiqOGGkMUEvrTL/f+mjS2RI2X2DaHpHoZTAigQn6s6Fhkblty8uhNNy4Ks16lA6EiYE8xHe4+ZMdMQLiRn9lGwoZ6A8nu3tVRHSSfO1A+k9qHiZTph2dHTEzSbAmqxF2Jg2ftuX45qB/LzWwzY/sA1GFnwodolrsT3toePFT1ANn4PytPZHTN7B1zWLfzKbfqyZqkpEU0V6cgzTaeglg34DDugBVBDcez23D3yBYCCYGPz86kvjZq2Ku2HkW7WcB1+sUD0EEyCBmz2Z8p0WHkQ==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1t1jH8-0005BG-K2 for bug-gnu-emacs@gnu.org; Fri, 18 Oct 2024 05:28:02 -0400 X-Loop: help-debbugs@gnu.org In-Reply-To: Resent-From: Sean Whitton Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 18 Oct 2024 09:28:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 64055 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 64055-submit@debbugs.gnu.org id=B64055.172924362819844 (code B ref 64055); Fri, 18 Oct 2024 09:28:02 +0000 Original-Received: (at 64055) by debbugs.gnu.org; 18 Oct 2024 09:27:08 +0000 Original-Received: from localhost ([127.0.0.1]:37091 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t1jGF-00059x-GP for submit@debbugs.gnu.org; Fri, 18 Oct 2024 05:27:08 -0400 Original-Received: from sendmail.purelymail.com ([34.202.193.197]:49272) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t1jGD-00059Q-61 for 64055@debbugs.gnu.org; Fri, 18 Oct 2024 05:27:06 -0400 DKIM-Signature: a=rsa-sha256; b=JlNcIFUxbab7GTqLo06Xtx9fmPO+ZS2apqumDGzoxTeSsLRb65KW87yRDVQ32ifA2GKTv6gfuIsT0tuXm0JWOXAOKjqVyJxCjpt0D93sKzB7O9B4vv5tNAN40mTZ6gUiPfe2DIy0ErON7zjgcWjOoqCFvrt2/H2y3kE8IcFEzSHXtzLBL9BIrw6F1d/yLqkpZwlA9oy/xsLCSyTCnE9FAhzI/2w0L29eeO9EjiE1++f6vOxNai0GDqa9rw8LDeyJ8baNIj1hC4Iy0lo0l0+NE0f1GTuBQQevdviWQpL7v1mMECW2k4rVHrsQx3FkJkId5r7diCaq4FxwS2856HFzdA==; s=purelymail1; d=spwhitton.name; v=1; bh=5aZqCDODyTA26u6RMEI8F5gxYAVmRst5UTR0NMEjT7M=; h=Received:Received:From:To:Subject:Date; DKIM-Signature: a=rsa-sha256; b=Z+0xAhTc9L06lo4c49+0KtGRTVsyQyFZuU7kTHl2nWQyZ/M6b5N/wTWyDWrEMzjL4AYR4Bq1eVE+1G/oaZRmIm4qpRXLKEjAobJcSbuCy0Ke+a9Y6qIkEMPL+36K8fLw6F+fGXFogVbsa4xFt+rDNfRJBLPfkFvBpBHqqV7NoB5VqJsdIo0wmnimTNpMu6/l3tSCAtLnqcQPPfiLoiG693hian0kG7iOhi4utBDOojzyS36ltMIVmKi0lzl8+FmBgLSH2SLOBtp1zqTBtEbldyfyqJlp05Bf/2Sg3xe6TOdqDzayY5gZ4msv5kO19vPdoPwRCxnmL853NQ2WObC8SQ==; s=purelymail1; d=purelymail.com; v=1; bh=5aZqCDODyTA26u6RMEI8F5gxYAVmRst5UTR0NMEjT7M=; h=Feedback-ID:Received:Received:From:To:Subject:Date; Feedback-ID: 20115:3760:null:purelymail X-Pm-Original-To: 64055@debbugs.gnu.org Original-Received: by smtp.purelymail.com (Purelymail SMTP) with ESMTPSA id 1624411188; (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Fri, 18 Oct 2024 09:26:32 +0000 (UTC) Original-Received: by melete.silentflame.com (Postfix, from userid 1000) id AD11E7EAA8E; Fri, 18 Oct 2024 17:26:28 +0800 (CST) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:293776 Archived-At: --=-=-= Content-Type: text/plain Hello, This patch is the rest of this feature. Eli, would you kindly test on MS-Windows, please? Just try to edit the message for an unpushed git commit and add some Unicode, and see if it works correctly. -- Sean Whitton --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-Support-modifying-VC-change-comments-for-Git.patch Content-Transfer-Encoding: quoted-printable >From 674f7b7c636a4e2ebcb4955b564f8c9c36bd3ddd Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Fri, 18 Oct 2024 17:19:45 +0800 Subject: [PATCH] Support modifying VC change comments for Git * lisp/vc/vc-git.el (vc-git-allow-rewriting-history): New option. (vc-git--assert-allowed-rewrite, vc-git-modify-change-comment): New functions (bug#64055). (vc-git--current-branch): Factor out of vc-git-dir--branch-headers. (vc-git--log-edit-extract-headers): Factor out of vc-git-checkin. * etc/NEWS: Announce the new support and option. --- etc/NEWS | 15 +++++ lisp/vc/vc-git.el | 147 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 134 insertions(+), 28 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 10d86173235..d2e72bc537a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -568,6 +568,21 @@ a desktop notification when the song changes, using customized using the new user options 'mpc-notifications-title' and 'mpc-notifications-body'. =20 +** VC + +--- +*** Using 'e' from Log View mode to modify change comments now works for G= it. + +--- +*** New user option 'vc-git-allow-rewriting-history'. +Many Git commands can change your copy of published change history +without warning. If VC commands detect that this could happen, they +will stop. You can customize this variable to permit rewriting history +even though Emacs thinks it is dangerous. + +So far, this applies only to the 'log-view-modify-change-comment' +command. + * New Modes and Packages in Emacs 31.1 =20 diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index f77bf0cc5ff..0680d8e7353 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -252,6 +252,27 @@ vc-git-revision-complete-only-branches :type 'boolean :version "28.1") =20 +;; The default is nil because only a VC user who also possesses a lot of +;; Git-specific knowledge can know when it is okay to rewrite history, +;; and we can't convey to a relatively Git-na=C3=AFve user the potential +;; risks in only the space of a minibuffer y/n prompt. +(defcustom vc-git-allow-rewriting-history nil + "When non-nil, permit Git operations that may rewrite published history. + +Many Git commands can change your copy of published change history +without warning. If this occurs, you won't be able to pull and push in +the ordinary way until you take special action. See \"Recovering from +Upstream Rebase\" in the Man page git-rebase(1). + +Normally, Emacs refuses to run Git commands that it thinks will rewrite +published history. If you customize this variable to a non-nil value, +Emacs will instead prompt you to confirm that you really want to perform +the rewrite. A value of `no-ask' means to proceed with no prompting." + :type '(choice (const :tag "Don't allow" nil) + (const :tag "Prompt to allow" t) + (const :tag "Allow without prompting" no-ask)) + :version "31.1") + ;; History of Git commands. (defvar vc-git-history nil) =20 @@ -728,11 +749,13 @@ vc-git-dir-status-files :files files :update-function update-function))) =20 +(defun vc-git--current-branch () + (vc-git--out-match '("symbolic-ref" "HEAD") + "^\\(refs/heads/\\)?\\(.+\\)$" 2)) + (defun vc-git-dir--branch-headers () "Return headers for branch-related information." - (let ((branch (vc-git--out-match - '("symbolic-ref" "HEAD") - "^\\(refs/heads/\\)?\\(.+\\)$" 2)) + (let ((branch (vc-git--current-branch)) tracking remote-url) (if branch (when-let ((branch-merge @@ -1082,6 +1105,17 @@ vc-git-checkin-patch =20 (autoload 'vc-switches "vc") =20 +(defun vc-git--log-edit-extract-headers (comment) + (cl-flet ((boolean-arg-fn (argument) + (lambda (v) (and (equal v "yes") (list argument))))) + (log-edit-extract-headers + `(("Author" . "--author") + ("Date" . "--date") + ("Amend" . ,(boolean-arg-fn "--amend")) + ("No-Verify" . ,(boolean-arg-fn "--no-verify")) + ("Sign-Off" . ,(boolean-arg-fn "--signoff"))) + comment))) + (defun vc-git-checkin (files comment &optional _rev) (let* ((file1 (or (car files) default-directory)) (root (vc-git-root file1)) @@ -1180,31 +1214,23 @@ vc-git-checkin (vc-git-command nil 0 patch-file "apply" "--cached") (delete-file patch-file)))) (when to-stash (vc-git--stash-staged-changes files))) - (cl-flet ((boolean-arg-fn - (argument) - (lambda (value) (when (equal value "yes") (list argument)))= )) - ;; When operating on the whole tree, better pass "-a" than ".", sinc= e "." - ;; fails when we're committing a merge. - (apply #'vc-git-command nil 0 (if (and only (not vc-git-patch-string= )) files) - (nconc (if msg-file (list "commit" "-F" - (file-local-name msg-file)) - (list "commit" "-m")) - (let ((args - (log-edit-extract-headers - `(("Author" . "--author") - ("Date" . "--date") - ("Amend" . ,(boolean-arg-fn "--amend")) - ("No-Verify" . ,(boolean-arg-fn "--no-verify= ")) - ("Sign-Off" . ,(boolean-arg-fn "--signoff"))) - comment))) - (when msg-file - (let ((coding-system-for-write - (or pcsw vc-git-commits-coding-system))) - (write-region (car args) nil msg-file)) - (setq args (cdr args))) - args) - (unless vc-git-patch-string - (if only (list "--only" "--") '("-a")))))) + ;; When operating on the whole tree, better pass "-a" than ".", + ;; since "." fails when we're committing a merge. + (apply #'vc-git-command nil 0 + (if (and only (not vc-git-patch-string)) files) + (nconc (if msg-file (list "commit" "-F" + (file-local-name msg-file)) + (list "commit" "-m")) + (let ((args + (vc-git--log-edit-extract-headers comment))) + (when msg-file + (let ((coding-system-for-write + (or pcsw vc-git-commits-coding-system))) + (write-region (car args) nil msg-file)) + (setq args (cdr args))) + args) + (unless vc-git-patch-string + (if only (list "--only" "--") '("-a"))))) (if (and msg-file (file-exists-p msg-file)) (delete-file msg-file)) (when to-stash (let ((cached (make-nearby-temp-file "git-cached"))) @@ -1960,6 +1986,71 @@ vc-git-get-change-comment (vc-git-command standard-output 1 nil "log" "--max-count=3D1" "--pretty=3Dformat:%B" rev))) =20 +(defun vc-git--assert-allowed-rewrite (rev) + (when (and (not (eq vc-git-allow-rewriting-history 'no-ask)) + ;; Check there is an upstream. + (with-temp-buffer + (vc-git--out-ok "config" "--get" + (format "branch.%s.merge" + (vc-git--current-branch))))) + (let ((outgoing (split-string + (with-output-to-string + (vc-git-command standard-output 0 nil "log" + "--pretty=3Dformat:%H" + "@{upstream}..HEAD"))))) + (unless (or (cl-member rev outgoing :test #'string-prefix-p) + (and vc-git-allow-rewriting-history + (yes-or-no-p + (format +"Commit %s looks to be published; are you sure you want to rewrite history= ?" + rev)))) + (user-error "Will not rewrite likely-public Git history"))))) + +(defun vc-git-modify-change-comment (files rev comment) + (vc-git--assert-allowed-rewrite rev) + (let* ((args (vc-git--log-edit-extract-headers comment)) + (message (format "amend! %s\n\n%s" rev (pop args))) + (msg-file + ;; On MS-Windows, pass the message through a file, to work + ;; around how command line arguments must be in the system + ;; codepage, and therefore might not support non-ASCII. + ;; + ;; As our other arguments are static, we need not be concerned + ;; about the encoding of command line arguments in general. + ;; See `vc-git-checkin' for the more complex case. + (and (eq system-type 'windows-nt) + (let ((default-directory + (or (file-name-directory (or (car files) + default-directory)) + default-directory))) + (make-nearby-temp-file "git-msg"))))) + (unwind-protect + (progn + (when (cl-intersection '("--author" "--date") args + :test #'string=3D) + ;; 'git rebase --autosquash' cannot alter authorship. + ;; See the description of --fixup in git-commit(1). + (error +"Author: and Date: not supported when modifying existing commits")) + (when msg-file + (let ((coding-system-for-write + (or coding-system-for-write + vc-git-commits-coding-system))) + (write-region message nil msg-file))) + ;; Regardless of the state of the index and working tree, this + ;; will always create an empty commit, thanks to --only. + (apply #'vc-git-command nil 0 nil + "commit" "--only" "--allow-empty" + (nconc (if msg-file + (list "-F" (file-local-name msg-file)) + (list "-m" message)) + args))) + (when (and msg-file (file-exists-p msg-file)) + (delete-file msg-file)))) + (with-environment-variables (("GIT_SEQUENCE_EDITOR" "true")) + (vc-git-command nil 0 nil "rebase" "--autostash" "--autosquash" "-i" + (format "%s~1" rev)))) + (defvar vc-git-extra-menu-map (let ((map (make-sparse-keymap))) (define-key map [git-grep] --=20 2.45.2 --=-=-=--