Chapa 1)


Learning git with "try it!"s (and eev) - subtitles

The main page about this video is here.
Its subtitles in Lua are here.
The rest of this page contains a conversion of the subtitles in Lua
to a slightly more readable format.


00:00 Hi! My name is Eduardo Ochs, and the title of this
00:03 video is "Learning git with `try it!'s (and eev)".
00:07 I'm the author of an Emacs package called
00:09 eev, that most people find hard to
00:12 understand, but its tutorials have
00:16 lots of things to try, and
00:18 lots of examples, and when people start
00:21 running the examples they...
00:24 sometimes they feel that everything
00:27 makes sense. Whatever...

00:28 Let me start with a bit of
00:31 context. A few weeks ago, in December
00:34 of 2023, something broke in the scripts
00:37 that I use to update the
00:39 git repository of eev, and the parts
00:42 that kept the two branches of eev
00:44 in sync stopped working - and I had to
00:47 merge the two branches many times.

00:50 I'm very bad with merging... each merge
00:53 took me hours and put me in panic - I
00:58 was very afraid of doing wrong things
01:01 that I wouldn't be able to undo later...

01:03 by the way, I'm very bad with git...
01:07 and I'm good with programs that
01:10 let me do small reproducible tests...
01:13 preferably in REPLs.

01:18 A few years ago I tried to
01:20 create a way to learn git using REPLs and
01:24 reproducible tests, and I felt that it
01:27 was time to work on that again.

The animation

01:30 And by the way, about this figure here...
01:34 my presentation at the last EmacsConf, the
01:37 EmacsConf 2023, was called "REPLs in strange
01:41 places: Lua, LaTeX, LPeg, LPegRex and TikZ",
01:45 and this figure here is part of an
01:48 animation that I did using these
01:52 techniques, and TikZ...

01:53 and the full animation is here and
01:56 it shows how we can create a complex git
01:59 repository
02:00 with several
02:02 branches and with a merge here...
02:06 step by step. So, these things show
02:10 the names of the commits, the graph
02:13 of the commits, the branches, how
02:17 the branches move from one commit to
02:20 another one... the red dot here is the HEAD...

02:28 whatever. Anyway the focus of this
02:31 presentation is on the "try it!"s.
02:34 Let me run this thing here to
02:37 activate screenkey... so now people
02:41 can see the keys that I'm typing...

02:45 and let me show the "try it"s. Note that I
02:48 have eev installed, and I have this
02:51 indication here that eev-mode is active...
02:54 if we click on that with mouse-2 it
02:58 shows the main keys of eev...

03:03 let's go to this sandboxed tutorial,
03:08 that is the tutorial about git, that
03:11 is what I'm going to show today...

03:14 it lists some prerequisites
03:18 here, but whatever...
03:20 the introduction starts with
03:24 a mention of a tutorial on git
03:27 with a free license.

03:28 It suggests that we download this thing here
03:33 using brep, and
03:37 brep is explained
03:39 here... the idea is that we can put the
03:42 point here, type M-x brep, and then it
03:46 will show a temporary buffer with
03:49 a script for downloading a
03:51 temporary copy of this
03:54 PDF...
03:58 done. And and now we can execute
04:02 these two sexps here to define short
04:07 hyperlinks to that PDF...

04:11 let's take a look at that PDF... note
04:15 that it has several figures here... for
04:18 example, this figure here that
04:20 shows the HEAD, the circles are commit
04:24 objects, triangles are tree objects,
04:27 squares are blob objects...
04:30 and then it has diagrams with
04:34 another shape and other
04:36 conventions, then similar diagrams but
04:40 with a more complex structure... then
04:43 here's another thing... so several kinds of
04:47 diagrams, and here they even have colors!

04:50 Anyway, let me go back...
04:54 this is a diagram that is going
04:58 to be very important for us. This is a
05:00 diagram that appears in one
05:03 document that comes with git, it's called
05:05 gitrevisions... if I open this manpage
05:10 here, it is
05:13 here... note that this link here not only
05:16 opens this manpage but also searches
05:19 for this string in that manpage, so it
05:21 goes straight to the middle of the manpage...

05:24 and here the man page says: "here is
05:28 an illustration by John Loeliger" - and I'm going
05:31 to refer to this kind of diagram here as
05:34 a "Loeliger diagram". This is not the official
05:37 name, of course...

