When the user initiates a commit, Magit calls git commit without the
--message argument, so Git has to get the message from the user. To
do so, it creates a file such as .git/COMMIT_EDITMSG and then opens
that file in the editor specified by $EDITOR (or $GIT_EDITOR).
Magit arranges for that editor to be the Emacsclient. Once the user finishes the editing session, the Emacsclient exits and Git creates the commit, using the file’s content as the commit message.
Also see the git-commit(1) manpage.
magit-commit) ¶This transient prefix command binds the following suffix commands along with the appropriate infix arguments and displays them in a temporary buffer until a suffix is invoked.
magit-commit-create) ¶Create a new commit.
These commands modify the last (a.k.a., "HEAD") commit. The commit is modified (a.k.a., replaced) immediately. Similar commands exist for modifying other (non-HEAD) commits. Those commands are described in the following two sections. For each command in this section, we mention the respective non-HEAD commands, to make the relation explicit.
The command descriptions below mention the specific arguments they use
when calling git commit. The arguments specified in the menu are
appended to those arguments.
magit-commit-extend) ¶This command amends the staged changes to the last commit, without editing its commit message.
This command calls git commit --amend --no-edit.
With a prefix argument the committer date is not updated; without an argument it is updated.
The option magit-commit-extend-override-date can be used to inverse
the meaning of the prefix argument. Non-interactively, the optional
OVERRIDE-DATE argument controls this behavior, and the option is of
no relevance.
magit-commit-amend) ¶This command amends the staged changes to the last commit, and pops up a buffer to let the user edit its commit message.
This command calls git commit --amend --edit.
magit-commit-reword) ¶This command pops up a buffer to let the user edit the message of the latest commit. The commit tree remains unchanged and staged changes remain staged.
This command calls git commit --amend --only --edit.
With a prefix argument the committer date is not updated; without an argument it is updated.
The option magit-commit-reword-override-date can be used to inverse
the meaning of the prefix argument. Non-interactively, the optional
OVERRIDE-DATE argument controls this behavior, and the option is of
no relevance.
These commands create a new commit, which targets an existing commit, from the staged changes and/or using a new commit message. Any commit that is reachable from HEAD, including HEAD itself, can be the target.
The new commit is intended to be eventually squashed into the targeted
commit, but this is not done immediately. The squashing is done at a
later time, when you explicitly call magit-rebase-autosquash, or use
--autosquash with another rebase command.
Some of these commands require that you immediately write a new commit message, or that you immediately edit an existing message.
The new commits are called "squash" and "fixup" commits. The difference is that when a "squash" commit is squashed into its targeted commit, the user gets a chance to modify the message to be used for the final commit; while for "fixup" commits the existing message of the targeted commit is used as-is and the message of the "fixup" commit is discarded.
If point is on a reachable commit, then all of these commands target
that commit, without requiring confirmation. If point is on some
reachable commit, but you want to target another commit, use a prefix
argument, to select a commit in a log buffer dedicated to that task.
The meaning of the prefix argument can be inverted by customizing
magit-commit-squash-confirm.
The command descriptions below mention the specific arguments they use
when calling git commit. The arguments specified in the menu are
appended to those arguments.
The next two commands also exist in "instant" variants, which are
described in the next section. Those variants behave the same as the
variants described here, except that they immediately initiate an
--autosquash rebase.
magit-commit-fixup) ¶This command creates a new fixup commit from the staged changes, targeting the reachable commit at point, if any. Otherwise the user is prompted for a commit.
Use this variant if you want to correct some minor defect in the targeted commit, which does not require changes to the existing message of the targeted commit.
This command calls git commit --fixup=COMMIT --no-edit.
magit-commit-squash) ¶This command creates a new squash commit from the staged changes, targeting the reachable commit at point, if any. Otherwise the user is prompted for a commit.
Use this variant if you want a chance to make changes to the final commit message, but not until the two commits are being squashed into the final combined commit.
This command calls git commit --squash=COMMIT --no-edit.
magit-commit-alter) ¶This command creates a new fixup commit from the staged changes, targeting the reachable commit at point, if any. Otherwise the user is prompted for a commit.
Use this variant if you want to write the final commit message now, but (as for all variants in this section) do not want to immediately squash the fixup and targeted commits into a final combined commit.
This command calls git commit --fixup=amend:COMMIT --edit.
magit-commit-augment) ¶This command creates a new squash commit from the staged changes, targeting the reachable commit at point, if any. Otherwise the user is prompted for a commit.
Use this variant if you want to describe the new changes now, but want to delay writing the final message, which describes the changes in the combined commit, until you actually combine the squash and target commits into the final commit. You can think of the new message, which you write here, as a "note", to be integrated once once you write the final commit message.
This command calls git commit --squash=COMMIT --edit.
magit-commit-revise) ¶This command pops up a buffer containing the commit message of the reachable commit at point, if any. Otherwise the user is prompted for a commit to target.
Use this variant if you want to correct the message of the targeted
commit, but want to delay performing the --autosquash rebase, which
actually changes that commit.
This command calls git commit --fixup=reword:COMMIT --edit.
These commands create a new commit, which targets an existing commit, from the staged changes. Any commit that is reachable from HEAD, including HEAD itself, can be the target.
The new commit is immediately squashed into its target commit, using
an --autosquash rebase.
The command descriptions below mention the specific arguments they use
when calling git commit. The arguments specified in the menu are
appended to those arguments when calling git commit.
magit-commit-instant-fixup) ¶This command creates a fixup commit, targeting the reachable commit at point, if any. Otherwise the user is prompted for a commit. Then it instantly performs a rebase, to squash the new commit into the targeted commit.
The original commit message of the targeted commit is left untouched.
This command calls git commit --fixup=COMMIT --no-edit
and then git rebase --autosquash MERGE-BASE.
magit-commit-instant-squash) ¶This command creates a squash commit, targeting the reachable commit at point, if any. Otherwise the user is prompted for a commit. Then it instantly performs a rebase, to squash the new commit into the targeted commit.
During the rebase phase the user is asked to author the final commit message, based on the original message of the targeted commit.
This command calls git commit --squash=COMMIT --no-edit
and then git rebase --autosquash MERGE-BASE.
Whether the relevant diff is automatically shown when committing.
Whether to ask to stage all unstaged changes when committing and nothing is staged.
Hook run after creating a commit without the user editing a message.
This hook is run by magit-refresh if this-command is a member
of magit-post-commit-hook-commands. This only includes commands
named magit-commit-* that do not require that the user edits
the commit message in a buffer.
Also see git-commit-post-finish-hook.
Whether to inhibit use of same window when showing diff while committing.
When writing a commit, then a diff of the changes to be committed is automatically shown. The idea is that the diff is shown in a different window of the same frame and for most users that just works. In other words most users can completely ignore this option because its value doesn’t make a difference for them.
However for users who configured Emacs to never create a new window even when the package explicitly tries to do so, then displaying two new buffers necessarily means that the first is immediately replaced by the second. In our case the message buffer is immediately replaced by the diff buffer, which is of course highly undesirable.
A workaround is to suppress this user configuration in this particular case. Users have to explicitly opt-in by toggling this option. We cannot enable the workaround unconditionally because that again causes issues for other users: if the frame is too tiny or the relevant settings too aggressive, then the diff buffer would end up being displayed in a new frame.
Whether the commit targeted by squash and fixup has to be confirmed.
When non-nil then the commit at point (if any) is used as default
choice. Otherwise it has to be confirmed. This option only affects
magit-commit-squash and magit-commit-fixup. The "instant" variants
always require confirmation because making an error while using
those is harder to recover from.
Whether using magit-commit-extend changes the committer date.
Whether using magit-commit-reword changes the committer date.
After initiating a commit as described in the previous section, two new buffers appear. One shows the changes that are about to be committed, while the other is used to write the message.
Commit messages are edited in an edit session - in the background git
is waiting for the editor, in our case emacsclient, to save the commit
message in a file (in most cases .git/COMMIT_EDITMSG) and then return.
If the editor returns with a non-zero exit status then git does not
create the commit. So the most important commands are those for
finishing and aborting the commit.
with-editor-finish) ¶Finish the current editing session by returning with exit code 0. Git then creates the commit using the message it finds in the file.
with-editor-cancel) ¶Cancel the current editing session by returning with exit code 1. Git then cancels the commit, but leaves the file untouched.
In addition to being used by git commit, messages may also be stored
in a ring that persists until Emacs is closed. By default the message
is stored at the beginning and the end of an edit session (regardless
of whether the session is finished successfully or was canceled). It
is sometimes useful to bring back messages from that ring.
git-commit-save-message) ¶Save the current buffer content to the commit message ring.
git-commit-prev-message) ¶Cycle backward through the commit message ring, after saving the current message to the ring. With a numeric prefix ARG, go back ARG comments.
git-commit-next-message) ¶Cycle forward through the commit message ring, after saving the current message to the ring. With a numeric prefix ARG, go back ARG comments.
By default the diff for the changes that are about to be committed are
automatically shown when invoking the commit. To prevent that, remove
magit-commit-diff from server-switch-hook.
When amending to an existing commit it may be useful to show either the changes that are about to be added to that commit or to show those changes alongside those that have already been committed.
magit-diff-while-committing) ¶While committing, show the changes that are about to be committed. While amending, invoking the command again toggles between showing just the new changes or all the changes that will be committed.
magit-pop-revision-stack) ¶This command inserts a representation of a revision into the current buffer. It can be used inside buffers used to write commit messages but also in other buffers such as buffers used to edit emails or ChangeLog files.
By default this command pops the revision which was last added to
the magit-revision-stack and inserts it into the current buffer
according to magit-pop-revision-stack-format. Revisions can be put
on the stack using magit-copy-section-value and
magit-copy-buffer-revision.
If the stack is empty or with a prefix argument it instead reads a revision in the minibuffer. By using the minibuffer history this allows selecting an item which was popped earlier or to insert an arbitrary reference or revision without first pushing it onto the stack.
When reading the revision from the minibuffer, then it might not be possible to guess the correct repository. When this command is called inside a repository (e.g., while composing a commit message), then that repository is used. Otherwise (e.g., while composing an email) then the repository recorded for the top element of the stack is used (even though we insert another revision). If not called inside a repository and with an empty stack, or with two prefix arguments, then read the repository in the minibuffer too.
This option controls how the command magit-pop-revision-stack
inserts a revision into the current buffer.
The entries on the stack have the format (HASH TOPLEVEL) and this
option has the format (POINT-FORMAT EOB-FORMAT INDEX-REGEXP), all
of which may be nil or a string (though either one of EOB-FORMAT
or POINT-FORMAT should be a string, and if INDEX-REGEXP is
non-nil, then the two formats should be too).
First INDEX-REGEXP is used to find the previously inserted entry,
by searching backward from point. The first submatch must match
the index number. That number is incremented by one, and becomes
the index number of the entry to be inserted. If you don’t want
to number the inserted revisions, then use nil for INDEX-REGEXP.
If INDEX-REGEXP is non-nil then both POINT-FORMAT and EOB-FORMAT
should contain \"%N\", which is replaced with the number that was
determined in the previous step.
Both formats, if non-nil and after removing %N, are then expanded
using git show --format=FORMAT ... inside TOPLEVEL.
The expansion of POINT-FORMAT is inserted at point, and the expansion of EOB-FORMAT is inserted at the end of the buffer (if the buffer ends with a comment, then it is inserted right before that).
Some projects use pseudo headers in commit messages. Magit colorizes such headers and provides some commands to insert such headers.
A list of Git pseudo headers to be highlighted.
git-commit-insert-pseudo-header) ¶Insert a commit message pseudo header.
git-commit-ack) ¶Insert a header acknowledging that you have looked at the commit.
git-commit-review) ¶Insert a header acknowledging that you have reviewed the commit.
git-commit-signoff) ¶Insert a header to sign off the commit.
git-commit-test) ¶Insert a header acknowledging that you have tested the commit.
git-commit-cc) ¶Insert a header mentioning someone who might be interested.
git-commit-reported) ¶Insert a header mentioning the person who reported the issue being fixed by the commit.
git-commit-suggested) ¶Insert a header mentioning the person who suggested the change.
git-commit-mode is a minor mode that is only used to establish certain
key bindings. This makes it possible to use an arbitrary major mode
in buffers used to edit commit messages. It is even possible to use
different major modes in different repositories, which is useful when
different projects impose different commit message conventions.
The value of this option is the major mode used to edit Git commit messages.
Because git-commit-mode is a minor mode, we don’t use its mode hook
to setup the buffer, except for the key bindings. All other setup
happens in the function git-commit-setup, which among other things runs
the hook git-commit-setup-hook.
Hook run at the end of git-commit-setup.
The following functions are suitable for this hook:
Save the current buffer content to the commit message ring.
After this function is called, ChangeLog entries are treated as paragraphs.
Turn on auto-fill-mode.
Turn on Flyspell mode. Also prevent comments from being checked and finally check current non-comment text.
Propertize the diff shown inside the commit message buffer. Git
inserts such diffs into the commit message template when the
--verbose argument is used. magit-commit by default does not offer
that argument because the diff that is shown in a separate buffer is
more useful. But some users disagree, which is why this function
exists.
Hyperlink bug references in the buffer.
Show usage information in the echo area.
Hook run after the user finished writing a commit message.
This hook is only run after pressing C-c C-c 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
doing so takes Git longer than one second, 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.
Git-Commit highlights certain violations of commonly accepted commit message conventions. Certain violations even cause Git-Commit to ask you to confirm that you really want to do that. This nagging can of course be turned off, but the result of doing that usually is that instead of some code it’s now the human who is reviewing your commits who has to waste some time telling you to fix your commits.
The intended maximal length of the summary line of commit messages. Characters beyond this column are colorized to indicate that this preference has been violated.
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.
By default the only member is git-commit-check-style-conventions.
This function checks for violations of certain basic style conventions. For each violation it asks users if they want to proceed anyway.
This option controls what conventions the function by the same name
tries to enforce. The value is a list of self-explanatory symbols
identifying certain conventions; non-empty-second-line and
overlong-summary-line.