Configure Git Pairs with Magit¶
Like me, you’ve probably used a git pair script at some point. There are a number of such scripts out there  and they all work the same way – creating a local git config with the pair author information.
While I used to be an avid user of the git cli, that’s changed since I switched to Magit. Unfortunately, I still need to do so when I want to setup my git pairing session. I decided to change that, partly to keep me from having to switch out of emacs but also as an exercise to improve my elisp chops.
Here are my requirements:
- Only override the commit author, not the committer.
- A single command to add the author override through the mini-buffer.
- A single command to remove the author override.
- A single command to toggle the author override.
- Persist the override across buffers.
- The overridden author value must be visible in the Magit commit popup.
After some code spelunking, I found that Magit exposes  the variable
magit-commit-arguments, defined in
git-commit.el, which holds
a list of strings representing commit arguments. While it is
customizable, my requirements call for a user experience that’s little
more dynamic than setting an emacs custom variable. But, by using this
variable, I’ll satisfy requirements
6. Time to
write some code to manipulate it!
First I’ll create a function named
let’s me add an
--author commit argument.
(defun my/git-set-author (author) "Sets the '--author' argument to the input author." (when (not (string= "" author)) (add-to-list 'magit-commit-arguments (concat "--author=" author)) (minibuffer-message (concat "Author overridden with '" author "'"))))
This works but it’s not interactive, meaning it can’t be invoked from the minibuffer, and I won’t get prompt for input. It’s a good start, though so I’ll add another function that fills in the gaps.
(defun my/git-override-author () "Activates a git commit author override using the input author." (interactive) (let ((author (read-string "i.e., A U Thor <[email protected]>: " my/magit-gc-override-author))) (my/git-set-author author)))
my/git-override-author is interactive and prompts
me with a message that’s a convenient reminder of the
format. This satisfies requirement
2. Now that I can set it, I
need to be able to remove it. The function,
my/git-remove-author-override will do that.
(defun my/git-remove-author-override () "Removes the '--author' commit argument." (interactive) (setq magit-commit-arguments (remove-if (lambda (s) (string-match "--author" s)) magit-commit-arguments)) (minibuffer-message "Author override removed."))
Great, now I can add and remove overrides! That checks off requirement
3. Time to add override toggling. To do that I’ll define the
my/magit-gc-override-author to persist the author
override. I can then update
my/git-override-author to use it as
(defun my/git-override-author () "Activates a git commit author override using the input author." (interactive) (let ((author (read-string "i.e., A U Thor <[email protected]>: " my/magit-gc-override-author))) (setq my/magit-gc-override-author author) (my/git-set-author author)))
Now I can implement
my/git-author-toggle to check of requirement
(defun my/git-author-toggle () "Toggles the git commit author override." (interactive) (if (find-if (lambda (s) (string-match "--author" s)) magit-commit-arguments) (my/git-remove-author-override) (my/git-set-author my/magit-gc-override-author)))
Finally, I’ll tie it all together through some keybindings that get
set when Magit is initialized. I really like
things like this.
(use-package magit :bind (("C-c C-p" . my/git-override-author) ("C-c C-u" . my/git-remove-author-override) ("C-c C-t" . my/git-author-toggle))) ;; Require 'magit-commit otherwise magit-commit-arguments won't be ;; initialized until you first try to commit something. (require 'magit-commit)
In the future I’ll probably add some niceties like support for selecting known pairs and support for pair initials but this is good enough for now.
|||Here are a few: pivotal/git_scripts, ryanbriones/git-pair, peterjwest/git-pair.|
|||Check out the source.|
|||I suppose this goes without saying, but never lift config without understanding what it does first!|
|||I’m constantly mucking with my Emacs configuration. It’s like a virtual garden that requires constant tending.|