05:39 so this is THE Loeliger diagram -
05:43 for me it's the canonical example
05:47 of a Loeliger diagram... and
05:51 things that are similar to this one I
05:53 will also call them as Loeliger diagrams...

05:57 we saw... sorry...
06:02 we saw here how
06:05 this Loeliger diagram with the names
06:09 of the branches can
06:12 be created step by step, so this is the
06:16 the final Loeliger diagram of a certain git
06:20 repository, and the other Loeliger diagrams
06:24 show intermediate steps of how to create
06:27 a git repository with that structure.

06:42 And in this tutorial - in this
06:46 intro here, find-git-intro,
06:48 I will explain a way to create
06:51 a git repository corresponding to this
06:54 Loeliger diagram here, and a lot more.

Try it! (No prerequisites)

06:57 Let me first show something
07:00 that doesn't have any prerequisites - I
07:03 mean, if you have eev installed then
07:07 you probably know how to turn on eev-mode,
07:11 which is this thing here... if eev-mode is
07:14 on
07:16 then
07:18 f8 is going to do this: it either sends
07:21 the current line to another Emacs buffer or
07:24 executes the current line if it starts
07:26 with a red star...

07:28 my example with no
07:32 prerequisites is in this page here...
07:36 so here we have an animation of how
07:40 that git repository can be constructed,
07:42 and we here we have this block here that
07:44 is an eepitch block. You can just copy...

07:53 we can just copy and paste this thing
07:57 here to an Emacs buffer,
08:00 and if
08:03 we execute this
08:06 thing these bullets here behave in
08:09 exactly the same way as the red stars, so
08:13 if I type f8 here three times it creates
08:16 a target buffer here running bash... note
08:20 that it says bash here, and it says bash
08:23 here... and now if I type f8 on the other
08:26 lines the lines will be sent to the
08:28 target buffer as if a user were
08:34 typing the lines one by one.

08:37 So here at the beginning I define
08:41 an environment variable called N and
08:45 several shell functions... and then here I
08:48 initialize a git repository and then I
08:51 give these commmands here.

08:53 Note that the commands... they
08:57 modify the file1 several times,
09:01 they have several "Commit"s, they create
09:02 new branches, they switch branches in
09:05 many points... and there's this obscure
09:10 command here, that merges two branches...

09:15 and if we execute this sexp
09:19 here it will show the result. The result
09:21 is in this directory here, /tmp/eevgit-test1/,
09:24 and this will run gitk
09:28 on that repository with certain
09:32 command-line options. It will show that
09:35 the contents of that repository is this...

09:38 this is the same tree as
09:41 before, but displayed in a
09:45 slightly messier way...

09:48 So, this was the first example -
09:51 one in which we just had to
09:55 copy this thing here to an Emacs buffer
09:59 and then execute this thing with f8s.


10:02 Now let's see the examples that are in...
10:06 in find-git-intro.

10:19 This section 1 shows some
10:22 preparations that we need to run.
10:26 We need to check that we have bash, git and
10:29 gitk installed, then we have to run
10:32 these things here just to make sure that
10:34 we have copies
10:36 of two files and that the
10:40 copies in this machine are the same
10:45 as the upstream copies...

10:47 after getting these two things
10:50 we can run these things here to access
10:55 the PDF with a flipbook animation -
10:59 in which each page is a frame of an
11:03 animation...
11:07 here - by the way, if you want to
11:10 understand what these things do
11:12 the trick is that you just have to duplicate
11:14 these lines and add a "find-" at the
11:18 beginning of each which function name here...
11:21 so instead of code-pdf-page and code-pdf-text
11:24 we will have find-code-pdf-page and
11:27 find-code-pdf-text, and if we execute
11:32 these things here... for example this
11:35 one... it will show us a temporary buffer
11:38 that
11:39 explains what this version here would do.
11:43 So this does something but does
11:46 not show us what it is doing, and
11:49 this explains what this thing here does.

11:54 We also need to run this thing
11:57 here to access
12:00 a local copy of my library of shell
12:04 functions... remember that here I defined
12:08 several shell functions and then I
12:10 used those shell functions
12:16 to create a certain git repository...

12:20 now this sexp here visits
12:24 that library of shell functions - it is
12:27 here... here we have an
12:31 index... here we have those shell
12:34 functions and a few others... here we have
12:38 basic tests that explain what are these
12:41 basic shell functions here...

12:44 and by the way, this thing here is something
12:48 that is very
12:49 interesting. It's something that I
12:51 call a "test block".

