3.1 KiB
- 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.