Every repository with this icon (
Every repository with this icon (
Home
Emacs Got Git
Egg is not a git porcelain. It shares the same goals with git aliases , make it more convenient to perform common git operations . To use egg, simply compile the egg.el file then load the egg.elc file. You can put the egg.elc file somewhere in your emacs load-path and add (require 'egg) in your .emacs file.
Once activated, egg will turn on egg-minor-mode when a file was open in a git repository.
Minor mode key-bindings
The git action that operation on a single file, are bound (via the egg-minor-mode) to a command starting with C-x v. The C-x prefix, however, is customizable. M-x customize-group RET egg would let you customize that prefix and many other options.
|key | lisp | description |
|
C-x v d|
egg-status|shows the repo’s current status.
git status && git diff && git diff —cached && …|
|
C-x v c|
egg-commit-log-edit|start editing the commit message for the current staged changes. With a prefix (
C-u C-x v c), amend HEAD instead. git commit -e …|
|
C-x v i|
egg-file-stage-current-file|stage new changes of the current file.
git add|
|
C-x v l|
egg-log|shows HEAD’s history . With a prefix (
C-u C-x v l), show history of all refs. git log|
|
C-x v o|
egg-file-checkout-other-version|checkout another version of the current file.
git checkout REV file||
C-x v u|
egg-file-cancel-modifications| unconditionally delete unstaged modifications in the current file. git checkout …|
|
C-x v v|
egg-next-action|perform the next logical action.
git dwim|
|
C-x v =|
egg-file-diff|compare file with index or other commits.
git diff…|
|
C-x v ~|
egg-file-version-other-window|show other version of the current file.
git checkout…|
|
C-x v b|
egg-start-new-branch| start a new branch from the current HEAD. git checkout -b new_branch|
|
C-x v a|
egg-file-toggle-blame-mode|enable/disable blame attributions (using overlays) in the current buffer. git blame|
Blame view mode
When blame-mode is on, the buffer is marked read-only. Disabling blame-mode will restore the original read-only mode of the buffer.

The Status Buffer
the status buffer is launched by the egg-status command. The primary usage for the status buffer:
- file-by-file or hunk-by-hunk index manipulation.
- stage a single unstaged hunk: add a single hunk from the a file to the index
- remove a single unstaged hunk: remove hunk of delta between the index and the file.
- unstage a single staged hunk: move a hunk from the index to the file.
- update the index with the (new) contents of a file.
- revert the contents of a file to match the index
- revert the contents of a file in the index to match the contents of the file in HEAD.
- resolve merge
- locate conflict marks in a file
- resolve merge using ediff3
- resolve/continue/skip/abort rebase
- locate conflict marks in a file
- resolve rebase using ediff3
Status Buffer Screenshot during rebase

During a normal edit/stage/commit cycle, the status buffer displayed 3 sections:
- Unstaged Changes section. this section show the delta between the files and the index.
- Staged Changes section. this section show the delta between the index and HEAD.
- Untracked Files section. this section files that are neither tracked nor ignored in the repository.
Status Buffer Screenshot showing the unstaged delta.

Many many parts of the status-buffer has local keymap. Example: the ‘s’ key may be bound to different elisp commands depending where the cursor currently is.
Common key-bindings for the status buffer
| key | lisp | description |
n |
egg-buffer-cmd-navigate-next |
move the cursor to the next section |
p |
egg-buffer-cmd-navigate-prev |
move the cursor to the previous section |
g |
egg-buffer-cmd-refresh |
redisplay the contents of the status buffer |
q |
quit-window |
burry the status buffer |
p |
egg-buffer-cmd-navigate-next |
move the cursor to the previous section |
c |
egg-commit-log-edit |
start editing the commit message for the current staged changes. With a prefix (C-u C-x v c), amend HEAD instead. git commit -e … |
l |
egg-log |
shows HEAD’s history . With a prefix (C-u C-x v l), show history of all refs. git log |
S |
egg-stage-all-files |
Stage all modified tracked files. git add |

The diff header
The diff header has local keymap which bind many commands to operate on the a whole contents (vs a hunk) of the file.
| key | lisp | description |
h |
egg-section-cmd-toggle-hide-show |
hide/show the entire diff of this file |
H |
egg-section-cmd-toggle-hide-show-children |
hide/show all the hunks (but keep header visible) of this file |
RET |
egg-diff-section-cmd-visit-file-other-window |
open the file in another window |
f |
egg-diff-section-cmd-visit-file |
open the file |
In the Staged Changes section, the diff header has the following extra bindings:
|
s|
egg-diff-section-cmd-unstage|unstage the staged changes (
git reset )|
In the Unstaged Changes section, the diff header has the following extra bindings:
|
u|
egg-diff-section-cmd-undo|throw away unstaged changes (
git checkout)||
s|
egg-diff-section-cmd-stage|stage the changes (
git add )|

The unmerged diff header
If the unstaged changes are actually unmerged changes, the combined-diff header has the following extra extra bindings (in addition to the bindings of a unstaged diff header)
= |
egg-diff-section-cmd-ediff3 |
launch ediff3 with ours staged contents, current-file and theirs staged_ contents |
Actually, the entire unmerged diff for the file (vs just the header) has the above extra binding.

The hunk
The diff hunk has local keymap which bind many commands to operate on the an individual diff hunk.
The visiting commands such as egg-hunk-section-cmd-visit-file-other-window try hard to locate the cursor at the exact line where the cursor was in the hunk. But since the diff between the index and HEAD can’t really be translated into the wordir’s file, the hunk-line location can fail.
| key | lisp | description |
h |
egg-section-cmd-toggle-hide-show |
hide/show this hunk |
RET |
egg-hunk-section-cmd-visit-file-other-window |
open the file in another window and locate the current hunk |
f |
egg-hunk-section-cmd-visit-file |
open the file and locate the current hunk |
In the Staged Changes section, the hunk has the following extra bindings:
|
s|
egg-hunk-section-cmd-unstage|unstage the staged hunk (
git apply --reverse )|
In the Unstaged Changes section, the has the following extra bindings:
|
u|
egg-hunk-section-cmd-undo|throw away the changes in this hunk (
patch --reverse)||
s|
egg-hunk-section-cmd-stage|stage the changes in this hunk(
git apply --cached)|
The Log Buffer
the log buffer is launched by the egg-logcommand. The primary usage for the log buffer:
- local push (updating a ref using HEAD or another ref)
- remote push (updating a remote repository)
- fetch
- merge
- rebase
- create tags and branches
- review history
Log Buffer Screenshot

The log-buffer shows history of HEAD (or with other refs). If egg-log was launched with a prefix (i.e. C-u), it will show the combined history of all refs. Some pickaxing commands like egg-search-history will pop up a log-buffer showing the history of HEAD and the pickaxed commit.
Generally, a line in the log-buffer represent a commit. The (short version of the) sha1 is shown just before the subject. If the commit are referred to by some refs, then refs would be listed just before the sha1. Their colours can be customized for easy differentiating between tags, heads and remotes.

The primary purpose of log buffer is for browing commit. Typing SPC on a commit line will fetch and show the details of commit under the cursor.

The commit line has following local key-bindings:
| key | lisp | description |
h |
egg-section-cmd-toggle-hide-show |
hide/show the details of this commit |
H |
egg-section-cmd-toggle-hide-show-children |
hide/show all the diffs of this commits (when details were fetched) |
B |
egg-log-buffer-create-new-branch |
Create a new branch starting at this commit (git branch). To create the new branch even if it would mean overwriting an existing one (with same name), use a prefix like C-u (e.g. C-u B |
b |
egg-log-buffer-start-new-branch |
Create and switch a new branch starting at this commit (git checkout -b). To create the new branch even if it would mean overwriting an existing one (with same name), use a prefix (e.g. C-u b |
o |
egg-log-buffer-checkout-commit |
Checkout the ref under the cursor or this commit (this might detach HEAD) |
t |
egg-log-buffer-tag-commit |
create a light-weight tag pointing at this commit (git tag). To create the new tag even if it would mean overwriting an existing one (with same name), use a prefix (e.g. C-u t) |
a |
egg-log-buffer-attach-head |
anchor HEAD at this commit (git reset). This command will detach HEAD. Use egg-log-buffer-checkout-commit instead if you want to attach HEAD to a branch. Normally, this command will only move HEAD and leave the index and the work dir untouched (git reset -soft). A prefix will launch a variant of this command.C-u a will reset the index as well as HEAD (git reset -mixed). C-u C-u a will reset HEAD, the index and the work dir to the current commit (git reset -hard). |
m |
egg-log-buffer-merge |
merge this commit to HEAD (git merge). To disable auto-commit, use a prefix (e.g. C-u m) |
r |
egg-log-buffer-rebase |
rebase HEAD on top this commit(git rebase). To the specify the starting commit (of the sequence of commits ending at HEAD, to be rebased onto the commit under the cursor), use a prefix (e.g. C-u r) |
If the cursor was on top of a ref. Then the following extra bindings are defined locally:
| key | lisp | description |
x |
egg-log-buffer-rm-ref |
delete the ref under the cursor (git tag -d, git branch -d, git branch -rd). To ignore safety check, use a prefix (e.g. C-u x) |
u |
egg-log-buffer-push-to-local |
local upload: use this ref to update another ref (git push . this:that ). This normally require a fast-forward update, to force non-ff update, use a prefix (e.g. C-u u) |
If the ref under the cursor was local ref. Then the following extra extra bindings are defined:
d |
egg-log-buffer-push-head-to-local |
local download: use head to update the ref under the cursor.(git push HEAD:this ). This normally requires a fast-forward update, to force non-ff update, use a prefix (e.g. C-u d) |
U |
egg-log-buffer-push-to-remote |
remote upload: update the tracking target of ref under the cursor. If the ref under the cursor wasn’t a remote tracking branch, the command will prompt for remote and target names. This command normally requires a fast-forward update, to force non-ff update, use a prefix (e.g. C-u U) |
If the ref under the cursor was instead a remote ref. Then the following extra extra bindings are defined:
d |
egg-log-buffer-fetch-remote |
remote download: download and update the ref under the cursor(git fetch) |







