Reputation: 1066
If we checkout a commit instead of branch, the HEAD (pointer to branch) will point to a commit instead of the name of branch (call this commit A). This is called a detached HEAD state. If I created a new commit - commit B, that new commit would be lost (okay, not immediately maybe) because there's no way we can reference it (actually, I don't get it, because every commit has an ID, right? We can reference it once we know the ID, but for some reason Git will remove such commits. It's probably that Git can't tell to which branch the commit belongs to).
Commits know only their parent, but not children. Is there a reason for this? If commit A had a reference to commit B, we could forget about detached HEAD problems, right? But I guess that would cause some other issues - what are those?
Upvotes: 2
Views: 69
Reputation: 66244
Commits know only their parent, but not children. Is there a reason for this?
Git commits don't keep track of their children because they are content-addressable and immutable. This design decision makes for a simpler and more efficient architecture.
Linus Torvalds, the designer of Git, intended it to provide data integrity; if some version of a file in a snapshot got corrupted, Git should be able to detect that.
To achieve data integrity, Git was designed as a content-addressable filesystem. In particular, commits, upon creation, receive a "unique" (barring collisions) identifier computed on the basis of their contents (using the SHA-1 algorithm). This identifier acts as a checksum for the commit, which can be used to detect data corruption.
Immutability is an advantage: immutable things are easier to reason about and can be shared. Accordingly, the immutability of commits was a very desirable feature. Once created, a commit is set in stone; it cannot be changed in any way. The most you can do is create a new commit that "resembles" an existing one (which is what happens when you run git commit --amend
).
However, if, as you suggest, commits kept track of their children, commits would have to be updated/replaced every time they got a new descendant, because their old hash wouldn't reflect the fact that they got a brand new descendant. This would defeat the benefits of immutability and make things way more complicated.
Upvotes: 5