Add change 30 to instructions

This commit is contained in:
David Doblas Jiménez 2024-06-05 20:18:06 +02:00
parent 7fe3e0f497
commit 772f631768

82
how_to/Change_30.md Normal file
View File

@ -0,0 +1,82 @@
- branch: Create new branch
Tags were an improvement since they freed us from the burden of remembering OIDs
directly. But they are still somewhat inconvenient, since they are static. Let
me illustrate:
```
o-----o-----o-----o-----o-----o-----o
\ ^
----o-----o tag2,HEAD
^
tag1
```
If we have the above situation, we can easily flip between *tag1* and *tag2* with
`checkout`. But what happens if we do
- ugit checkout tag2
- Make some changes
- ugit commit?
Now it looks like this:
```
o-----o-----o-----o-----o-----o-----o-----o
\ ^ ^
----o-----o tag2 HEAD
^
tag1
```
The upper branch has advanced, but *tag2* still points to the previous commit.
This is by design, since tags are supposed to just name a specific OID. So if we
want to remember the new HEAD position we need to create another tag.
But now let's create a ref that will "move forward" as the branch grows. Just
like we have `ugit tag`, we'll create `ugit branch` that will point a branch to
a specific OID. This time the ref will be created under *refs/heads*.
At this stage, `branch` doesn't look any different from tag (the only difference
is that the branch is created under *refs/heads* rather than *refs/tags*). But
the magic will happen once we try to `checkout` a branch.
So far when we checkout anything we update HEAD to point to the OID that we've
just checked out. But if we checkout a branch by name, we'll do something
different, we will update HEAD to point to the **name of the branch!** Assume
that we have a branch here:
```
o-----o-----o-----o-----o-----o-----o
\ ^
----o-----o tag2,branch2
^
tag1
```
Running `ugit checkout branch2` will create the following situation:
```
o-----o-----o-----o-----o-----o-----o
\ ^
----o-----o tag2,branch2 <--- HEAD
^
tag1
```
You see? HEAD points to *branch2* rather than the OID of the commit directly.
Now if we create another commit, ugit will update HEAD to point to the latest
commit (just like it does every time) but as a side effect it will also update
*branch2* to point to the latest commit.
```
o-----o-----o-----o-----o-----o-----o-----o
\ ^ ^
----o-----o tag2 branch2 <--- HEAD
^
tag1
```
This way, if we checkout a branch and create some commits on top of it, the ref
will always point to the latest commit.
But right now HEAD (or any ref for that matter) may only point to an OID. It
can't point to another ref, like I described above. So our next step would be
to implement this concept. To mirror Git's terminology, we will call a ref that
points to another ref a "symbolic ref". Please see the next change for an
implementation of symbolic refs.