# git contribution layer for Spacemacs
![git](img/git.png) ![github](img/github.png)
**Table of Contents**
- [git contribution layer for Spacemacs](#git-contribution-layer-for-spacemacs)
- [Description](#description)
- [Install](#install)
- [Layer](#layer)
- [Github support](#github-support)
- [Magit status fullscreen](#magit-status-fullscreen)
- [Magit auto-complete](#magit-auto-complete)
- [Magit SVN plugin](#magit-svn-plugin)
- [Git gutter](#git-gutter)
- [Git](#git)
- [Working with Git](#working-with-git)
- [Magit](#magit)
- [Commit message edition buffer](#commit-message-edition-buffer)
- [Interactive rebase buffer](#interactive-rebase-buffer)
- [Quick guide for recurring use cases in Magit](#quick-guide-for-recurring-use-cases-in-magit)
- [Git time machine](#git-time-machine)
- [Git gutter](#git-gutter)
- [Github support](#github-support)
- [magit-gh-pulls](#magit-gh-pulls)
- [gist.el](#gistel)
- [Browse files](#browse-files)
## Description
This layers adds extensive support for [git][].
Features:
- git repository management the indispensable [magit][] package
- [git-flow][] add-on for magit.
- quick in buffer history browsing with [git-timemachine][]
- quick in buffer last commit message per line with [git-messenger][]
- colorize buffer line by age of commit with [smeargle][]
- git gutter in fringe with [git-gutter][]
This layer also provides support for Github with:
- [magit-gh-pulls][]: handy `magit` add-on to manage Github pull requests.
- [gist.el][]: full-featured mode to browse and post Githug gists.
- [github-browse-file][] and [git-link][]: quickly browse github URL in your
browser.
New to Magit? Checkout the [official intro][].
## Install
### Layer
To use this contribution add it to your `~/.spacemacs`
```elisp
(setq-default dotspacemacs-configuration-layers '(git))
```
### Github support
To enable the Github support set the variable `git-enable-github-support`
to `t` in your `dotspacemacs/init` function.
```elisp
(defun dotspacemacs/init ()
(setq-default git-enable-github-support t)
)
```
### Magit status fullscreen
To display the `magit status` buffer in fullscreen set the variable
`git-magit-status-fullscreen` to `t` in your `dotspacemacs/init` function.
```elisp
(defun dotspacemacs/init ()
(setq-default git-magit-status-fullscreen t)
)
```
### Magit auto-complete
Magit auto-complete feature is enabled. For this feature to work best you
have to setup your Git repository directory in your `dotspacemacs/config`
function, this is the folder where you keep all your git-controlled projects
(the path should end up with a `/` to respect Emacs conventions):
```elisp
(setq magit-repo-dirs '("~/repos/"))
```
For more information, see [Magit-User-Manual#Status][]
### Magit SVN plugin
For convenience the magit SVN plugin can be activated directly in the Git
layer by setting the variable `git-enable-magit-svn-plugin` to `t`.
```elisp
(defun dotspacemacs/init ()
(setq-default git-enable-magit-svn-plugin t)
)
```
### Git gutter
In graphical environment `Spacemacs` will display [git-gutter][] icons in
the fringe by default.
It is possible to disable the usage of the fringe by setting the variable
`git-gutter-use-fringe` to `nil` in the `dotspacemacs/init` function:
```elisp
(defun dotspacemacs/init ()
(setq-default git-gutter-use-fringe nil)
)
```
### Git
Of course if your OS does not ship with git (!) you'll have to install it
on your machine, [download page][].
## Working with Git
Git commands (start with `g`):
Key Binding | Description
---------------------------|------------------------------------------------------------
SPC g b | open a `magit` blame
SPC g C | commit changes
SPC g h c | clear highlights
SPC g h h | highlight regions by age of commits
SPC g h t | highlight regions by last updated time
SPC g l | open a `magit` log
SPC g s | open a `magit` status window
SPC g m | display the last commit message of the current line
SPC g t | launch the git time machine
- Highlight by age of commit or last update time is provided by
[smeargle][].
- Git time machine is provided by [git-timemachine][].
- Git last commit message per line is provided by
[git-messenger][]
### Magit
`Spacemacs` uses [magit][] to manage Git repositories.
To open a `status buffer`, type in a buffer of a Git repository:
g s
`hjkl` navigation is enabled in all Magit buffers. The default Magit keys
on `hjkl` (if they exist) are remapped on `HJKL`.
Here are the often used bindings inside a `status buffer`:
Key Binding | Description
------------------|------------------------------------------------------------
/ | evil-search
$ | open `command output buffer`
c c | open a `commit message buffer`
b b | checkout a branch
b c | create a branch
b v | open the `branch manager buffer`
f f | fetch changes
F -r F | pull and rebase
h | go left
j | go down
C-jk | go up
K | discard changes
C-kl | go right
L l | open `log buffer`
n | next search occurrence
C-nN | previous search occurrence _or_ SVN sub-menu
P P | push
C-pq | quit
s | on a file or hunk in a diff: stage the file or hunk
+ | on a hunk: increase hunk size
- | on a hunk: decrease hunk size
S | stage all
TAB | on a file: expand/collapse diff
u | on a staged file: unstage
U | unstage all staged files
v | `visual state`
V | `visual-line state`
C-v | revert item at point
z z | stash changes
### Commit message edition buffer
In a commit message buffer press C-c C-c or SPC m c c
to commit the changes with the entered message.
Pressing C-c C-k or SPC m k will discard the commit
message.
Key Binding | Description
----------------------|--------------------------------------------------------
h | go left
j | go down
k | go up
l | go right
SPC m c c | commit
SPC m k | abort
### Interactive rebase buffer
Key Binding | Description
----------------------|--------------------------------------------------------
c | pick
e | edit
f | fixup
h | go left
j | go down
J | move line down
k | go up
K | move line up
C-k | kill line
l | go right
r | reword
s | squash
u | undo
x | execute
y | insert
SPC m c c | rebase
SPC m k | abort
### Quick guide for recurring use cases in Magit
- Amend a commit:
- `L l` to open `log buffer`
- `c a` on the commit you want to amend
- `C-c C-c` to submit the changes
- Squash last commit:
- `L l` to open `log buffer`
- `E` on the second to last commit, it opens the `rebase buffer`
- `j` to put point on last commit
- `s` to squash it
- `C-c C-c` to continue to the `commit message buffer`
- `C-c C-c` again when you have finished to edit the commit message
- Force push a squashed commit:
- in the `status buffer` you should see the new commit unpushed and the
old commit unpulled
- `P -f P` for force a push (**beware** usually it is not recommended to
rewrite the history of a public repository, but if you are *sure* that you
are the only one to work on a repository it is ok - i.e. in your fork).
- Add upstream remote (the parent repository you have forked):
- `b v` to open the `branch manager buffer`
- `a` to add a remote, type the name (i.e. `upstream`) and the URL
- Pull changes from upstream (the parent repository you have forked) and push:
- `F -r C-u F` and choose `upstream` or the name you gave to it
- `P P` to push the commit to `origin`
### Git time machine
[git-timemachine] allows to quickly browse the commits of the current buffer.
Key Binding | Description
--------------------|------------------------------------------------------------
SPC g t | start git timemachine and initiate micro-state
c | show current commit
n | show next commit
N | show previous commit
p | show previous commit
q | leave micro-state and git timemachine
Y | copy current commit hash
### Git gutter
With [git-gutter][] it is possible to navigate between hunks, stage them and
revert them.
Git gutter hunks commands start with `gh`:
Key Binding | Description
----------------------|------------------------------------------------------------
SPC g h n | next hunk in buffer
SPC g h N | previous hunk in buffer
SPC g h r | revert current hunk
SPC g h s | stage current hunk
SPC g h p | preview current hunk
`Spacemacs` has custom fringe bitmaps for [git-gutter-fringe][git-gutter]:
Symbol | Description
:-------------------------------:|-----------------
![git-new](img/git-new-line.png) | new line
![git-del](img/git-del-line.png) | at least one line has been deleted
![git-mod](img/git-mod-line.png) | modified line
## Github support
### magit-gh-pulls
In a `magit status` buffer (SPC g s):
Key Binding | Description
--------------------|------------------------------------------------------------
# g g | get a list of all PRs in the current repository
# g f | fetch the commits associated to the current PR
# g b | create a branch for the current PR
# g m | merge the PR with current branch
Note that `magit-gh-pulls` will try to fast-forward the PRs whenever it is
possible.
### gist.el
Key Binding | Description
----------------------|------------------------------------------------------------
SPC g g b | create a public gist with the buffer content
SPC g g B | create a private gist with the buffer content
SPC g g l | open the gist list buffer
SPC g g r | create a public gist with the region content
SPC g g R | create a private gist with the region content
In the gist list buffer:
Key Binding | Description
-----------------------------|------------------------------------------------------------
/ | evil search
+ | add buffer to gist
- | remove file for gist
b or o | open current gist in browser
f | fetch current gist
g | refresh the list
h | go left
j | go down
k | go up
K | kill current gist
l | go right
n | next search occurrence
N | next previous occurrence
v | `visual state`
V | `visual-line state`
y | print URL and copy it
### Browse files
Key Binding | Description
----------------------|------------------------------------------------------------
SPC g f b | browse to file on github
SPC g f c | browse to file on github/bitbucket/etc (on current line at commit)
SPC g f C | only copy the generated link on the kill ring
SPC g f l | browse to file on github/bitbucket/etc (on current line position)
SPC g f L | only copy the generated link on the kill ring
**Notes**
- You can use the universal argument `SPC u` to select a remote repository.
- You can use `git-link` on a region.
- When the link is opened, the URL is also copied in the kill ring, you can
override this behavior by setting the variable `git-link-open-in-browser` to
`nil`.
[git]: http://git-scm.com/
[download page]: http://git-scm.com/downloads
[git-gutter]: https://github.com/syohex/emacs-git-gutter-fringe
[magit]: http://magit.github.io/
[official intro]: https://magit.github.io/master/magit.html#Introduction
[Magit-User-Manual#Status]: https://magit.github.io/master/magit.html#Status
[git-flow]: https://github.com/jtatarik/magit-gitflow
[smeargle]: https://github.com/syohex/emacs-smeargle
[git-timemachine]: https://github.com/pidu/git-timemachine
[git-messenger]: https://github.com/syohex/emacs-git-messenger
[magit-gh-pulls]: https://github.com/sigma/magit-gh-pulls
[gist.el]: https://github.com/defunkt/gist.el
[git-link]: https://github.com/sshaw/git-link
[github-browse-file]: https://github.com/osener/github-browse-file