12:52 If I type M-x eeit
12:59 this will insert a test block at
13:03 the current point, and the syntax of the
13:07 test block depends on the
13:09 language that I'm using, so here
13:13 we are editing a shell script, and a test
13:16 block has this funny format here...
13:20 and this thing acts as a multi-line comment.

13:24 So for the shell this thing is a
13:28 multi-line comment, but for me this
13:31 thing is executable with f8s... if I put the
13:35 point here and type f8 several times it
13:39 runs some tests that sort of
13:45 explain these definitions here... so here
13:49 we have a section with basic commands
13:52 and the tests for these basic commands...

13:56 and then we have a section with this big
13:59 function here, MakeTree1, and then some
14:03 tests for MakeTree1...
14:09 this is this tree in an ugly format.

14:17 And note that in this test here
14:22 we created a tree with this
14:24 shape here, and now we have some extra
14:29 things here... these extra things here
14:32 are some examples of how to
14:34 query the data structures of that
14:36 repository. For example, if I ask git to
14:39 "show" what is the HEAD, in this case it
14:42 will show me that the HEAD is this thing
14:45 here... is a commit with this author, this
14:47 date, and so on... this message... and the
14:51 contents of the commit are this thing
14:52 here, that is being displayed as a diff
14:56 between the repository in a certain
14:59 moment and the repository in another
15:01 moment. If I run this thing here... if I ask
15:06 git to show what is the file1 in HEAD
15:10 it shows the file in another format
15:13 that is totally different... it's not a
15:15 diff it's just... it looks like a
15:18 normal file, not a diff. And I can also
15:21 run these things here to inspect all the
15:24 data structures...

15:26 and these things here in
15:29 comments are ways of accessing
15:32 the documentation of some things
15:34 that are here. So, for example I used
15:38 show-ref
15:39 here... the docs of git that come
15:44 with Debian come in many formats, so I
15:47 usually prefer to be able to choose
15:50 between all formats when I want to...
15:54 for example, to get more
15:57 information about show-ref
15:59 I can run this thing here, and it shows
16:03 me ways of accessing all these
16:07 formats - for example this thing here
16:09 opens the manpage converted to txt,
16:14 this thing here opens the manpage
16:17 itself, so it has boldface, underlined,
16:20 and so on... this thing here shows the
16:24 on page in
16:27 HTML...
16:30 and this thing
16:32 here asks git help to show me the
16:37 help about show-ref...

16:41 so here we have a big
16:45 shell function, and also an export...
16:49 and here we have the tests for this big
16:53 shell function, and some other
16:57 tests that I decided that this was the
17:00 best place to put them...

17:05 Note that
17:12 here we just saw how to run the tests
17:16 that are in this file here, in test
17:19 blocks... this test here in find-git-intro
17:24 is essentially the same thing as
17:27 before...
17:36 sorry, I deleted
17:40 this
17:43 thing... I had deleted the the
17:48 copy of eevgitlib1.sh in /tmp/, but now
17:53 these things are going to
17:55 work - I hope... yes.

17:59 So, it created that big tree...
18:04 it shows the tree in a certain
18:07 ugly format... now I can ask gitk to
18:11 display that tree in another ugly
18:14 format, but with more colors...

18:17 here it opens my flipbook
18:22 animation in the final page, that shows
18:24 the tree in another
18:27 format...
18:29 and so this explains the first
18:33 test... and note
18:42 that
18:46 this thing has several pages, and
18:51 the pages has some labels
18:54 here... what are these labels? Let me
18:58 explain that - because this is something
19:01 that I wrote a few days ago and I found
19:03 very interesting, very useful...

19:06 Let's go back to this file
19:11 here with my shell functions and
19:13 tests... note that here we have the
19:17 index, and at this moment the final
19:21 block
19:23 defines things about "Time" that are
19:25 commands for recording how a repository
19:28 changes through time, it has pointers to
19:31 the to the flipbook animation...

19:33 and the idea is that a
19:36 command like this one, Time 4:20, in a
19:40 script means "it's 4:20 now", or "at this
19:44 point of the script the timestamp
19:47 is
19:48 4:20"... or if we think on that as an
19:52 action, the action means: "take a low
19:55 resolution picture of the git repository
19:58 and save it in the file /tmp/eevgit_4:20"...

20:10 so, in this test here I will run
20:14 something very similar
20:18 to this big function here, that
20:21 created this tree here...

