问题
As we all know, git is very popular in these days, since it is highly efficient for it has all the history on local computer, and retrieve of history can be done without network. Maybe for extranet users, the network issue is not that important, but git also have other kinds of advantages, such as lightweight branch (i am still not sure what is the differece between it and svn's branch, why git's branch is light weight)?
I also know lots of person is still using subversion, why? If git is that nice, they may switch to git:)
So, can anybody here tell me some advantages of subversion?
one more question:
is there anything which can be done by svn, but cannot be done with git?
回答1:
I advise you to read the article "10 things I hate about Git" and the StackOverflow thread SVN vs Git. I also advise reading this doc about Subversion and Git.
While others already mentioned simplicity (simplicity is a trademark of Apache Subversion ;) BTW) and clear workflow as the major Subversion advantage I would like to add some of other important Apache Subversion pros:
Better IDE integration and GUIs. You can see built-in SVN client in most IDEs (or implemented as a plug-in). Some of them provide very comfortable and intuitive version-control integration with IDE. On the other hand, Git does not have good graphical interface except maybe well-known GitHub. IDE integration is also still in process, but hacky command-line nature of Git does not really translate to GUIs. You still have to use command-line for anything more complicated than branching or pulling / pushing.
BTW, TortoiseSVN Subversion client can be considered as the best version-control client available for Windows.
Subversion is centralized. In other words, distributed systems are NOT so-called "next generation VCS" (hello, Eric Sink et al!), they are, ehm, just distributed. Being distributed is just another approach which is great for open-source projects such as Linux Kernel (Git was developed for Linux Kernel, remember?) but has its own downsides.
Full revision history. SVN maintains versioning for directories, renames, and file metadata. Subversion acts like a time machine with immutable history. You can always use the machine to travel back in time to check how your date looked like on e.g. January 3rd 2009.
Partial checkouts. With Subversion you don't need to get a complete repository clone. You can checkout a particular branch or trunk of your project. Even more, you can get any subtree of your repository. Greatly minimizes traffic required to start working on a task. If you already have a working copy, switching to another branch or shelve is instant (if you have connectivity to the remote repo, obviously).
Locking support. Subversion supports lock-modify-unlock versioning model. Git does not. This can be really helpful in case you have non-mergeable files. Hello gamedev! :)
Built-in authorization and authentication mechanisms.
回答2:
Simplicity.
Questions like "What is a remote?", "Why amending a message?", "What is this rebase thing?" are necessary to understand all the features that Git provides, and you need to understand them to really know why Git is so awesome.
But for a designer or any technical person starting on Git, it's really just a headache. Subversion is well known, and its centralized way make it a lot more understandable for all these people.
You can start working and producing stuff a lot faster with Subversion (provided you already have an environment set up ;)).
回答3:
Git is about having personal power, while Svn is about corporate power (as a grand assertion).
Git knows that there is no longer a Master document which must be protected from harm. Rather that there are now many copies which, unless verified by the sha1, are more difficult to manage.
Svn knows people are dumb (but not you and I;-) and think that knowing who renamed and moved what is important, and that content can be signed off later.
Git lets you run with scissors, juggle chain saws and craft your product. Svn offers protective clothing, work instructions and a type of security.
It's about choosing which foot you want nailed to the floor ;-)
回答4:
Git branches are 'lightweight' insofar as they're simply pointers: git just points 'master' or 'development' or 'trunk' or 'myfeature' at a particular commit. When you commit afresh on a branch, the pointer advances. Consider this diagram from the git-scm docs, a stellar resource on the subject.

