Based on the short white paper Git: from the bottom up, I've interpreted the differences between Subversion and Git as:
Commit
- In Subversion, a commit is a set of changes to some files on your branch ("revision" or "changeset").
- In Git, a commit is a snapshot of your repository ("branch").
Parents
- In Subversion, a revision may store references to related (parent) revisions through metadata.
- In Git, a commit has multiple parents and is stored as a tree.
For a long time, Subversion did not store enough information about merged parents in metadata, which is why it had a bit of history about being terrible to merge. It now stores plenty of metadata now (and this metadata is revisioned too).
Merge
- In Subversion, a "merge" combines the sets of changes from two branches into a new set of changes.
- In Git, a "merge" sets the parent commits of a new commit to the two trees of both branches, and this commit contains the entire merge at once.
This also means that a Git merge only considers the two top commits (repository snapshots) of each branch, which is why merge conflicts are so massive and requires you to re-edit whole files. Whereas Subversion considers the combination of all change sets, and only requires editing of conflicting individual diffs.
Rebase
- In Git, a "rebase" sets the parent commit of the current branch root, to the parent commit of the source branch, and then transforms every previous branch commit to a new tree, and sets the parent commit of this tree to the top of the new branch root.
The closest concept in Subversion for a rebase would be branching the target branch into a new branch, and then merging in all changesets from a different branch. This is identical to a Subversion merge, which is why the concept doesn't make sense.
Tags
- In Subversion, a tag is the same as a branch and exists on the repository as any other branch.
- In Git, a tag is hidden away, similar to a branch but by default isn't pulled, and you can only interact with tags using voodoo magic
Conclusion
Git seems great if you want to spend most of your time acting as a version control repository administrator, and you want lots of powerful functionality.
The critical concept (a commit being either a changeset or a repository snapshot) does not preclude a version control system from being centralised or distributed, so why isn't there a distributed version control system based around changesets?
Categories: Git | Subversion