aboutsummaryrefslogtreecommitdiff
path: root/README.org
blob: 396c3cb20a04608f529ab1f3547f62b370ea4025 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#+TITLE: Magit Tutorial
#+AUTHOR: Christopher Baines
#+EMAIL: mail@cbaines.net

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
[[mailto:mail@cbaines.net][mail@cbaines.net]].

* Getting started
** 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 [[https://magit.vc/manual/magit/Installing-from-an-Elpa-Archive.html#Installing-from-an-Elpa-Archive][Magit manual to install from
the Elpa archive]].

** Bind =C-x g= to =magit-status=

As described in the [[https://magit.vc/manual/magit.html#Getting-Started][Getting started]] guide in the Magit manual, this
keybinding can be useful.

Add the following to your =.emacs= file.

#+BEGIN_EXAMPLE
(global-set-key (kbd "C-x g") 'magit-status)
#+END_EXAMPLE

** 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.

#+BEGIN_EXAMPLE
M-x magit-clone RET https://git.cbaines.net/magit-tutorial ~/magit-tutorial RET
#+END_EXAMPLE

** Open the tutorial, and continue from Emacs

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

#+BEGIN_EXAMPLE
C-x C-f ~/magit-tutorial/README.org RET
#+END_EXAMPLE

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

* 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.

* Comitting

Add some text in to the empty example block below.

#+BEGIN_EXAMPLE

#+END_EXAMPLE

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.

* 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=.

* Adding remotes

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

** 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.

** 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.

** 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.

* Using Branches

** 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.

** 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.

* Pushing [[info:magit#Pushing][(documentation)]]

For experimenting with pushing, switch back to the =test-branch=
branch ([[*Switching branches][notes]]).

** 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=.

** 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 ([[*Comitting][notes]]).

#+BEGIN_EXAMPLE

#+END_EXAMPLE

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.

* Resetting

** 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.

** 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][Pulling]].

* 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 ([[*Setting the upstream branch][as defined
previously]]). Like pushing, the are a few options for pulling, but for
now this is the only one needed.

* 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.

** 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.

#+BEGIN_EXAMPLE

#+END_EXAMPLE

#+BEGIN_EXAMPLE

#+END_EXAMPLE

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

** 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.

* Splitting commits

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

** Preparation

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

#+BEGIN_EXAMPLE

#+END_EXAMPLE

#+BEGIN_EXAMPLE

#+END_EXAMPLE

Then commit the additions as a single commit.

** 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.

** 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.

** 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.

* Viewing a file at a particular revision

* 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. [[https://github.com/syohex/emacs-git-gutter][git-gutter.el]] provides indications within each buffer
when you add, remove or modify the contents.

[[https://github.com/rmuslimov/browse-at-remote][browse-at-remote.el]] allows you to jump from Emacs to common Git
hosting providers, for example, a specific commit.