aboutsummaryrefslogtreecommitdiff

This tutorial is designed as a practical introduction to Magit, both core features like committing, pushing and pulling, as well as more complicated operations like splitting commits.

Problem reports, fixes and patches are all welcome. Send them to mail@cbaines.net.

1. Getting started

1.1. Install Magit

There are different ways of installing Magit, if there is one suited to your platform then try that first.

Otherwise, follow the instructions in the Magit manual to install from the Elpa archive.

1.2. Bind C-x g to magit-status

As described in the Getting started guide in the Magit manual, this keybinding can be useful.

Add the following to your .emacs file.

(global-set-key (kbd "C-x g") 'magit-status)

1.3. Clone this repository

Use the following command to clone the repository for the tutorial. Change ~/magit-tutorial to the directory you wish to use if that is different.

M-x magit-clone RET https://git.cbaines.net/magit-tutorial ~/magit-tutorial RET

1.4. Open the tutorial, and continue from Emacs

Now you have the tutorial on your computer, open it in Emacs and continue.

C-x C-f ~/magit-tutorial/README.org RET

This file and the repository itself are used for the tutorial.

2. Status

Opening the status window is the main way to interact with Magit. This can be done by running M-x magit-status or M-x g if you have setup that binding.

3. Comitting

Add some text in to the empty example block below.


Use M-x g to open the Magit status window. If you haven't saved this file, you'll be prompted to save it, answer y to save the file.

Once in the status window, stage the changes by pressing s when you have the file highlighted (the cursor should be on the line which says modified README.org.

Once you've staged the file, it's time to commit it. First, remember these commands to use after you've written the commit message, use C-c C-c to finish the commit and if you wish to cancel, use C-c C-k.

When you commit with Magit, a new window will be opened to enter the commit message. Press c and then c again to commit, which will open a window to prompt for the commit message. Use the C-c C-c command mentioned above to confirm the message once you've written it, and finish the commit.

4. Viewing the log

From the Magit status window, you can view a log of commits by pressing l and then l again.

You can move up and down the log by pressing p and n respectively.

To view the details for an individual commit, press RET (also known as Enter). To close the window, press q.

5. Adding remotes

A remote can be added by pressing M from the Magit status window.

5.1. Creating a new (temporary) Git repository

For the purposes of the tutorial, create a temporary Git repository on your computer to use as a remote.

The magit-init command can be used to create a new Git repository.

In this case, press M-x magit-init, and then enter an appropriate path. Remember where you've created the temporary repository.

5.2. Adding the test remote

To use the temporary Git repository as a remote, from the Magit status window, press M to bring up the Remote options, then a for adding a new remote.

Enter test as the remote name, and then the full filename for the temporary Git repository you created above as the remote URL. When prompted to set this remote as the pushDefault, answer n for no.

5.3. Easily viewing remotes and branches

From the Magit status window, press y to get an overview of your local branches, and those on all of the remotes. Press q to return to the Magit status window.

6. Using Branches

6.1. Creating a new branch

To create a new branch, from the Magit status window, press b and then c, then select the starting point, in this case, use the default master, so just press RET. After that enter test-branch as the branch name and press RET once more.

Your now working on the test-branch branch. At the top of the Magit status window, you should see the branch name displayed.

6.2. Switching branches

To switch branch press b and then b again. In this case, switch back to the master branch, so just press RET when prompted for the branch to switch to.

7. Pushing (documentation)

For experimenting with pushing, switch back to the test-branch branch (notes).

7.1. Explicit pushing

To push, from the Magit status window press P. For the purposes of this tutorial, lets push the master branch of the local repository to a branch called test-branch in the test remote. To do this, after pressing P, select e for elsewhere, then enter test/test-branch and press RET.

7.2. Setting the upstream branch

Explicit pushing is useful, but usually you'll be pushing to a single main remote. When doing this, it can be useful to set the "upstream" branch, and have Git remember this.

Press P to begin pushing as before, then u to select the @{upstream} option. When prompted for the branch, select test/test-branch.

Then, put some text in the following example block, and commit the change (notes).


Once you're done committing, return to the Magit status window, it should say you're ahead of the upstream branch by one commit.

Press P and then u as before to push this new commit. As Git has remembered the upstream branch, you won't need to select it manually.

8. Resetting

8.1. Soft reset

There are multiple different types of reset actions, one is a soft reset, this is the default in Magit.

Press x then type HEAD^ to discard the commit created in the previous section. Note that a soft reset retains the actual changes within the commit.

8.2. Hard reset

A hard reset will discard both the changes, and the commit. Press X to get the list of reset options, then h to select a hard reset. Enter test/test-branch when prompted where to reset to. This action will have undone the previous reset.

Perform another hard reset, this time to HEAD^ like the soft reset, to get the repository ready for Pulling.

9. Pulling

At this point, the local test-branch should be one commit behind the remote test-branch. Pulling will fetch and merge that commit in to the local branch.

Press F, the u to pull from the upstream branch (as defined previously). Like pushing, the are a few options for pulling, but for now this is the only one needed.

10. Interactive rebasing

Interactive rebasing is very powerful, but can be quite tricky. Magit can help with setting up an interactive rebase as well as providing context and information while it's underway.

10.1. Preparation

Enter some text in the following two example sections. Commit the change to the first section in one commit, and then the second section in a second commit.



The interactive rebase we'll try will reverse the order of these commits.

10.2. Starting the interactive rebase

From the Magit status window, press r then i to select the starting point for the interactive rebase. Move down (using C-n) to the first of the commits you just created, and press C-c C-c to start the interactive rebase.

This will open a buffer for inputting the operations, you should see the supported operations at the bottom of the buffer. In this case, use the M-n and M-p to reverse the order of the commits. Press C-c C-c to finish the interactive rebase.

11. Splitting commits

To split a commit, you can combine Magit's ability to revert portions of a commit with an interactive rebase.

11.1. Preparation

First, lets create a single commit to split. Add some text to both of the following example blocks.



Then commit the additions as a single commit.

11.2. Starting the interactive rebase

As the commit needing splitting is the most recent, it's not necessary to rebase to edit the right commit, however, in general, you may need to interactively rebase, and choose to edit the commit you intend to split.

In the Magit status window, begin the interactive rebase, and then edit the most recent commit.

Once you've begun the rebase, in the status window, select the commit to split and press RET (Enter) to show the full details.

11.3. The actual splitting

To split the contents of the commit, we are going to remove some parts from it. To do that, we can revert those parts, stage that change, then revert the staged changes. Once the staged changes have been reverted, those changes can be appended to the commit, effectively removing that part of the commit. Once this is done, the extracted part of the commit can then be staged and committed.

First, select the part of the commit to remove and split out. This can be a file, or a part of a file. To select individual lines, move the cursor to the start or end of the section, use C-Space to start selecting lines, and then n or p to move up or down.

Once the target region has been selected, use v to begin reverting the region, press y to confirm. Then stage the unstaged changes, select them and press s. Once this is done, revert the staged changes, move the cursor to the "Staged changes" section, press v and then y to confirm.

Then, amend the current commit by pressing c then a. Once this is done, stage the unstaged changes, and commit them. When you're finished committing the unstaged changes, continue the rebase to finish.

11.4. Splitting one commit in to more than two commits

If you wish to split one commit in to more than two commits, then you can repeat the above process again once finished, or revert all the parts you wish to split out, and then stage and commit the appropriate parts of those unstaged changes.

12. Viewing a file at a particular revision

12.1. With magit-find-file

Press M-x magit-find-file select the revision (e.g. HEAD^^) and press RET to select the default file.

12.2. With VC (docs)

The Emacs version control interface (called VC) supports viewing a file at a specific revision, press C-x v ~, then enter the desired revision (e.g. HEAD^^).

13. Next steps

From the Magit status buffer, press ? to get the full list of commands.

You can view the Magit manual within Emacs, start by pressing C-h i and then navigating to the Magit section.

There are packages other than Magit that extend Emacs to work with Git repositories. git-gutter.el provides indications within each buffer when you add, remove or modify the contents.

browse-at-remote.el allows you to jump from Emacs to common Git hosting providers, for example, a specific commit.