The 'master' branch in this diagram points to commit f30ab
. The 'testing' branch points to commit c2b9e
. HEAD
in this diagram is a special pointer: Most of the time it points at another branch (in git terminology, it is a "symbolic reference") to show the currently checked-out state of the working directory. When you issue, say, git checkout f30ab
, you put the repository into "detached HEAD" state. In other words, you move the pointer from a symbolic reference, 'testing', to a commit, f30ab
.
Take an example, one you should be able to setup yourself locally.
git init /tmp/test && cd /tmp/test ;# make a repo and cd to it
echo A > A ;# add a file
git add A && git commit -m "first commit" ;# make the first commit
echo B > B ;# add another file
git add B && git commit -m "second commit" ;# commit that one too
git checkout -b development ;# now let's checkout development
echo C > C ;# commit one more file
git add C && git commit -m "third commit" ;# and commit that final one
You've now got something like the below. I don't have omnigraffle so we're stuck with a directed graph:
* 93e71ee - (HEAD, development) third commit
/
* 6378754 - (master) second commit
* d2b4ba9 - first commit
As you can infer from the parentheses, 'master' points at commit 6378754
, 'development' points at commit 93e71ee
, and HEAD
points at 'development'. Don't take my word for it. Explore the pointers yourself:
$ cat .git/refs/heads/master ;# cat the 'master' pointer
5a744a27e01ae9cddad02531c1005df8244d188b
$ cat .git/refs/heads/development ;# now cat the 'development' one
93e71ee0a538b0e8ac548e3936f696fa4936f8dc
$ cat .git/HEAD ;# note that 'HEAD' points at 'development'
ref: refs/heads/development
$ git symbolic-ref HEAD ;# as we can also show with 'symbolic-ref'
refs/heads/development
When branches are just pointers, switching between them is trivial. One special case is HEAD
. Consider what happens when we checkout master:
$ git checkout master ;# checkout master...
$ cat .git/HEAD ;# where are we now?
ref: refs/heads/master
What about checking out a commit?
$ git checkout d2b4ba9 ;# this will throw some advice
Note: checking out 'd2b4ba9'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
$ cat .git/HEAD ;# 'HEAD' points at a commit
d2b4ba97698d7f528f9ba1e08d978a70651b3b1d
$ git symbolic-ref HEAD ;# and thus isn't a symbolic reference
fatal: ref HEAD is not a symbolic ref
What's that advice mean? It's that committing against a repository in "detached HEAD" state generates commits unreachable from any branch. When HEAD
changes (from any checkout operation, such as git checkout master
), those commits will be lost. This is easier to see in a graph:
echo D > D ;# add another file
git add D && git commit -m "fourth commit" ;# and commit it
Let's look at our graph. Note no git command will generate what you see below. I've modified existing output for the purposes of this example.
* 93e71ee - (development) third commit
/
* 6378754 - (master) second commit
/
* / 72c1f03 - (HEAD) fourth commit
|/
* d2b4ba9 - first commit
HEAD
is still detached. It points at 72c1f03
. 'master' and 'development' point where we expect, but 72c1f03
isn't reachable from any branch. That's a problem. If I want to keep 72c1f03
around, I have to give it a branch:
$ git checkout -b experimental ;# checkout 'experimental' based on '72c1f03'
$ cat .git/HEAD ;# HEAD is once again pointed at a branch
ref: refs/heads/experimental
$ git symbolic-ref HEAD ;# and is a symbolic ref
refs/heads/experimental
And the graph:
* 93e71ee - (development) third commit
/
* 6378754 - (master) second commit
/
* / 72c1f03 - (HEAD, experimental) fourth commit
|/
* d2b4ba9 - first commit
Git makes branching easy. Pushing and pulling information about pointers is much faster than pushing and pulling entire sets of files. Cutting a branch takes milliseconds. It's so easy it almost feels wrong. As a result, git allows more distributed workflow options, although it can certainly handle centralized ones, too.
回答5:
Switching from SVN to git is a laborious task (we have been on it for 6 month in my company), since it require a lot of changes in a company (training, server, communication with other tools like issue tracking..., security).
The only advantage I can find is its simplicity (since you cannot do so many things than in git), workflows are easier to understand and apply, so if you are affraid not all coworkers could/want to handle the complexity of git or do not need its features, then keep with svn.
Have a look at this SO thread to convince yourself :).
来源:https://stackoverflow.com/questions/12156011/what-is-the-advantage-of-subversion-when-compared-with-git