Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For home projects, can Mercurial or Git (or other DVCS) provide more advantages over Subversion? [closed]

Which free source control system is most preferable with reason for home projects and documents?

I am thinking to use Subversion (as I am familiar with it).

Characteristic of home project:

  1. Most likely single person will be committing changes. (May be one day (not now), it is possible that I share a project with my friend who is in other city)

  2. I would like to store other documents (non-programming files)

Is Mercurial or GIT (distributed version control system) can give me any more advantage over to subversion in Home Projects?

like image 478
Sun Avatar asked Aug 02 '09 08:08

Sun


People also ask

What are the advantages of Git over SVN?

Many people prefer Git for version control for a few reasons: It's faster to commit. Because you commit to the central repository more often in SVN, network traffic slows everyone down. Whereas with Git, you're working mostly on your local repository and only committing to the central repository every so often.

What are the advantages of Git over Mercurial?

Mercurial Is Safer For Less Experienced Users By default, Mercurial doesn't allow you to change history. However, Git allows all involved developers to change the version history. Obviously, this can have disastrous consequences. With basic Mercurial, you can only change your last commit with “hg commit – amend”.

Is Subversion better than Git?

SVN is better than Git for architecture performance, binary files, and usability. And it may be better for access control and auditability, based on your needs.

What is Git Mercurial and SVN?

SVN is different from Git and Mercurial, in that it is a single repository that all users have to pull and commit to. Git and Mercurial have a distributed model.


1 Answers

Take a look at part about version control for single developer in my answer to "Difference between GIT and CVS" question here on StackOverflow. Some of those issues do still apply also to Subversion versus Git (or other distributed VCS: Mercurial, Bazaar, or less known: Monotone, Darcs), even if Subversion is improvement over CVS.

DISCLAIMER: I use Git (so I am biased), and know Subversion only from documentation (and other resources), never having used it myself. I might be then mistaken about Subversion capabilities.