20:26 but now my new version of that...
20:32 let me open the old and and the new
20:35 versions side to side...

20:39 the new version has more columns,
20:43 and it has timestamps at many points...

20:46 for example, this point here is
20:48 going to be the timestamp A0, this is the
20:51 timestamp A1, timestamp A2, and so on...

20:57 so each one of these things takes a
20:59 low resolution picture of the repository
21:01 at that point... the low resolution picture
21:03 is just a tree
21:04 generated by git log...

21:09 and all these low resolution
21:12 pictures are saved to files with certain
21:14 names, and then at the end I can run
21:17 this thing here,
21:19 Timeline, that concatenates all these
21:23 files... so let's run that...

21:30 now if I run Timeline it generates
21:33 all these trees here, and this line here
21:38 does the same thing, but it
21:41 also generates a file called /tmp/all.

21:50 Now that we have that file we
21:54 can use that file to see how the
21:56 repository changes at each point... for
22:00 example, now we can understand
22:04 what happens when you create a new
22:06 commit, in the sense that some tags
22:10 are going to be moved to the new commit,
22:13 some tags are not going to be moved...

22:15 I found the rules very hard to
22:18 understand... I mean, when I was
22:23 able to draw the diagram then things
22:25 became much simpler, but just by
22:28 reading the rules and the manuals I
22:30 found them very complex, but... so, when I
22:35 started studying this diagram here the
22:38 the rules started to become clear to me,
22:41 and when I found a way to translate that
22:43 diagram to the other format, that is
22:46 much prettier, then things become much
22:50 clearer. So these diagrams helped me a lot.

22:58 So, this section here is about how to
23:01 create timelines, and how to inspect all
23:04 the files that were created... note that
23:07 here we have the individual files, and
23:10 then these files were concatenated into
23:12 this thing here, called "all"...

23:18 And here's one application.
23:23 Now that we have reproducible tests
23:26 it should be possible
23:28 to use these reproducible tests to create
23:31 a tutorial for
23:33 magit...

23:38 this eepitch block here creates a very
23:42 simple repository in /tmp/eevgit-test2/, and
23:49 this repository has two commits and then
23:53 I modify one of its files, file1,
23:58 and my shell functions do not
24:02 create a third commit.

24:08 And if we run magit on that repository...

24:11 by the way, if you do not have
24:14 magit installed then you can either
24:16 install it in the usual way or you can
24:19 use this thing here and install it in
24:22 the eev way... you may need this thing here
24:27 to configure MELPA,
24:30 like running this and this...
24:35 and then you can execute these
24:39 things here: package-initialize,
24:42 package-refresh-contents and package-install,
24:44 and then you will have magit in
24:47 your machine.

24:48 Anyway, I do have magit here.

24:52 Let me run this thing here... it runs magit
24:55 on that repository that I just created,
24:58 that has an uncommitted change.

25:01 Magit will say that we have unstaged changes,
25:05 then I can type uppercase S to stage
25:09 all these changes then I can type
25:13 lowercase c lowercase c to commit the
25:16 new change...

25:17 then magit will ask me to
25:21 write a commit message here... let me write
25:25 a very simple message, like Blah, here...
25:27 and then I can type C-x #
25:31 to save that commit...

25:33 and now it says that the HEAD is in
25:37 that commit here, whose message is Blah...

25:42 So I'm changing styles here. Up to
25:46 this point I was doing everything with
25:49 just shell commmands, and now I'm
25:52 using this thing here to create the
25:54 basis for learning, or for practicing,
25:58 magit commands...

26:03 so instead of creating a commit by
26:06 running "Commit C" or "Commit Blah"
26:09 I did that from magit, and it should be
26:12 possible to use that to create a
26:14 tutorial for magit that will explain some
26:16 operations that most people find difficult...

26:19 or anyway, or at least the
26:23 people like me find them difficult.

26:30 By the way, these are links to the
26:35 manual of
26:37 magit... this is the part that
26:40 explains how to use uppercase S to
26:44 stage changes, and this is a link to the
26:47 part that explains how to create new
26:50 commits... and again, I found these things
26:53 very hard to understand when I
26:56 started to learn magit...

27:00 and now here we have a section about
27:02 "Why this?", and about... anyway, let me
27:07 read this. I found git and magit both very
27:11 hard to learn. To test most concepts we
27:14 would need a repository with tags and
27:16 branches, and a second repository that
27:18 pulls from that...and even with that
27:21 most tests would be very hard to undo
27:24 and to reproduce...

