Revision History: My understanding of SVN and Git
This is revision 444 of the page My understanding of SVN and Git, as it appeared on Tue, 08 Apr 2014 20:38:22 -0700.SVN / Git
Based on the short white paper Git: from the bottom up, I think I can personally understand the differences between Subversion and Git as:
- In Subversion, a commit is a set of changes to some files in your repository ("revision" or "changeset").
- In Git, a commit is a snapshot of your repository ("branch").
- 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).
- 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.
- 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.
- 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