> To understand Git's design philosophy better it is helpful to understand the circumstances in which the Git project was started in the Linux Kernel Community.
I don't understand this sentiment. It's not helpful to know the history at all. At best, it romanticize the choices made. Stating the goals would be an intro that shows some level of analysis.
No, the author is right. Git us in its core a database for managing patches. Understanding the needs of Linus Torvalds as his role of Kernel maintainer is about the only good way to understand why git is so strangely designed.
Darcs is a database for managing patches. Nothing in Git inherently cares about patches. To a first approximation it's a database for managing full snapshots of trees of files.
Git only needs lists of files because it needs entry points into its lists of patch fragments that make up the file and to assign file names to them. Other than that, a changeset is just another name for a patch that can be added, altered, rewritten or removed. That makes git a patch database in my book.
Darcs feels more like a research project to me. The developers try to find a theoretical foundation in which they can base a VCS, but they have not managed to make their theory work with the level of perfection that they want. But if they eventually get it right, it will probably have the provably best text-based merge tool possible.
This is not how Git's data model works. You may be thinking of delta-compression which during "git gc" and purely as an optimization step does delta-compression across content in the repository.
But that's purely an optimization that has nothing to do with the intrinsic data model. There's no point at which the patch output you see with "git diff/show" is actually stored as-is in Git. It's computed on-the-fly.
This separates Git from many other SCMs where patches or other deltas are permanently stored at the time of commit in a way that can't modified afterwards.
The distinction matters because those systems generally have storage that doesn't compress as well, since they need to compute and store a diff at the time, whereas a system like Git can keep finding better delta candidates as history progresses.
This goes all the way back to the likes of RCS. The Subversion FSFS backend also works like this, and I believe Mercurial to some extent, and certainly Darcs since storing a history of patches is what it's for.
There are three things in git that I consider design errors:
- The staging area/index/cache should not even exist. That the same construct has three interchangeable names is already a sign that something is wrong. The fact that that construct is used to confusingly stage snapshots of files for committing as well as moerge operations makes it an unwieldy thing that has probably teleported too many lines of code into the digital nirvana already.
- Branches should be immutable properties of changesets instead of flimsy, easily deleted tags with special flags. Deleting a branch after a merge makes it impossible to tell which branch in the history was the master and which the feature branch.
- Gits graph of changesets is also too lightweight and is missing forward references. This is the reason why deleting branches irreversibly deletes their entire history. The reflog is only a crude hack around that and exists only because the crude data structures require taking stock of the entire set of internal references to figure out that a certain part of it (an "object", but essentially a file in the repository) is actually no longer referenced and can be removed.
I can probably come up with more reasons why git is very flawed. But this is enough fuel for the fire for one post.
Maybe -- but the index is ridiculously useful. being able to commit some of your changes is part of what makes git so much more useful than something like mercurial.
To be honest you may have a complaint for 2 and 3, but i'm not sure what it is, as i've never had any of the issues you bring up.
mercurial and git both have commands that allow you to select part of a change to commit, and both allow you to amend an existing commit. No index necessary.
If it had been started in e.g the game development scene there would have been some other design decisions made. The idea that the source tree is rather small and the history is short and there are few binary assets managed are definitely showing in the design.
The goals are stated, just a few lines down in the same section you quoted. What makes you think design goals and philosophy aren't formed by history? How does knowing the history of a project romanticize it? Personally, I'd assume exactly the opposite, that knowing history is the only way to understand the goals and philosophy, and that romaticizing only happens when a history is not understood and/or the story is changed or told through a tinted lens.
I don't understand this sentiment. It's not helpful to know the history at all. At best, it romanticize the choices made. Stating the goals would be an intro that shows some level of analysis.