user5539357
user5539357

Reputation: 1066

Why don't commits keep track of their children commits?

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

Answers (1)

jub0bs
jub0bs

Reputation: 66244

Commits know only their parent, but not children. Is there a reason for this?

In short

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.

More details

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

Related Questions