Below there are list of differences between Git over Subversion for a single developer, on single machine (single account):

  • Setting up repository. Git stores repository in .git directory in top directory of your project. Starting a new project from unversioned tree of files is as easy as doing "git init" in a top directory of your project (and then of course "git add ." to add files, and e.g. "git commit -m 'Initial commit'" to create first commit).

    In Subversion (in any centralized version control system) you need to set up central repository (unless you did that earlier) using "svnadmin create" (well, you need to do that only once). Then you have to import files into Subversion using "svn import" (or "svn add")... But note that after the import is finished, the original tree is not converted into a working copy. To start working, you still need to "svn checkout" a fresh working copy of the tree.

  • Repository and repository metadata. Git stores both repository (i.e. information about revisions and branches, etc.) and repository metadata (e.g. your identity, list of ignored files, which branch is currently checked out) in .git directory in top directory of your projects.

    Subversion stores repository in separate area you have to put for that purpose, and stores repository metadata (e.g. where central repository is, identity used to contact central repository, and I think also properties like svn:ignore) are stored in .svn directory in each directory of your project. (Note that Subversion stores pristine copy of your checkout, to have fast "svn status" and "svn diff")

  • Naming revisions / version numbers. Subversion uses global revision identifiers in the form of single number specifying revision (so you can for example refer to r344, revision 344). Subversion also supports a few symbolic revision specifiers: HEAD, BASE, COMITTED, PREV.

    In Git each version of a project (each commit) has its unique name given by 40 hexdigits SHA-1 id; usually first 7-8 characters are enough to identify a commit (you can't use simple numbering scheme for versions in distributed version control system -- that requires central numbering authority). But Git offers also other kinds of revision specifiers, for example HEAD^ means parent of a current commit, master~5 means revision 5 ancestors back (in straight first-parent line) from top commit on a 'master' branch, v1.6.3-rc2 might mean revision tagged v1.6.3-rc2.

    See also Many different kinds of revision specifiers blog post by Elijah Newren.

  • Easy branching and merging. In Git creating and merging branches is very easy; Git remembers all required info by itself (so merging a branch is as easu as "git merge branchname")... it had to, because distributed development naturally leads to multiple branches. Git uses heuristic similarity-based rename detection, so it while merging it can deal with the case where one side renamed file (and other similar cases related to renaming). This means that you are able to use topic branches workflow, i.e. develop a separate feature in multiple steps in separate feature branch.

    Branches have an unusual implementation in Subversion; they are handled by a namespacing convention: a branch is the combination of revisions within the global repository that exist within a certain namespace. Creating a new branch is done by copying an existing set of files from one namespace to another, recorded as a revision itself. Subversion made it easy to create new branch... but up till version 1.5 you had to use extra tools such as SVK or svnmerge extensions to be able to merge easily. Subversion 1.5 introduced svn:mergeinfo property, but even then merging is slightly more complicated than in Git; also you need to use extra options to show and make use of merge tracking information in tools such as "svn log" and "svn blame". I have heard that it doesn't work correctly in more complicated situations (criss-cross merge), and cannot deal currently with renames (there is even chance of silent corruption in such case). See also (for example) this post on git mailing list by Dmitry Potapov, explaining intended use case for svn:mergeinfo and its (current) limitations.

  • Tagging. In Git tags are immutable, can have comment associated with them, and can be signed using PGP/GPG signature (and verified). They are made using "git tag". You can refer to revision using tag name.

    In Subversion tags use the same path_info-like namespace convention as branches (recommended convention is svnroot/project/tags/tagname), and are not protected against changing. They are made using "svn copy". They can have comment associated with [the commit creating a tag].

  • Keyword expansion. Git offers very, very limited set of keywords as compared to Subversion (by default). This is because of two facts: changes in Git are per repository and not per file, and Git avoids modifying files that did not change when switching to other branch or revinding to other point in history. If you want to embed revision number using Git, you should do this using your build system, e.g. following exaple of GIT-VERSION-GEN script in Linux kernel sources and in Git sources. There is also 'ident' gitattribute which allows expansion of "$Id$" keyword to SHA-1 identifier of file contents (not identifier of a commit).

    Both Git and Subversion do keyword expansion only on request.

  • Binary files. Both Git and Subversion deal correctly woth binary files. Git does binary file detection using similar algorithm to the one used by e.g. GNU diff, unless overriden on per-path basis using gitattributes. Subversion does it in slightly different way, by detecting type of file during adding file and setting svn:mime-type property, which you can then modify. Both Git and Subversion can do end of line character conversion on demand; Git has additionally core.safecrlf config option which warn and prevent irreversible change (all CR to all CRLF is reversible, mixed CR and CRLF is not reversible).

  • Ignoring files. Git stores ignore patterns using in-tree .gitignore file, which can be put under version control and distributed; it usually contain patterns for build products and other generated files, and in .git/info/excludes file, which usually contains ignore patterns specific to user or system, e.g. ignore pattersn for backup files of your editor. Git patterns apply recursively, unless patter contain directory delimiter i.e. forward slash character '/', then it is anchored to directory .gitignore file is; to top dir for .git/info/excludes. (There is also core.excludesfile configuration variable; this variable can exist in per-user ~/.gitconfig configuration file, and point to per-user ignore file).

    Subversion uses global-ignores runtime configuration option (which generally apply to particular computer or by a particular user of a computer), and "svn:ignore" property on SVN-versioned directories. However unlike the global-ignores option (and in .gitignore), the patterns found in the "svn:ignore" property apply only to the directory on which that property is set, and not to any of its subdirectories. Also, Subversion does not recognize the use of the ! prefix to pattern as exception mechanism.

  • Amending commits. distributed VCS such as Git act of publishing is separate from creating a commit, one can change (edit, rewrite) unpublished part of history without inconveniencing other users. In particular if you notice typo (or other error) in commit message, or a bug in commit, you can simply use "git commit --amend". (Note: technically it is re-creating a commit, not changing existing commit; the changed commit has different identifier).

    Subversion allows only to modify commit message after the fact, by changing appropriate property.

  • Tools. On one hand Git offers richer set of commands. One of more important is "git bisect" that can be used to find a commit (revision) that introduced a bug; if your commits are small and self-contained it should be fairly easy then to discover where the bug is.

    On the other hand, Subversion because exists longer, has perhaps wider set of third party tools, and Subversion support in tools, than Git. Or at least more mature. Especially on MS Windows.


And there is another issue, which might be quite important later:

  • Publishing repository. If (when?) at some time you would want to share your repository, turning it from one-person project developed on a single home computer, to something other contribute, with Git is as simple as creating empty repository on server or on one of existing git hosting sites / software hosting sites with git support (like http://repo.or.cz, GitHub, Gitorious, InDefero; more--also for other DVCS--are listed in that answer), and then pusing your project to this public repository.

    I guess it is more complicated with Subversion, if you don't start at software hosting site with Subversion support (like SourceForge) from the beginning, unless you don't want to preserve existing revision history. On the other hand for example Google Code suggest to use svnsync tool (part of the standard Subversion distribution), as explained in Google Products‎ > ‎Project Hosting (the Data Liberation Front) article.


Take a look also at http://whygitisbetterthanx.com/ site.

like image 162
Jakub Narębski Avatar answered Oct 14 '22 21:10

Jakub Narębski