]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update git
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sat, 25 Nov 2023 10:34:58 +0000 (11:34 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 26 Nov 2023 15:44:17 +0000 (16:44 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
18 files changed:
elpa/git-commit-20230103.2224/git-commit-autoloads.el [deleted file]
elpa/git-commit-20230103.2224/git-commit-pkg.el [deleted file]
elpa/git-commit-20230103.2224/git-commit.el [deleted file]
elpa/git-commit-20230521.2344/git-commit-autoloads.el [new file with mode: 0644]
elpa/git-commit-20230521.2344/git-commit-pkg.el [new file with mode: 0644]
elpa/git-commit-20230521.2344/git-commit.el [new file with mode: 0644]
elpa/git-link-20230420.48/git-link-autoloads.el [deleted file]
elpa/git-link-20230420.48/git-link-pkg.el [deleted file]
elpa/git-link-20230420.48/git-link.el [deleted file]
elpa/git-link-20230518.204/git-link-autoloads.el [new file with mode: 0644]
elpa/git-link-20230518.204/git-link-pkg.el [new file with mode: 0644]
elpa/git-link-20230518.204/git-link.el [new file with mode: 0644]
elpa/git-timemachine-20230413.620/git-timemachine-autoloads.el [deleted file]
elpa/git-timemachine-20230413.620/git-timemachine-pkg.el [deleted file]
elpa/git-timemachine-20230413.620/git-timemachine.el [deleted file]
elpa/git-timemachine-20230630.1214/git-timemachine-autoloads.el [new file with mode: 0644]
elpa/git-timemachine-20230630.1214/git-timemachine-pkg.el [new file with mode: 0644]
elpa/git-timemachine-20230630.1214/git-timemachine.el [new file with mode: 0755]

diff --git a/elpa/git-commit-20230103.2224/git-commit-autoloads.el b/elpa/git-commit-20230103.2224/git-commit-autoloads.el
deleted file mode 100644 (file)
index a194e2b..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-;;; git-commit-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "git-commit" "git-commit.el" (0 0 0 0))
-;;; Generated autoloads from git-commit.el
-(put 'git-commit-major-mode 'safe-local-variable
-    (lambda (val)
-      (memq val '(text-mode
-                  markdown-mode
-                  org-mode
-                  fundamental-mode
-                  git-commit-elisp-text-mode))))
-
-(register-definition-prefixes "git-commit" '("git-commit-" "global-git-commit-mode"))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("git-commit-pkg.el") (0 0 0 0))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; git-commit-autoloads.el ends here
diff --git a/elpa/git-commit-20230103.2224/git-commit-pkg.el b/elpa/git-commit-20230103.2224/git-commit-pkg.el
deleted file mode 100644 (file)
index 51fa86d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-(define-package "git-commit" "20230103.2224" "Edit Git commit messages."
-  '((emacs "25.1")
-    (compat "28.1.1.2")
-    (transient "20210920")
-    (with-editor "20211001"))
-  :commit "f47b68929f01a1b8299f3160b0ab02d69d59fcb7" :authors
-  '(("Jonas Bernoulli" . "jonasNOSPAMbernoul.li")
-    ("Sebastian Wiesner" . "lunaryornNOSPAMgmail.com")
-    ("Florian Ragwitz" . "raflNOSPAMdebian.org")
-    ("Marius Vollmer" . "marius.vollmerNOSPAMgmail.com"))
-  :maintainer
-  '("Jonas Bernoulli" . "jonasNOSPAMbernoul.li")
-  :keywords
-  '("git" "tools" "vc")
-  :url "https://github.com/magit/magit")
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/git-commit-20230103.2224/git-commit.el b/elpa/git-commit-20230103.2224/git-commit.el
deleted file mode 100644 (file)
index 2c90a6f..0000000
+++ /dev/null
@@ -1,1158 +0,0 @@
-;;; git-commit.el --- Edit Git commit messages  -*- lexical-binding:t; coding:utf-8 -*-
-
-;; Copyright (C) 2008-2023 The Magit Project Contributors
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;;     Sebastian Wiesner <lunaryornNOSPAMgmail.com>
-;;     Florian Ragwitz <raflNOSPAMdebian.org>
-;;     Marius Vollmer <marius.vollmerNOSPAMgmail.com>
-;; Maintainer: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-
-;; Homepage: https://github.com/magit/magit
-;; Keywords: git tools vc
-
-;; Package-Version: 3.3.0.50-git
-;; Package-Requires: (
-;;     (emacs "25.1")
-;;     (compat "28.1.1.2")
-;;     (transient "0.3.6")
-;;     (with-editor "3.0.5"))
-
-;; SPDX-License-Identifier: GPL-3.0-or-later
-
-;; Magit is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published
-;; by the Free Software Foundation, either version 3 of the License,
-;; or (at your option) any later version.
-;;
-;; Magit is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with Magit.  If not, see <https://www.gnu.org/licenses/>.
-
-;; You should have received a copy of the AUTHORS.md file, which
-;; lists all contributors.  If not, see https://magit.vc/authors.
-
-;;; Commentary:
-
-;; This package assists the user in writing good Git commit messages.
-
-;; While Git allows for the message to be provided on the command
-;; line, it is preferable to tell Git to create the commit without
-;; actually passing it a message.  Git then invokes the `$GIT_EDITOR'
-;; (or if that is undefined `$EDITOR') asking the user to provide the
-;; message by editing the file ".git/COMMIT_EDITMSG" (or another file
-;; in that directory, e.g. ".git/MERGE_MSG" for merge commits).
-
-;; When `global-git-commit-mode' is enabled, which it is by default,
-;; then opening such a file causes the features described below, to
-;; be enabled in that buffer.  Normally this would be done using a
-;; major-mode but to allow the use of any major-mode, as the user sees
-;; fit, it is done here by running a setup function, which among other
-;; things turns on the preferred major-mode, by default `text-mode'.
-
-;; Git waits for the `$EDITOR' to finish and then either creates the
-;; commit using the contents of the file as commit message, or, if the
-;; editor process exited with a non-zero exit status, aborts without
-;; creating a commit.  Unfortunately Emacsclient (which is what Emacs
-;; users should be using as `$EDITOR' or at least as `$GIT_EDITOR')
-;; does not differentiate between "successfully" editing a file and
-;; aborting; not out of the box that is.
-
-;; By making use of the `with-editor' package this package provides
-;; both ways of finish an editing session.  In either case the file
-;; is saved, but Emacseditor's exit code differs.
-;;
-;;   C-c C-c  Finish the editing session successfully by returning
-;;            with exit code 0.  Git then creates the commit using
-;;            the message it finds in the file.
-;;
-;;   C-c C-k  Aborts the edit editing session by returning with exit
-;;            code 1.  Git then aborts the commit.
-
-;; Aborting the commit does not cause the message to be lost, but
-;; relying solely on the file not being tampered with is risky.  This
-;; package additionally stores all aborted messages for the duration
-;; of the current session (i.e. until you close Emacs).  To get back
-;; an aborted message use M-p and M-n while editing a message.
-;;
-;;   M-p      Replace the buffer contents with the previous message
-;;            from the message ring.  Of course only after storing
-;;            the current content there too.
-;;
-;;   M-n      Replace the buffer contents with the next message from
-;;            the message ring, after storing the current content.
-
-;; Some support for pseudo headers as used in some projects is
-;; provided by these commands:
-;;
-;;   C-c C-s  Insert a Signed-off-by header.
-;;   C-c C-a  Insert a Acked-by header.
-;;   C-c C-m  Insert a Modified-by header.
-;;   C-c C-t  Insert a Tested-by header.
-;;   C-c C-r  Insert a Reviewed-by header.
-;;   C-c C-o  Insert a Cc header.
-;;   C-c C-p  Insert a Reported-by header.
-;;   C-c C-i  Insert a Suggested-by header.
-
-;; When Git requests a commit message from the user, it does so by
-;; having her edit a file which initially contains some comments,
-;; instructing her what to do, and providing useful information, such
-;; as which files were modified.  These comments, even when left
-;; intact by the user, do not become part of the commit message.  This
-;; package ensures these comments are propertizes as such and further
-;; prettifies them by using different faces for various parts, such as
-;; files.
-
-;; Finally this package highlights style errors, like lines that are
-;; too long, or when the second line is not empty.  It may even nag
-;; you when you attempt to finish the commit without having fixed
-;; these issues.  The style checks and many other settings can easily
-;; be configured:
-;;
-;;   M-x customize-group RET git-commit RET
-
-;;; Code:
-
-(require 'seq)
-(require 'subr-x)
-
-(require 'log-edit)
-(require 'ring)
-(require 'rx)
-(require 'server)
-(require 'transient)
-(require 'with-editor)
-
-;; For historic reasons Magit isn't a hard dependency.
-(unless (and (require 'magit-base nil t)
-             (require 'magit-git nil t))
-  (declare-function magit-completing-read "magit-base"
-                    ( prompt collection &optional predicate require-match
-                      initial-input hist def fallback))
-  (declare-function magit-expand-git-file-name "magit-git" (filename))
-  (declare-function magit-git-lines "magit-git" (&rest args))
-  (declare-function magit-hook-custom-get "magit-base" (symbol))
-  (declare-function magit-list-local-branch-names "magit-git" ()))
-
-(defvar diff-default-read-only)
-(defvar flyspell-generic-check-word-predicate)
-(defvar font-lock-beg)
-(defvar font-lock-end)
-(defvar recentf-exclude)
-
-;;; Options
-;;;; Variables
-
-(defgroup git-commit nil
-  "Edit Git commit messages."
-  :prefix "git-commit-"
-  :link '(info-link "(magit)Editing Commit Messages")
-  :group 'tools)
-
-(define-minor-mode global-git-commit-mode
-  "Edit Git commit messages.
-
-This global mode arranges for `git-commit-setup' to be called
-when a Git commit message file is opened.  That usually happens
-when Git uses the Emacsclient as $GIT_EDITOR to have the user
-provide such a commit message.
-
-Loading the library `git-commit' by default enables this mode,
-but the library is not automatically loaded because doing that
-would pull in many dependencies and increase startup time too
-much.  You can either rely on `magit' loading this library or
-you can load it explicitly.  Autoloading is not an alternative
-because in this case autoloading would immediately trigger
-full loading."
-  :group 'git-commit
-  :type 'boolean
-  :global t
-  :init-value t
-  :initialize (lambda (symbol exp)
-                (custom-initialize-default symbol exp)
-                (when global-git-commit-mode
-                  (add-hook 'find-file-hook #'git-commit-setup-check-buffer)))
-  (if global-git-commit-mode
-      (add-hook  'find-file-hook #'git-commit-setup-check-buffer)
-    (remove-hook 'find-file-hook #'git-commit-setup-check-buffer)))
-
-(defcustom git-commit-major-mode #'text-mode
-  "Major mode used to edit Git commit messages.
-The major mode configured here is turned on by the minor mode
-`git-commit-mode'."
-  :group 'git-commit
-  :type '(choice (function-item text-mode)
-                 (function-item markdown-mode)
-                 (function-item org-mode)
-                 (function-item fundamental-mode)
-                 (function-item git-commit-elisp-text-mode)
-                 (function :tag "Another mode")
-                 (const :tag "No major mode")))
-;;;###autoload(put 'git-commit-major-mode 'safe-local-variable
-;;;###autoload     (lambda (val)
-;;;###autoload       (memq val '(text-mode
-;;;###autoload                   markdown-mode
-;;;###autoload                   org-mode
-;;;###autoload                   fundamental-mode
-;;;###autoload                   git-commit-elisp-text-mode))))
-
-(defcustom git-commit-setup-hook
-  '(git-commit-save-message
-    git-commit-setup-changelog-support
-    git-commit-turn-on-auto-fill
-    git-commit-propertize-diff
-    bug-reference-mode
-    with-editor-usage-message)
-  "Hook run at the end of `git-commit-setup'."
-  :group 'git-commit
-  :type 'hook
-  :get (and (featurep 'magit-base) #'magit-hook-custom-get)
-  :options '(git-commit-save-message
-             git-commit-setup-changelog-support
-             magit-generate-changelog
-             git-commit-turn-on-auto-fill
-             git-commit-turn-on-orglink
-             git-commit-turn-on-flyspell
-             git-commit-propertize-diff
-             bug-reference-mode
-             with-editor-usage-message))
-
-(defcustom git-commit-post-finish-hook nil
-  "Hook run after the user finished writing a commit message.
-
-\\<with-editor-mode-map>\
-This hook is only run after pressing \\[with-editor-finish] in a buffer used
-to edit a commit message.  If a commit is created without the
-user typing a message into a buffer, then this hook is not run.
-
-This hook is not run until the new commit has been created.  If
-that takes Git longer than `git-commit-post-finish-hook-timeout'
-seconds, then this hook isn't run at all.  For certain commands
-such as `magit-rebase-continue' this hook is never run because
-doing so would lead to a race condition.
-
-This hook is only run if `magit' is available.
-
-Also see `magit-post-commit-hook'."
-  :group 'git-commit
-  :type 'hook
-  :get (and (featurep 'magit-base) #'magit-hook-custom-get))
-
-(defcustom git-commit-post-finish-hook-timeout 1
-  "Time in seconds to wait for git to create a commit.
-
-The hook `git-commit-post-finish-hook' (which see) is run only
-after git is done creating a commit.  If it takes longer than
-`git-commit-post-finish-hook-timeout' seconds to create the
-commit, then the hook is not run at all."
-  :group 'git-commit
-  :safe 'numberp
-  :type 'number)
-
-(defcustom git-commit-finish-query-functions
-  '(git-commit-check-style-conventions)
-  "List of functions called to query before performing commit.
-
-The commit message buffer is current while the functions are
-called.  If any of them returns nil, then the commit is not
-performed and the buffer is not killed.  The user should then
-fix the issue and try again.
-
-The functions are called with one argument.  If it is non-nil,
-then that indicates that the user used a prefix argument to
-force finishing the session despite issues.  Functions should
-usually honor this wish and return non-nil."
-  :options '(git-commit-check-style-conventions)
-  :type 'hook
-  :group 'git-commit)
-
-(defcustom git-commit-style-convention-checks '(non-empty-second-line)
-  "List of checks performed by `git-commit-check-style-conventions'.
-Valid members are `non-empty-second-line' and `overlong-summary-line'.
-That function is a member of `git-commit-finish-query-functions'."
-  :options '(non-empty-second-line overlong-summary-line)
-  :type '(list :convert-widget custom-hook-convert-widget)
-  :group 'git-commit)
-
-(defcustom git-commit-summary-max-length 68
-  "Column beyond which characters in the summary lines are highlighted.
-
-The highlighting indicates that the summary is getting too long
-by some standards.  It does in no way imply that going over the
-limit a few characters or in some cases even many characters is
-anything that deserves shaming.  It's just a friendly reminder
-that if you can make the summary shorter, then you might want
-to consider doing so."
-  :group 'git-commit
-  :safe 'numberp
-  :type 'number)
-
-(defcustom git-commit-fill-column nil
-  "Override `fill-column' in commit message buffers.
-
-If this is non-nil, then it should be an integer.  If that is the
-case and the buffer-local value of `fill-column' is not already
-set by the time `git-commit-turn-on-auto-fill' is called as a
-member of `git-commit-setup-hook', then that function sets the
-buffer-local value of `fill-column' to the value of this option.
-
-This option exists mostly for historic reasons.  If you are not
-already using it, then you probably shouldn't start doing so."
-  :group 'git-commit
-  :safe 'numberp
-  :type '(choice (const :tag "use regular fill-column")
-                 number))
-
-(make-obsolete-variable 'git-commit-fill-column 'fill-column
-                        "Magit 2.11.0" 'set)
-
-(defcustom git-commit-known-pseudo-headers
-  '("Signed-off-by" "Acked-by" "Modified-by" "Cc"
-    "Suggested-by" "Reported-by" "Tested-by" "Reviewed-by"
-    "Co-authored-by" "Co-developed-by")
-  "A list of Git pseudo headers to be highlighted."
-  :group 'git-commit
-  :safe (lambda (val) (and (listp val) (seq-every-p #'stringp val)))
-  :type '(repeat string))
-
-(defcustom git-commit-use-local-message-ring nil
-  "Whether to use a local message ring instead of the global one.
-This can be set globally, in which case every repository gets its
-own commit message ring, or locally for a single repository.  If
-Magit isn't available, then setting this to a non-nil value has
-no effect."
-  :group 'git-commit
-  :safe 'booleanp
-  :type 'boolean)
-
-;;;; Faces
-
-(defgroup git-commit-faces nil
-  "Faces used for highlighting Git commit messages."
-  :prefix "git-commit-"
-  :group 'git-commit
-  :group 'faces)
-
-(defface git-commit-summary
-  '((t :inherit font-lock-type-face))
-  "Face used for the summary in commit messages."
-  :group 'git-commit-faces)
-
-(defface git-commit-overlong-summary
-  '((t :inherit font-lock-warning-face))
-  "Face used for the tail of overlong commit message summaries."
-  :group 'git-commit-faces)
-
-(defface git-commit-nonempty-second-line
-  '((t :inherit font-lock-warning-face))
-  "Face used for non-whitespace on the second line of commit messages."
-  :group 'git-commit-faces)
-
-(defface git-commit-keyword
-  '((t :inherit font-lock-string-face))
-  "Face used for keywords in commit messages.
-In this context a \"keyword\" is text surrounded by brackets."
-  :group 'git-commit-faces)
-
-(define-obsolete-face-alias 'git-commit-note
-  'git-commit-keyword "Git-Commit 3.0.0")
-
-(defface git-commit-pseudo-header
-  '((t :inherit font-lock-string-face))
-  "Face used for pseudo headers in commit messages."
-  :group 'git-commit-faces)
-
-(defface git-commit-known-pseudo-header
-  '((t :inherit font-lock-keyword-face))
-  "Face used for the keywords of known pseudo headers in commit messages."
-  :group 'git-commit-faces)
-
-(defface git-commit-comment-branch-local
-  (if (featurep 'magit)
-      '((t :inherit magit-branch-local))
-    '((t :inherit font-lock-variable-name-face)))
-  "Face used for names of local branches in commit message comments."
-  :group 'git-commit-faces)
-
-(define-obsolete-face-alias 'git-commit-comment-branch
-  'git-commit-comment-branch-local "Git-Commit 2.12.0")
-
-(defface git-commit-comment-branch-remote
-  (if (featurep 'magit)
-      '((t :inherit magit-branch-remote))
-    '((t :inherit font-lock-variable-name-face)))
-  "Face used for names of remote branches in commit message comments.
-This is only used if Magit is available."
-  :group 'git-commit-faces)
-
-(defface git-commit-comment-detached
-  '((t :inherit git-commit-comment-branch-local))
-  "Face used for detached `HEAD' in commit message comments."
-  :group 'git-commit-faces)
-
-(defface git-commit-comment-heading
-  '((t :inherit git-commit-known-pseudo-header))
-  "Face used for headings in commit message comments."
-  :group 'git-commit-faces)
-
-(defface git-commit-comment-file
-  '((t :inherit git-commit-pseudo-header))
-  "Face used for file names in commit message comments."
-  :group 'git-commit-faces)
-
-(defface git-commit-comment-action
-  '((t :inherit bold))
-  "Face used for actions in commit message comments."
-  :group 'git-commit-faces)
-
-;;; Keymap
-
-(defvar git-commit-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "M-p")     #'git-commit-prev-message)
-    (define-key map (kbd "M-n")     #'git-commit-next-message)
-    (define-key map (kbd "C-c M-p") #'git-commit-search-message-backward)
-    (define-key map (kbd "C-c M-n") #'git-commit-search-message-forward)
-    (define-key map (kbd "C-c C-i") #'git-commit-insert-pseudo-header)
-    (define-key map (kbd "C-c C-a") #'git-commit-ack)
-    (define-key map (kbd "C-c M-i") #'git-commit-suggested)
-    (define-key map (kbd "C-c C-m") #'git-commit-modified)
-    (define-key map (kbd "C-c C-o") #'git-commit-cc)
-    (define-key map (kbd "C-c C-p") #'git-commit-reported)
-    (define-key map (kbd "C-c C-r") #'git-commit-review)
-    (define-key map (kbd "C-c C-s") #'git-commit-signoff)
-    (define-key map (kbd "C-c C-t") #'git-commit-test)
-    (define-key map (kbd "C-c M-s") #'git-commit-save-message)
-    map)
-  "Key map used by `git-commit-mode'.")
-
-;;; Menu
-
-(require 'easymenu)
-(easy-menu-define git-commit-mode-menu git-commit-mode-map
-  "Git Commit Mode Menu"
-  '("Commit"
-    ["Previous" git-commit-prev-message t]
-    ["Next" git-commit-next-message t]
-    "-"
-    ["Ack" git-commit-ack :active t
-     :help "Insert an 'Acked-by' header"]
-    ["Sign-Off" git-commit-signoff :active t
-     :help "Insert a 'Signed-off-by' header"]
-    ["Modified-by" git-commit-modified :active t
-     :help "Insert a 'Modified-by' header"]
-    ["Tested-by" git-commit-test :active t
-     :help "Insert a 'Tested-by' header"]
-    ["Reviewed-by" git-commit-review :active t
-     :help "Insert a 'Reviewed-by' header"]
-    ["CC" git-commit-cc t
-     :help "Insert a 'Cc' header"]
-    ["Reported" git-commit-reported :active t
-     :help "Insert a 'Reported-by' header"]
-    ["Suggested" git-commit-suggested t
-     :help "Insert a 'Suggested-by' header"]
-    ["Co-authored-by" git-commit-co-authored t
-     :help "Insert a 'Co-authored-by' header"]
-    ["Co-developed-by" git-commit-co-developed t
-     :help "Insert a 'Co-developed-by' header"]
-    "-"
-    ["Save" git-commit-save-message t]
-    ["Cancel" with-editor-cancel t]
-    ["Commit" with-editor-finish t]))
-
-;;; Hooks
-
-(defconst git-commit-filename-regexp "/\\(\
-\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|MERGEREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\
-\\|\\(BRANCH\\|EDIT\\)_DESCRIPTION\\)\\'")
-
-(with-eval-after-load 'recentf
-  (add-to-list 'recentf-exclude git-commit-filename-regexp))
-
-(add-to-list 'with-editor-file-name-history-exclude git-commit-filename-regexp)
-
-(defun git-commit-setup-font-lock-in-buffer ()
-  (and buffer-file-name
-       (string-match-p git-commit-filename-regexp buffer-file-name)
-       (git-commit-setup-font-lock)))
-
-(add-hook 'after-change-major-mode-hook #'git-commit-setup-font-lock-in-buffer)
-
-(defun git-commit-setup-check-buffer ()
-  (and buffer-file-name
-       (string-match-p git-commit-filename-regexp buffer-file-name)
-       (git-commit-setup)))
-
-(defvar git-commit-mode)
-
-(defun git-commit-file-not-found ()
-  ;; cygwin git will pass a cygwin path (/cygdrive/c/foo/.git/...),
-  ;; try to handle this in window-nt Emacs.
-  (when-let
-      ((file (and (or (string-match-p git-commit-filename-regexp
-                                      buffer-file-name)
-                      (and (boundp 'git-rebase-filename-regexp)
-                           (string-match-p git-rebase-filename-regexp
-                                           buffer-file-name)))
-                  (not (file-accessible-directory-p
-                        (file-name-directory buffer-file-name)))
-                  (if (require 'magit-git nil t)
-                      ;; Emacs prepends a "c:".
-                      (magit-expand-git-file-name
-                       (substring buffer-file-name 2))
-                    ;; Fallback if we can't load `magit-git'.
-                    (and (string-match
-                          "\\`[a-z]:/\\(cygdrive/\\)?\\([a-z]\\)/\\(.*\\)"
-                          buffer-file-name)
-                         (concat (match-string 2 buffer-file-name) ":/"
-                                 (match-string 3 buffer-file-name)))))))
-    (when (file-accessible-directory-p (file-name-directory file))
-      (let ((inhibit-read-only t))
-        (insert-file-contents file t)
-        t))))
-
-(when (eq system-type 'windows-nt)
-  (add-hook 'find-file-not-found-functions #'git-commit-file-not-found))
-
-(defconst git-commit-usage-message "\
-Type \\[with-editor-finish] to finish, \
-\\[with-editor-cancel] to cancel, and \
-\\[git-commit-prev-message] and \\[git-commit-next-message] \
-to recover older messages")
-
-(defun git-commit-setup ()
-  (when (fboundp 'magit-toplevel)
-    ;; `magit-toplevel' is autoloaded and defined in magit-git.el,
-    ;; That library declares this functions without loading
-    ;; magit-process.el, which defines it.
-    (require 'magit-process nil t))
-  (when git-commit-major-mode
-    (let ((auto-mode-alist (list (cons (concat "\\`"
-                                               (regexp-quote buffer-file-name)
-                                               "\\'")
-                                       git-commit-major-mode)))
-          ;; The major-mode hook might want to consult these minor
-          ;; modes, while the minor-mode hooks might want to consider
-          ;; the major mode.
-          (git-commit-mode t)
-          (with-editor-mode t))
-      (normal-mode t)))
-  ;; Pretend that git-commit-mode is a major-mode,
-  ;; so that directory-local settings can be used.
-  (let ((default-directory
-         (or (and (not (file-exists-p ".dir-locals.el"))
-                  ;; When $GIT_DIR/.dir-locals.el doesn't exist,
-                  ;; fallback to $GIT_WORK_TREE/.dir-locals.el,
-                  ;; because the maintainer can use the latter
-                  ;; to enforce conventions, while s/he has no
-                  ;; control over the former.
-                  (fboundp 'magit-toplevel)  ; silence byte-compiler
-                  (magit-toplevel))
-             default-directory)))
-    (let ((buffer-file-name nil)         ; trick hack-dir-local-variables
-          (major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables
-      (hack-dir-local-variables)
-      (hack-local-variables-apply)))
-  ;; Show our own message using our hook.
-  (setq with-editor-show-usage nil)
-  (setq with-editor-usage-message git-commit-usage-message)
-  (unless with-editor-mode
-    ;; Maybe already enabled when using `shell-command' or an Emacs shell.
-    (with-editor-mode 1))
-  (add-hook 'with-editor-finish-query-functions
-            #'git-commit-finish-query-functions nil t)
-  (add-hook 'with-editor-pre-finish-hook
-            #'git-commit-save-message nil t)
-  (add-hook 'with-editor-pre-cancel-hook
-            #'git-commit-save-message nil t)
-  (when (fboundp 'magit-commit--reset-command)
-    (add-hook 'with-editor-post-finish-hook #'magit-commit--reset-command)
-    (add-hook 'with-editor-post-cancel-hook #'magit-commit--reset-command))
-  (when (and (fboundp 'magit-rev-parse)
-             (not (memq last-command
-                        '(magit-sequencer-continue
-                          magit-sequencer-skip
-                          magit-am-continue
-                          magit-am-skip
-                          magit-rebase-continue
-                          magit-rebase-skip))))
-    (add-hook 'with-editor-post-finish-hook
-              (apply-partially #'git-commit-run-post-finish-hook
-                               (magit-rev-parse "HEAD"))
-              nil t)
-    (when (fboundp 'magit-wip-maybe-add-commit-hook)
-      (magit-wip-maybe-add-commit-hook)))
-  (setq with-editor-cancel-message
-        #'git-commit-cancel-message)
-  (git-commit-mode 1)
-  (git-commit-setup-font-lock)
-  (git-commit-prepare-message-ring)
-  (when (boundp 'save-place)
-    (setq save-place nil))
-  (save-excursion
-    (goto-char (point-min))
-    (when (looking-at "\\`\\(\\'\\|\n[^\n]\\)")
-      (open-line 1)))
-  (with-demoted-errors "Error running git-commit-setup-hook: %S"
-    (run-hooks 'git-commit-setup-hook))
-  (set-buffer-modified-p nil))
-
-(defun git-commit-run-post-finish-hook (previous)
-  (when (and git-commit-post-finish-hook
-             (require 'magit nil t)
-             (fboundp 'magit-rev-parse))
-    (cl-block nil
-      (let ((break (time-add (current-time)
-                             (seconds-to-time
-                              git-commit-post-finish-hook-timeout))))
-        (while (equal (magit-rev-parse "HEAD") previous)
-          (if (time-less-p (current-time) break)
-              (sit-for 0.01)
-            (message "No commit created after 1 second.  Not running %s."
-                     'git-commit-post-finish-hook)
-            (cl-return))))
-      (run-hooks 'git-commit-post-finish-hook))))
-
-(define-minor-mode git-commit-mode
-  "Auxiliary minor mode used when editing Git commit messages.
-This mode is only responsible for setting up some key bindings.
-Don't use it directly, instead enable `global-git-commit-mode'."
-  :lighter "")
-
-(put 'git-commit-mode 'permanent-local t)
-
-(defun git-commit-setup-changelog-support ()
-  "Treat ChangeLog entries as unindented paragraphs."
-  (when (fboundp 'log-indent-fill-entry) ; New in Emacs 27.
-    (setq-local fill-paragraph-function #'log-indent-fill-entry))
-  (setq-local fill-indent-according-to-mode t)
-  (setq-local paragraph-start (concat paragraph-start "\\|\\*\\|(")))
-
-(defun git-commit-turn-on-auto-fill ()
-  "Unconditionally turn on Auto Fill mode.
-If `git-commit-fill-column' is non-nil, and `fill-column'
-doesn't already have a buffer-local value, then set that
-to `git-commit-fill-column'."
-  (when (and (numberp git-commit-fill-column)
-             (not (local-variable-p 'fill-column)))
-    (setq fill-column git-commit-fill-column))
-  (setq-local comment-auto-fill-only-comments nil)
-  (turn-on-auto-fill))
-
-(defun git-commit-turn-on-orglink ()
-  "Turn on Orglink mode if it is available.
-If `git-commit-major-mode' is `org-mode', then silently forgo
-turning on `orglink-mode'."
-  (when (and (not (derived-mode-p 'org-mode))
-             (boundp 'orglink-match-anywhere)
-             (fboundp 'orglink-mode))
-    (setq-local orglink-match-anywhere t)
-    (orglink-mode 1)))
-
-(defun git-commit-turn-on-flyspell ()
-  "Unconditionally turn on Flyspell mode.
-Also prevent comments from being checked and
-finally check current non-comment text."
-  (require 'flyspell)
-  (turn-on-flyspell)
-  (setq flyspell-generic-check-word-predicate
-        #'git-commit-flyspell-verify)
-  (let ((end)
-        (comment-start-regex (format "^\\(%s\\|$\\)" comment-start)))
-    (save-excursion
-      (goto-char (point-max))
-      (while (and (not (bobp)) (looking-at comment-start-regex))
-        (forward-line -1))
-      (unless (looking-at comment-start-regex)
-        (forward-line))
-      (setq end (point)))
-    (flyspell-region (point-min) end)))
-
-(defun git-commit-flyspell-verify ()
-  (not (= (char-after (line-beginning-position))
-          (aref comment-start 0))))
-
-(defun git-commit-finish-query-functions (force)
-  (run-hook-with-args-until-failure
-   'git-commit-finish-query-functions force))
-
-(defun git-commit-check-style-conventions (force)
-  "Check for violations of certain basic style conventions.
-
-For each violation ask the user if she wants to proceed anyway.
-Option `git-commit-style-convention-checks' controls which
-conventions are checked."
-  (or force
-      (save-excursion
-        (goto-char (point-min))
-        (re-search-forward (git-commit-summary-regexp) nil t)
-        (if (equal (match-string 1) "")
-            t ; Just try; we don't know whether --allow-empty-message was used.
-          (and (or (not (memq 'overlong-summary-line
-                              git-commit-style-convention-checks))
-                   (equal (match-string 2) "")
-                   (y-or-n-p "Summary line is too long.  Commit anyway? "))
-               (or (not (memq 'non-empty-second-line
-                              git-commit-style-convention-checks))
-                   (not (match-string 3))
-                   (y-or-n-p "Second line is not empty.  Commit anyway? ")))))))
-
-(defun git-commit-cancel-message ()
-  (message
-   (concat "Commit canceled"
-           (and (memq 'git-commit-save-message with-editor-pre-cancel-hook)
-                ".  Message saved to `log-edit-comment-ring'"))))
-
-;;; History
-
-(defun git-commit-prev-message (arg)
-  "Cycle backward through message history, after saving current message.
-With a numeric prefix ARG, go back ARG comments."
-  (interactive "*p")
-  (let ((len (ring-length log-edit-comment-ring)))
-    (if (<= len 0)
-        (progn (message "Empty comment ring") (ding))
-      ;; Unlike `log-edit-previous-comment' we save the current
-      ;; non-empty and newly written comment, because otherwise
-      ;; it would be irreversibly lost.
-      (when-let ((message (git-commit-buffer-message)))
-        (unless (ring-member log-edit-comment-ring message)
-          (ring-insert log-edit-comment-ring message)
-          (cl-incf arg)
-          (setq len (ring-length log-edit-comment-ring))))
-      ;; Delete the message but not the instructions at the end.
-      (save-restriction
-        (goto-char (point-min))
-        (narrow-to-region
-         (point)
-         (if (re-search-forward (concat "^" comment-start) nil t)
-             (max 1 (- (point) 2))
-           (point-max)))
-        (delete-region (point-min) (point)))
-      (setq log-edit-comment-ring-index (log-edit-new-comment-index arg len))
-      (message "Comment %d" (1+ log-edit-comment-ring-index))
-      (insert (ring-ref log-edit-comment-ring log-edit-comment-ring-index)))))
-
-(defun git-commit-next-message (arg)
-  "Cycle forward through message history, after saving current message.
-With a numeric prefix ARG, go forward ARG comments."
-  (interactive "*p")
-  (git-commit-prev-message (- arg)))
-
-(defun git-commit-search-message-backward (string)
-  "Search backward through message history for a match for STRING.
-Save current message first."
-  (interactive
-   ;; Avoid `format-prompt' because it isn't available until Emacs 28.
-   (list (read-string (format "Comment substring (default %s): "
-                              log-edit-last-comment-match)
-                      nil nil log-edit-last-comment-match)))
-  (cl-letf (((symbol-function #'log-edit-previous-comment)
-             (symbol-function #'git-commit-prev-message)))
-    (log-edit-comment-search-backward string)))
-
-(defun git-commit-search-message-forward (string)
-  "Search forward through message history for a match for STRING.
-Save current message first."
-  (interactive
-   ;; Avoid `format-prompt' because it isn't available until Emacs 28.
-   (list (read-string (format "Comment substring (default %s): "
-                              log-edit-last-comment-match)
-                      nil nil log-edit-last-comment-match)))
-  (cl-letf (((symbol-function #'log-edit-previous-comment)
-             (symbol-function #'git-commit-prev-message)))
-    (log-edit-comment-search-forward string)))
-
-(defun git-commit-save-message ()
-  "Save current message to `log-edit-comment-ring'."
-  (interactive)
-  (if-let ((message (git-commit-buffer-message)))
-      (progn
-        (when-let ((index (ring-member log-edit-comment-ring message)))
-          (ring-remove log-edit-comment-ring index))
-        (ring-insert log-edit-comment-ring message)
-        (when (and git-commit-use-local-message-ring
-                   (fboundp 'magit-repository-local-set))
-          (magit-repository-local-set 'log-edit-comment-ring
-                                      log-edit-comment-ring))
-        (message "Message saved"))
-    (message "Only whitespace and/or comments; message not saved")))
-
-(defun git-commit-prepare-message-ring ()
-  (make-local-variable 'log-edit-comment-ring-index)
-  (when (and git-commit-use-local-message-ring
-             (fboundp 'magit-repository-local-get))
-    (setq-local log-edit-comment-ring
-                (magit-repository-local-get
-                 'log-edit-comment-ring
-                 (make-ring log-edit-maximum-comment-ring-size)))))
-
-(defun git-commit-buffer-message ()
-  (let ((flush (concat "^" comment-start))
-        (str (buffer-substring-no-properties (point-min) (point-max))))
-    (with-temp-buffer
-      (insert str)
-      (goto-char (point-min))
-      (when (re-search-forward (concat flush " -+ >8 -+$") nil t)
-        (delete-region (line-beginning-position) (point-max)))
-      (goto-char (point-min))
-      (flush-lines flush)
-      (goto-char (point-max))
-      (unless (eq (char-before) ?\n)
-        (insert ?\n))
-      (setq str (buffer-string)))
-    (unless (string-match "\\`[ \t\n\r]*\\'" str)
-      (when (string-match "\\`\n\\{2,\\}" str)
-        (setq str (replace-match "\n" t t str)))
-      (when (string-match "\n\\{2,\\}\\'" str)
-        (setq str (replace-match "\n" t t str)))
-      str)))
-
-;;; Utilities
-
-(defsubst git-commit-executable ()
-  (if (fboundp 'magit-git-executable)
-      (magit-git-executable)
-    "git"))
-
-;;; Headers
-
-(transient-define-prefix git-commit-insert-pseudo-header ()
-  "Insert a commit message pseudo header."
-  [["Insert ... by yourself"
-    ("a"   "Ack"          git-commit-ack)
-    ("m"   "Modified"     git-commit-modified)
-    ("r"   "Reviewed"     git-commit-review)
-    ("s"   "Signed-off"   git-commit-signoff)
-    ("t"   "Tested"       git-commit-test)]
-   ["Insert ... by someone"
-    ("C-c" "Cc"           git-commit-cc)
-    ("C-r" "Reported"     git-commit-reported)
-    ("C-i" "Suggested"    git-commit-suggested)
-    ("C-a" "Co-authored"  git-commit-co-authored)
-    ("C-d" "Co-developed" git-commit-co-developed)]])
-
-(defun git-commit-ack (name mail)
-  "Insert a header acknowledging that you have looked at the commit."
-  (interactive (git-commit-self-ident))
-  (git-commit-insert-header "Acked-by" name mail))
-
-(defun git-commit-modified (name mail)
-  "Insert a header to signal that you have modified the commit."
-  (interactive (git-commit-self-ident))
-  (git-commit-insert-header "Modified-by" name mail))
-
-(defun git-commit-review (name mail)
-  "Insert a header acknowledging that you have reviewed the commit."
-  (interactive (git-commit-self-ident))
-  (git-commit-insert-header "Reviewed-by" name mail))
-
-(defun git-commit-signoff (name mail)
-  "Insert a header to sign off the commit."
-  (interactive (git-commit-self-ident))
-  (git-commit-insert-header "Signed-off-by" name mail))
-
-(defun git-commit-test (name mail)
-  "Insert a header acknowledging that you have tested the commit."
-  (interactive (git-commit-self-ident))
-  (git-commit-insert-header "Tested-by" name mail))
-
-(defun git-commit-cc (name mail)
-  "Insert a header mentioning someone who might be interested."
-  (interactive (git-commit-read-ident "Cc"))
-  (git-commit-insert-header "Cc" name mail))
-
-(defun git-commit-reported (name mail)
-  "Insert a header mentioning the person who reported the issue."
-  (interactive (git-commit-read-ident "Reported-by"))
-  (git-commit-insert-header "Reported-by" name mail))
-
-(defun git-commit-suggested (name mail)
-  "Insert a header mentioning the person who suggested the change."
-  (interactive (git-commit-read-ident "Suggested-by"))
-  (git-commit-insert-header "Suggested-by" name mail))
-
-(defun git-commit-co-authored (name mail)
-  "Insert a header mentioning the person who co-authored the commit."
-  (interactive (git-commit-read-ident "Co-authored-by"))
-  (git-commit-insert-header "Co-authored-by" name mail))
-
-(defun git-commit-co-developed (name mail)
-  "Insert a header mentioning the person who co-developed the commit."
-  (interactive (git-commit-read-ident "Co-developed-by"))
-  (git-commit-insert-header "Co-developed-by" name mail))
-
-(defun git-commit-self-ident ()
-  (list (or (getenv "GIT_AUTHOR_NAME")
-            (getenv "GIT_COMMITTER_NAME")
-            (with-demoted-errors "Error running 'git config user.name': %S"
-              (car (process-lines
-                    (git-commit-executable) "config" "user.name")))
-            user-full-name
-            (read-string "Name: "))
-        (or (getenv "GIT_AUTHOR_EMAIL")
-            (getenv "GIT_COMMITTER_EMAIL")
-            (getenv "EMAIL")
-            (with-demoted-errors "Error running 'git config user.email': %S"
-              (car (process-lines
-                    (git-commit-executable) "config" "user.email")))
-            (read-string "Email: "))))
-
-(defvar git-commit-read-ident-history nil)
-
-(defun git-commit-read-ident (prompt)
-  (if (require 'magit-git nil t)
-      (let ((str (magit-completing-read
-                  prompt
-                  (sort (delete-dups
-                         (magit-git-lines "log" "-n9999" "--format=%aN <%ae>"))
-                        #'string<)
-                  nil nil nil 'git-commit-read-ident-history)))
-        (save-match-data
-          (if (string-match "\\`\\([^<]+\\) *<\\([^>]+\\)>\\'" str)
-              (list (save-match-data (string-trim (match-string 1 str)))
-                    (string-trim (match-string 2 str)))
-            (user-error "Invalid input"))))
-    (list (read-string "Name: ")
-          (read-string "Email: "))))
-
-(defun git-commit-insert-header (header name email)
-  (setq header (format "%s: %s <%s>" header name email))
-  (save-excursion
-    (goto-char (point-max))
-    (cond ((re-search-backward "^[-a-zA-Z]+: [^<]+? <[^>]+>" nil t)
-           (end-of-line)
-           (insert ?\n header)
-           (unless (= (char-after) ?\n)
-             (insert ?\n)))
-          (t
-           (while (re-search-backward (concat "^" comment-start) nil t))
-           (unless (looking-back "\n\n" nil)
-             (insert ?\n))
-           (insert header ?\n)))
-    (unless (or (eobp) (= (char-after) ?\n))
-      (insert ?\n))))
-
-;;; Font-Lock
-
-(defvar-local git-commit-need-summary-line t
-  "Whether the text should have a heading that is separated from the body.
-
-For commit messages that is a convention that should not
-be violated.  For notes it is up to the user.  If you do
-not want to insist on an empty second line here, then use
-something like:
-
-  (add-hook \\='git-commit-setup-hook
-            (lambda ()
-              (when (equal (file-name-nondirectory (buffer-file-name))
-                           \"NOTES_EDITMSG\")
-                (setq git-commit-need-summary-line nil))))")
-
-(defun git-commit-summary-regexp ()
-  (if git-commit-need-summary-line
-      (concat
-       ;; Leading empty lines and comments
-       (format "\\`\\(?:^\\(?:\\s-*\\|%s.*\\)\n\\)*" comment-start)
-       ;; Summary line
-       (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length)
-       ;; Non-empty non-comment second line
-       (format "\\(?:\n%s\\|\n\\(.+\\)\\)?" comment-start))
-    "\\(EASTER\\) \\(EGG\\)"))
-
-(defun git-commit-extend-region-summary-line ()
-  "Identify the multiline summary-regexp construct.
-Added to `font-lock-extend-region-functions'."
-  (save-excursion
-    (save-match-data
-      (goto-char (point-min))
-      (when (looking-at (git-commit-summary-regexp))
-        (let ((summary-beg (match-beginning 0))
-              (summary-end (match-end 0)))
-          (when (or (< summary-beg font-lock-beg summary-end)
-                    (< summary-beg font-lock-end summary-end))
-            (setq font-lock-beg (min font-lock-beg summary-beg))
-            (setq font-lock-end (max font-lock-end summary-end))))))))
-
-(defvar-local git-commit--branch-name-regexp nil)
-
-(defconst git-commit-comment-headings
-  '("Changes to be committed:"
-    "Untracked files:"
-    "Changed but not updated:"
-    "Changes not staged for commit:"
-    "Unmerged paths:"
-    "Author:"
-    "Date:")
-  "Also fontified outside of comments in `git-commit-font-lock-keywords-2'.")
-
-(defconst git-commit-font-lock-keywords-1
-  '(;; Pseudo headers
-    (eval . `(,(format "^\\(%s:\\)\\( .*\\)"
-                       (regexp-opt git-commit-known-pseudo-headers))
-              (1 'git-commit-known-pseudo-header)
-              (2 'git-commit-pseudo-header)))
-    ;; Summary
-    (eval . `(,(git-commit-summary-regexp)
-              (1 'git-commit-summary)))
-    ;; - Keyword [aka "text in brackets"] (overrides summary)
-    ("\\[[^][]+?\\]"
-     (0 'git-commit-keyword t))
-    ;; - Non-empty second line (overrides summary and note)
-    (eval . `(,(git-commit-summary-regexp)
-              (2 'git-commit-overlong-summary t t)
-              (3 'git-commit-nonempty-second-line t t)))))
-
-(defconst git-commit-font-lock-keywords-2
-  `(,@git-commit-font-lock-keywords-1
-    ;; Comments
-    (eval . `(,(format "^%s.*" comment-start)
-              (0 'font-lock-comment-face append)))
-    (eval . `(,(format "^%s On branch \\(.*\\)" comment-start)
-              (1 'git-commit-comment-branch-local t)))
-    (eval . `(,(format "^%s \\(HEAD\\) detached at" comment-start)
-              (1 'git-commit-comment-detached t)))
-    (eval . `(,(format "^%s %s" comment-start
-                       (regexp-opt git-commit-comment-headings t))
-              (1 'git-commit-comment-heading t)))
-    (eval . `(,(format "^%s\t\\(?:\\([^:\n]+\\):\\s-+\\)?\\(.*\\)" comment-start)
-              (1 'git-commit-comment-action t t)
-              (2 'git-commit-comment-file t)))
-    ;; "commit HASH"
-    (eval . `(,(rx bol "commit " (1+ alnum) eol)
-              (0 'git-commit-pseudo-header)))
-    ;; `git-commit-comment-headings' (but not in commented lines)
-    (eval . `(,(rx-to-string `(seq bol (or ,@git-commit-comment-headings) (1+ blank) (1+ nonl) eol))
-              (0 'git-commit-pseudo-header)))))
-
-(defconst git-commit-font-lock-keywords-3
-  `(,@git-commit-font-lock-keywords-2
-    ;; More comments
-    (eval
-     ;; Your branch is ahead of 'master' by 3 commits.
-     ;; Your branch is behind 'master' by 2 commits, and can be fast-forwarded.
-     . `(,(format
-           "^%s Your branch is \\(?:ahead\\|behind\\) of '%s' by \\([0-9]*\\)"
-           comment-start git-commit--branch-name-regexp)
-         (1 'git-commit-comment-branch-local t)
-         (2 'git-commit-comment-branch-remote t)
-         (3 'bold t)))
-    (eval
-     ;; Your branch is up to date with 'master'.
-     ;; Your branch and 'master' have diverged,
-     . `(,(format
-           "^%s Your branch \\(?:is up[- ]to[- ]date with\\|and\\) '%s'"
-           comment-start git-commit--branch-name-regexp)
-         (1 'git-commit-comment-branch-local t)
-         (2 'git-commit-comment-branch-remote t)))
-    (eval
-     ;; and have 1 and 2 different commits each, respectively.
-     . `(,(format
-           "^%s and have \\([0-9]*\\) and \\([0-9]*\\) commits each"
-           comment-start)
-         (1 'bold t)
-         (2 'bold t)))))
-
-(defvar git-commit-font-lock-keywords git-commit-font-lock-keywords-3
-  "Font-Lock keywords for Git-Commit mode.")
-
-(defun git-commit-setup-font-lock ()
-  (with-demoted-errors "Error running git-commit-setup-font-lock: %S"
-    (let ((table (make-syntax-table (syntax-table))))
-      (when comment-start
-        (modify-syntax-entry (string-to-char comment-start) "." table))
-      (modify-syntax-entry ?#  "." table)
-      (modify-syntax-entry ?\" "." table)
-      (modify-syntax-entry ?\' "." table)
-      (modify-syntax-entry ?`  "." table)
-      (set-syntax-table table))
-    (setq-local comment-start
-                (or (with-temp-buffer
-                      (and (zerop
-                            (call-process
-                             (git-commit-executable) nil (list t nil) nil
-                             "config" "core.commentchar"))
-                           (not (bobp))
-                           (progn
-                             (goto-char (point-min))
-                             (buffer-substring (point) (line-end-position)))))
-                    "#"))
-    (setq-local comment-start-skip (format "^%s+[\s\t]*" comment-start))
-    (setq-local comment-end-skip "\n")
-    (setq-local comment-use-syntax nil)
-    (setq-local git-commit--branch-name-regexp
-                (if (and (featurep 'magit-git)
-                         ;; When using cygwin git, we may end up in a
-                         ;; non-existing directory, which would cause
-                         ;; any git calls to signal an error.
-                         (file-accessible-directory-p default-directory))
-                    (progn
-                      ;; Make sure the below functions are available.
-                      (require 'magit)
-                      ;; Font-Lock wants every submatch to succeed, so
-                      ;; also match the empty string.  Avoid listing
-                      ;; remote branches and using `regexp-quote',
-                      ;; because in repositories have thousands of
-                      ;; branches that would be very slow.  See #4353.
-                      (format "\\(\\(?:%s\\)\\|\\)\\([^']+\\)"
-                              (mapconcat #'identity
-                                         (magit-list-local-branch-names)
-                                         "\\|")))
-                  "\\([^']*\\)"))
-    (setq-local font-lock-multiline t)
-    (add-hook 'font-lock-extend-region-functions
-              #'git-commit-extend-region-summary-line
-              t t)
-    (font-lock-add-keywords nil git-commit-font-lock-keywords)))
-
-(defun git-commit-propertize-diff ()
-  (require 'diff-mode)
-  (save-excursion
-    (goto-char (point-min))
-    (when (re-search-forward "^diff --git" nil t)
-      (beginning-of-line)
-      (let ((buffer (current-buffer)))
-        (insert
-         (with-temp-buffer
-           (insert
-            (with-current-buffer buffer
-              (prog1 (buffer-substring-no-properties (point) (point-max))
-                (delete-region (point) (point-max)))))
-           (let ((diff-default-read-only nil))
-             (diff-mode))
-           (let (font-lock-verbose font-lock-support-mode)
-             (if (fboundp 'font-lock-ensure)
-                 (font-lock-ensure)
-               (with-no-warnings
-                 (font-lock-fontify-buffer))))
-           (let (next (pos (point-min)))
-             (while (setq next (next-single-property-change pos 'face))
-               (put-text-property pos next 'font-lock-face
-                                  (get-text-property pos 'face))
-               (setq pos next))
-             (put-text-property pos (point-max) 'font-lock-face
-                                (get-text-property pos 'face)))
-           (buffer-string)))))))
-
-;;; Elisp Text Mode
-
-(define-derived-mode git-commit-elisp-text-mode text-mode "ElText"
-  "Major mode for editing commit messages of elisp projects.
-This is intended for use as `git-commit-major-mode' for projects
-that expect `symbols' to look like this.  I.e. like they look in
-Elisp doc-strings, including this one.  Unlike in doc-strings,
-\"strings\" also look different than the other text."
-  (setq font-lock-defaults '(git-commit-elisp-text-mode-keywords)))
-
-(defvar git-commit-elisp-text-mode-keywords
-  `((,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]")
-     (1 font-lock-constant-face prepend))
-    ("\"[^\"]*\"" (0 font-lock-string-face prepend))))
-
-;;; _
-(provide 'git-commit)
-;;; git-commit.el ends here
diff --git a/elpa/git-commit-20230521.2344/git-commit-autoloads.el b/elpa/git-commit-20230521.2344/git-commit-autoloads.el
new file mode 100644 (file)
index 0000000..a194e2b
--- /dev/null
@@ -0,0 +1,33 @@
+;;; git-commit-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "git-commit" "git-commit.el" (0 0 0 0))
+;;; Generated autoloads from git-commit.el
+(put 'git-commit-major-mode 'safe-local-variable
+    (lambda (val)
+      (memq val '(text-mode
+                  markdown-mode
+                  org-mode
+                  fundamental-mode
+                  git-commit-elisp-text-mode))))
+
+(register-definition-prefixes "git-commit" '("git-commit-" "global-git-commit-mode"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("git-commit-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; git-commit-autoloads.el ends here
diff --git a/elpa/git-commit-20230521.2344/git-commit-pkg.el b/elpa/git-commit-20230521.2344/git-commit-pkg.el
new file mode 100644 (file)
index 0000000..fa74ef0
--- /dev/null
@@ -0,0 +1,18 @@
+(define-package "git-commit" "20230521.2344" "Edit Git commit messages."
+  '((emacs "25.1")
+    (compat "29.1.3.4")
+    (transient "20230201")
+    (with-editor "20230118"))
+  :commit "d81db78a0611d21048c1e2ff069a83f964092f10" :authors
+  '(("Jonas Bernoulli" . "jonasNOSPAMbernoul.li")
+    ("Sebastian Wiesner" . "lunaryornNOSPAMgmail.com")
+    ("Florian Ragwitz" . "raflNOSPAMdebian.org")
+    ("Marius Vollmer" . "marius.vollmerNOSPAMgmail.com"))
+  :maintainer
+  '("Jonas Bernoulli" . "jonasNOSPAMbernoul.li")
+  :keywords
+  '("git" "tools" "vc")
+  :url "https://github.com/magit/magit")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/git-commit-20230521.2344/git-commit.el b/elpa/git-commit-20230521.2344/git-commit.el
new file mode 100644 (file)
index 0000000..a22a3e7
--- /dev/null
@@ -0,0 +1,1144 @@
+;;; git-commit.el --- Edit Git commit messages  -*- lexical-binding:t; coding:utf-8 -*-
+
+;; Copyright (C) 2008-2023 The Magit Project Contributors
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;;     Sebastian Wiesner <lunaryornNOSPAMgmail.com>
+;;     Florian Ragwitz <raflNOSPAMdebian.org>
+;;     Marius Vollmer <marius.vollmerNOSPAMgmail.com>
+;; Maintainer: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+
+;; Homepage: https://github.com/magit/magit
+;; Keywords: git tools vc
+
+;; Package-Version: 3.3.0.50-git
+;; Package-Requires: (
+;;     (emacs "25.1")
+;;     (compat "29.1.3.4")
+;;     (transient "0.3.6")
+;;     (with-editor "3.0.5"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation, either version 3 of the License,
+;; or (at your option) any later version.
+;;
+;; Magit is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit.  If not, see <https://www.gnu.org/licenses/>.
+
+;; You should have received a copy of the AUTHORS.md file, which
+;; lists all contributors.  If not, see https://magit.vc/authors.
+
+;;; Commentary:
+
+;; This package assists the user in writing good Git commit messages.
+
+;; While Git allows for the message to be provided on the command
+;; line, it is preferable to tell Git to create the commit without
+;; actually passing it a message.  Git then invokes the `$GIT_EDITOR'
+;; (or if that is undefined `$EDITOR') asking the user to provide the
+;; message by editing the file ".git/COMMIT_EDITMSG" (or another file
+;; in that directory, e.g., ".git/MERGE_MSG" for merge commits).
+
+;; When `global-git-commit-mode' is enabled, which it is by default,
+;; then opening such a file causes the features described below, to
+;; be enabled in that buffer.  Normally this would be done using a
+;; major-mode but to allow the use of any major-mode, as the user sees
+;; fit, it is done here by running a setup function, which among other
+;; things turns on the preferred major-mode, by default `text-mode'.
+
+;; Git waits for the `$EDITOR' to finish and then either creates the
+;; commit using the contents of the file as commit message, or, if the
+;; editor process exited with a non-zero exit status, aborts without
+;; creating a commit.  Unfortunately Emacsclient (which is what Emacs
+;; users should be using as `$EDITOR' or at least as `$GIT_EDITOR')
+;; does not differentiate between "successfully" editing a file and
+;; aborting; not out of the box that is.
+
+;; By making use of the `with-editor' package this package provides
+;; both ways of finish an editing session.  In either case the file
+;; is saved, but Emacseditor's exit code differs.
+;;
+;;   C-c C-c  Finish the editing session successfully by returning
+;;            with exit code 0.  Git then creates the commit using
+;;            the message it finds in the file.
+;;
+;;   C-c C-k  Aborts the edit editing session by returning with exit
+;;            code 1.  Git then aborts the commit.
+
+;; Aborting the commit does not cause the message to be lost, but
+;; relying solely on the file not being tampered with is risky.  This
+;; package additionally stores all aborted messages for the duration
+;; of the current session (i.e., until you close Emacs).  To get back
+;; an aborted message use M-p and M-n while editing a message.
+;;
+;;   M-p      Replace the buffer contents with the previous message
+;;            from the message ring.  Of course only after storing
+;;            the current content there too.
+;;
+;;   M-n      Replace the buffer contents with the next message from
+;;            the message ring, after storing the current content.
+
+;; Some support for pseudo headers as used in some projects is
+;; provided by these commands:
+;;
+;;   C-c C-s  Insert a Signed-off-by header.
+;;   C-c C-a  Insert a Acked-by header.
+;;   C-c C-m  Insert a Modified-by header.
+;;   C-c C-t  Insert a Tested-by header.
+;;   C-c C-r  Insert a Reviewed-by header.
+;;   C-c C-o  Insert a Cc header.
+;;   C-c C-p  Insert a Reported-by header.
+;;   C-c C-i  Insert a Suggested-by header.
+
+;; When Git requests a commit message from the user, it does so by
+;; having her edit a file which initially contains some comments,
+;; instructing her what to do, and providing useful information, such
+;; as which files were modified.  These comments, even when left
+;; intact by the user, do not become part of the commit message.  This
+;; package ensures these comments are propertizes as such and further
+;; prettifies them by using different faces for various parts, such as
+;; files.
+
+;; Finally this package highlights style errors, like lines that are
+;; too long, or when the second line is not empty.  It may even nag
+;; you when you attempt to finish the commit without having fixed
+;; these issues.  The style checks and many other settings can easily
+;; be configured:
+;;
+;;   M-x customize-group RET git-commit RET
+
+;;; Code:
+
+(require 'compat)
+(require 'subr-x)
+(require 'log-edit)
+(require 'ring)
+(require 'rx)
+(require 'server)
+(require 'transient)
+(require 'with-editor)
+
+;; For historic reasons Magit isn't a hard dependency.
+(require 'magit-base nil t)
+(require 'magit-git nil t)
+(declare-function magit-completing-read "magit-base"
+                  ( prompt collection &optional predicate require-match
+                    initial-input hist def fallback))
+(declare-function magit-expand-git-file-name "magit-git" (filename))
+(declare-function magit-git-lines "magit-git" (&rest args))
+(declare-function magit-hook-custom-get "magit-base" (symbol))
+(declare-function magit-list-local-branch-names "magit-git" ())
+
+(defvar diff-default-read-only)
+(defvar flyspell-generic-check-word-predicate)
+(defvar font-lock-beg)
+(defvar font-lock-end)
+(defvar recentf-exclude)
+
+;;; Options
+;;;; Variables
+
+(defgroup git-commit nil
+  "Edit Git commit messages."
+  :prefix "git-commit-"
+  :link '(info-link "(magit)Editing Commit Messages")
+  :group 'tools)
+
+(define-minor-mode global-git-commit-mode
+  "Edit Git commit messages.
+
+This global mode arranges for `git-commit-setup' to be called
+when a Git commit message file is opened.  That usually happens
+when Git uses the Emacsclient as $GIT_EDITOR to have the user
+provide such a commit message.
+
+Loading the library `git-commit' by default enables this mode,
+but the library is not automatically loaded because doing that
+would pull in many dependencies and increase startup time too
+much.  You can either rely on `magit' loading this library or
+you can load it explicitly.  Autoloading is not an alternative
+because in this case autoloading would immediately trigger
+full loading."
+  :group 'git-commit
+  :type 'boolean
+  :global t
+  :init-value t
+  :initialize (lambda (symbol exp)
+                (custom-initialize-default symbol exp)
+                (when global-git-commit-mode
+                  (add-hook 'find-file-hook #'git-commit-setup-check-buffer)))
+  (if global-git-commit-mode
+      (add-hook  'find-file-hook #'git-commit-setup-check-buffer)
+    (remove-hook 'find-file-hook #'git-commit-setup-check-buffer)))
+
+(defcustom git-commit-major-mode #'text-mode
+  "Major mode used to edit Git commit messages.
+The major mode configured here is turned on by the minor mode
+`git-commit-mode'."
+  :group 'git-commit
+  :type '(choice (function-item text-mode)
+                 (function-item markdown-mode)
+                 (function-item org-mode)
+                 (function-item fundamental-mode)
+                 (function-item git-commit-elisp-text-mode)
+                 (function :tag "Another mode")
+                 (const :tag "No major mode")))
+;;;###autoload(put 'git-commit-major-mode 'safe-local-variable
+;;;###autoload     (lambda (val)
+;;;###autoload       (memq val '(text-mode
+;;;###autoload                   markdown-mode
+;;;###autoload                   org-mode
+;;;###autoload                   fundamental-mode
+;;;###autoload                   git-commit-elisp-text-mode))))
+
+(defcustom git-commit-setup-hook
+  '(git-commit-save-message
+    git-commit-setup-changelog-support
+    git-commit-turn-on-auto-fill
+    git-commit-propertize-diff
+    bug-reference-mode)
+  "Hook run at the end of `git-commit-setup'."
+  :group 'git-commit
+  :type 'hook
+  :get (and (featurep 'magit-base) #'magit-hook-custom-get)
+  :options '(git-commit-save-message
+             git-commit-setup-changelog-support
+             magit-generate-changelog
+             git-commit-turn-on-auto-fill
+             git-commit-turn-on-orglink
+             git-commit-turn-on-flyspell
+             git-commit-propertize-diff
+             bug-reference-mode))
+
+(defcustom git-commit-post-finish-hook nil
+  "Hook run after the user finished writing a commit message.
+
+\\<with-editor-mode-map>\
+This hook is only run after pressing \\[with-editor-finish] in a buffer used
+to edit a commit message.  If a commit is created without the
+user typing a message into a buffer, then this hook is not run.
+
+This hook is not run until the new commit has been created.  If
+that takes Git longer than `git-commit-post-finish-hook-timeout'
+seconds, then this hook isn't run at all.  For certain commands
+such as `magit-rebase-continue' this hook is never run because
+doing so would lead to a race condition.
+
+This hook is only run if `magit' is available.
+
+Also see `magit-post-commit-hook'."
+  :group 'git-commit
+  :type 'hook
+  :get (and (featurep 'magit-base) #'magit-hook-custom-get))
+
+(defcustom git-commit-post-finish-hook-timeout 1
+  "Time in seconds to wait for git to create a commit.
+
+The hook `git-commit-post-finish-hook' (which see) is run only
+after git is done creating a commit.  If it takes longer than
+`git-commit-post-finish-hook-timeout' seconds to create the
+commit, then the hook is not run at all."
+  :group 'git-commit
+  :safe 'numberp
+  :type 'number)
+
+(defcustom git-commit-finish-query-functions
+  '(git-commit-check-style-conventions)
+  "List of functions called to query before performing commit.
+
+The commit message buffer is current while the functions are
+called.  If any of them returns nil, then the commit is not
+performed and the buffer is not killed.  The user should then
+fix the issue and try again.
+
+The functions are called with one argument.  If it is non-nil,
+then that indicates that the user used a prefix argument to
+force finishing the session despite issues.  Functions should
+usually honor this wish and return non-nil."
+  :options '(git-commit-check-style-conventions)
+  :type 'hook
+  :group 'git-commit)
+
+(defcustom git-commit-style-convention-checks '(non-empty-second-line)
+  "List of checks performed by `git-commit-check-style-conventions'.
+Valid members are `non-empty-second-line' and `overlong-summary-line'.
+That function is a member of `git-commit-finish-query-functions'."
+  :options '(non-empty-second-line overlong-summary-line)
+  :type '(list :convert-widget custom-hook-convert-widget)
+  :group 'git-commit)
+
+(defcustom git-commit-summary-max-length 68
+  "Column beyond which characters in the summary lines are highlighted.
+
+The highlighting indicates that the summary is getting too long
+by some standards.  It does in no way imply that going over the
+limit a few characters or in some cases even many characters is
+anything that deserves shaming.  It's just a friendly reminder
+that if you can make the summary shorter, then you might want
+to consider doing so."
+  :group 'git-commit
+  :safe 'numberp
+  :type 'number)
+
+(defcustom git-commit-known-pseudo-headers
+  '("Signed-off-by" "Acked-by" "Modified-by" "Cc"
+    "Suggested-by" "Reported-by" "Tested-by" "Reviewed-by"
+    "Co-authored-by" "Co-developed-by")
+  "A list of Git pseudo headers to be highlighted."
+  :group 'git-commit
+  :safe (lambda (val) (and (listp val) (seq-every-p #'stringp val)))
+  :type '(repeat string))
+
+(defcustom git-commit-use-local-message-ring nil
+  "Whether to use a local message ring instead of the global one.
+This can be set globally, in which case every repository gets its
+own commit message ring, or locally for a single repository.  If
+Magit isn't available, then setting this to a non-nil value has
+no effect."
+  :group 'git-commit
+  :safe 'booleanp
+  :type 'boolean)
+
+;;;; Faces
+
+(defgroup git-commit-faces nil
+  "Faces used for highlighting Git commit messages."
+  :prefix "git-commit-"
+  :group 'git-commit
+  :group 'faces)
+
+(defface git-commit-summary
+  '((t :inherit font-lock-type-face))
+  "Face used for the summary in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-overlong-summary
+  '((t :inherit font-lock-warning-face))
+  "Face used for the tail of overlong commit message summaries."
+  :group 'git-commit-faces)
+
+(defface git-commit-nonempty-second-line
+  '((t :inherit font-lock-warning-face))
+  "Face used for non-whitespace on the second line of commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-keyword
+  '((t :inherit font-lock-string-face))
+  "Face used for keywords in commit messages.
+In this context a \"keyword\" is text surrounded by brackets."
+  :group 'git-commit-faces)
+
+(defface git-commit-pseudo-header
+  '((t :inherit font-lock-string-face))
+  "Face used for pseudo headers in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-known-pseudo-header
+  '((t :inherit font-lock-keyword-face))
+  "Face used for the keywords of known pseudo headers in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-branch-local
+  (if (featurep 'magit)
+      '((t :inherit magit-branch-local))
+    '((t :inherit font-lock-variable-name-face)))
+  "Face used for names of local branches in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-branch-remote
+  (if (featurep 'magit)
+      '((t :inherit magit-branch-remote))
+    '((t :inherit font-lock-variable-name-face)))
+  "Face used for names of remote branches in commit message comments.
+This is only used if Magit is available."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-detached
+  '((t :inherit git-commit-comment-branch-local))
+  "Face used for detached `HEAD' in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-heading
+  '((t :inherit git-commit-known-pseudo-header))
+  "Face used for headings in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-file
+  '((t :inherit git-commit-pseudo-header))
+  "Face used for file names in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-action
+  '((t :inherit bold))
+  "Face used for actions in commit message comments."
+  :group 'git-commit-faces)
+
+;;; Keymap
+
+(defvar-keymap git-commit-mode-map
+  :doc "Key map used by `git-commit-mode'."
+  "M-p"     #'git-commit-prev-message
+  "M-n"     #'git-commit-next-message
+  "C-c M-p" #'git-commit-search-message-backward
+  "C-c M-n" #'git-commit-search-message-forward
+  "C-c C-i" #'git-commit-insert-pseudo-header
+  "C-c C-a" #'git-commit-ack
+  "C-c M-i" #'git-commit-suggested
+  "C-c C-m" #'git-commit-modified
+  "C-c C-o" #'git-commit-cc
+  "C-c C-p" #'git-commit-reported
+  "C-c C-r" #'git-commit-review
+  "C-c C-s" #'git-commit-signoff
+  "C-c C-t" #'git-commit-test
+  "C-c M-s" #'git-commit-save-message)
+
+;;; Menu
+
+(require 'easymenu)
+(easy-menu-define git-commit-mode-menu git-commit-mode-map
+  "Git Commit Mode Menu"
+  '("Commit"
+    ["Previous" git-commit-prev-message t]
+    ["Next" git-commit-next-message t]
+    "-"
+    ["Ack" git-commit-ack :active t
+     :help "Insert an 'Acked-by' header"]
+    ["Sign-Off" git-commit-signoff :active t
+     :help "Insert a 'Signed-off-by' header"]
+    ["Modified-by" git-commit-modified :active t
+     :help "Insert a 'Modified-by' header"]
+    ["Tested-by" git-commit-test :active t
+     :help "Insert a 'Tested-by' header"]
+    ["Reviewed-by" git-commit-review :active t
+     :help "Insert a 'Reviewed-by' header"]
+    ["CC" git-commit-cc t
+     :help "Insert a 'Cc' header"]
+    ["Reported" git-commit-reported :active t
+     :help "Insert a 'Reported-by' header"]
+    ["Suggested" git-commit-suggested t
+     :help "Insert a 'Suggested-by' header"]
+    ["Co-authored-by" git-commit-co-authored t
+     :help "Insert a 'Co-authored-by' header"]
+    ["Co-developed-by" git-commit-co-developed t
+     :help "Insert a 'Co-developed-by' header"]
+    "-"
+    ["Save" git-commit-save-message t]
+    ["Cancel" with-editor-cancel t]
+    ["Commit" with-editor-finish t]))
+
+;;; Hooks
+
+(defconst git-commit-filename-regexp "/\\(\
+\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|MERGEREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\
+\\|\\(BRANCH\\|EDIT\\)_DESCRIPTION\\)\\'")
+
+(with-eval-after-load 'recentf
+  (add-to-list 'recentf-exclude git-commit-filename-regexp))
+
+(add-to-list 'with-editor-file-name-history-exclude git-commit-filename-regexp)
+
+(defun git-commit-setup-font-lock-in-buffer ()
+  (and buffer-file-name
+       (string-match-p git-commit-filename-regexp buffer-file-name)
+       (git-commit-setup-font-lock)))
+
+(add-hook 'after-change-major-mode-hook #'git-commit-setup-font-lock-in-buffer)
+
+(defun git-commit-setup-check-buffer ()
+  (and buffer-file-name
+       (string-match-p git-commit-filename-regexp buffer-file-name)
+       (git-commit-setup)))
+
+(defvar git-commit-mode)
+
+(defun git-commit-file-not-found ()
+  ;; cygwin git will pass a cygwin path (/cygdrive/c/foo/.git/...),
+  ;; try to handle this in window-nt Emacs.
+  (when-let
+      ((file (and (or (string-match-p git-commit-filename-regexp
+                                      buffer-file-name)
+                      (and (boundp 'git-rebase-filename-regexp)
+                           (string-match-p git-rebase-filename-regexp
+                                           buffer-file-name)))
+                  (not (file-accessible-directory-p
+                        (file-name-directory buffer-file-name)))
+                  (if (require 'magit-git nil t)
+                      ;; Emacs prepends a "c:".
+                      (magit-expand-git-file-name
+                       (substring buffer-file-name 2))
+                    ;; Fallback if we can't load `magit-git'.
+                    (and (string-match
+                          "\\`[a-z]:/\\(cygdrive/\\)?\\([a-z]\\)/\\(.*\\)"
+                          buffer-file-name)
+                         (concat (match-string 2 buffer-file-name) ":/"
+                                 (match-string 3 buffer-file-name)))))))
+    (when (file-accessible-directory-p (file-name-directory file))
+      (let ((inhibit-read-only t))
+        (insert-file-contents file t)
+        t))))
+
+(when (eq system-type 'windows-nt)
+  (add-hook 'find-file-not-found-functions #'git-commit-file-not-found))
+
+(defconst git-commit-default-usage-message "\
+Type \\[with-editor-finish] to finish, \
+\\[with-editor-cancel] to cancel, and \
+\\[git-commit-prev-message] and \\[git-commit-next-message] \
+to recover older messages")
+
+(defvar git-commit-usage-message git-commit-default-usage-message
+  "Message displayed when editing a commit message.
+When this is nil, then `with-editor-usage-message' is displayed
+instead.  One of these messages has to be displayed; otherwise
+the user gets to see the message displayed by `server-execute'.
+That message is misleading and because we cannot prevent it from
+being displayed, we have to immediately show another message to
+prevent the user from seeing it.")
+
+(defvar git-commit-header-line-format nil
+  "If non-nil, header line format used by `git-commit-mode'.
+Used as the local value of `header-line-format', in buffer using
+`git-commit-mode'.  If it is a string, then it is passed through
+`substitute-command-keys' first.  A useful setting may be:
+  (setq git-commit-header-line-format git-commit-default-usage-message)
+  (setq git-commit-usage-message nil) ; show a shorter message")
+
+(defun git-commit-setup ()
+  (when (fboundp 'magit-toplevel)
+    ;; `magit-toplevel' is autoloaded and defined in magit-git.el,
+    ;; That library declares this functions without loading
+    ;; magit-process.el, which defines it.
+    (require 'magit-process nil t))
+  ;; Pretend that git-commit-mode is a major-mode,
+  ;; so that directory-local settings can be used.
+  (let ((default-directory
+         (or (and (not (file-exists-p ".dir-locals.el"))
+                  ;; When $GIT_DIR/.dir-locals.el doesn't exist,
+                  ;; fallback to $GIT_WORK_TREE/.dir-locals.el,
+                  ;; because the maintainer can use the latter
+                  ;; to enforce conventions, while s/he has no
+                  ;; control over the former.
+                  (fboundp 'magit-toplevel)  ; silence byte-compiler
+                  (magit-toplevel))
+             default-directory)))
+    (let ((buffer-file-name nil)         ; trick hack-dir-local-variables
+          (major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables
+      (hack-dir-local-variables)
+      (hack-local-variables-apply)))
+  (when git-commit-major-mode
+    (let ((auto-mode-alist (list (cons (concat "\\`"
+                                               (regexp-quote buffer-file-name)
+                                               "\\'")
+                                       git-commit-major-mode)))
+          ;; The major-mode hook might want to consult these minor
+          ;; modes, while the minor-mode hooks might want to consider
+          ;; the major mode.
+          (git-commit-mode t)
+          (with-editor-mode t))
+      (normal-mode t)))
+  ;; Below we instead explicitly show a message.
+  (setq with-editor-show-usage nil)
+  (unless with-editor-mode
+    ;; Maybe already enabled when using `shell-command' or an Emacs shell.
+    (with-editor-mode 1))
+  (add-hook 'with-editor-finish-query-functions
+            #'git-commit-finish-query-functions nil t)
+  (add-hook 'with-editor-pre-finish-hook
+            #'git-commit-save-message nil t)
+  (add-hook 'with-editor-pre-cancel-hook
+            #'git-commit-save-message nil t)
+  (when (fboundp 'magit-commit--reset-command)
+    (add-hook 'with-editor-post-finish-hook #'magit-commit--reset-command)
+    (add-hook 'with-editor-post-cancel-hook #'magit-commit--reset-command))
+  (when (and (fboundp 'magit-rev-parse)
+             (not (memq last-command
+                        '(magit-sequencer-continue
+                          magit-sequencer-skip
+                          magit-am-continue
+                          magit-am-skip
+                          magit-rebase-continue
+                          magit-rebase-skip))))
+    (add-hook 'with-editor-post-finish-hook
+              (apply-partially #'git-commit-run-post-finish-hook
+                               (magit-rev-parse "HEAD"))
+              nil t)
+    (when (fboundp 'magit-wip-maybe-add-commit-hook)
+      (magit-wip-maybe-add-commit-hook)))
+  (setq with-editor-cancel-message
+        #'git-commit-cancel-message)
+  (git-commit-mode 1)
+  (git-commit-setup-font-lock)
+  (git-commit-prepare-message-ring)
+  (when (boundp 'save-place)
+    (setq save-place nil))
+  (save-excursion
+    (goto-char (point-min))
+    (when (looking-at "\\`\\(\\'\\|\n[^\n]\\)")
+      (open-line 1)))
+  (with-demoted-errors "Error running git-commit-setup-hook: %S"
+    (run-hooks 'git-commit-setup-hook))
+  (when git-commit-usage-message
+    (setq with-editor-usage-message git-commit-usage-message))
+  (with-editor-usage-message)
+  (when-let ((format git-commit-header-line-format))
+    (setq header-line-format
+          (if (stringp format) (substitute-command-keys format) format)))
+  (set-buffer-modified-p nil))
+
+(defun git-commit-run-post-finish-hook (previous)
+  (when (and git-commit-post-finish-hook
+             (require 'magit nil t)
+             (fboundp 'magit-rev-parse))
+    (cl-block nil
+      (let ((break (time-add (current-time)
+                             (seconds-to-time
+                              git-commit-post-finish-hook-timeout))))
+        (while (equal (magit-rev-parse "HEAD") previous)
+          (if (time-less-p (current-time) break)
+              (sit-for 0.01)
+            (message "No commit created after 1 second.  Not running %s."
+                     'git-commit-post-finish-hook)
+            (cl-return))))
+      (run-hooks 'git-commit-post-finish-hook))))
+
+(define-minor-mode git-commit-mode
+  "Auxiliary minor mode used when editing Git commit messages.
+This mode is only responsible for setting up some key bindings.
+Don't use it directly, instead enable `global-git-commit-mode'."
+  :lighter "")
+
+(put 'git-commit-mode 'permanent-local t)
+
+(defun git-commit-setup-changelog-support ()
+  "Treat ChangeLog entries as unindented paragraphs."
+  (when (fboundp 'log-indent-fill-entry) ; New in Emacs 27.
+    (setq-local fill-paragraph-function #'log-indent-fill-entry))
+  (setq-local fill-indent-according-to-mode t)
+  (setq-local paragraph-start (concat paragraph-start "\\|\\*\\|(")))
+
+(defun git-commit-turn-on-auto-fill ()
+  "Unconditionally turn on Auto Fill mode."
+  (setq-local comment-auto-fill-only-comments nil)
+  (turn-on-auto-fill))
+
+(defun git-commit-turn-on-orglink ()
+  "Turn on Orglink mode if it is available.
+If `git-commit-major-mode' is `org-mode', then silently forgo
+turning on `orglink-mode'."
+  (when (and (not (derived-mode-p 'org-mode))
+             (boundp 'orglink-match-anywhere)
+             (fboundp 'orglink-mode))
+    (setq-local orglink-match-anywhere t)
+    (orglink-mode 1)))
+
+(defun git-commit-turn-on-flyspell ()
+  "Unconditionally turn on Flyspell mode.
+Also prevent comments from being checked and
+finally check current non-comment text."
+  (require 'flyspell)
+  (turn-on-flyspell)
+  (setq flyspell-generic-check-word-predicate
+        #'git-commit-flyspell-verify)
+  (let ((end)
+        (comment-start-regex (format "^\\(%s\\|$\\)" comment-start)))
+    (save-excursion
+      (goto-char (point-max))
+      (while (and (not (bobp)) (looking-at comment-start-regex))
+        (forward-line -1))
+      (unless (looking-at comment-start-regex)
+        (forward-line))
+      (setq end (point)))
+    (flyspell-region (point-min) end)))
+
+(defun git-commit-flyspell-verify ()
+  (not (= (char-after (line-beginning-position))
+          (aref comment-start 0))))
+
+(defun git-commit-finish-query-functions (force)
+  (run-hook-with-args-until-failure
+   'git-commit-finish-query-functions force))
+
+(defun git-commit-check-style-conventions (force)
+  "Check for violations of certain basic style conventions.
+
+For each violation ask the user if she wants to proceed anyway.
+Option `git-commit-style-convention-checks' controls which
+conventions are checked."
+  (or force
+      (save-excursion
+        (goto-char (point-min))
+        (re-search-forward (git-commit-summary-regexp) nil t)
+        (if (equal (match-string 1) "")
+            t ; Just try; we don't know whether --allow-empty-message was used.
+          (and (or (not (memq 'overlong-summary-line
+                              git-commit-style-convention-checks))
+                   (equal (match-string 2) "")
+                   (y-or-n-p "Summary line is too long.  Commit anyway? "))
+               (or (not (memq 'non-empty-second-line
+                              git-commit-style-convention-checks))
+                   (not (match-string 3))
+                   (y-or-n-p "Second line is not empty.  Commit anyway? ")))))))
+
+(defun git-commit-cancel-message ()
+  (message
+   (concat "Commit canceled"
+           (and (memq 'git-commit-save-message with-editor-pre-cancel-hook)
+                ".  Message saved to `log-edit-comment-ring'"))))
+
+;;; History
+
+(defun git-commit-prev-message (arg)
+  "Cycle backward through message history, after saving current message.
+With a numeric prefix ARG, go back ARG comments."
+  (interactive "*p")
+  (let ((len (ring-length log-edit-comment-ring)))
+    (if (<= len 0)
+        (progn (message "Empty comment ring") (ding))
+      ;; Unlike `log-edit-previous-comment' we save the current
+      ;; non-empty and newly written comment, because otherwise
+      ;; it would be irreversibly lost.
+      (when-let ((message (git-commit-buffer-message)))
+        (unless (ring-member log-edit-comment-ring message)
+          (ring-insert log-edit-comment-ring message)
+          (cl-incf arg)
+          (setq len (ring-length log-edit-comment-ring))))
+      ;; Delete the message but not the instructions at the end.
+      (save-restriction
+        (goto-char (point-min))
+        (narrow-to-region
+         (point)
+         (if (re-search-forward (concat "^" comment-start) nil t)
+             (max 1 (- (point) 2))
+           (point-max)))
+        (delete-region (point-min) (point)))
+      (setq log-edit-comment-ring-index (log-edit-new-comment-index arg len))
+      (message "Comment %d" (1+ log-edit-comment-ring-index))
+      (insert (ring-ref log-edit-comment-ring log-edit-comment-ring-index)))))
+
+(defun git-commit-next-message (arg)
+  "Cycle forward through message history, after saving current message.
+With a numeric prefix ARG, go forward ARG comments."
+  (interactive "*p")
+  (git-commit-prev-message (- arg)))
+
+(defun git-commit-search-message-backward (string)
+  "Search backward through message history for a match for STRING.
+Save current message first."
+  (interactive
+   ;; Avoid `format-prompt' because it isn't available until Emacs 28.
+   (list (read-string (format "Comment substring (default %s): "
+                              log-edit-last-comment-match)
+                      nil nil log-edit-last-comment-match)))
+  (cl-letf (((symbol-function #'log-edit-previous-comment)
+             (symbol-function #'git-commit-prev-message)))
+    (log-edit-comment-search-backward string)))
+
+(defun git-commit-search-message-forward (string)
+  "Search forward through message history for a match for STRING.
+Save current message first."
+  (interactive
+   ;; Avoid `format-prompt' because it isn't available until Emacs 28.
+   (list (read-string (format "Comment substring (default %s): "
+                              log-edit-last-comment-match)
+                      nil nil log-edit-last-comment-match)))
+  (cl-letf (((symbol-function #'log-edit-previous-comment)
+             (symbol-function #'git-commit-prev-message)))
+    (log-edit-comment-search-forward string)))
+
+(defun git-commit-save-message ()
+  "Save current message to `log-edit-comment-ring'."
+  (interactive)
+  (if-let ((message (git-commit-buffer-message)))
+      (progn
+        (when-let ((index (ring-member log-edit-comment-ring message)))
+          (ring-remove log-edit-comment-ring index))
+        (ring-insert log-edit-comment-ring message)
+        (when (and git-commit-use-local-message-ring
+                   (fboundp 'magit-repository-local-set))
+          (magit-repository-local-set 'log-edit-comment-ring
+                                      log-edit-comment-ring))
+        (message "Message saved"))
+    (message "Only whitespace and/or comments; message not saved")))
+
+(defun git-commit-prepare-message-ring ()
+  (make-local-variable 'log-edit-comment-ring-index)
+  (when (and git-commit-use-local-message-ring
+             (fboundp 'magit-repository-local-get))
+    (setq-local log-edit-comment-ring
+                (magit-repository-local-get
+                 'log-edit-comment-ring
+                 (make-ring log-edit-maximum-comment-ring-size)))))
+
+(defun git-commit-buffer-message ()
+  (let ((flush (concat "^" comment-start))
+        (str (buffer-substring-no-properties (point-min) (point-max))))
+    (with-temp-buffer
+      (insert str)
+      (goto-char (point-min))
+      (when (re-search-forward (concat flush " -+ >8 -+$") nil t)
+        (delete-region (line-beginning-position) (point-max)))
+      (goto-char (point-min))
+      (flush-lines flush)
+      (goto-char (point-max))
+      (unless (eq (char-before) ?\n)
+        (insert ?\n))
+      (setq str (buffer-string)))
+    (unless (string-match "\\`[ \t\n\r]*\\'" str)
+      (when (string-match "\\`\n\\{2,\\}" str)
+        (setq str (replace-match "\n" t t str)))
+      (when (string-match "\n\\{2,\\}\\'" str)
+        (setq str (replace-match "\n" t t str)))
+      str)))
+
+;;; Utilities
+
+(defsubst git-commit-executable ()
+  (if (fboundp 'magit-git-executable)
+      (magit-git-executable)
+    "git"))
+
+;;; Headers
+
+(transient-define-prefix git-commit-insert-pseudo-header ()
+  "Insert a commit message pseudo header."
+  [["Insert ... by yourself"
+    ("a"   "Ack"          git-commit-ack)
+    ("m"   "Modified"     git-commit-modified)
+    ("r"   "Reviewed"     git-commit-review)
+    ("s"   "Signed-off"   git-commit-signoff)
+    ("t"   "Tested"       git-commit-test)]
+   ["Insert ... by someone"
+    ("C-c" "Cc"           git-commit-cc)
+    ("C-r" "Reported"     git-commit-reported)
+    ("C-i" "Suggested"    git-commit-suggested)
+    ("C-a" "Co-authored"  git-commit-co-authored)
+    ("C-d" "Co-developed" git-commit-co-developed)]])
+
+(defun git-commit-ack (name mail)
+  "Insert a header acknowledging that you have looked at the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Acked-by" name mail))
+
+(defun git-commit-modified (name mail)
+  "Insert a header to signal that you have modified the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Modified-by" name mail))
+
+(defun git-commit-review (name mail)
+  "Insert a header acknowledging that you have reviewed the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Reviewed-by" name mail))
+
+(defun git-commit-signoff (name mail)
+  "Insert a header to sign off the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Signed-off-by" name mail))
+
+(defun git-commit-test (name mail)
+  "Insert a header acknowledging that you have tested the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Tested-by" name mail))
+
+(defun git-commit-cc (name mail)
+  "Insert a header mentioning someone who might be interested."
+  (interactive (git-commit-read-ident "Cc"))
+  (git-commit-insert-header "Cc" name mail))
+
+(defun git-commit-reported (name mail)
+  "Insert a header mentioning the person who reported the issue."
+  (interactive (git-commit-read-ident "Reported-by"))
+  (git-commit-insert-header "Reported-by" name mail))
+
+(defun git-commit-suggested (name mail)
+  "Insert a header mentioning the person who suggested the change."
+  (interactive (git-commit-read-ident "Suggested-by"))
+  (git-commit-insert-header "Suggested-by" name mail))
+
+(defun git-commit-co-authored (name mail)
+  "Insert a header mentioning the person who co-authored the commit."
+  (interactive (git-commit-read-ident "Co-authored-by"))
+  (git-commit-insert-header "Co-authored-by" name mail))
+
+(defun git-commit-co-developed (name mail)
+  "Insert a header mentioning the person who co-developed the commit."
+  (interactive (git-commit-read-ident "Co-developed-by"))
+  (git-commit-insert-header "Co-developed-by" name mail))
+
+(defun git-commit-self-ident ()
+  (list (or (getenv "GIT_AUTHOR_NAME")
+            (getenv "GIT_COMMITTER_NAME")
+            (with-demoted-errors "Error running 'git config user.name': %S"
+              (car (process-lines
+                    (git-commit-executable) "config" "user.name")))
+            user-full-name
+            (read-string "Name: "))
+        (or (getenv "GIT_AUTHOR_EMAIL")
+            (getenv "GIT_COMMITTER_EMAIL")
+            (getenv "EMAIL")
+            (with-demoted-errors "Error running 'git config user.email': %S"
+              (car (process-lines
+                    (git-commit-executable) "config" "user.email")))
+            (read-string "Email: "))))
+
+(defvar git-commit-read-ident-history nil)
+
+(defun git-commit-read-ident (prompt)
+  (if (require 'magit-git nil t)
+      (let ((str (magit-completing-read
+                  prompt
+                  (sort (delete-dups
+                         (magit-git-lines "log" "-n9999" "--format=%aN <%ae>"))
+                        #'string<)
+                  nil nil nil 'git-commit-read-ident-history)))
+        (save-match-data
+          (if (string-match "\\`\\([^<]+\\) *<\\([^>]+\\)>\\'" str)
+              (list (save-match-data (string-trim (match-string 1 str)))
+                    (string-trim (match-string 2 str)))
+            (user-error "Invalid input"))))
+    (list (read-string "Name: ")
+          (read-string "Email: "))))
+
+(defun git-commit-insert-header (header name email)
+  (setq header (format "%s: %s <%s>" header name email))
+  (save-excursion
+    (goto-char (point-max))
+    (cond ((re-search-backward "^[-a-zA-Z]+: [^<]+? <[^>]+>" nil t)
+           (end-of-line)
+           (insert ?\n header)
+           (unless (= (char-after) ?\n)
+             (insert ?\n)))
+          (t
+           (while (re-search-backward (concat "^" comment-start) nil t))
+           (unless (looking-back "\n\n" nil)
+             (insert ?\n))
+           (insert header ?\n)))
+    (unless (or (eobp) (= (char-after) ?\n))
+      (insert ?\n))))
+
+;;; Font-Lock
+
+(defvar-local git-commit-need-summary-line t
+  "Whether the text should have a heading that is separated from the body.
+
+For commit messages that is a convention that should not
+be violated.  For notes it is up to the user.  If you do
+not want to insist on an empty second line here, then use
+something like:
+
+  (add-hook \\='git-commit-setup-hook
+            (lambda ()
+              (when (equal (file-name-nondirectory (buffer-file-name))
+                           \"NOTES_EDITMSG\")
+                (setq git-commit-need-summary-line nil))))")
+
+(defun git-commit-summary-regexp ()
+  (if git-commit-need-summary-line
+      (concat
+       ;; Leading empty lines and comments
+       (format "\\`\\(?:^\\(?:\\s-*\\|%s.*\\)\n\\)*" comment-start)
+       ;; Summary line
+       (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length)
+       ;; Non-empty non-comment second line
+       (format "\\(?:\n%s\\|\n\\(.+\\)\\)?" comment-start))
+    "\\(EASTER\\) \\(EGG\\)"))
+
+(defun git-commit-extend-region-summary-line ()
+  "Identify the multiline summary-regexp construct.
+Added to `font-lock-extend-region-functions'."
+  (save-excursion
+    (save-match-data
+      (goto-char (point-min))
+      (when (looking-at (git-commit-summary-regexp))
+        (let ((summary-beg (match-beginning 0))
+              (summary-end (match-end 0)))
+          (when (or (< summary-beg font-lock-beg summary-end)
+                    (< summary-beg font-lock-end summary-end))
+            (setq font-lock-beg (min font-lock-beg summary-beg))
+            (setq font-lock-end (max font-lock-end summary-end))))))))
+
+(defvar-local git-commit--branch-name-regexp nil)
+
+(defconst git-commit-comment-headings
+  '("Changes to be committed:"
+    "Untracked files:"
+    "Changed but not updated:"
+    "Changes not staged for commit:"
+    "Unmerged paths:"
+    "Author:"
+    "Date:")
+  "Also fontified outside of comments in `git-commit-font-lock-keywords-2'.")
+
+(defconst git-commit-font-lock-keywords-1
+  '(;; Pseudo headers
+    (eval . `(,(format "^\\(%s:\\)\\( .*\\)"
+                       (regexp-opt git-commit-known-pseudo-headers))
+              (1 'git-commit-known-pseudo-header)
+              (2 'git-commit-pseudo-header)))
+    ;; Summary
+    (eval . `(,(git-commit-summary-regexp)
+              (1 'git-commit-summary)))
+    ;; - Keyword [aka "text in brackets"] (overrides summary)
+    ("\\[[^][]+?\\]"
+     (0 'git-commit-keyword t))
+    ;; - Non-empty second line (overrides summary and note)
+    (eval . `(,(git-commit-summary-regexp)
+              (2 'git-commit-overlong-summary t t)
+              (3 'git-commit-nonempty-second-line t t)))))
+
+(defconst git-commit-font-lock-keywords-2
+  `(,@git-commit-font-lock-keywords-1
+    ;; Comments
+    (eval . `(,(format "^%s.*" comment-start)
+              (0 'font-lock-comment-face append)))
+    (eval . `(,(format "^%s On branch \\(.*\\)" comment-start)
+              (1 'git-commit-comment-branch-local t)))
+    (eval . `(,(format "^%s \\(HEAD\\) detached at" comment-start)
+              (1 'git-commit-comment-detached t)))
+    (eval . `(,(format "^%s %s" comment-start
+                       (regexp-opt git-commit-comment-headings t))
+              (1 'git-commit-comment-heading t)))
+    (eval . `(,(format "^%s\t\\(?:\\([^:\n]+\\):\\s-+\\)?\\(.*\\)" comment-start)
+              (1 'git-commit-comment-action t t)
+              (2 'git-commit-comment-file t)))
+    ;; "commit HASH"
+    (eval . `(,(rx bol "commit " (1+ alnum) eol)
+              (0 'git-commit-pseudo-header)))
+    ;; `git-commit-comment-headings' (but not in commented lines)
+    (eval . `(,(rx-to-string `(seq bol (or ,@git-commit-comment-headings) (1+ blank) (1+ nonl) eol))
+              (0 'git-commit-pseudo-header)))))
+
+(defconst git-commit-font-lock-keywords-3
+  `(,@git-commit-font-lock-keywords-2
+    ;; More comments
+    (eval
+     ;; Your branch is ahead of 'master' by 3 commits.
+     ;; Your branch is behind 'master' by 2 commits, and can be fast-forwarded.
+     . `(,(format
+           "^%s Your branch is \\(?:ahead\\|behind\\) of '%s' by \\([0-9]*\\)"
+           comment-start git-commit--branch-name-regexp)
+         (1 'git-commit-comment-branch-local t)
+         (2 'git-commit-comment-branch-remote t)
+         (3 'bold t)))
+    (eval
+     ;; Your branch is up to date with 'master'.
+     ;; Your branch and 'master' have diverged,
+     . `(,(format
+           "^%s Your branch \\(?:is up[- ]to[- ]date with\\|and\\) '%s'"
+           comment-start git-commit--branch-name-regexp)
+         (1 'git-commit-comment-branch-local t)
+         (2 'git-commit-comment-branch-remote t)))
+    (eval
+     ;; and have 1 and 2 different commits each, respectively.
+     . `(,(format
+           "^%s and have \\([0-9]*\\) and \\([0-9]*\\) commits each"
+           comment-start)
+         (1 'bold t)
+         (2 'bold t)))))
+
+(defvar git-commit-font-lock-keywords git-commit-font-lock-keywords-3
+  "Font-Lock keywords for Git-Commit mode.")
+
+(defun git-commit-setup-font-lock ()
+  (with-demoted-errors "Error running git-commit-setup-font-lock: %S"
+    (let ((table (make-syntax-table (syntax-table))))
+      (when comment-start
+        (modify-syntax-entry (string-to-char comment-start) "." table))
+      (modify-syntax-entry ?#  "." table)
+      (modify-syntax-entry ?\" "." table)
+      (modify-syntax-entry ?\' "." table)
+      (modify-syntax-entry ?`  "." table)
+      (set-syntax-table table))
+    (setq-local comment-start
+                (or (with-temp-buffer
+                      (and (zerop
+                            (call-process
+                             (git-commit-executable) nil (list t nil) nil
+                             "config" "core.commentchar"))
+                           (not (bobp))
+                           (progn
+                             (goto-char (point-min))
+                             (buffer-substring (point) (line-end-position)))))
+                    "#"))
+    (setq-local comment-start-skip (format "^%s+[\s\t]*" comment-start))
+    (setq-local comment-end-skip "\n")
+    (setq-local comment-use-syntax nil)
+    (setq-local git-commit--branch-name-regexp
+                (if (and (featurep 'magit-git)
+                         ;; When using cygwin git, we may end up in a
+                         ;; non-existing directory, which would cause
+                         ;; any git calls to signal an error.
+                         (file-accessible-directory-p default-directory))
+                    (progn
+                      ;; Make sure the below functions are available.
+                      (require 'magit)
+                      ;; Font-Lock wants every submatch to succeed, so
+                      ;; also match the empty string.  Avoid listing
+                      ;; remote branches and using `regexp-quote',
+                      ;; because in repositories have thousands of
+                      ;; branches that would be very slow.  See #4353.
+                      (format "\\(\\(?:%s\\)\\|\\)\\([^']+\\)"
+                              (mapconcat #'identity
+                                         (magit-list-local-branch-names)
+                                         "\\|")))
+                  "\\([^']*\\)"))
+    (setq-local font-lock-multiline t)
+    (add-hook 'font-lock-extend-region-functions
+              #'git-commit-extend-region-summary-line
+              t t)
+    (font-lock-add-keywords nil git-commit-font-lock-keywords)))
+
+(defun git-commit-propertize-diff ()
+  (require 'diff-mode)
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward "^diff --git" nil t)
+      (beginning-of-line)
+      (let ((buffer (current-buffer)))
+        (insert
+         (with-temp-buffer
+           (insert
+            (with-current-buffer buffer
+              (prog1 (buffer-substring-no-properties (point) (point-max))
+                (delete-region (point) (point-max)))))
+           (let ((diff-default-read-only nil))
+             (diff-mode))
+           (let (font-lock-verbose font-lock-support-mode)
+             (if (fboundp 'font-lock-ensure)
+                 (font-lock-ensure)
+               (with-no-warnings
+                 (font-lock-fontify-buffer))))
+           (let (next (pos (point-min)))
+             (while (setq next (next-single-property-change pos 'face))
+               (put-text-property pos next 'font-lock-face
+                                  (get-text-property pos 'face))
+               (setq pos next))
+             (put-text-property pos (point-max) 'font-lock-face
+                                (get-text-property pos 'face)))
+           (buffer-string)))))))
+
+;;; Elisp Text Mode
+
+(define-derived-mode git-commit-elisp-text-mode text-mode "ElText"
+  "Major mode for editing commit messages of elisp projects.
+This is intended for use as `git-commit-major-mode' for projects
+that expect `symbols' to look like this.  I.e., like they look in
+Elisp doc-strings, including this one.  Unlike in doc-strings,
+\"strings\" also look different than the other text."
+  (setq font-lock-defaults '(git-commit-elisp-text-mode-keywords)))
+
+(defvar git-commit-elisp-text-mode-keywords
+  `((,(concat "[`‘]\\(" lisp-mode-symbol-regexp "\\)['’]")
+     (1 font-lock-constant-face prepend))
+    ("\"[^\"]*\"" (0 font-lock-string-face prepend))))
+
+;;; _
+(provide 'git-commit)
+;;; git-commit.el ends here
diff --git a/elpa/git-link-20230420.48/git-link-autoloads.el b/elpa/git-link-20230420.48/git-link-autoloads.el
deleted file mode 100644 (file)
index a617dfc..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-;;; git-link-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "git-link" "git-link.el" (0 0 0 0))
-;;; Generated autoloads from git-link.el
-
-(autoload 'git-link "git-link" "\
-Create a URL representing the current buffer's location in its
-GitHub/Bitbucket/GitLab/... repository at the current line number
-or active region. The URL will be added to the kill ring.  If
-`git-link-open-in-browser' is non-nil also call `browse-url'.
-
-With a prefix argument of - generate a link without line number(s).
-Also see `git-link-use-single-line-number'.
-
-With a single prefix argument prompt for the remote's name.
-Defaults to \"origin\".
-
-With a double prefix argument invert the value of
-`git-link-use-commit'.
-
-\(fn REMOTE START END)" t nil)
-
-(autoload 'git-link-commit "git-link" "\
-Create a URL representing the commit for the hash under point
-in the current buffer's GitHub/Bitbucket/GitLab/...
-repository. The URL will be added to the kill ring.
-
-With a prefix argument prompt for the remote's name.
-Defaults to \"origin\".
-
-\(fn REMOTE)" t nil)
-
-(autoload 'git-link-homepage "git-link" "\
-Create a URL representing the homepage of the current
-buffer's GitHub/Bitbucket/GitLab/... repository. The
-URL will be added to the kill ring.
-
-With a prefix argument prompt for the remote's name.
-Defaults to \"origin\".
-
-\(fn REMOTE)" t nil)
-
-(register-definition-prefixes "git-link" '("git-link-"))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; git-link-autoloads.el ends here
diff --git a/elpa/git-link-20230420.48/git-link-pkg.el b/elpa/git-link-20230420.48/git-link-pkg.el
deleted file mode 100644 (file)
index 4855569..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-;;; Generated package description from git-link.el  -*- no-byte-compile: t -*-
-(define-package "git-link" "20230420.48" "Get the GitHub/Bitbucket/GitLab URL for a buffer location" '((emacs "24.3")) :commit "1727e9b7ec41a234a2cc14151b9ffd9c1c4f4b14" :authors '(("Skye Shaw" . "skye.shawNOSPAMgmail.com")) :maintainers '(("Skye Shaw" . "skye.shawNOSPAMgmail.com")) :maintainer '("Skye Shaw" . "skye.shawNOSPAMgmail.com") :keywords '("git" "vc" "github" "bitbucket" "gitlab" "sourcehut" "aws" "azure" "convenience") :url "http://github.com/sshaw/git-link")
diff --git a/elpa/git-link-20230420.48/git-link.el b/elpa/git-link-20230420.48/git-link.el
deleted file mode 100644 (file)
index 9387059..0000000
+++ /dev/null
@@ -1,885 +0,0 @@
-;;; git-link.el --- Get the GitHub/Bitbucket/GitLab URL for a buffer location -*- lexical-binding: t -*-
-
-;; Copyright (C) 2013-2022 Skye Shaw and others
-;; Author: Skye Shaw <skye.shawNOSPAMgmail.com>
-;; Version: 0.9.0
-;; Package-Version: 20230420.48
-;; Package-Commit: 1727e9b7ec41a234a2cc14151b9ffd9c1c4f4b14
-;; Keywords: git, vc, github, bitbucket, gitlab, sourcehut, aws, azure, convenience
-;; URL: http://github.com/sshaw/git-link
-;; Package-Requires: ((emacs "24.3"))
-
-;; This file is NOT part of GNU Emacs.
-
-;;; License:
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Create URLs for files and commits in GitHub/Bitbucket/GitLab/...
-;; repositories.  `git-link' returns the URL for the current buffer's file
-;; location at the current line number or active region.  `git-link-commit'
-;; returns the URL for a commit.  URLs are added to the kill ring.
-;;
-;; With a prefix argument prompt for the remote's name.  Defaults to "origin".
-
-;;; Change Log:
-
-;; 2023-02-15 - v0.9.0
-;; * Add support for GoogleSource (thanks Peter Becich)
-;; * Add plain=1 to force showing a non rendered GitHub links (thanks Erick Navarro)
-;; * Add prefix arg to override git-link-use-commit when calling git-link (thanks Nacho Barrientos)
-;; * Fix git-link-homepage for Bitbucket (Issue #97 thanks Sibi Prabakaran)
-;; * Fix the Codeberg links to line ranges (Issue #109 thanks Wojciech Siewierski)
-;;
-;; 2022-02-17 - v0.8.6
-;; * Fix URL escaping of pathnames on Emacs < 27 (Issue #93 thanks David Ongaro)
-;;
-;; 2022-02-06 - v0.8.5
-;; * URL escape pathnames (thanks David Ongaro)
-;; * Mark misspelled Savannah functions as obsolete (thanks Hendursaga)
-;; * Add support for AWS CodeCommit (thanks Ram Krishnan)
-;; * Add support for cgit (thanks Hendursaga)
-;;
-;; 2020-01-20 - v0.8.4
-;; * Add support for Codeberg (thanks Jeremy Friesen)
-;; * Add git-link-homepage-remote-alist (thanks Wim Van Deun)
-;;
-;; 2020-01-20 - v0.8.3
-;; * Add support for Savannah
-;;
-;; 2020-12-14 - v0.8.2
-;; * Fix sourcehut URL, don't link to raw version (Issue #77)
-;; * Fix sourcehut multi-line URLs
-;;
-;; 2020-11-23 - v0.8.1
-;; * Fix URL casing (Issue #57)
-;; * Fix byte-compile warnings (Issue #75 thanks Brian Leung)
-;;
-;; 2020-07-21 - v0.8.0
-;; * Add `-' prefix argument to git-link to generate links without line numbers
-;; * Add git-link-use-single-line-number
-;; * Fix sourcehut's git-link handler
-;;
-;; 2020-03-31 - v0.7.6
-;; * Adapt to changes in Azure interface (Issue #65, thanks Roey Darwish Dror)
-;;
-;; 2019-08-28 - v0.7.5
-;; * Add support for Azure DevOps (Issue #62, thanks Roey Darwish Dror)
-;;
-;; 2019-08-16 - v0.7.4
-;; * Add support for Magit-Blob buffers (Issue #61, thanks Miciah Dashiel Butler Masters)
-;;
-;; 2019-03-09 - v0.7.3
-;; * Add support for sourcehut
-;;
-;; 2018-10-30 - v0.7.2
-;; * Fix suffix stripping on remote path only if it ends in .git (Issue #58, thanks Marko Crnic)
-;;
-;; 2018-07-08 - v0.7.1
-;; * Add support for vc-revision-other-window files (Issue #54)
-;;
-;; 2018-06-07 - v0.7.0
-;; * Add support for Tramp (Issue #49, thanks Jürgen Hötzel)
-;; * Fix various compiler warnings
-;; * Fix differences between url-path-and-query across Emacs versions
-;; * Require Emacs 24.3
-;;
-;; 2018-04-23 - v0.6.0
-;; * Fix parsing of remotes with auth info (Issue #51)
-;; * Removed remote regex in favor of url-parse
-;;
-;; 2017-06-03 - v0.5.1
-;; * Add support for more magit modes
-;;
-;; 2017-06-01 - v0.5.0
-;; * Add support for linking in dired and magit modes
-;; * Add support for defcustom
-;; * Change git-link-remote-regex to support more remote URL formats (Thanks Kaushal Modi)
-;; * Change git-link-remote-alist to use regex matching (Thanks Kaushal Modi)
-;; * Fix point on commit hash regex and support uppercase SHAs (Thanks Kaushal Modi!)
-;; * Fix git-link-commit message so that SHA text is displayed without properties
-;; * Enabled lexical-binding (Thanks Kaushal Modi!!)
-;;
-;; -- Note that v0.5.0 was released as "v0.5.0 (unreleased)"
-;;
-;; 2016-10-19 - v0.4.5
-;; * Fix for branches containing reserved URLs characters (Issue #36)
-;;
-;; 2016-09-11 - v0.4.4
-;; * Added support for git-link-homepage
-;;
-;; 2016-08-13 - v0.4.3
-;; * Added support for git-timemachine (Issue #22, thanks Diego Berrocal)
-;;
-;; 2016-08-09 - v0.4.2
-;; * Fix for URLs with ports (Issue #32)
-;;
-;; 2016-04-01 - v0.4.1
-;; * Better handling for branches that have no explicit remote
-;; * Better error messages
-;;
-;; 2016-02-16 - v0.4.0
-;; * Try branch's tracking remote when other branch settings are not specified
-;; * git-link-default-remote now defaults to nil
-;;
-;; 2015-09-21 - v0.3.0
-;; * Support for setting branch and remote names via `git config`
-;; * Added git-link-default-branch
-;; * Removed some functions, use emacs "private" convention for others
-;;
-;; 2015-09-12 - v0.2.2
-;; * Support for BitBucket's multiline format
-;;
-;; 2015-07-25 - v0.2.1
-;; * Fix for BitBucket's new URL format (Thanks Ev Dolzhenko)
-;; * Fix for GitLab's multiline format (Thanks Enrico Carlesso)
-;;
-;; 2015-06-05 - v0.2.0
-;; * Deactivate mark after killing the link (Thanks Kaushal Modi)
-;; * Support for GitLab (Thanks Swaroop C H)
-;; * Use completing-read when prompting for remotes (Thanks Andrew Gwozdziewycz)
-;; * Display URL in minibuffer when adding to kill ring (Thanks Andrew Gwozdziewycz)
-;; * Added git-link-use-commit variable (Thanks Kaushal Modi)
-;; * Fix for displaying link in minibuffer when interprogram-cut-function is set (Thanks Ric Lister)
-;; * Fix to ignore point at beginning of line in regions (Thanks Kaushal Modi)
-;; * Fix for narrow-to-region (Bug #10, thanks Andrew Gwozdziewycz)
-;; * Fix to use remote hostname when constructing link URLs (Thanks David Hull)
-;;
-;; 2015-02-05 - v0.1.0
-;; * Added git-link-commit (Thanks Ryan Barrett)
-;; * Added git-link-open-in-browser variable (Thanks Ryan Barrett)
-;; * Use call-process instead of shell-command-to-string
-;; * Use --short option when calling symbolic-ref (Thanks Steven Huwig)
-;;
-;; 2014-02-27 - v0.0.2
-;; * Fix for buffers visiting files through symlinks (Issue #1, thanks Evgeniy Dolzhenko)
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'dired)
-(require 'thingatpt)
-(require 'url-util)
-(require 'url-parse)
-
-(defgroup git-link nil
-  "Get the GitHub/Bitbucket/GitLab URL for a buffer location"
-  :prefix "git-link-"
-  :link '(url-link :tag "Report a Bug" "https://github.com/sshaw/git-link/issues")
-  :link '(url-link :tag "Homepage" "https://github.com/sshaw/git-link")
-  :group 'convenience)
-
-(eval-when-compile
-  (defvar git-timemachine-revision))    ;; silence reference to free variable warning
-
-(defcustom git-link-default-remote nil
-  "Name of the remote to link to."
-  :type 'string
-  :group 'git-link)
-
-(defcustom git-link-default-branch nil
-  "Name of the branch to link to."
-  :type 'string
-  :group 'git-link)
-
-(defcustom git-link-open-in-browser nil
-  "If t also open the link via `browse-url'.  To use an alternate
-function set to that function's symbol."
-  :type '(choice boolean function)
-  :group 'git-link)
-
-(defcustom git-link-use-commit nil
-  "If non-nil use the latest commit's hash in the link instead of the branch name."
-  :type 'boolean
-  :group 'git-link)
-
-(defcustom git-link-use-single-line-number t
-  "If t a link to a single line will always contain the line number.
-If nil line numbers will only be added when a selection contains
-more than 1 line.
-
-Note that `git-link' can exclude line numbers on a per invocation basis.
-See its docs."
-  :type 'boolean
-  :group 'git-link)
-
-(defcustom git-link-remote-alist
-  '(("git.sr.ht" git-link-sourcehut)
-    ("codeberg.org" git-link-codeberg)
-    ("github" git-link-github)
-    ("bitbucket" git-link-bitbucket)
-    ("gitorious" git-link-gitorious)
-    ("gitlab" git-link-gitlab)
-    ("git\\.\\(sv\\|savannah\\)\\.gnu\\.org" git-link-savannah)
-    ("googlesource.com" git-link-googlesource)
-    ("visualstudio\\|azure" git-link-azure)
-    ("sourcegraph" git-link-sourcegraph)
-    ("\\(amazonaws\\|amazon\\)\\.com" git-link-codecommit))
-  "Alist of host names and functions creating file links for those.
-Each element looks like (REGEXP FUNCTION) where REGEXP is used to
-match the remote's host name and FUNCTION is used to generate a link
-to the file on remote host.
-
-As an example, \"gitlab\" will match with both \"gitlab.com\" and
-\"gitlab.example.com\"."
-  :type '(alist :key-type string :value-type (group function))
-  :group 'git-link)
-
-(defcustom git-link-commit-remote-alist
-  '(("git.sr.ht" git-link-commit-github)
-    ("codeberg.org" git-link-commit-codeberg)
-    ("github" git-link-commit-github)
-    ("bitbucket" git-link-commit-bitbucket)
-    ("gitorious" git-link-commit-gitorious)
-    ("gitlab" git-link-commit-github)
-    ("git\\.\\(sv\\|savannah\\)\\.gnu\\.org" git-link-commit-savannah)
-    ("googlesource.com" git-link-commit-googlesource)
-    ("visualstudio\\|azure" git-link-commit-azure)
-    ("sourcegraph" git-link-commit-sourcegraph)
-    ("\\(amazonaws\\|amazon\\)\\.com" git-link-commit-codecommit))
-  "Alist of host names and functions creating commit links for those.
-Each element looks like (REGEXP FUNCTION) where REGEXP is used to
-match the remote's host name and FUNCTION is used to generate a link
-to the commit on remote host.
-
-As an example, \"gitlab\" will match with both \"gitlab.com\" and
-\"gitlab.example.com\"."
-  :type '(alist :key-type string :value-type (group function))
-  :group 'git-link)
-
-(defcustom git-link-homepage-remote-alist
-  '(("git.sr.ht" git-link-homepage-github)
-    ("github" git-link-homepage-github)
-    ("bitbucket" git-link-homepage-github)
-    ("gitorious" git-link-homepage-github)
-    ("gitlab" git-link-homepage-github)
-    ("git\\.\\(sv\\|savannah\\)\\.gnu\\.org" git-link-homepage-savannah)
-    ("googlesource.com" git-link-homepage-github)
-    ("visualstudio\\|azure" git-link-homepage-github)
-    ("sourcegraph" git-link-homepage-github)
-    ("\\(amazonaws\\|amazon\\)\\.com" git-link-homepage-codecommit))
-  "Alist of host names and functions creating homepage links for those.
-Each element looks like (REGEXP FUNCTION) where REGEXP is used to
-match the remote's host name and FUNCTION is used to generate a link
-to the commit on remote host.
-
-As an example, \"gitlab\" will match with both \"gitlab.com\" and
-\"gitlab.example.com\"."
-  :type '(alist :key-type string :value-type (group function))
-  :group 'git-link)
-
-(defcustom git-link-extensions-rendered-plain '("org" "md" "rst" "adoc" "markdown" "asciidoc")
-  "List of extensions that should be rendered in plain mode, systems like
-Github, Gitlab, etc show a rendered version by default, for these extensions
-we can prevent that behaviour."
-  :type 'list
-  :group 'git-link)
-
-(defun git-link--exec(&rest args)
-  (ignore-errors
-    (with-temp-buffer
-      (when (zerop (apply #'process-file "git" nil (current-buffer) nil args))
-        (goto-char (point-min))
-        (cl-loop until (eobp)
-                 collect (buffer-substring-no-properties
-                          (line-beginning-position)
-                          (line-end-position))
-                 do (forward-line 1))))))
-
-(defun git-link--get-config (name)
-  (car (git-link--exec "config" "--get" name)))
-
-(defun git-link--remotes ()
-  (git-link--exec "remote"))
-
-(defun git-link--last-commit ()
-  (car (git-link--exec "--no-pager" "log" "-n1" "--pretty=format:%H")))
-
-(defvar magit-buffer-revision)
-
-(defun git-link--commit ()
-  (cond
-   ((git-link--using-git-timemachine)
-    (car git-timemachine-revision))
-   ((git-link--using-magit-blob-mode)
-    magit-buffer-revision)
-   (t (git-link--last-commit))))
-
-(defun git-link--current-branch ()
-  (car (git-link--exec "symbolic-ref" "--short" "HEAD")))
-
-(defun git-link--repo-root ()
-  (let ((dir (car (git-link--exec "rev-parse" "--show-toplevel"))))
-    (if (file-remote-p default-directory)
-       (concat (file-remote-p default-directory) dir)
-      dir)))
-
-(defun git-link--remote-url (name)
-  (car (git-link--exec "remote" "get-url" name)))
-
-(defun git-link--branch-remote (branch)
-  (git-link--get-config (format "branch.%s.remote" branch)))
-
-(declare-function magit-rev-branch "ext:magit-git")
-
-(defun git-link--branch ()
-  (or (git-link--get-config "git-link.branch")
-      git-link-default-branch
-      (when (git-link--using-magit-blob-mode)
-        (magit-rev-branch magit-buffer-revision))
-      (git-link--current-branch)))
-
-(defun git-link--remote ()
-  (let* ((branch (git-link--current-branch))
-        (remote (or (git-link--get-config "git-link.remote")
-                    git-link-default-remote
-                    (git-link--branch-remote branch))))
-
-    ;; Git defaults to "." if the branch has no remote.
-    ;; If the branch has no remote we try master's, which may be set.
-    (if (or (null remote)
-           (and (string= remote ".")
-                (not (string= branch "master"))))
-       (setq remote (git-link--branch-remote "master")))
-
-    (if (or (null remote) (string= remote "."))
-       "origin"
-      remote)))
-
-(defun git-link--handler (alist str)
-  "For an ALIST whose `car' (a regexp) matches STR, return cadr.
-
-The ALIST consists of (REGEXP FN) list elements.
-Valid ALISTs are `git-link-remote-alist',`git-link-commit-remote-alist'.
-
-For the first ALIST element whose REGEXP matches with STR, FN is
-returned.
-
-Return nil,
-- if STR does not match with REGEXP in any of the elements of ALIST, or
-- if STR is not a string"
-  (when (stringp str)
-    (cadr (cl-find-if (lambda (lst)
-                        (string-match-p (car lst) str))
-                      alist))))
-
-(defun git-link--parse-vc-revision (filename)
-"If FILENAME appears to be from `vc-revision-other-window'
-return (FILENAME . REVISION) otherwise nil."
-  (when (and (string-match "\\(.+\\)\\.~\\([^~]+\\)~$" filename)
-             (file-exists-p (match-string 1 filename)))
-    (cons (match-string 1 filename)
-          (match-string 2 filename))))
-
-(defvar magit-buffer-file-name)
-
-(defun git-link--relative-filename ()
-  (let* ((filename (buffer-file-name (buffer-base-buffer)))
-        (dir      (git-link--repo-root)))
-
-    (when (null filename)
-      (cond
-       ((eq major-mode 'dired-mode)
-        (setq filename (dired-file-name-at-point)))
-       ((git-link--using-magit-blob-mode)
-        (setq filename magit-buffer-file-name))
-       ((and (string-match-p "^magit-" (symbol-name major-mode))
-             (fboundp 'magit-file-at-point))
-        (setq filename (magit-file-at-point)))))
-
-    (if (and dir filename
-             ;; Make sure filename is not above dir, e.g. "/foo/repo-root/.."
-             (< (length dir) (length (file-truename filename))))
-       (substring (file-truename filename)
-                  (1+ (length dir))))))
-
-(defun git-link--parse-remote (url)
-  "Parse URL and return a list as (HOST DIR).  DIR has no leading slash or `git' extension."
-  (let (host path parsed)
-    (unless (string-match "^[a-zA-Z0-9]+://" url)
-      (setq url (concat "ssh://" url)))
-
-    (setq parsed (url-generic-parse-url url)
-          ;; Normalize path.
-          ;; If none, will be nil on Emacs < 25. Later versions return "".
-          path (or (car (url-path-and-query parsed)) "")
-          host (url-host parsed))
-
-    (when host
-      (when (and (not (string= "/" path))
-                 (not (string= ""  path)))
-        (setq path (substring
-                    (if (string-match "\\.git\\'" path)
-                        (file-name-sans-extension path)
-                      path)
-                    1)))
-
-      ;; Fix-up scp style URLs.
-      ;; git@foo:UsEr/repo gives a host of foo:user
-      ;; We also need to preserve case so we take UsEr from the original url
-      (when (string-match ":" host)
-        (let ((parts (split-string host ":" t))
-              (case-fold-search t))
-          (string-match (concat (car parts) ":\\(" (cadr parts) "\\)/") url)
-          (setq host (car parts)
-                path (concat (match-string 1 url) "/" path))))
-
-      ;; Fix-up Azure SSH URLs
-      (when (string= "ssh.dev.azure.com" host)
-        (setq host "dev.azure.com")
-        (setq path (replace-regexp-in-string
-                    "v3/\\([^/]+\\)/\\([^/]+\\)/\\([^/]+\\)"
-                    "\\1/\\2/_git/\\3"
-                    path)))
-      (when (string= "vs-ssh.visualstudio.com" host)
-        (setq host (concat (url-user parsed) ".visualstudio.com"))
-        (setq path (replace-regexp-in-string
-                    (concat "^v3/" (url-user parsed) "/\\([^/]+\\)/")
-                    "\\1/_git/"
-                    path)))
-
-      ;; For Savannah
-      (when (string= "git.savannah.gnu.org" host)
-        (cond
-         ((string-match "\\`git/" path)
-          (setq path (substring path 4)))
-         ((string-match "\\`srv/git/" path)
-          (setq path (substring path 8)))))
-
-      ;; For AWS CodeCommit
-      (when (string-match "git-codecommit\\.\\(.*\\)\\.amazonaws.com" host)
-        (let* ((matchp (string-match "\\([^\\.]*\\)\\.\\([^\\.]*\\)" host))
-               (region (when matchp
-                         (match-string 2 host)))
-               (domainname ".console.aws.amazon.com"))
-          (when region
-            (setq host (concat region domainname))))
-        (when (string-match "v1/repos/" path)
-          (setq path (concat "codesuite/codecommit/repositories/"
-                             (substring path 9)))))
-
-      (list host path))))
-
-(defun git-link--using-git-timemachine ()
-  (and (boundp 'git-timemachine-revision)
-       git-timemachine-revision))
-
-(defun git-link--using-magit-blob-mode ()
-  (bound-and-true-p magit-blob-mode))
-
-(defun git-link--read-remote ()
-  (let ((remotes (git-link--remotes))
-       (current (git-link--remote)))
-    (completing-read "Remote: "
-                    remotes
-                    nil
-                    t
-                    ""
-                    nil
-                    (if (member current remotes)
-                        current
-                      (car remotes)))))
-
-(defun git-link--get-region ()
-  (save-restriction
-    (widen)
-    (save-excursion
-      (let* ((use-region (use-region-p))
-             (start (when use-region (region-beginning)))
-             (end   (when use-region (region-end)))
-             (line-start (line-number-at-pos start))
-             line-end)
-        (when use-region
-          ;; Avoid adding an extra blank line to the selection.
-          ;; This happens when point or mark is at the start of the next line.
-          ;;
-          ;; When selection is from bottom to top, exchange point and mark
-          ;; so that the `point' and `(region-end)' are the same.
-          (when (< (point) (mark))
-            (exchange-point-and-mark))
-          (when (= end (line-beginning-position))
-            ;; Go up and avoid the blank line
-            (setq end (1- end)))
-          (setq line-end (line-number-at-pos end))
-          (when (<= line-end line-start)
-            (setq line-end nil)))
-        (list line-start line-end)))))
-
-(defun git-link--new (link)
-  (kill-new link)
-  ;; prevent URL escapes from being interpreted as format strings
-  (message (replace-regexp-in-string "%" "%%" link t t))
-  (setq deactivate-mark t)
-  (when git-link-open-in-browser
-    (if (fboundp git-link-open-in-browser)
-        (funcall git-link-open-in-browser link)
-      (browse-url link))))
-
-(defun git-link-codeberg (hostname dirname filename branch commit start end)
-    (format "https://%s/%s/src/%s/%s"
-           hostname
-           dirname
-           (or branch commit)
-            (concat filename
-                    (when start
-                      (concat "#"
-                              (if end
-                                  (format "L%s-L%s" start end)
-                                (format "L%s" start)))))))
-
-(defun git-link-gitlab (hostname dirname filename branch commit start end)
-  (format "https://%s/%s/blob/%s/%s"
-         hostname
-         dirname
-         (or branch commit)
-          (concat filename
-                  (when start
-                    (concat "#"
-                            (if end
-                                (format "L%s-%s" start end)
-                              (format "L%s" start)))))))
-
-(defun git-link-github (hostname dirname filename branch commit start end)
-  (format "https://%s/%s/blob/%s/%s"
-         hostname
-         dirname
-         (or branch commit)
-         (concat filename
-                  (when start
-                    (concat (if (git-link--should-render-plain filename) "?plain=1#" "#")
-                            (if end
-                                (format "L%s-L%s" start end)
-                              (format "L%s" start)))))))
-
-(defun git-link-googlesource (hostname dirname filename branch commit start end)
-  (format "https://%s/%s/+/%s/%s"
-         hostname
-         dirname
-         (or branch commit)
-         (concat filename
-                  (when start
-                    (format "#%s" start)
-                    ))))
-
-(defun git-link-azure (hostname dirname filename branch commit start end)
-  (format "https://%s/%s?path=%%2F%s&version=%s&line=%s&lineEnd=%s&lineStartColumn=1&lineEndColumn=9999&lineStyle=plain"
-         hostname
-         dirname
-      filename
-      (concat "G" (if branch "B" "C") (or branch commit))
-      (or start "")
-      (or end start "")))
-
-(defun git-link-sourcehut (hostname dirname filename branch commit start end)
-  (format "https://%s/%s/tree/%s/%s"
-         hostname
-         dirname
-         (or branch commit)
-         (concat filename
-                  (when start
-                    (concat "#"
-                            (if end
-                                (format "L%s-%s" start end)
-                              (format "L%s" start)))))))
-
-
-(defun git-link-commit-github (hostname dirname commit)
-  (format "https://%s/%s/commit/%s"
-         hostname
-         dirname
-         commit))
-
-(defun git-link-commit-googlesource (hostname dirname commit)
-  (format "https://%s/%s/+/%s"
-         hostname
-         dirname
-          commit))
-
-(defun git-link-commit-azure (hostname dirname commit)
- (format "https://%s/%s/commit/%s"
-         hostname
-         dirname
-
-      ;; Azure only supports full 32 characters SHA
-      (car (git-link--exec "rev-parse" commit))))
-
-(defun git-link-commit-codeberg (hostname dirname commit)
-    (format "https://%s/%s/commit/%s"
-           hostname
-           dirname
-           commit))
-
-(defun git-link-gitorious (hostname dirname filename _branch commit start _end)
-  (format "https://%s/%s/source/%s:%s#L%s"
-         hostname
-         dirname
-         commit
-         filename
-         start))
-
-(defun git-link-commit-gitorious (hostname dirname commit)
-  (format "https://%s/%s/commit/%s"
-         hostname
-         dirname
-         commit))
-
-(defun git-link-bitbucket (hostname dirname filename _branch commit start end)
-  ;; ?at=branch-name
-  (format "https://%s/%s/src/%s/%s"
-          hostname
-          dirname
-          commit
-          (if (string= "" (file-name-nondirectory filename))
-              filename
-            (concat filename
-                    "#"
-                    (file-name-nondirectory filename)
-                    (when start
-                      (if end
-                          (format "-%s:%s" start end)
-                        (format "-%s" start)))))))
-
-(defun git-link-commit-bitbucket (hostname dirname commit)
-  ;; ?at=branch-name
-  (format "https://%s/%s/commits/%s"
-         hostname
-         dirname
-         commit))
-
-(defun git-link-cgit (hostname dirname filename branch commit start _end)
-  (format "https://%s/%s/tree/%s?h=%s"
-         hostname
-         dirname
-          filename
-          (concat
-           (or branch commit)
-           (when start
-             (concat "#" (format "n%s" start))))))
-
-(defun git-link-commit-cgit (hostname dirname commit)
-  (format "https://%s/%s/commit/?id=%s"
-         hostname
-          dirname
-         commit))
-
-(defun git-link-savannah (hostname dirname filename branch commit start end)
-  (git-link-cgit hostname
-                 (format "cgit/%s.git" dirname) ; unique to Savannah
-                 filename
-                 branch
-                 commit
-                 start
-                 end))
-
-(defun git-link-commit-savannah (hostname dirname commit)
-  (git-link-commit-cgit hostname
-                        (format "cgit/%s.git" dirname) ; also unique to Savannah
-                        commit))
-
-(defun git-link-sourcegraph (hostname dirname filename branch commit start end)
-  (let ((line-or-range (cond ((and start end) (format "#L%s-%s" start end))
-                             (start (format "#L%s" start))
-                             (t "")))
-        (branch-or-commit (or branch commit))
-        (dir-file-name (directory-file-name dirname)))
-    (format "https://%s/%s@%s/-/blob/%s%s"
-            hostname
-            dir-file-name
-            branch-or-commit
-            filename
-            line-or-range)))
-
-(defun git-link-commit-sourcegraph (hostname dirname commit)
-  (let ((dir-file-name (directory-file-name dirname)))
-    (format "https://%s/%s/-/commit/%s"
-            hostname
-            dir-file-name
-            commit)))
-
-(defun git-link-homepage-github (hostname dirname)
-  (format "https://%s/%s"
-         hostname
-         dirname))
-
-(defun git-link-homepage-savannah (hostname dirname)
-  (format "https://%s/cgit/%s.git/"
-         hostname
-         dirname))
-
-(defun git-link-codecommit (hostname
-                            dirname
-                            filename
-                            branch
-                            commit
-                            start
-                            end)
-  (format "https://%s/%s/browse/refs/heads/%s/--/%s"
-          hostname
-          dirname
-          (or branch commit)
-          (concat filename
-                  (when start
-                    (format "?lines=%s-%s"
-                            start
-                            (or end start))))))
-
-(defun git-link-commit-codecommit (hostname dirname commit)
-  (format "https://%s/%s/commit/%s" hostname dirname commit))
-
-(defun git-link-homepage-codecommit (hostname dirname)
-  (format "https://%s/%s/browse" hostname dirname))
-
-(define-obsolete-function-alias
-  'git-link-homepage-svannah 'git-link-homepage-savannah "cf947f9")
-
-(defun git-link--select-remote ()
-  (if (equal '(4) current-prefix-arg)
-      (git-link--read-remote)
-    (git-link--remote)))
-
-(defun git-link--should-render-plain (filename)
-  "Check if the extension of the given filename belongs
-to the list of extensions which generated link should be
-shown as a plain file"
-  (let ((extension (or (file-name-extension filename) "")))
-    (member (downcase extension) git-link-extensions-rendered-plain)))
-
-;;;###autoload
-(defun git-link (remote start end)
-  "Create a URL representing the current buffer's location in its
-GitHub/Bitbucket/GitLab/... repository at the current line number
-or active region. The URL will be added to the kill ring.  If
-`git-link-open-in-browser' is non-nil also call `browse-url'.
-
-With a prefix argument of - generate a link without line number(s).
-Also see `git-link-use-single-line-number'.
-
-With a single prefix argument prompt for the remote's name.
-Defaults to \"origin\".
-
-With a double prefix argument invert the value of
-`git-link-use-commit'."
-  (interactive
-   (if (equal '- current-prefix-arg)
-       (list (git-link--remote) nil nil)
-     (let* ((remote (git-link--select-remote))
-            (region (when (or buffer-file-name (git-link--using-magit-blob-mode))
-                      (git-link--get-region))))
-
-       (if (and (null git-link-use-single-line-number) (null (cadr region)))
-           (list remote nil nil)
-         (list remote (car region) (cadr region))))))
-
-  (let (filename branch commit handler remote-info (remote-url (git-link--remote-url remote)))
-    (if (null remote-url)
-        (message "Remote `%s' not found" remote)
-
-      (setq remote-info (git-link--parse-remote remote-url)
-            filename    (git-link--relative-filename)
-            branch      (git-link--branch)
-            commit      (git-link--commit)
-            handler     (git-link--handler git-link-remote-alist (car remote-info)))
-
-      (cond ((null filename)
-             (message "Can't figure out what to link to"))
-            ((null (car remote-info))
-             (message "Remote `%s' contains an unsupported URL" remote))
-            ((not (functionp handler))
-             (message "No handler found for %s" (car remote-info)))
-            ;; TODO: null ret val
-            (t
-             (let ((vc-revison (git-link--parse-vc-revision filename)))
-               (when vc-revison
-                 (setq filename (car vc-revison)
-                       commit   (cdr vc-revison)))
-
-               (git-link--new
-                (funcall handler
-                         (car remote-info)
-                         (cadr remote-info)
-                         (url-hexify-string filename (url--allowed-chars (cons ?/ url-unreserved-chars)))
-                         (if (or (git-link--using-git-timemachine)
-                                 (git-link--using-magit-blob-mode)
-                                 vc-revison
-                                 (if (equal '(16) current-prefix-arg)
-                                     (not git-link-use-commit)
-                                   git-link-use-commit))
-                             nil
-                           (url-hexify-string branch))
-                         commit
-                         start
-                         end))))))))
-
-;;;###autoload
-(defun git-link-commit (remote)
-  "Create a URL representing the commit for the hash under point
-in the current buffer's GitHub/Bitbucket/GitLab/...
-repository. The URL will be added to the kill ring.
-
-With a prefix argument prompt for the remote's name.
-Defaults to \"origin\"."
-
-  (interactive (list (git-link--select-remote)))
-  (let* (commit handler remote-info (remote-url (git-link--remote-url remote)))
-    (if (null remote-url)
-        (message "Remote `%s' not found" remote)
-
-      (setq remote-info (git-link--parse-remote remote-url)
-            commit (word-at-point)
-            handler (git-link--handler git-link-commit-remote-alist (car remote-info)))
-
-      (cond ((null (car remote-info))
-             (message "Remote `%s' contains an unsupported URL" remote))
-            ((not (string-match-p "[a-fA-F0-9]\\{7,40\\}" (or commit "")))
-             (message "Point is not on a commit hash"))
-            ((not (functionp handler))
-             (message "No handler for %s" (car remote-info)))
-            ;; null ret val
-            ((git-link--new
-              (funcall handler
-                       (car remote-info)
-                       (cadr remote-info)
-                       (substring-no-properties commit))))))))
-
-;;;###autoload
-(defun git-link-homepage (remote)
-  "Create a URL representing the homepage of the current
-buffer's GitHub/Bitbucket/GitLab/... repository. The
-URL will be added to the kill ring.
-
-With a prefix argument prompt for the remote's name.
-Defaults to \"origin\"."
-
-  (interactive (list (git-link--select-remote)))
-  (let* (handler remote-info (remote-url (git-link--remote-url remote)))
-    (if (null remote-url)
-        (message "Remote `%s' not found" remote)
-
-      (setq remote-info (git-link--parse-remote remote-url)
-            handler (git-link--handler git-link-homepage-remote-alist (car remote-info)))
-
-      (cond ((null (car remote-info))
-             (message "Remote `%s' contains an unsupported URL" remote))
-            ((not (functionp handler))
-             (message "No handler for %s" (car remote-info)))
-            ;; null ret val
-            ((git-link--new
-              (funcall handler
-                       (car remote-info)
-                       (cadr remote-info))))))))
-
-(provide 'git-link)
-;;; git-link.el ends here
diff --git a/elpa/git-link-20230518.204/git-link-autoloads.el b/elpa/git-link-20230518.204/git-link-autoloads.el
new file mode 100644 (file)
index 0000000..e3ae51b
--- /dev/null
@@ -0,0 +1,63 @@
+;;; git-link-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "git-link" "git-link.el" (0 0 0 0))
+;;; Generated autoloads from git-link.el
+
+(autoload 'git-link "git-link" "\
+Create a URL representing the current buffer's location in its
+GitHub/Bitbucket/GitLab/... repository at the current line number
+or active region. The URL will be added to the kill ring.  If
+`git-link-open-in-browser' is non-nil also call `browse-url'.
+
+With a prefix argument of - generate a link without line number(s).
+Also see `git-link-use-single-line-number'.
+
+With a single prefix argument prompt for the remote's name.
+Defaults to \"origin\".
+
+With a double prefix argument invert the value of
+`git-link-use-commit'.
+
+\(fn REMOTE START END)" t nil)
+
+(autoload 'git-link-commit "git-link" "\
+Create a URL representing the commit for the hash under point
+in the current buffer's GitHub/Bitbucket/GitLab/...
+repository. The URL will be added to the kill ring.
+
+With a prefix argument prompt for the remote's name.
+Defaults to \"origin\".
+
+\(fn REMOTE)" t nil)
+
+(autoload 'git-link-homepage "git-link" "\
+Create a URL representing the homepage of the current
+buffer's GitHub/Bitbucket/GitLab/... repository. The
+URL will be added to the kill ring.
+
+With a prefix argument prompt for the remote's name.
+Defaults to \"origin\".
+
+\(fn REMOTE)" t nil)
+
+(register-definition-prefixes "git-link" '("git-link-"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("git-link-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; git-link-autoloads.el ends here
diff --git a/elpa/git-link-20230518.204/git-link-pkg.el b/elpa/git-link-20230518.204/git-link-pkg.el
new file mode 100644 (file)
index 0000000..fac7e7e
--- /dev/null
@@ -0,0 +1,14 @@
+(define-package "git-link" "20230518.204" "Get the GitHub/Bitbucket/GitLab URL for a buffer location"
+  '((emacs "24.3"))
+  :commit "aded95807f277f30e1607313bdf9ac9a016a2305" :authors
+  '(("Skye Shaw" . "skye.shawNOSPAMgmail.com"))
+  :maintainers
+  '(("Skye Shaw" . "skye.shawNOSPAMgmail.com"))
+  :maintainer
+  '("Skye Shaw" . "skye.shawNOSPAMgmail.com")
+  :keywords
+  '("git" "vc" "github" "bitbucket" "gitlab" "sourcehut" "aws" "azure" "convenience")
+  :url "http://github.com/sshaw/git-link")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/git-link-20230518.204/git-link.el b/elpa/git-link-20230518.204/git-link.el
new file mode 100644 (file)
index 0000000..d5a6d6d
--- /dev/null
@@ -0,0 +1,888 @@
+;;; git-link.el --- Get the GitHub/Bitbucket/GitLab URL for a buffer location -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013-2022 Skye Shaw and others
+;; Author: Skye Shaw <skye.shawNOSPAMgmail.com>
+;; Version: 0.9.0
+;; Keywords: git, vc, github, bitbucket, gitlab, sourcehut, aws, azure, convenience
+;; URL: http://github.com/sshaw/git-link
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Create URLs for files and commits in GitHub/Bitbucket/GitLab/...
+;; repositories.  `git-link' returns the URL for the current buffer's file
+;; location at the current line number or active region.  `git-link-commit'
+;; returns the URL for a commit.  URLs are added to the kill ring.
+;;
+;; With a prefix argument prompt for the remote's name.  Defaults to "origin".
+
+;;; Change Log:
+
+;; 2023-02-15 - v0.9.0
+;; * Add support for GoogleSource (thanks Peter Becich)
+;; * Add plain=1 to force showing a non rendered GitHub links (thanks Erick Navarro)
+;; * Add prefix arg to override git-link-use-commit when calling git-link (thanks Nacho Barrientos)
+;; * Fix git-link-homepage for Bitbucket (Issue #97 thanks Sibi Prabakaran)
+;; * Fix the Codeberg links to line ranges (Issue #109 thanks Wojciech Siewierski)
+;;
+;; 2022-02-17 - v0.8.6
+;; * Fix URL escaping of pathnames on Emacs < 27 (Issue #93 thanks David Ongaro)
+;;
+;; 2022-02-06 - v0.8.5
+;; * URL escape pathnames (thanks David Ongaro)
+;; * Mark misspelled Savannah functions as obsolete (thanks Hendursaga)
+;; * Add support for AWS CodeCommit (thanks Ram Krishnan)
+;; * Add support for cgit (thanks Hendursaga)
+;;
+;; 2020-01-20 - v0.8.4
+;; * Add support for Codeberg (thanks Jeremy Friesen)
+;; * Add git-link-homepage-remote-alist (thanks Wim Van Deun)
+;;
+;; 2020-01-20 - v0.8.3
+;; * Add support for Savannah
+;;
+;; 2020-12-14 - v0.8.2
+;; * Fix sourcehut URL, don't link to raw version (Issue #77)
+;; * Fix sourcehut multi-line URLs
+;;
+;; 2020-11-23 - v0.8.1
+;; * Fix URL casing (Issue #57)
+;; * Fix byte-compile warnings (Issue #75 thanks Brian Leung)
+;;
+;; 2020-07-21 - v0.8.0
+;; * Add `-' prefix argument to git-link to generate links without line numbers
+;; * Add git-link-use-single-line-number
+;; * Fix sourcehut's git-link handler
+;;
+;; 2020-03-31 - v0.7.6
+;; * Adapt to changes in Azure interface (Issue #65, thanks Roey Darwish Dror)
+;;
+;; 2019-08-28 - v0.7.5
+;; * Add support for Azure DevOps (Issue #62, thanks Roey Darwish Dror)
+;;
+;; 2019-08-16 - v0.7.4
+;; * Add support for Magit-Blob buffers (Issue #61, thanks Miciah Dashiel Butler Masters)
+;;
+;; 2019-03-09 - v0.7.3
+;; * Add support for sourcehut
+;;
+;; 2018-10-30 - v0.7.2
+;; * Fix suffix stripping on remote path only if it ends in .git (Issue #58, thanks Marko Crnic)
+;;
+;; 2018-07-08 - v0.7.1
+;; * Add support for vc-revision-other-window files (Issue #54)
+;;
+;; 2018-06-07 - v0.7.0
+;; * Add support for Tramp (Issue #49, thanks Jürgen Hötzel)
+;; * Fix various compiler warnings
+;; * Fix differences between url-path-and-query across Emacs versions
+;; * Require Emacs 24.3
+;;
+;; 2018-04-23 - v0.6.0
+;; * Fix parsing of remotes with auth info (Issue #51)
+;; * Removed remote regex in favor of url-parse
+;;
+;; 2017-06-03 - v0.5.1
+;; * Add support for more magit modes
+;;
+;; 2017-06-01 - v0.5.0
+;; * Add support for linking in dired and magit modes
+;; * Add support for defcustom
+;; * Change git-link-remote-regex to support more remote URL formats (Thanks Kaushal Modi)
+;; * Change git-link-remote-alist to use regex matching (Thanks Kaushal Modi)
+;; * Fix point on commit hash regex and support uppercase SHAs (Thanks Kaushal Modi!)
+;; * Fix git-link-commit message so that SHA text is displayed without properties
+;; * Enabled lexical-binding (Thanks Kaushal Modi!!)
+;;
+;; -- Note that v0.5.0 was released as "v0.5.0 (unreleased)"
+;;
+;; 2016-10-19 - v0.4.5
+;; * Fix for branches containing reserved URLs characters (Issue #36)
+;;
+;; 2016-09-11 - v0.4.4
+;; * Added support for git-link-homepage
+;;
+;; 2016-08-13 - v0.4.3
+;; * Added support for git-timemachine (Issue #22, thanks Diego Berrocal)
+;;
+;; 2016-08-09 - v0.4.2
+;; * Fix for URLs with ports (Issue #32)
+;;
+;; 2016-04-01 - v0.4.1
+;; * Better handling for branches that have no explicit remote
+;; * Better error messages
+;;
+;; 2016-02-16 - v0.4.0
+;; * Try branch's tracking remote when other branch settings are not specified
+;; * git-link-default-remote now defaults to nil
+;;
+;; 2015-09-21 - v0.3.0
+;; * Support for setting branch and remote names via `git config`
+;; * Added git-link-default-branch
+;; * Removed some functions, use emacs "private" convention for others
+;;
+;; 2015-09-12 - v0.2.2
+;; * Support for BitBucket's multiline format
+;;
+;; 2015-07-25 - v0.2.1
+;; * Fix for BitBucket's new URL format (Thanks Ev Dolzhenko)
+;; * Fix for GitLab's multiline format (Thanks Enrico Carlesso)
+;;
+;; 2015-06-05 - v0.2.0
+;; * Deactivate mark after killing the link (Thanks Kaushal Modi)
+;; * Support for GitLab (Thanks Swaroop C H)
+;; * Use completing-read when prompting for remotes (Thanks Andrew Gwozdziewycz)
+;; * Display URL in minibuffer when adding to kill ring (Thanks Andrew Gwozdziewycz)
+;; * Added git-link-use-commit variable (Thanks Kaushal Modi)
+;; * Fix for displaying link in minibuffer when interprogram-cut-function is set (Thanks Ric Lister)
+;; * Fix to ignore point at beginning of line in regions (Thanks Kaushal Modi)
+;; * Fix for narrow-to-region (Bug #10, thanks Andrew Gwozdziewycz)
+;; * Fix to use remote hostname when constructing link URLs (Thanks David Hull)
+;;
+;; 2015-02-05 - v0.1.0
+;; * Added git-link-commit (Thanks Ryan Barrett)
+;; * Added git-link-open-in-browser variable (Thanks Ryan Barrett)
+;; * Use call-process instead of shell-command-to-string
+;; * Use --short option when calling symbolic-ref (Thanks Steven Huwig)
+;;
+;; 2014-02-27 - v0.0.2
+;; * Fix for buffers visiting files through symlinks (Issue #1, thanks Evgeniy Dolzhenko)
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dired)
+(require 'thingatpt)
+(require 'url-util)
+(require 'url-parse)
+
+(defgroup git-link nil
+  "Get the GitHub/Bitbucket/GitLab URL for a buffer location"
+  :prefix "git-link-"
+  :link '(url-link :tag "Report a Bug" "https://github.com/sshaw/git-link/issues")
+  :link '(url-link :tag "Homepage" "https://github.com/sshaw/git-link")
+  :group 'convenience)
+
+(eval-when-compile
+  (defvar git-timemachine-revision))    ;; silence reference to free variable warning
+
+(defcustom git-link-default-remote nil
+  "Name of the remote to link to."
+  :type 'string
+  :group 'git-link)
+
+(defcustom git-link-default-branch nil
+  "Name of the branch to link to."
+  :type 'string
+  :group 'git-link)
+
+(defcustom git-link-open-in-browser nil
+  "If t also open the link via `browse-url'.  To use an alternate
+function set to that function's symbol."
+  :type '(choice boolean function)
+  :group 'git-link)
+
+(defcustom git-link-use-commit nil
+  "If non-nil use the latest commit's hash in the link instead of the branch name."
+  :type 'boolean
+  :group 'git-link)
+
+(defcustom git-link-use-single-line-number t
+  "If t a link to a single line will always contain the line number.
+If nil line numbers will only be added when a selection contains
+more than 1 line.
+
+Note that `git-link' can exclude line numbers on a per invocation basis.
+See its docs."
+  :type 'boolean
+  :group 'git-link)
+
+(defcustom git-link-remote-alist
+  '(("git.sr.ht" git-link-sourcehut)
+    ("codeberg.org" git-link-codeberg)
+    ("github" git-link-github)
+    ("bitbucket" git-link-bitbucket)
+    ("gitorious" git-link-gitorious)
+    ("gitlab" git-link-gitlab)
+    ("git\\.\\(sv\\|savannah\\)\\.gnu\\.org" git-link-savannah)
+    ("googlesource.com" git-link-googlesource)
+    ("visualstudio\\|azure" git-link-azure)
+    ("sourcegraph" git-link-sourcegraph)
+    ("\\(amazonaws\\|amazon\\)\\.com" git-link-codecommit))
+  "Alist of host names and functions creating file links for those.
+Each element looks like (REGEXP FUNCTION) where REGEXP is used to
+match the remote's host name and FUNCTION is used to generate a link
+to the file on remote host.
+
+As an example, \"gitlab\" will match with both \"gitlab.com\" and
+\"gitlab.example.com\"."
+  :type '(alist :key-type string :value-type (group function))
+  :group 'git-link)
+
+(defcustom git-link-commit-remote-alist
+  '(("git.sr.ht" git-link-commit-github)
+    ("codeberg.org" git-link-commit-codeberg)
+    ("github" git-link-commit-github)
+    ("bitbucket" git-link-commit-bitbucket)
+    ("gitorious" git-link-commit-gitorious)
+    ("gitlab" git-link-commit-gitlab)
+    ("git\\.\\(sv\\|savannah\\)\\.gnu\\.org" git-link-commit-savannah)
+    ("googlesource.com" git-link-commit-googlesource)
+    ("visualstudio\\|azure" git-link-commit-azure)
+    ("sourcegraph" git-link-commit-sourcegraph)
+    ("\\(amazonaws\\|amazon\\)\\.com" git-link-commit-codecommit))
+  "Alist of host names and functions creating commit links for those.
+Each element looks like (REGEXP FUNCTION) where REGEXP is used to
+match the remote's host name and FUNCTION is used to generate a link
+to the commit on remote host.
+
+As an example, \"gitlab\" will match with both \"gitlab.com\" and
+\"gitlab.example.com\"."
+  :type '(alist :key-type string :value-type (group function))
+  :group 'git-link)
+
+(defcustom git-link-homepage-remote-alist
+  '(("git.sr.ht" git-link-homepage-github)
+    ("github" git-link-homepage-github)
+    ("bitbucket" git-link-homepage-github)
+    ("gitorious" git-link-homepage-github)
+    ("gitlab" git-link-homepage-github)
+    ("git\\.\\(sv\\|savannah\\)\\.gnu\\.org" git-link-homepage-savannah)
+    ("googlesource.com" git-link-homepage-github)
+    ("visualstudio\\|azure" git-link-homepage-github)
+    ("sourcegraph" git-link-homepage-github)
+    ("\\(amazonaws\\|amazon\\)\\.com" git-link-homepage-codecommit))
+  "Alist of host names and functions creating homepage links for those.
+Each element looks like (REGEXP FUNCTION) where REGEXP is used to
+match the remote's host name and FUNCTION is used to generate a link
+to the commit on remote host.
+
+As an example, \"gitlab\" will match with both \"gitlab.com\" and
+\"gitlab.example.com\"."
+  :type '(alist :key-type string :value-type (group function))
+  :group 'git-link)
+
+(defcustom git-link-extensions-rendered-plain '("org" "md" "rst" "adoc" "markdown" "asciidoc")
+  "List of extensions that should be rendered in plain mode, systems like
+Github, Gitlab, etc show a rendered version by default, for these extensions
+we can prevent that behaviour."
+  :type 'list
+  :group 'git-link)
+
+(defun git-link--exec(&rest args)
+  (ignore-errors
+    (with-temp-buffer
+      (when (zerop (apply #'process-file "git" nil (current-buffer) nil args))
+        (goto-char (point-min))
+        (cl-loop until (eobp)
+                 collect (buffer-substring-no-properties
+                          (line-beginning-position)
+                          (line-end-position))
+                 do (forward-line 1))))))
+
+(defun git-link--get-config (name)
+  (car (git-link--exec "config" "--get" name)))
+
+(defun git-link--remotes ()
+  (git-link--exec "remote"))
+
+(defun git-link--last-commit ()
+  (car (git-link--exec "--no-pager" "log" "-n1" "--pretty=format:%H")))
+
+(defvar magit-buffer-revision)
+
+(defun git-link--commit ()
+  (cond
+   ((git-link--using-git-timemachine)
+    (car git-timemachine-revision))
+   ((git-link--using-magit-blob-mode)
+    magit-buffer-revision)
+   (t (git-link--last-commit))))
+
+(defun git-link--current-branch ()
+  (car (git-link--exec "symbolic-ref" "--short" "HEAD")))
+
+(defun git-link--repo-root ()
+  (let ((dir (car (git-link--exec "rev-parse" "--show-toplevel"))))
+    (if (file-remote-p default-directory)
+       (concat (file-remote-p default-directory) dir)
+      dir)))
+
+(defun git-link--remote-url (name)
+  (car (git-link--exec "remote" "get-url" name)))
+
+(defun git-link--branch-remote (branch)
+  (git-link--get-config (format "branch.%s.remote" branch)))
+
+(declare-function magit-rev-branch "ext:magit-git")
+
+(defun git-link--branch ()
+  (or (git-link--get-config "git-link.branch")
+      git-link-default-branch
+      (when (git-link--using-magit-blob-mode)
+        (magit-rev-branch magit-buffer-revision))
+      (git-link--current-branch)))
+
+(defun git-link--remote ()
+  (let* ((branch (git-link--current-branch))
+        (remote (or (git-link--get-config "git-link.remote")
+                    git-link-default-remote
+                    (git-link--branch-remote branch))))
+
+    ;; Git defaults to "." if the branch has no remote.
+    ;; If the branch has no remote we try master's, which may be set.
+    (if (or (null remote)
+           (and (string= remote ".")
+                (not (string= branch "master"))))
+       (setq remote (git-link--branch-remote "master")))
+
+    (if (or (null remote) (string= remote "."))
+       "origin"
+      remote)))
+
+(defun git-link--handler (alist str)
+  "For an ALIST whose `car' (a regexp) matches STR, return cadr.
+
+The ALIST consists of (REGEXP FN) list elements.
+Valid ALISTs are `git-link-remote-alist',`git-link-commit-remote-alist'.
+
+For the first ALIST element whose REGEXP matches with STR, FN is
+returned.
+
+Return nil,
+- if STR does not match with REGEXP in any of the elements of ALIST, or
+- if STR is not a string"
+  (when (stringp str)
+    (cadr (cl-find-if (lambda (lst)
+                        (string-match-p (car lst) str))
+                      alist))))
+
+(defun git-link--parse-vc-revision (filename)
+"If FILENAME appears to be from `vc-revision-other-window'
+return (FILENAME . REVISION) otherwise nil."
+  (when (and (string-match "\\(.+\\)\\.~\\([^~]+\\)~$" filename)
+             (file-exists-p (match-string 1 filename)))
+    (cons (match-string 1 filename)
+          (match-string 2 filename))))
+
+(defvar magit-buffer-file-name)
+
+(defun git-link--relative-filename ()
+  (let* ((filename (buffer-file-name (buffer-base-buffer)))
+        (dir      (git-link--repo-root)))
+
+    (when (null filename)
+      (cond
+       ((eq major-mode 'dired-mode)
+        (setq filename (dired-file-name-at-point)))
+       ((git-link--using-magit-blob-mode)
+        (setq filename magit-buffer-file-name))
+       ((and (string-match-p "^magit-" (symbol-name major-mode))
+             (fboundp 'magit-file-at-point))
+        (setq filename (magit-file-at-point)))))
+
+    (if (and dir filename
+             ;; Make sure filename is not above dir, e.g. "/foo/repo-root/.."
+             (< (length dir) (length (file-truename filename))))
+       (substring (file-truename filename)
+                  (1+ (length dir))))))
+
+(defun git-link--parse-remote (url)
+  "Parse URL and return a list as (HOST DIR).  DIR has no leading slash or `git' extension."
+  (let (host path parsed)
+    (unless (string-match "^[a-zA-Z0-9]+://" url)
+      (setq url (concat "ssh://" url)))
+
+    (setq parsed (url-generic-parse-url url)
+          ;; Normalize path.
+          ;; If none, will be nil on Emacs < 25. Later versions return "".
+          path (or (car (url-path-and-query parsed)) "")
+          host (url-host parsed))
+
+    (when host
+      (when (and (not (string= "/" path))
+                 (not (string= ""  path)))
+        (setq path (substring
+                    (if (string-match "\\.git\\'" path)
+                        (file-name-sans-extension path)
+                      path)
+                    1)))
+
+      ;; Fix-up scp style URLs.
+      ;; git@foo:UsEr/repo gives a host of foo:user
+      ;; We also need to preserve case so we take UsEr from the original url
+      (when (string-match ":" host)
+        (let ((parts (split-string host ":" t))
+              (case-fold-search t))
+          (string-match (concat (car parts) ":\\(" (cadr parts) "\\)/") url)
+          (setq host (car parts)
+                path (concat (match-string 1 url) "/" path))))
+
+      ;; Fix-up Azure SSH URLs
+      (when (string= "ssh.dev.azure.com" host)
+        (setq host "dev.azure.com")
+        (setq path (replace-regexp-in-string
+                    "v3/\\([^/]+\\)/\\([^/]+\\)/\\([^/]+\\)"
+                    "\\1/\\2/_git/\\3"
+                    path)))
+      (when (string= "vs-ssh.visualstudio.com" host)
+        (setq host (concat (url-user parsed) ".visualstudio.com"))
+        (setq path (replace-regexp-in-string
+                    (concat "^v3/" (url-user parsed) "/\\([^/]+\\)/")
+                    "\\1/_git/"
+                    path)))
+
+      ;; For Savannah
+      (when (string= "git.savannah.gnu.org" host)
+        (cond
+         ((string-match "\\`git/" path)
+          (setq path (substring path 4)))
+         ((string-match "\\`srv/git/" path)
+          (setq path (substring path 8)))))
+
+      ;; For AWS CodeCommit
+      (when (string-match "git-codecommit\\.\\(.*\\)\\.amazonaws.com" host)
+        (let* ((matchp (string-match "\\([^\\.]*\\)\\.\\([^\\.]*\\)" host))
+               (region (when matchp
+                         (match-string 2 host)))
+               (domainname ".console.aws.amazon.com"))
+          (when region
+            (setq host (concat region domainname))))
+        (when (string-match "v1/repos/" path)
+          (setq path (concat "codesuite/codecommit/repositories/"
+                             (substring path 9)))))
+
+      (list host path))))
+
+(defun git-link--using-git-timemachine ()
+  (and (boundp 'git-timemachine-revision)
+       git-timemachine-revision))
+
+(defun git-link--using-magit-blob-mode ()
+  (bound-and-true-p magit-blob-mode))
+
+(defun git-link--read-remote ()
+  (let ((remotes (git-link--remotes))
+       (current (git-link--remote)))
+    (completing-read "Remote: "
+                    remotes
+                    nil
+                    t
+                    ""
+                    nil
+                    (if (member current remotes)
+                        current
+                      (car remotes)))))
+
+(defun git-link--get-region ()
+  (save-restriction
+    (widen)
+    (save-excursion
+      (let* ((use-region (use-region-p))
+             (start (when use-region (region-beginning)))
+             (end   (when use-region (region-end)))
+             (line-start (line-number-at-pos start))
+             line-end)
+        (when use-region
+          ;; Avoid adding an extra blank line to the selection.
+          ;; This happens when point or mark is at the start of the next line.
+          ;;
+          ;; When selection is from bottom to top, exchange point and mark
+          ;; so that the `point' and `(region-end)' are the same.
+          (when (< (point) (mark))
+            (exchange-point-and-mark))
+          (when (= end (line-beginning-position))
+            ;; Go up and avoid the blank line
+            (setq end (1- end)))
+          (setq line-end (line-number-at-pos end))
+          (when (<= line-end line-start)
+            (setq line-end nil)))
+        (list line-start line-end)))))
+
+(defun git-link--new (link)
+  (kill-new link)
+  ;; prevent URL escapes from being interpreted as format strings
+  (message (replace-regexp-in-string "%" "%%" link t t))
+  (setq deactivate-mark t)
+  (when git-link-open-in-browser
+    (if (fboundp git-link-open-in-browser)
+        (funcall git-link-open-in-browser link)
+      (browse-url link))))
+
+(defun git-link-codeberg (hostname dirname filename branch commit start end)
+    (format "https://%s/%s/src/%s/%s"
+           hostname
+           dirname
+           (or branch commit)
+            (concat filename
+                    (when start
+                      (concat "#"
+                              (if end
+                                  (format "L%s-L%s" start end)
+                                (format "L%s" start)))))))
+
+(defun git-link-gitlab (hostname dirname filename branch commit start end)
+  (format "https://%s/%s/-/blob/%s/%s"
+         hostname
+         dirname
+         (or branch commit)
+          (concat filename
+                  (when start
+                    (concat "#"
+                            (if end
+                                (format "L%s-%s" start end)
+                              (format "L%s" start)))))))
+
+(defun git-link-github (hostname dirname filename branch commit start end)
+  (format "https://%s/%s/blob/%s/%s"
+         hostname
+         dirname
+         (or branch commit)
+         (concat filename
+                  (when start
+                    (concat (if (git-link--should-render-plain filename) "?plain=1#" "#")
+                            (if end
+                                (format "L%s-L%s" start end)
+                              (format "L%s" start)))))))
+
+(defun git-link-googlesource (hostname dirname filename branch commit start end)
+  (format "https://%s/%s/+/%s/%s"
+         hostname
+         dirname
+         (or branch commit)
+         (concat filename
+                  (when start
+                    (format "#%s" start)
+                    ))))
+
+(defun git-link-azure (hostname dirname filename branch commit start end)
+  (format "https://%s/%s?path=%%2F%s&version=%s&line=%s&lineEnd=%s&lineStartColumn=1&lineEndColumn=9999&lineStyle=plain"
+         hostname
+         dirname
+      filename
+      (concat "G" (if branch "B" "C") (or branch commit))
+      (or start "")
+      (or end start "")))
+
+(defun git-link-sourcehut (hostname dirname filename branch commit start end)
+  (format "https://%s/%s/tree/%s/%s"
+         hostname
+         dirname
+         (or branch commit)
+         (concat filename
+                  (when start
+                    (concat "#"
+                            (if end
+                                (format "L%s-%s" start end)
+                              (format "L%s" start)))))))
+
+(defun git-link-commit-gitlab (hostname dirname commit)
+  (format "https://%s/%s/-/commit/%s"
+         hostname
+         dirname
+         commit))
+
+(defun git-link-commit-github (hostname dirname commit)
+  (format "https://%s/%s/commit/%s"
+         hostname
+         dirname
+         commit))
+
+(defun git-link-commit-googlesource (hostname dirname commit)
+  (format "https://%s/%s/+/%s"
+         hostname
+         dirname
+          commit))
+
+(defun git-link-commit-azure (hostname dirname commit)
+ (format "https://%s/%s/commit/%s"
+         hostname
+         dirname
+
+      ;; Azure only supports full 32 characters SHA
+      (car (git-link--exec "rev-parse" commit))))
+
+(defun git-link-commit-codeberg (hostname dirname commit)
+    (format "https://%s/%s/commit/%s"
+           hostname
+           dirname
+           commit))
+
+(defun git-link-gitorious (hostname dirname filename _branch commit start _end)
+  (format "https://%s/%s/source/%s:%s#L%s"
+         hostname
+         dirname
+         commit
+         filename
+         start))
+
+(defun git-link-commit-gitorious (hostname dirname commit)
+  (format "https://%s/%s/commit/%s"
+         hostname
+         dirname
+         commit))
+
+(defun git-link-bitbucket (hostname dirname filename _branch commit start end)
+  ;; ?at=branch-name
+  (format "https://%s/%s/src/%s/%s"
+          hostname
+          dirname
+          commit
+          (if (string= "" (file-name-nondirectory filename))
+              filename
+            (concat filename
+                    "#"
+                    (file-name-nondirectory filename)
+                    (when start
+                      (if end
+                          (format "-%s:%s" start end)
+                        (format "-%s" start)))))))
+
+(defun git-link-commit-bitbucket (hostname dirname commit)
+  ;; ?at=branch-name
+  (format "https://%s/%s/commits/%s"
+         hostname
+         dirname
+         commit))
+
+(defun git-link-cgit (hostname dirname filename branch commit start _end)
+  (format "https://%s/%s/tree/%s?h=%s"
+         hostname
+         dirname
+          filename
+          (concat
+           (or branch commit)
+           (when start
+             (concat "#" (format "n%s" start))))))
+
+(defun git-link-commit-cgit (hostname dirname commit)
+  (format "https://%s/%s/commit/?id=%s"
+         hostname
+          dirname
+         commit))
+
+(defun git-link-savannah (hostname dirname filename branch commit start end)
+  (git-link-cgit hostname
+                 (format "cgit/%s.git" dirname) ; unique to Savannah
+                 filename
+                 branch
+                 commit
+                 start
+                 end))
+
+(defun git-link-commit-savannah (hostname dirname commit)
+  (git-link-commit-cgit hostname
+                        (format "cgit/%s.git" dirname) ; also unique to Savannah
+                        commit))
+
+(defun git-link-sourcegraph (hostname dirname filename branch commit start end)
+  (let ((line-or-range (cond ((and start end) (format "#L%s-%s" start end))
+                             (start (format "#L%s" start))
+                             (t "")))
+        (branch-or-commit (or branch commit))
+        (dir-file-name (directory-file-name dirname)))
+    (format "https://%s/%s@%s/-/blob/%s%s"
+            hostname
+            dir-file-name
+            branch-or-commit
+            filename
+            line-or-range)))
+
+(defun git-link-commit-sourcegraph (hostname dirname commit)
+  (let ((dir-file-name (directory-file-name dirname)))
+    (format "https://%s/%s/-/commit/%s"
+            hostname
+            dir-file-name
+            commit)))
+
+(defun git-link-homepage-github (hostname dirname)
+  (format "https://%s/%s"
+         hostname
+         dirname))
+
+(defun git-link-homepage-savannah (hostname dirname)
+  (format "https://%s/cgit/%s.git/"
+         hostname
+         dirname))
+
+(defun git-link-codecommit (hostname
+                            dirname
+                            filename
+                            branch
+                            commit
+                            start
+                            end)
+  (format "https://%s/%s/browse/refs/heads/%s/--/%s"
+          hostname
+          dirname
+          (or branch commit)
+          (concat filename
+                  (when start
+                    (format "?lines=%s-%s"
+                            start
+                            (or end start))))))
+
+(defun git-link-commit-codecommit (hostname dirname commit)
+  (format "https://%s/%s/commit/%s" hostname dirname commit))
+
+(defun git-link-homepage-codecommit (hostname dirname)
+  (format "https://%s/%s/browse" hostname dirname))
+
+(define-obsolete-function-alias
+  'git-link-homepage-svannah 'git-link-homepage-savannah "cf947f9")
+
+(defun git-link--select-remote ()
+  (if (equal '(4) current-prefix-arg)
+      (git-link--read-remote)
+    (git-link--remote)))
+
+(defun git-link--should-render-plain (filename)
+  "Check if the extension of the given filename belongs
+to the list of extensions which generated link should be
+shown as a plain file"
+  (let ((extension (or (file-name-extension filename) "")))
+    (member (downcase extension) git-link-extensions-rendered-plain)))
+
+;;;###autoload
+(defun git-link (remote start end)
+  "Create a URL representing the current buffer's location in its
+GitHub/Bitbucket/GitLab/... repository at the current line number
+or active region. The URL will be added to the kill ring.  If
+`git-link-open-in-browser' is non-nil also call `browse-url'.
+
+With a prefix argument of - generate a link without line number(s).
+Also see `git-link-use-single-line-number'.
+
+With a single prefix argument prompt for the remote's name.
+Defaults to \"origin\".
+
+With a double prefix argument invert the value of
+`git-link-use-commit'."
+  (interactive
+   (if (equal '- current-prefix-arg)
+       (list (git-link--remote) nil nil)
+     (let* ((remote (git-link--select-remote))
+            (region (when (or buffer-file-name (git-link--using-magit-blob-mode))
+                      (git-link--get-region))))
+
+       (if (and (null git-link-use-single-line-number) (null (cadr region)))
+           (list remote nil nil)
+         (list remote (car region) (cadr region))))))
+
+  (let (filename branch commit handler remote-info (remote-url (git-link--remote-url remote)))
+    (if (null remote-url)
+        (message "Remote `%s' not found" remote)
+
+      (setq remote-info (git-link--parse-remote remote-url)
+            filename    (git-link--relative-filename)
+            branch      (git-link--branch)
+            commit      (git-link--commit)
+            handler     (git-link--handler git-link-remote-alist (car remote-info)))
+
+      (cond ((null filename)
+             (message "Can't figure out what to link to"))
+            ((null (car remote-info))
+             (message "Remote `%s' contains an unsupported URL" remote))
+            ((not (functionp handler))
+             (message "No handler found for %s" (car remote-info)))
+            ;; TODO: null ret val
+            (t
+             (let ((vc-revison (git-link--parse-vc-revision filename)))
+               (when vc-revison
+                 (setq filename (car vc-revison)
+                       commit   (cdr vc-revison)))
+
+               (git-link--new
+                (funcall handler
+                         (car remote-info)
+                         (cadr remote-info)
+                         (url-hexify-string filename (url--allowed-chars (cons ?/ url-unreserved-chars)))
+                         (if (or (git-link--using-git-timemachine)
+                                 (git-link--using-magit-blob-mode)
+                                 vc-revison
+                                 (if (equal '(16) current-prefix-arg)
+                                     (not git-link-use-commit)
+                                   git-link-use-commit))
+                             nil
+                           (url-hexify-string branch))
+                         commit
+                         start
+                         end))))))))
+
+;;;###autoload
+(defun git-link-commit (remote)
+  "Create a URL representing the commit for the hash under point
+in the current buffer's GitHub/Bitbucket/GitLab/...
+repository. The URL will be added to the kill ring.
+
+With a prefix argument prompt for the remote's name.
+Defaults to \"origin\"."
+
+  (interactive (list (git-link--select-remote)))
+  (let* (commit handler remote-info (remote-url (git-link--remote-url remote)))
+    (if (null remote-url)
+        (message "Remote `%s' not found" remote)
+
+      (setq remote-info (git-link--parse-remote remote-url)
+            commit (word-at-point)
+            handler (git-link--handler git-link-commit-remote-alist (car remote-info)))
+
+      (cond ((null (car remote-info))
+             (message "Remote `%s' contains an unsupported URL" remote))
+            ((not (string-match-p "[a-fA-F0-9]\\{7,40\\}" (or commit "")))
+             (message "Point is not on a commit hash"))
+            ((not (functionp handler))
+             (message "No handler for %s" (car remote-info)))
+            ;; null ret val
+            ((git-link--new
+              (funcall handler
+                       (car remote-info)
+                       (cadr remote-info)
+                       (substring-no-properties commit))))))))
+
+;;;###autoload
+(defun git-link-homepage (remote)
+  "Create a URL representing the homepage of the current
+buffer's GitHub/Bitbucket/GitLab/... repository. The
+URL will be added to the kill ring.
+
+With a prefix argument prompt for the remote's name.
+Defaults to \"origin\"."
+
+  (interactive (list (git-link--select-remote)))
+  (let* (handler remote-info (remote-url (git-link--remote-url remote)))
+    (if (null remote-url)
+        (message "Remote `%s' not found" remote)
+
+      (setq remote-info (git-link--parse-remote remote-url)
+            handler (git-link--handler git-link-homepage-remote-alist (car remote-info)))
+
+      (cond ((null (car remote-info))
+             (message "Remote `%s' contains an unsupported URL" remote))
+            ((not (functionp handler))
+             (message "No handler for %s" (car remote-info)))
+            ;; null ret val
+            ((git-link--new
+              (funcall handler
+                       (car remote-info)
+                       (cadr remote-info))))))))
+
+(provide 'git-link)
+;;; git-link.el ends here
diff --git a/elpa/git-timemachine-20230413.620/git-timemachine-autoloads.el b/elpa/git-timemachine-20230413.620/git-timemachine-autoloads.el
deleted file mode 100644 (file)
index 7a2971b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-;;; git-timemachine-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "git-timemachine" "git-timemachine.el" (0 0
-;;;;;;  0 0))
-;;; Generated autoloads from git-timemachine.el
-
-(autoload 'git-timemachine-toggle "git-timemachine" "\
-Toggle git timemachine mode." t nil)
-
-(autoload 'git-timemachine "git-timemachine" "\
-Enable git timemachine for file of current buffer." t nil)
-
-(autoload 'git-timemachine-switch-branch "git-timemachine" "\
-Enable git timemachine for current buffer, switching to GIT-BRANCH.
-
-\(fn GIT-BRANCH)" t nil)
-
-(register-definition-prefixes "git-timemachine" '("git-timemachine-"))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; git-timemachine-autoloads.el ends here
diff --git a/elpa/git-timemachine-20230413.620/git-timemachine-pkg.el b/elpa/git-timemachine-20230413.620/git-timemachine-pkg.el
deleted file mode 100644 (file)
index 5a98911..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-;;; Generated package description from git-timemachine.el  -*- no-byte-compile: t -*-
-(define-package "git-timemachine" "20230413.620" "Walk through git revisions of a file" '((emacs "24.3") (transient "0.1.0")) :commit "13769fb603ae88c64566529eae4525ce88026e86" :authors '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se")) :maintainers '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se")) :maintainer '("Peter Stiernström" . "peterNOSPAMstiernstrom.se") :keywords '("vc") :url "https://gitlab.com/pidu/git-timemachine")
diff --git a/elpa/git-timemachine-20230413.620/git-timemachine.el b/elpa/git-timemachine-20230413.620/git-timemachine.el
deleted file mode 100644 (file)
index fac9d65..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-;;; git-timemachine.el --- Walk through git revisions of a file
-
-;; Copyright (C) 2014 Peter Stiernström
-
-;; Author: Peter Stiernström <peterNOSPAMstiernstrom.se>
-;; Version: 4.12
-;; Package-Version: 20230413.620
-;; Package-Commit: 13769fb603ae88c64566529eae4525ce88026e86
-;; URL: https://gitlab.com/pidu/git-timemachine
-;; Keywords: vc
-;; Package-Requires: ((emacs "24.3") (transient "0.1.0"))
-
-;; This file is not part of GNU Emacs
-
-;; This program is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Use git-timemachine to browse historic versions of a file with p
-;;; (previous) and n (next).
-
-;;; Code:
-
-(require 'vc-git)
-(require 'cl-lib)
-(require 'transient)
-
-(defgroup git-timemachine nil
-  "Walk through git revisions of a file."
-  :link '(url-link "https://codeberg.org/pidu/git-timemachine")
-  :group 'tools)
-
-(defcustom git-timemachine-abbreviation-length 12
-  "Number of chars from the full sha1 hash to use for abbreviation."
-  :type 'integer
-  :group 'git-timemachine)
-
-(defcustom git-timemachine-show-minibuffer-details t
-  "Non-nil means that details of the commit (its hash and date)
-will be shown in the minibuffer while navigating commits."
-  :type 'boolean
-  :group 'git-timemachine)
-
-(defface git-timemachine-commit
-  '((default :weight bold))
-  "Face for git timemachine commit sha."
-  :group 'git-timemachine)
-
-(defface git-timemachine-minibuffer-detail-face
-  '((((class color) (background dark))
-      :foreground "yellow")
-     (((class color) (background light))
-       :foreground "yellow4"))
-  "How to display the minibuffer detail."
-  :group 'git-timemachine)
-
-(defface git-timemachine-minibuffer-author-face
-  '((((class color) (background dark))
-      :foreground "orange")
-     (((class color) (background light))
-       :foreground "DarkOrange4"))
-  "How to display the author in minibuffer."
-  :group 'git-timemachine)
-
-(defcustom git-timemachine-minibuffer-detail
-  'subject
-  "What to display when `git-timemachine-show-minibuffer-details` is t.
-Available values are:
-`commit` : The SHA hash of the commit
-`subject`: The subject of the commit message"
-  :type '(radio (const :tag "Commit SHA" commit) (const :tag "Commit Subject" subject))
-  :group 'git-timemachine)
-
-(defcustom git-timemachine-show-author
-  t
-  "Prepend author to minibuffer details."
-  :type 'boolean
-  :group 'git-timemachine)
-
-(defcustom git-timemachine-global-git-arguments
-  '("-c" "log.showSignature=false" "--no-pager")
-  "Common arguments for all git commands."
-  :type 'list
-  :group 'git-timemachine)
-
-(defcustom git-timemachine-quit-to-invoking-buffer
-  t
-  "Switch to invoking buffer on `git-timemachine-quit`."
-  :type 'boolean
-  :group 'git-timemachine)
-
-(defvar-local git-timemachine-directory nil)
-(defvar-local git-timemachine-revision nil)
-(defvar-local git-timemachine-file nil)
-(defvar-local git-timemachine--revisions-cache nil)
-
-(defun git-timemachine--process-file (&rest args)
-  "Run `process-file` with ARGS and `git-timemachine-global-git-arguments` applied."
-  (apply #'process-file vc-git-program nil t nil (append git-timemachine-global-git-arguments args)))
-
-(defun git-timemachine--revisions (&optional git-branch)
-  "List git revisions of current buffers file.
-
-When passed a GIT-BRANCH, lists revisions from that branch."
-  (if git-timemachine--revisions-cache
-    git-timemachine--revisions-cache
-    (setq git-timemachine--revisions-cache
-      (prog2
-             (message "Fetching Revisions...")
-             (let ((default-directory git-timemachine-directory)
-               (file git-timemachine-file))
-          (with-temp-buffer
-
-            (unless (zerop (if git-branch
-                             (git-timemachine--process-file "log" git-branch "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)
-                             (git-timemachine--process-file "log" "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)))
-              (error "Git log command exited with non-zero exit status for file: %s" file))
-
-            (goto-char (point-min))
-            (let ((lines)
-                   (commit-number (/ (1+ (count-lines (point-min) (point-max))) 3)))
-              (while (not (eobp))
-                (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
-                  (string-match "\\([^\0]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0\\(.*\\)\0\\(.*\\)" line)
-                  (let ((commit (match-string 1 line))
-                         (date-relative (match-string 2 line))
-                         (date-full (match-string 3 line))
-                         (subject (match-string 4 line))
-                         (author (match-string 5 line)))
-                    (forward-line 1)
-                    (let ((file-name (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
-                      (push (list commit file-name commit-number date-relative date-full subject author) lines))))
-                (setq commit-number (1- commit-number))
-                (forward-line 2))
-              (nreverse lines))))
-        (message "Fetching Revisions...done")))))
-
-(defun git-timemachine-show-current-revision ()
-  "Show last (current) revision of file."
-  (interactive)
-  (git-timemachine-show-revision (car (git-timemachine--revisions))))
-
-(defun git-timemachine-show-latest-revision-in-branch (git-branch)
-  "Show last (current) revision of file in GIT-BRANCH."
-  (interactive "MGit branch: ")
-  (git-timemachine-show-revision (car (git-timemachine--revisions git-branch))))
-
-(defun git-timemachine--next-revision (revisions)
-  "Return the revision following the current revision in REVISIONS."
-  (or (cadr (cl-member (car git-timemachine-revision) revisions :key #'car :test #'string=))
-    (car (reverse revisions))))
-
-(defun git-timemachine-show-previous-revision ()
-  "Show previous revision of file."
-  (interactive)
-  (let ((new-line nil)
-         (curr-revision git-timemachine-revision)
-         (new-revision (git-timemachine--next-revision (git-timemachine--revisions)))
-         (cursor-win-pos (git-timemachine--get-cursor-position)))
-    (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
-    (git-timemachine-show-revision new-revision)
-    (forward-line (- new-line (line-number-at-pos)))
-    (git-timemachine--set-cursor-position cursor-win-pos)))
-
-(defun git-timemachine-show-next-revision ()
-  "Show next revision of file."
-  (interactive)
-  (let ((new-line nil)
-         (curr-revision git-timemachine-revision)
-         (new-revision (git-timemachine--next-revision (reverse (git-timemachine--revisions))))
-         (cursor-win-pos (git-timemachine--get-cursor-position)))
-    (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
-    (git-timemachine-show-revision new-revision)
-    (forward-line (- new-line (line-number-at-pos)))
-    (git-timemachine--set-cursor-position cursor-win-pos)))
-
-(defun git-timemachine-show-revision-fuzzy ()
-  "Show the revision with the chosen commit message."
-  (interactive)
-  (let* ((revisions (git-timemachine--revisions))
-          (wanted
-            (funcall #'completing-read "Commit message: "
-              (mapcar (apply-partially #'nth 5) revisions))))
-    (git-timemachine-show-revision
-      (cl-find wanted revisions
-             :key (apply-partially #'nth 5)
-             :test #'equal))))
-
-(defun git-timemachine-show-nth-revision (rev-number)
-  "Show the REV-NUMBER revision."
-  (interactive "nEnter revision number: ")
-  (let* ((revisions (reverse (git-timemachine--revisions)))
-          (num-revisions (length revisions))
-          (curr-revision git-timemachine-revision)
-          (new-revision (nth (1- rev-number) revisions))
-          (new-line nil)
-          (cursor-win-pos (git-timemachine--get-cursor-position)))
-    (if (not new-revision)
-      (message "Only %d revisions exist." num-revisions)
-      (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
-      (git-timemachine-show-revision new-revision)
-      (forward-line (- new-line (line-number-at-pos)))
-      (git-timemachine--set-cursor-position cursor-win-pos))))
-
-(defun git-timemachine-show-revision (revision)
-  "Show a REVISION (commit hash) of the current file."
-  (when revision
-    (let ((current-position (point))
-           (commit (car revision))
-           (revision-file-name (nth 1 revision))
-           (commit-index (nth 2 revision))
-           (date-relative (nth 3 revision))
-           (date-full (nth 4 revision))
-           (subject (nth 5 revision)))
-      (setq buffer-read-only nil)
-      (erase-buffer)
-      (let ((default-directory git-timemachine-directory)
-             (process-coding-system-alist (list (cons "" (cons buffer-file-coding-system default-process-coding-system)))))
-        (git-timemachine--process-file "show" (concat commit ":" revision-file-name)))
-      (setq buffer-read-only t)
-      (set-buffer-modified-p nil)
-      (let* ((revisions (git-timemachine--revisions))
-              (n-of-m (format "(%d/%d %s)" commit-index (length revisions) date-relative)))
-        (setq mode-line-buffer-identification
-          (list (propertized-buffer-identification "%12b") "@"
-            (propertize (git-timemachine-abbreviate commit) 'face 'git-timemachine-commit) " name:" revision-file-name" " n-of-m)))
-      (setq git-timemachine-revision revision)
-      (goto-char current-position)
-      (when git-timemachine-show-minibuffer-details
-        (git-timemachine--show-minibuffer-details revision))
-      (git-timemachine--erm-workaround))))
-
-(declare-function erm-reset-buffer "ext:enh-ruby-mode")
-
-(defun git-timemachine--erm-workaround ()
-  "Workaround for enhanced ruby mode not detecting revision change."
-  (when (eq major-mode 'enh-ruby-mode)
-    (ignore-errors (erm-reset-buffer))))
-
-(defun git-timemachine--show-minibuffer-details (revision)
-  "Show details for REVISION in minibuffer."
-  (let* ((date-relative (nth 3 revision))
-          (date-full (nth 4 revision))
-          (author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
-          (sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
-    (message "%s%s [%s (%s)]"
-      (propertize author 'face 'git-timemachine-minibuffer-author-face)
-      (propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face) date-full date-relative)))
-
-(defun git-timemachine--find-new-current-line (curr-revision new-revision current-line)
-  "Return the new current line after a revision jump.
-
-Given CURR-REVISION and NEW-REVISION determine if we need to
-updated CURRENT-LINE."
-  (let* ((revisions (reverse (git-timemachine--revisions)))
-          (current-commit (car curr-revision))
-          (curr-rev-number (+ (or (cl-position curr-revision revisions) 0) 1))
-          (new-commit (car new-revision))
-          (new-rev-number (+ (or (cl-position new-revision revisions) 0) 1))
-          (new-line nil)
-          (file git-timemachine-file)
-          (reverse (< curr-rev-number new-rev-number)))
-    ;; If no commit change, do nothing
-    (if (= curr-rev-number new-rev-number)
-      current-line
-      ;; Get new current line number using `git-blame`
-      (with-temp-buffer
-        (if reverse
-          (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit))
-          (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit)))
-        (goto-char (point-min))
-        ;; If end-of-buffer problem
-        (when (search-forward-regexp "^fatal: file .+ has only .+ lines" nil t)
-          (setq current-line (- current-line 1))
-          (erase-buffer)
-          (if reverse
-            (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit))
-            (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit))))
-        (goto-char (point-min))
-        (search-forward-regexp "^[^ ]+ \\([^ ]+\\)")
-        (setq new-line (string-to-number (match-string 1)))
-        ;; In case git blame doesn't give what we expect
-        (when (= new-line 0) (setq new-line current-line))
-        new-line))))
-
-(defun git-timemachine--get-cursor-position ()
- "Return the cursor visual line number with respect to the current window first line."
- (let* ((win-point-min (save-excursion (move-to-window-line 0) (point)))
-        (cur-pos (count-screen-lines win-point-min (point))))
-  cur-pos))
-
-(defun git-timemachine--set-cursor-position (POS)
- "Set the cursor position to the POS visual line with respect to the window first line."
- (recenter POS))
-
-(defun git-timemachine-abbreviate (revision)
-  "Return REVISION abbreviated to `git-timemachine-abbreviation-length' chars."
-  (substring revision 0 git-timemachine-abbreviation-length))
-
-(defun git-timemachine-quit ()
-  "Exit the timemachine."
-  (interactive)
-  (let ((parent-buffer-name buffer-file-name))
-    (kill-buffer)
-    (let ((parent-buffer (find-buffer-visiting parent-buffer-name)))
-      (when (and parent-buffer git-timemachine-quit-to-invoking-buffer)
-        (switch-to-buffer parent-buffer nil t)))))
-
-(defun git-timemachine-blame ()
-  "Call `magit-blame` on current revision."
-  (interactive)
-  (if (fboundp 'magit-blame)
-    (let ((magit-buffer-revision (car git-timemachine-revision)))
-      (magit-blame))
-    (message "You need to install magit for blame capabilities")))
-
-(defun git-timemachine-kill-revision ()
-  "Kill the current revisions abbreviated commit hash."
-  (interactive)
-  (let ((revision (car git-timemachine-revision)))
-    (message revision)
-    (kill-new revision)))
-
-(defun git-timemachine-kill-abbreviated-revision ()
-  "Kill the current revisions full commit hash."
-  (interactive)
-  (let ((revision (git-timemachine-abbreviate (car git-timemachine-revision))))
-    (message revision)
-    (kill-new revision)))
-
-(defun git-timemachine-show-commit ()
-  "Show commit for current revision."
-  (interactive)
-  (let ((rev (car git-timemachine-revision)))
-    (if (fboundp 'magit-show-commit)
-      (magit-show-commit rev)
-      (message "You need to install magit to show commit"))))
-
-(transient-define-prefix git-timemachine-help ()
-  "Show online help."
-  ["Navigate"
-    [("p" "show previous revision" git-timemachine-show-previous-revision)
-      ("n" "show next revision" git-timemachine-show-next-revision)
-      ("g" "show nth revision" git-timemachine-show-nth-revision)
-      ("t" "show fuzzy revision" git-timemachine-show-revision-fuzzy)]]
-  ["Kill current revision"
-    [("w" "kill abbreviated revision" git-timemachine-kill-abbreviated-revision)
-      ("W" "kill revision" git-timemachine-kill-revision)]]
-  ["Misc"
-    [("b" "blame current revision" git-timemachine-blame)
-      ("c" "show commit" git-timemachine-show-commit)
-      ("?" "show help" git-timemachine-help)
-      ("q" "quit" git-timemachine-quit)]])
-
-(define-minor-mode git-timemachine-mode
-  "Git Timemachine, feel the wings of history."
-  :init-value nil
-  :lighter " Timemachine"
-  :keymap
-  '(("p" . git-timemachine-show-previous-revision)
-     ("n" . git-timemachine-show-next-revision)
-     ("g" . git-timemachine-show-nth-revision)
-     ("t" . git-timemachine-show-revision-fuzzy)
-     ("q" . git-timemachine-quit)
-     ("w" . git-timemachine-kill-abbreviated-revision)
-     ("W" . git-timemachine-kill-revision)
-     ("b" . git-timemachine-blame)
-     ("c" . git-timemachine-show-commit)
-     ("?" . git-timemachine-help))
-  :group 'git-timemachine)
-
-(defun git-timemachine-validate (file)
-  "Validate that there is a FILE and that it belongs to a git repository.
-Call with the value of 'buffer-file-name."
-  (unless file
-    (error "This buffer is not visiting a file"))
-  (unless (vc-git-registered file)
-    (error "This file is not git tracked")))
-
-(defun git-timemachine--start (get-revision-fn)
-  "Setup a timemachine buffer and populate it from the result of GET-REVISION-FN."
-  (setq git-timemachine--revisions-cache nil)
-  (git-timemachine-validate (buffer-file-name))
-  (let ((git-directory (expand-file-name (vc-git-root (buffer-file-name))))
-         (file-name (buffer-file-name))
-         (timemachine-buffer (format "timemachine:%s" (buffer-name)))
-         (cur-line (line-number-at-pos))
-         (cursor-position (git-timemachine--get-cursor-position))
-         (new-line nil)
-         (mode major-mode)
-         (coding-system buffer-file-coding-system))
-    (with-current-buffer (get-buffer-create timemachine-buffer)
-      (switch-to-buffer timemachine-buffer)
-      (setq buffer-file-name file-name)
-      (setq buffer-file-coding-system coding-system)
-      (delay-mode-hooks (funcall mode))
-      (setq git-timemachine-directory git-directory
-        git-timemachine-file (file-relative-name file-name git-directory)
-        git-timemachine-revision nil)
-      (funcall get-revision-fn)
-      (setq new-line (git-timemachine--find-new-current-line git-timemachine-revision (list "HEAD" "" 0 "" "" "" "") cur-line)) ;; Allow to stay on the same line
-      (goto-char (point-min))
-      (forward-line (- new-line 1))
-      (git-timemachine--set-cursor-position cursor-position)
-      (git-timemachine-mode))))
-
-;;;###autoload
-(defun git-timemachine-toggle ()
-  "Toggle git timemachine mode."
-  (interactive)
-  (if (bound-and-true-p git-timemachine-mode)
-    (git-timemachine-quit)
-    (git-timemachine)))
-
-;;;###autoload
-(defun git-timemachine ()
-  "Enable git timemachine for file of current buffer."
-  (interactive)
-  (git-timemachine--start #'git-timemachine-show-current-revision))
-
-;;;###autoload
-(defun git-timemachine-switch-branch (git-branch)
-  "Enable git timemachine for current buffer, switching to GIT-BRANCH."
-  (interactive (list (completing-read "Branch to switch to: "(vc-git-branches))))
-  (git-timemachine--start (lambda () (git-timemachine-show-latest-revision-in-branch git-branch))))
-
-(provide 'git-timemachine)
-
-;;; git-timemachine.el ends here
diff --git a/elpa/git-timemachine-20230630.1214/git-timemachine-autoloads.el b/elpa/git-timemachine-20230630.1214/git-timemachine-autoloads.el
new file mode 100644 (file)
index 0000000..d196f94
--- /dev/null
@@ -0,0 +1,38 @@
+;;; git-timemachine-autoloads.el --- automatically extracted autoloads  -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "git-timemachine" "git-timemachine.el" (0 0
+;;;;;;  0 0))
+;;; Generated autoloads from git-timemachine.el
+
+(autoload 'git-timemachine-toggle "git-timemachine" "\
+Toggle git timemachine mode." t nil)
+
+(autoload 'git-timemachine "git-timemachine" "\
+Enable git timemachine for file of current buffer." t nil)
+
+(autoload 'git-timemachine-switch-branch "git-timemachine" "\
+Enable git timemachine for current buffer, switching to GIT-BRANCH.
+
+\(fn GIT-BRANCH)" t nil)
+
+(register-definition-prefixes "git-timemachine" '("git-timemachine-"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("git-timemachine-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; git-timemachine-autoloads.el ends here
diff --git a/elpa/git-timemachine-20230630.1214/git-timemachine-pkg.el b/elpa/git-timemachine-20230630.1214/git-timemachine-pkg.el
new file mode 100644 (file)
index 0000000..03da232
--- /dev/null
@@ -0,0 +1,15 @@
+(define-package "git-timemachine" "20230630.1214" "Walk through git revisions of a file"
+  '((emacs "24.3")
+    (transient "0.1.0"))
+  :commit "ac933e5cd29583c131401f3bd991d98129c316df" :authors
+  '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se"))
+  :maintainers
+  '(("Peter Stiernström" . "peterNOSPAMstiernstrom.se"))
+  :maintainer
+  '("Peter Stiernström" . "peterNOSPAMstiernstrom.se")
+  :keywords
+  '("vc")
+  :url "https://gitlab.com/pidu/git-timemachine")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/git-timemachine-20230630.1214/git-timemachine.el b/elpa/git-timemachine-20230630.1214/git-timemachine.el
new file mode 100755 (executable)
index 0000000..65bba0b
--- /dev/null
@@ -0,0 +1,438 @@
+;;; git-timemachine.el --- Walk through git revisions of a file
+
+;; Copyright (C) 2014 Peter Stiernström
+
+;; Author: Peter Stiernström <peterNOSPAMstiernstrom.se>
+;; Version: 4.13
+;; URL: https://gitlab.com/pidu/git-timemachine
+;; Keywords: vc
+;; Package-Requires: ((emacs "24.3") (transient "0.1.0"))
+
+;; This file is not part of GNU Emacs
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Use git-timemachine to browse historic versions of a file with p
+;;; (previous) and n (next).
+
+;;; Code:
+
+(require 'vc-git)
+(require 'cl-lib)
+(require 'transient)
+
+(defgroup git-timemachine nil
+  "Walk through git revisions of a file."
+  :link '(url-link "https://codeberg.org/pidu/git-timemachine")
+  :group 'tools)
+
+(defcustom git-timemachine-abbreviation-length 12
+  "Number of chars from the full sha1 hash to use for abbreviation."
+  :type 'integer
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-show-minibuffer-details t
+  "Non-nil means that details of the commit (its hash and date)
+will be shown in the minibuffer while navigating commits."
+  :type 'boolean
+  :group 'git-timemachine)
+
+(defface git-timemachine-commit
+  '((default :weight bold))
+  "Face for git timemachine commit sha."
+  :group 'git-timemachine)
+
+(defface git-timemachine-minibuffer-detail-face
+  '((((class color) (background dark))
+      :foreground "yellow")
+     (((class color) (background light))
+       :foreground "yellow4"))
+  "How to display the minibuffer detail."
+  :group 'git-timemachine)
+
+(defface git-timemachine-minibuffer-author-face
+  '((((class color) (background dark))
+      :foreground "orange")
+     (((class color) (background light))
+       :foreground "DarkOrange4"))
+  "How to display the author in minibuffer."
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-minibuffer-detail
+  'subject
+  "What to display when `git-timemachine-show-minibuffer-details` is t.
+Available values are:
+`commit` : The SHA hash of the commit
+`subject`: The subject of the commit message"
+  :type '(radio (const :tag "Commit SHA" commit) (const :tag "Commit Subject" subject))
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-show-author
+  t
+  "Prepend author to minibuffer details."
+  :type 'boolean
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-global-git-arguments
+  '("-c" "log.showSignature=false" "--no-pager")
+  "Common arguments for all git commands."
+  :type 'list
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-quit-to-invoking-buffer
+  t
+  "Switch to invoking buffer on `git-timemachine-quit`."
+  :type 'boolean
+  :group 'git-timemachine)
+
+(defvar-local git-timemachine-directory nil)
+(defvar-local git-timemachine-revision nil)
+(defvar-local git-timemachine-file nil)
+(defvar-local git-timemachine--revisions-cache nil)
+
+(defun git-timemachine--process-file (&rest args)
+  "Run `process-file` with ARGS and `git-timemachine-global-git-arguments` applied."
+  (apply #'process-file vc-git-program nil t nil (append git-timemachine-global-git-arguments args)))
+
+(defun git-timemachine--revisions (&optional git-branch)
+  "List git revisions of current buffers file.
+
+When passed a GIT-BRANCH, lists revisions from that branch."
+  (if git-timemachine--revisions-cache
+    git-timemachine--revisions-cache
+    (setq git-timemachine--revisions-cache
+      (prog2
+             (message "Fetching Revisions...")
+             (let ((default-directory git-timemachine-directory)
+               (file git-timemachine-file))
+          (with-temp-buffer
+
+            (unless (zerop (if git-branch
+                             (git-timemachine--process-file "log" git-branch "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)
+                             (git-timemachine--process-file "log" "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)))
+              (error "Git log command exited with non-zero exit status for file: %s" file))
+
+            (goto-char (point-min))
+            (let ((lines)
+                   (commit-number (/ (1+ (count-lines (point-min) (point-max))) 3)))
+              (while (not (eobp))
+                (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+                  (string-match "\\([^\0]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0\\(.*\\)\0\\(.*\\)" line)
+                  (let ((commit (match-string 1 line))
+                         (date-relative (match-string 2 line))
+                         (date-full (match-string 3 line))
+                         (subject (match-string 4 line))
+                         (author (match-string 5 line)))
+                    (forward-line 1)
+                    (let ((file-name (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+                      (push (list commit file-name commit-number date-relative date-full subject author) lines))))
+                (setq commit-number (1- commit-number))
+                (forward-line 2))
+              (nreverse lines))))
+        (message "Fetching Revisions...done")))))
+
+(defun git-timemachine-show-current-revision ()
+  "Show last (current) revision of file."
+  (interactive)
+  (git-timemachine-show-revision (car (git-timemachine--revisions))))
+
+(defun git-timemachine-show-latest-revision-in-branch (git-branch)
+  "Show last (current) revision of file in GIT-BRANCH."
+  (interactive "MGit branch: ")
+  (git-timemachine-show-revision (car (git-timemachine--revisions git-branch))))
+
+(defun git-timemachine--next-revision (revisions)
+  "Return the revision following the current revision in REVISIONS."
+  (or (cadr (cl-member (car git-timemachine-revision) revisions :key #'car :test #'string=))
+    (car (reverse revisions))))
+
+(defun git-timemachine-show-previous-revision ()
+  "Show previous revision of file."
+  (interactive)
+  (let ((new-line nil)
+         (curr-revision git-timemachine-revision)
+         (new-revision (git-timemachine--next-revision (git-timemachine--revisions)))
+         (cursor-win-pos (git-timemachine--get-cursor-position)))
+    (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
+    (git-timemachine-show-revision new-revision)
+    (forward-line (- new-line (line-number-at-pos)))
+    (git-timemachine--set-cursor-position cursor-win-pos)))
+
+(defun git-timemachine-show-next-revision ()
+  "Show next revision of file."
+  (interactive)
+  (let ((new-line nil)
+         (curr-revision git-timemachine-revision)
+         (new-revision (git-timemachine--next-revision (reverse (git-timemachine--revisions))))
+         (cursor-win-pos (git-timemachine--get-cursor-position)))
+    (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
+    (git-timemachine-show-revision new-revision)
+    (forward-line (- new-line (line-number-at-pos)))
+    (git-timemachine--set-cursor-position cursor-win-pos)))
+
+(defun git-timemachine-show-revision-fuzzy ()
+  "Show the revision with the chosen commit message."
+  (interactive)
+  (let* ((revisions (git-timemachine--revisions))
+          (wanted
+            (funcall #'completing-read "Commit message: "
+              (mapcar (apply-partially #'nth 5) revisions))))
+    (git-timemachine-show-revision
+      (cl-find wanted revisions
+             :key (apply-partially #'nth 5)
+             :test #'equal))))
+
+(defun git-timemachine-show-nth-revision (rev-number)
+  "Show the REV-NUMBER revision."
+  (interactive "nEnter revision number: ")
+  (let* ((revisions (reverse (git-timemachine--revisions)))
+          (num-revisions (length revisions))
+          (curr-revision git-timemachine-revision)
+          (new-revision (nth (1- rev-number) revisions))
+          (new-line nil)
+          (cursor-win-pos (git-timemachine--get-cursor-position)))
+    (if (not new-revision)
+      (message "Only %d revisions exist." num-revisions)
+      (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
+      (git-timemachine-show-revision new-revision)
+      (forward-line (- new-line (line-number-at-pos)))
+      (git-timemachine--set-cursor-position cursor-win-pos))))
+
+(defun git-timemachine-show-revision (revision)
+  "Show a REVISION (commit hash) of the current file."
+  (when revision
+    (let ((current-position (point))
+           (commit (car revision))
+           (revision-file-name (nth 1 revision))
+           (commit-index (nth 2 revision))
+           (date-relative (nth 3 revision))
+           (date-full (nth 4 revision))
+           (subject (nth 5 revision)))
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (let ((default-directory git-timemachine-directory)
+             (process-coding-system-alist (list (cons "" (cons buffer-file-coding-system default-process-coding-system)))))
+        (git-timemachine--process-file "show" (concat commit ":" revision-file-name)))
+      (setq buffer-read-only t)
+      (set-buffer-modified-p nil)
+      (let* ((revisions (git-timemachine--revisions))
+              (n-of-m (format "(%d/%d %s)" commit-index (length revisions) date-relative)))
+        (setq mode-line-buffer-identification
+          (list (propertized-buffer-identification "%12b") "@"
+            (propertize (git-timemachine-abbreviate commit) 'face 'git-timemachine-commit) " name:" revision-file-name" " n-of-m)))
+      (setq git-timemachine-revision revision)
+      (goto-char current-position)
+      (when git-timemachine-show-minibuffer-details
+        (git-timemachine--show-minibuffer-details revision))
+      (git-timemachine--erm-workaround))))
+
+(declare-function erm-reset-buffer "ext:enh-ruby-mode")
+
+(defun git-timemachine--erm-workaround ()
+  "Workaround for enhanced ruby mode not detecting revision change."
+  (when (eq major-mode 'enh-ruby-mode)
+    (ignore-errors (erm-reset-buffer))))
+
+(defun git-timemachine--show-minibuffer-details (revision)
+  "Show details for REVISION in minibuffer."
+  (let* ((date-relative (nth 3 revision))
+          (date-full (nth 4 revision))
+          (author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
+          (sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
+    (message "%s%s [%s (%s)]"
+      (propertize author 'face 'git-timemachine-minibuffer-author-face)
+      (propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face) date-full date-relative)))
+
+(defun git-timemachine--find-new-current-line (curr-revision new-revision current-line)
+  "Return the new current line after a revision jump.
+
+Given CURR-REVISION and NEW-REVISION determine if we need to
+updated CURRENT-LINE."
+  (let* ((revisions (reverse (git-timemachine--revisions)))
+          (current-commit (car curr-revision))
+          (curr-rev-number (+ (or (cl-position curr-revision revisions) 0) 1))
+          (new-commit (car new-revision))
+          (new-rev-number (+ (or (cl-position new-revision revisions) 0) 1))
+          (new-line nil)
+          (file git-timemachine-file)
+          (reverse (< curr-rev-number new-rev-number)))
+    ;; If no commit change, do nothing
+    (if (= curr-rev-number new-rev-number)
+      current-line
+      ;; Get new current line number using `git-blame`
+      (with-temp-buffer
+        (if reverse
+          (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit))
+          (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit)))
+        (goto-char (point-min))
+        ;; If end-of-buffer problem
+        (when (search-forward-regexp "^fatal: file .+ has only .+ lines" nil t)
+          (setq current-line (- current-line 1))
+          (erase-buffer)
+          (if reverse
+            (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit))
+            (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit))))
+        (goto-char (point-min))
+        (search-forward-regexp "^[^ ]+ \\([^ ]+\\)")
+        (setq new-line (string-to-number (match-string 1)))
+        ;; In case git blame doesn't give what we expect
+        (when (= new-line 0) (setq new-line current-line))
+        new-line))))
+
+(defun git-timemachine--get-cursor-position ()
+ "Return the cursor visual line number with respect to the current window first line."
+ (let* ((win-point-min (save-excursion (move-to-window-line 0) (point)))
+        (cur-pos (count-screen-lines win-point-min (point))))
+  cur-pos))
+
+(defun git-timemachine--set-cursor-position (POS)
+ "Set the cursor position to the POS visual line with respect to the window first line."
+ (recenter POS))
+
+(defun git-timemachine-abbreviate (revision)
+  "Return REVISION abbreviated to `git-timemachine-abbreviation-length' chars."
+  (substring revision 0 git-timemachine-abbreviation-length))
+
+(defun git-timemachine-quit ()
+  "Exit the timemachine."
+  (interactive)
+  (let ((parent-buffer-name buffer-file-name))
+    (kill-buffer)
+    (let ((parent-buffer (find-buffer-visiting parent-buffer-name)))
+      (when (and parent-buffer git-timemachine-quit-to-invoking-buffer)
+        (switch-to-buffer parent-buffer nil t)))))
+
+(defun git-timemachine-blame ()
+  "Call `magit-blame` on current revision."
+  (interactive)
+  (if (fboundp 'magit-blame)
+    (let ((magit-buffer-revision (car git-timemachine-revision)))
+      (magit-blame))
+    (message "You need to install magit for blame capabilities")))
+
+(defun git-timemachine-kill-revision ()
+  "Kill the current revision's full commit hash."
+  (interactive)
+  (let ((revision (car git-timemachine-revision)))
+    (message revision)
+    (kill-new revision)))
+
+(defun git-timemachine-kill-abbreviated-revision ()
+  "Kill the current revision's abbreviated commit hash."
+  (interactive)
+  (let ((revision (git-timemachine-abbreviate (car git-timemachine-revision))))
+    (message revision)
+    (kill-new revision)))
+
+(defun git-timemachine-show-commit ()
+  "Show commit for current revision."
+  (interactive)
+  (let ((rev (car git-timemachine-revision)))
+    (if (fboundp 'magit-show-commit)
+      (magit-show-commit rev)
+      (message "You need to install magit to show commit"))))
+
+(transient-define-prefix git-timemachine-help ()
+  "Show online help."
+  ["Navigate"
+    [("p" "show previous revision" git-timemachine-show-previous-revision)
+      ("n" "show next revision" git-timemachine-show-next-revision)
+      ("g" "show nth revision" git-timemachine-show-nth-revision)
+      ("t" "show fuzzy revision" git-timemachine-show-revision-fuzzy)]]
+  ["Kill current revision"
+    [("w" "kill abbreviated revision" git-timemachine-kill-abbreviated-revision)
+      ("W" "kill revision" git-timemachine-kill-revision)]]
+  ["Misc"
+    [("b" "blame current revision" git-timemachine-blame)
+      ("c" "show commit" git-timemachine-show-commit)
+      ("?" "show help" git-timemachine-help)
+      ("q" "quit" git-timemachine-quit)]])
+
+(define-minor-mode git-timemachine-mode
+  "Git Timemachine, feel the wings of history."
+  :init-value nil
+  :lighter " Timemachine"
+  :keymap
+  '(("p" . git-timemachine-show-previous-revision)
+     ("n" . git-timemachine-show-next-revision)
+     ("g" . git-timemachine-show-nth-revision)
+     ("t" . git-timemachine-show-revision-fuzzy)
+     ("q" . git-timemachine-quit)
+     ("w" . git-timemachine-kill-abbreviated-revision)
+     ("W" . git-timemachine-kill-revision)
+     ("b" . git-timemachine-blame)
+     ("c" . git-timemachine-show-commit)
+     ("?" . git-timemachine-help))
+  :group 'git-timemachine)
+
+(defun git-timemachine-validate (file)
+  "Validate that there is a FILE and that it belongs to a git repository.
+Call with the value of 'buffer-file-name."
+  (unless file
+    (error "This buffer is not visiting a file"))
+  (unless (vc-git-registered file)
+    (error "This file is not git tracked")))
+
+(defun git-timemachine--start (get-revision-fn)
+  "Setup a timemachine buffer and populate it from the result of GET-REVISION-FN."
+  (setq git-timemachine--revisions-cache nil)
+  (git-timemachine-validate (buffer-file-name))
+  (let ((git-directory (expand-file-name (vc-git-root (buffer-file-name))))
+         (file-name (buffer-file-name))
+         (timemachine-buffer (format "timemachine:%s" (buffer-name)))
+         (cur-line (line-number-at-pos))
+         (cursor-position (git-timemachine--get-cursor-position))
+         (new-line nil)
+         (mode major-mode)
+         (coding-system buffer-file-coding-system))
+    (with-current-buffer (get-buffer-create timemachine-buffer)
+      (switch-to-buffer timemachine-buffer)
+      (setq buffer-file-name file-name)
+      (setq buffer-file-coding-system coding-system)
+      (delay-mode-hooks (funcall mode))
+      (setq git-timemachine-directory git-directory
+        git-timemachine-file (file-relative-name file-name git-directory)
+        git-timemachine-revision nil)
+      (funcall get-revision-fn)
+      (setq new-line (git-timemachine--find-new-current-line git-timemachine-revision (list "HEAD" "" 0 "" "" "" "") cur-line)) ;; Allow to stay on the same line
+      (goto-char (point-min))
+      (forward-line (- new-line 1))
+      (git-timemachine--set-cursor-position cursor-position)
+      (git-timemachine-mode))))
+
+;;;###autoload
+(defun git-timemachine-toggle ()
+  "Toggle git timemachine mode."
+  (interactive)
+  (if (bound-and-true-p git-timemachine-mode)
+    (git-timemachine-quit)
+    (git-timemachine)))
+
+;;;###autoload
+(defun git-timemachine ()
+  "Enable git timemachine for file of current buffer."
+  (interactive)
+  (git-timemachine--start #'git-timemachine-show-current-revision))
+
+;;;###autoload
+(defun git-timemachine-switch-branch (git-branch)
+  "Enable git timemachine for current buffer, switching to GIT-BRANCH."
+  (interactive (list (completing-read "Branch to switch to: "(vc-git-branches))))
+  (git-timemachine--start (lambda () (git-timemachine-show-latest-revision-in-branch git-branch))))
+
+(provide 'git-timemachine)
+
+;;; git-timemachine.el ends here