27:26 and when I was trying to learn git...
27:29 more specifically, I was learning git
27:32 to set up a git repository
27:35 for eev, my package...

27:39 When I was trying to set up a git
27:42 repository for eev on GitHub for the
27:44 first time I did several things wrong on
27:47 the GitHub side, and I didn't know how to
27:50 fix that... I didn't know how to undo these
27:53 things... and after spending several
27:56 days trying to fix that I gave up, I
27:59 deleted that repository, I created a new
28:02 one, and I decided that I would be very
28:05 coward from that point on, because I
28:08 didn't know how to undo certain things...
28:11 and I decided I would always do lots
28:14 of local tests before messing up my
28:16 public repository again.

28:19 So at that point I started playing
28:22 with the idea of reproducible tests and
28:26 not committing everything to a
28:29 repository in GitHub, and this is my n-th
28:31 version of my tools for doing lots of
28:34 local tests. And, of course,
28:35 if you like this approach
28:38 then please get in contact!

28:43 Let me show another example of
28:46 something that the tutorials suppose
28:52 that... no, sorry, let me explain it
28:55 in another way. A typical use
28:58 case for git is like this: there's a
29:00 "shared" git repository in a "server",
29:03 and there are several "developers",
29:05 each one on a different
29:07 machine, and the developers are working
29:09 on copies of that shared repository, and
29:12 they are making changes on that and they are
29:15 trying to somehow synchronize their work.

29:17 So they are going to save
29:20 their changes to their local repositories,
29:21 and then they're going to push those
29:23 changes to the "server" somehow...

29:29 and I found that the
29:33 tutorials suppose that you are one
29:36 of the developers, and that you are
29:38 working with colleagues on that shared
29:42 repository... but I couldn't find easy
29:47 instructions for creating that
29:49 server repository, or for creating that
29:52 on a local machine... so this is my attempt
29:55 to fix that. This is a minimal version,
29:58 a miniature, of how to create the
30:02 server and the developer machines... and
30:05 instead of using several machines I just
30:07 use different directories in /tmp/.

30:11 So let me type f8 several times...
30:17 this first block here copies my
30:21 library to /tmp/ and loads the functions in
30:25 eevgitlib1.sh... this block here creates
30:29 a shared repository, that is going to
30:31 play the role of a server... the second
30:34 block creates a directory that will
30:38 play the role of the first
30:40 developer... in this block here
30:43 the Developer 1 creates two
30:45 commits and pushes them to the server...
30:49 so Commit A and Commit B, and then git
30:52 push... and now we create a second
30:56 directory, that will play the role of
30:58 a second
31:02 developer... so now we are going to have
31:04 three repositories, one ending with "s",
31:08 that plays the role of a server, one
31:10 that ends with "1", that plays the
31:12 rollers of the first developer, and
31:15 one that ends with "2", that plays the
31:17 role of the second developer...

31:19 and now here the second
31:23 developer creates a new commit, and
31:25 pushes that commit to that
31:27 repository... and that's a new commit
31:30 that the first developer
31:32 doesn't have yet, so now we switch to the
31:35 to the first developer... we just
31:39 switch to this directory here instead of
31:41 switching machines... and we run git pull.

31:45 So this is a miniature that
31:48 probably can be used - in the future,
31:52 say - to show how to do these things
31:55 with magit... I mean, we probably
31:58 can use that to teach people how
32:01 to do pulls and pushes with magit...
32:06 I haven't done that yet.

32:13 So, yeah, that's it for the moment!
32:17 So, a few ideas are already
32:20 implemented, we have some basic tests
32:23 here, all the "try it!"s should be very
32:26 easy to try...

32:28 but I only have one small section
32:31 about how to use that to teach magit.
32:36 To do things with magit we have to
32:39 create a
32:41 repository... preferably in a way in
32:44 which this creation mechanism is easy to
32:48 run again...

32:50 and then we have to teach people
32:54 what are the keys that they have to
32:55 press in magit... for example
32:58 here for staging the changes people
33:02 have to to press S in a certain part of
33:05 the magit buffer, and then they have to
33:08 type "c c" in another position of
33:13 the magit buffer... so it's a totally
33:17 different interface...

33:18 So: this is a prototype, but
33:23 again... if you like this approach,
33:26 please get in contact!

33:28 And... that's it! That's what we have
33:30 now.
33:32 Yeah, that's it. Bye! Thanks!