That said though, you are probably right something will eventually supplant git. It would be arrogant to think that my failure to imagine something better means there isn't anything.
That said though, you are probably right something will eventually supplant git. It would be arrogant to think that my failure to imagine something better means there isn't anything.
For what it's worth, SVN was pretty straightforward and worked well enough at the time. Later, Mercurial addressed SVN's deficiencies with a familiar interface.
I think the way Git handles renames is ugly – it doesn't actually record them, it just tries to guess when they occur based on file contents (inevitably imperfect). I think Subversion handled this better.
The problem is that a Git tree object only contains file name, file mode, and blob/subtree hash. If it also contained some kind of "file ID" (such as a UUID), then you could track renames properly – renaming a file would change its name but not its file ID, so you'd track the rename properly, even if the contents changed at the same time.
Given they didn't do that... maybe create a file-id Git attribute? (Alas, "git mv" doesn't update .gitattributes, so renaming a file forgets the attributes; but it could learn.)
I'm not quite sure why Linus decided not to make renames/moves/copies explicit/strict and my only guess is it simplified things. Being able to say with 100% certainty all the time that something was renamed or copied is extremely handy, but with Git we just get a percentage like the following shows:
https://oss.gitsense.com/insights/github?bq=move%2Bpull-age%...
I guess knowing the mapper.go file in the example above was likely copied is good to know, but it would be much better to know this with 100% certainty.
Full disclosure: The link above goes to my tool
I don't think it has anything to do with the fact that Git is distributed. It is a question of how rich the repository data model is. The richness of the repository data model is an orthogonal concern from distributed-vs-centralised.
I think Linus just wanted to keep it as simple as possible – but, maybe in some areas he made it too simple. The Subversion developers on the contrary, maybe went too far in the other direction.
I think it does since meta-data increases merge complexity, which is probably a headache when dealing with a distributed system. With a centralized system, you are basically creating a lock when you do a rename/copy/etc. which doesn't translate well to distributed systems.
With Git as it is currently implemented, you only need to worry about one state which is the tree. With meta-data, the number of states that needs to be tracked can increase significantly.
Having said all of that, I guess it probably wouldn't be too hard to implement a layer on top of Git that ensures every directory has something like a .git.meta file and have hooks that ensures all renames,copies,etc. are recorded in the meta-data file.
I disagree. In Git, merging always happens locally, between two local commits; there is nothing distributed about merging itself.
> With a centralized system, you are basically creating a lock when you do a rename/copy/etc. which doesn't translate well to distributed systems.
I don't think that is really true. If I rename a file in Subversion, that doesn't involve "creating a lock". I rename the file locally (using "svn mv"), Subversion locally remembers I have done it, but doesn't send anything to the server. When I want to commit, it then contacts the server and uploads the commit data, including the rename tracking info. Now, that commit operation takes a write lock on the branch – to prevent any other commit for that branch being processed at the same time – but it is the exact same write lock regardless of whether renames are involved or not. If we take Subversion as an example of a centralised version control system with rename tracking, the rename tracking and the locking are orthogonal. (When I say "locking" here, I mean the internal locks within the Subversion server, not the end-user-visible advisory locks you get with the "svn lock" command–that advisory locking feature is unrelated to the topic of rename tracking.)
Like Git, merging is essentially a local process in Subversion – the client constructs a merge commit, and then sends the completed merge commit to the server. The actual merge, meaning construction of the merge commit contents, always happens on the client side, at least as far as the core Subversion protocol is concerned.
In fact on the whole repo, since branches are just subdirectories. (Shows how long it has been since I've actually used Subversion, I'm starting to forget it.)