Git 相比 svn 和其他版本管理工具的核心優勢有哪些?


=== 2016/03/23 更新 ===
舊的鏈接已經死了, 重新搜索了一下, 找了個 ZoomQuiet 保存的繁體中文的鏡像:
Why Git is Better Than X

=== 以下是原回答 ===
也許你需要的是這個:Why Git is Better Than X - http://zh-cn.whygitisbetterthanx.com/


cvs, git, svn都用過,以下完全是主觀感受:
1. git比svn快,用起來更流暢。
2. git在本地就可以用,可以隨便保存各種歷史痕迹,不用擔心污染伺服器。svn commit就到伺服器了,有時候發現commit錯了或不全就得再來一遍,有review更吐血了。(git commit --amend太好用了)
3. git拉branch和在branch之間切換都非常簡單,可以隨便折騰。svn一個branch就是一個copy。
4. git絕對不會有被lock了不能commit的情況。。
5. svn老版本每個目錄都有一個.svn目錄,非常繁瑣。(新版本svn也只在最上層有.svn目錄了,不過仍然比較難用,不在.svn同目錄下很多命令不給用,比如svn info)
------------------------------------
最後吐槽,目前頂的最高的答案,根本就是答所非問嘛!!怎麼還會有人點贊同?!


閃開讓我來。

依我看,說git好的,都沒有說到點子上。說git不好的,可能真是不懂linus創造git的上下文。要是拿企業內開發的上下文來看git,可是看不出什麼好的。我呢,也就是試著去懂吧。

=======

我覺得這問題不能僅僅考慮技術,得考慮人。
我暫時忘掉SVN,為了Git而學習Git,以Linus的思維替代我的思維。然後我發現了如此深刻的人性洞察和簡單的應對方法。linux的工作流使得git是顯然必須的。以下內容是我看了linus在google的演講後寫的,因此很多就是對linus思想的DUMP。

1. 自洽的、最少依賴的個人工作得到支持。1000多人的Linux開發團隊是分布在世界各地的,使用git也就不必依賴中心伺服器、不必需要很少的網路。就在自己的電腦上就有完整的倉庫,可以做任何版本管理,除了分享代碼。SVN顯然是不合適的,因為單點故障大家甚至無法提交,更加無法開分支,這是無法忍受的。
2. 剔除害群之馬很簡單。如果Linus經過觀察,發現有些程序員特別容易出漏子,那麼封殺的辦法就是不必拉取即可。實際上Linus就是這樣干過。如果是SVN,就變成了撤銷惹麻煩的開發者的賬號或者限定他的訪問範圍,並且從倉庫中移除麻煩的代碼提交。就是說,封殺的方法在git而言,是不做某事即可,SVN是做一系列事情才可以。一正一反,大家可以體會一下。Linus喜歡前者,並且得心應手。這樣的工作流程就避開了很多「政治」問題,讓他的集成代碼過程變得主動。
3. 可以使用信任網路。Linux太大了,不可能完全看完補丁代碼的方式來識別信任,這個Linus曾經干過,最後的結果當然是放棄。如果發現有些程序員特別優秀,他只要選擇拉取他們的實現。這些程序員也只是拉取他們信任的程序員的實現。這樣的信任網路是可以層次化的,因此對應於1000多人的開發者來說,這樣做確實可以通過分層的信任網路達成大規模的團隊協作。如果是SVN,我不知道如何做可以更好
4.輕量的分支開銷鼓勵大量被使用。對於這樣的團隊,為了敏捷的迭代,如果有想法就分支(這樣的開發隔離想法是很有價值的),那麼在svn上分支是海量的並且全局的大家互相影響,因此是要命的。而對於Git總數當然是海量,但是每個人的分支都在自己的倉庫內,不會影響到他人。且分支無需連接伺服器,因此是飛速的。

所以,對於Linux團隊來說,Git是必須的。特別是它的分散式,可以幫助建立信任網路,減少政治問題。它的設計,首先是關於人的,關於最佳的工作流程的、技術這是這些思想的完美載體。Linus不僅僅創建了Linux,也實際上管理著一個巨大的團隊,做法就是用一套工具提供信任網路和少政治的工作流程,從而可以不管。說Linus是此團隊的「仁君」,並非繆贊。想想混亂的現實世界,我確實對這個高手團隊的管理方法感到敬佩。

這解釋了開源代碼項目使用git的熱潮。它符合人性的光輝。
==============技術上的支持
##自身優勢

1. 自己可以玩。伺服器下架,啟動不了,客戶端離線,都可以繼續工作。什麼都不缺
2. 分支。隨時開分支以便實驗想法,不干擾別人
3. 大部分都可以本地,本地就是快
4. 提交粒度大小隨意,最少一行,參見hunk

##夥伴優勢
1. github太火,人多高手多,熱鬧
2. github社交特性,引發PK,不再一個人

##對手形勢
我就用過svn和git,就比較他們兩.svn已經藥丸
https://www.google.com/trends/explore#q=git%2C%20svncmpt=qtz=Etc%2FGMT-8

這些年企業內的開發流程乏善可陳,開源界紅紅火火,那些整日貧乏的面孔,不去學習開源界的性感怎麼辦。所以,git就這麼火了唄。

## 廣告

http小書 圖靈社區 : 圖書 : HTTP 小書
Git小書 圖靈社區 : 圖書 : Git小書


1.軟體版本不在是一條時間線,而是一個無環有向圖;
2.branch不再是成本極高的事情,而是每個員工都可以在自己機器上做;
3.去中心化。


給題主一個啟發性答案吧:要說 Git 好,起碼也得跟 P4、ClearCase 之類次優的比。SVN 是最爛的了。


對我來說可以最有用的功能是可以本地開分支。我不是每次修改都想上傳到伺服器給眾人看的好嘛。我可以搞地下活動了。我就搞一搞代碼,又回滾了,還沒有人知道我搞過,搞之於無形無聲無色之中,愛怎麼搞就怎麼搞。簡單來講就是git讓碼農們更爽了。


來自官方的如下黑體字應該是最好的總結了

推薦閱讀Git官方文檔最前面兩個小章節
外鏈:1,Git - 關於版本控制

SVN類集中式系統
這麼做最顯而易見的缺點是中央伺服器的單點故障。
如果宕機一小時,那麼在這一小時內,誰都無法提交更新,也就無法協同工作。
如果中心資料庫所在的磁碟發生損壞,又沒有做恰當備份,毫無疑問你將丟失所有數據——包括項目的整個變更歷史,只剩下人們在各自機器上保留的單獨快照。
本地版本控制系統也存在類似問題,只要整個項目的歷史記錄被保存在單一位置,就有丟失所有歷史更新記錄的風險。
分散式版本控制
.......許多這類系統都可以指定和若干不同的遠端代碼倉庫進行交互。籍此,你就可以在同一個項目中,分別和不同工作小組的人相互協作。
你可以根據需要設定不同的協作流程,比如層次模型式的工作流,而這在以前的集中式系統中是無法實現的

2,Git - Git 簡史

到了 2005 年,開發 BitKeeper 的商業公司同 Linux 內核開源社區的合作關係結束,他們收回了 Linux 內核社區免費使用 BitKeeper 的權力。
這就迫使 Linux 開源社區(特別是 Linux 的締造者 Linux Torvalds)基於使用 BitKeeper 時的經驗教訓,開發出自己的版本系統。
他們對新的系統制訂了若干目標:

  • 速度
  • 簡單的設計
  • 對非線性開發模式的強力支持(允許成千上萬個並行開發的分支)
  • 完全分散式
  • 有能力高效管理類似 Linux 內核一樣的超大規模項目(速度和數據量)

自誕生於 2005 年以來,Git 日臻成熟完善,在高度易用的同時,仍然保留著初期設定的目標。
它的速度飛快,極其適合管理大項目,有著令人難以置信的非線性分支管理系統


作為一個版本管理工具,竟然需要有一堆教程去說明如何「學」,這本身就是很蠢的事情


在IBM developer上有一篇文章可以看看 http://www.ibm.com/developerworks/cn/aix/library/au-mercurial/ 以下轉載部分
Mercurial 和 Git 之間的一些差異如下:

  • 多種內置的撤消操作:Mercurial 的 revert、backout 和 rollback 命令可以簡便地返回到特定文件的以前版本或以前的已提交更改集。Git 只提供一個內置的 revert 命令,而且語法非常複雜。
  • 內置的 web 伺服器:Mercurial 提供一個簡單的集成的 web 伺服器,很容易快速地駐留存儲庫,讓其他用戶可以從中獲取更改。推操作需要忽略安全性或支持 Secure Sockets Layer (SSL) 的更複雜的設置。
  • 在複製/移動操作期間保存歷史:Mercurial 的 copy 和 move 命令都保存完整的歷史信息,而 Git 在這兩種情況下不保存歷史。
  • 分支:Mercurial 自動地共享所有分支,而 Git 要求每個存儲庫設置自己的分支(在本地創建它們或者把它們映射到遠程存儲庫中的特定分支)。
  • 全局和本地標籤:Mercurial 支持在存儲庫之間共享的全局標籤,可以在沒有分支的情況下方便地共享代碼開發中特定點的相關信息。
  • Windows 平台上的原生支持:Mercurial 是用 Python 編寫的,而 Microsoft? Windows? 系統支持 Python。因此,可以以 Windows 可執行程序的形式使用 Mercurial(見 參考資料)。Windows 上的 Git 比較複雜,可以選用 msysGit、在 Cygwin 下使用標準的 Git 或者使用基於 web 的託管系統或存儲庫。
  • 自動的存儲庫收縮:Git 要求您顯式地對存儲庫進行收縮和垃圾收集,而 Mercurial 自動地執行功能相當的操作。但是,對於相同的代碼庫,Mercurial 存儲庫往往比 Git 存儲庫大。

有一群鐵杆linus粉,逢L神出的東西都是宇宙最強的,逢ms出的都是渣渣
svn啊,hg啊,tfs啊,perforce啊,ClearCase啊,跟git比都是戰五渣,大神光環加成,你不懂

求摺疊


title: Git常用命令和Git團隊使用規範指南
date: 2016-04-22 16:22:32
categories: 學習 | Study
description: Git是目前世界上最先進的分散式版本控制系統
---

## 前言

在2005年的某一天,Linux之父Linus Torvalds 發布了他的又一個里程碑作品——Git。它的出現改變了軟體開發流程,大大地提高了開發流暢度,直到現在仍十分流行,完全沒有衰退的跡象。其實一般情況下,只需要掌握git的幾個常用命令即可,但是在使用的過程中難免會遇到各種複雜的需求,這時候經常需要搜索,非常麻煩,故總結了一下自己平常會用到的git操作。本文根據團隊實踐記錄Git入門指南和Git常用命令,文章中不僅記錄了Git的搭建和使用教程,還參考了大量Git團隊使用規範上的經驗,希望大家可以結合自己團隊的實際應用場景讓Git協作優雅的落地。

&> Git是目前世界上最先進的分散式版本控制系統

## 更新記錄

2016年04月22日 - 初稿

閱讀原文 - http://wsgzao.github.io/post/git/

**擴展閱讀**

Git Book - https://git-scm.com/book/zh/
git簡明指南 - http://rogerdudler.github.io/git-guide/index.zh.html
常用 Git 命令清單 - http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html
猴子都能懂的GIT入門 - http://backlogtool.com/git-guide/cn/
Git教程 - http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

## SVN與Git的最主要的區別

SVN是集中式版本控制系統,版本庫是集中放在中央伺服器的,而幹活的時候,用的都是自己的電腦,所以首先要從中央伺服器哪裡得到最新的版本,然後幹活,幹完後,需要把自己做完的活推送到中央伺服器。集中式版本控制系統是必須聯網才能工作,如果在區域網還可以,帶寬夠大,速度夠快,如果在互聯網下,如果網速慢的話,就納悶了。

Git是分散式版本控制系統,那麼它就沒有中央伺服器的,每個人的電腦就是一個完整的版本庫,這樣,工作的時候就不需要聯網了,因為版本都是在自己的電腦上。既然每個人的電腦都有一個完整的版本庫,那多個人如何協作呢?比如說自己在電腦上改了文件A,其他人也在電腦上改了文件A,這時,你們兩之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。

## Git搭建和使用

&> Git上手並不難,深入學習還是建議多實踐,可以參考擴展閱讀中廖雪峰的Git教程

### Git服務端

&> 服務端搭建Git很簡單,有更多需求不妨試試Gogs和Gitlab

使用Gogs輕鬆搭建可能比GitLab更好用的Git服務平台 - http://wsgzao.github.io/post/gogs/

``` bash
#安裝git
sudo apt-get install git
yum install git

#創建一個git用戶,用來運行git服務
sudo adduser git

#創建證書使用公鑰免密碼登錄(可選)
ssh-keygen -t rsa
vi ~/.ssh/authorized_keys

#初始化Git倉庫
sudo git init --bare sample.git
sudo chown -R git:git sample.git

#禁用shell登錄
vi /etc/passwd
git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

#在客戶端上克隆遠程倉庫
git clone git@server:/srv/sample.git

```

管理公鑰推薦使用Gitosis
Gitosis - https://github.com/res0nat0r/gitosis
Gitosis配置手記 - http://debugo.com/gitosis/

管理許可權推薦使用Gitolite
Gitolite - https://github.com/sitaramc/gitolite

### Git客戶端

&> Git客戶端可以按個人習慣來選擇,遵守團隊協作中的Git規範標準才是更重要的

Git - https://git-scm.com/
TortoiseGit - https://tortoisegit.org/
SourceTree - https://www.sourcetreeapp.com/

``` bash
#以最基本的Git命令行為例,先下載Git
https://git-scm.com/download/

#配置git提交用戶名和郵箱,定義別名方便區分
git config --global user.name "你的姓名"
git config --global user.email "you@example.com"

#克隆倉庫
git clone cap@172.28.70.243:/cap/cap.git

$ git clone cap@172.28.70.243:/cap/cap.git
Cloning into "cap"...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

#測試推送
touch README
git add README
git commit -m "add readme"
git push origin master

Counting objects: 3, done.
Writing objects: 100% (3/3), 199 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To cap@172.28.70.243:/cap/cap.git
* [new branch] master -&> master

```

## Git常用命令

**符號約定**

- `&` 自定義內容
- `[xxx]` 可選內容
- `[&]`自定義可選內容

``` bash
#初始設置
git config --global user.name "&<用戶名&>" #設置用戶名
git config --global user.email "&<電子郵件&>" #設置電子郵件

#本地操作
git add [-i] #保存更新,-i為逐個確認。
git status #檢查更新。
git commit [-a] -m "&<更新說明&>" #提交更新,-a為包含內容修改和增刪,-m為說明信息,也可以使用 -am。

#遠端操作
git clone & #克隆到本地。
git fetch #遠端抓取。
git merge #與本地當前分支合併。
git pull [&<遠端別名&>] [&<遠端branch&>] #抓取併合並,相當於第2、3步
git push [-f] [&<遠端別名&>] [&<遠端branch&>] #推送到遠端,-f為強制覆蓋
git remote add &<別名&> & #設置遠端別名
git remote [-v] #列出遠端,-v為詳細信息
git remote show &<遠端別名&> #查看遠端信息
git remote rename &<遠端別名&> &<新遠端別名&> #重命名遠端
git remote rm &<遠端別名&> #刪除遠端
git remote update [&<遠端別名&>] #更新分支列表

#分支相關
git branch [-r] [-a] #列出分支,-r遠端 ,-a全部
git branch &<分支名&> #新建分支
git branch -b &<分支名&> #新建並切換分支
git branch -d &<分支名&> #刪除分支
git checkout &<分支名&> #切換到分支
git checkout -b &<本地branch&> [-t &<遠端別名&>/&<遠端分支&>] #-b新建本地分支並切換到分支, -t綁定遠端分支
git merge &<分支名&> #合併某分支到當前分支

```

Git常用命令 - http://gityuan.com/2015/06/27/git-notes/

- workspace: 本地的工作目錄。(記作A)
- index:緩存區域,臨時保存本地改動。(記作B)
- local repository: 本地倉庫,只想最後一次提交HEAD。(記作C)
- remote repository:遠程倉庫。(記作D)

&> 以下所有的命令的功能說明,都採用上述的標記的A、B、C、D的方式來闡述。

``` bash
#初始化
git init //創建
git clone /path/to/repository //檢出
git config --global user.email "you@example.com" //配置email
git config --global user.name "Name" //配置用戶名

#操作
git add & // 文件添加,A → B
git add . // 所有文件添加,A → B

git commit -m "代碼提交信息" //文件提交,B → C
git commit --amend //與上次commit合併, *B → C

git push origin master //推送至master分支, C → D
git pull //更新本地倉庫至最新改動, D → A
git fetch //抓取遠程倉庫更新, D → C

git log //查看提交記錄
git status //查看修改狀態
git diff//查看詳細修改內容
git show//顯示某次提交的內容

#撤銷操作
git reset &//某個文件索引會回滾到最後一次提交, C → B
git reset//索引會回滾到最後一次提交, C → B
git reset --hard // 索引會回滾到最後一次提交, C → B → A

git checkout // 從index複製到workspace, B → A
git checkout -- files // 文件從index複製到workspace, B → A
git checkout HEAD -- files // 文件從local repository複製到workspace, C → A

#分支相關
git checkout -b branch_name //創建名叫「branch_name」的分支,並切換過去
git checkout master //切換回主分支
git branch -d branch_name // 刪除名叫「branch_name」的分支
git push origin branch_name //推送分支到遠端倉庫
git merge branch_name // 合併分支branch_name到當前分支(如master)
git rebase //衍合,線性化的自動, D → A

#衝突處理
git diff //對比workspace與index
git diff HEAD //對於workspace與最後一次commit
git diff && //對比差異
git add & //修改完衝突,需要add以標記合併成功

#其他
gitk //開燈圖形化git
git config color.ui true //彩色的 git 輸出
git config format.pretty oneline //顯示歷史記錄時,每個提交的信息只顯示一行
git add -i //互動式添加文件到暫存區
```

## Git使用規範

Git 使用規範流程 - http://www.ruanyifeng.com/blog/2015/08/git-use-process.html
團隊中的 Git 實踐 - https://ourai.ws/posts/working-with-git-in-team/
構家網 git 團隊協作使用規範 v2 - http://wenku.baidu.com/view/e1430d1b7f1922791788e81e

&> Git使用規範提醒

- 使用Git過程中,必須通過創建分支進行開發,堅決禁止在主幹分支上直接開發。review的同事有責任檢查其他同事是否遵循分支規範。
- 在Git中,默認是不會提交空目錄的,如果想提交某個空目錄到版本庫中,需要在該目錄下新建一個 .gitignore 的空白文件,就可以提交了
- 把外部文件納入到自己的 Git 分支來的時候一定要記得是先比對,確認所有修改都是自己修改的,然後再納入。不然,容易出現代碼回溯
- 多人協作時,不要各自在自己的 Git 分支開發,然後發文件合併。正確的方法應該是開一個遠程分支,然後一起在遠程分支里協作。不然,容易出現代碼回溯(即別人的代碼被覆蓋的情況)
- 每個人提交代碼是一定要 git diff 看提交的東西是不是都是自己修改的。如果有不是自己修改的內容,很可能就是代碼回溯
- review 代碼的時候如果看到有被刪除掉的代碼,一定要確實是否是寫代碼的同事自己刪除的。如果不是,很可能就是代碼回溯


好吧,當初打動我下功夫從SVN轉向GIT的關鍵是這句話:「SVN沒有後悔葯,git有一堆後悔葯」。


git為什麼這麼好? 來自: http://www.douban.com/note/145945675/

linus威武? .好吧,其實我也不知道.真正紮實在用git也就這幾個月.之前都是svn.曾經用過cvs.

git給我帶來的好處:

本地的版本管理

不需要遠程或架設伺服器就能做到本地版本管理.

不污染子目錄的track文件

svn每個子目錄都要扔一個.svn.這個實在是.. .(我想很多人都碰到過svn lock folder的情況.實在讓人氣急敗壞.實際上.svn文件就是罪魁禍首.各種clean up無果. delelte後svn up異常.真是.. 摔!.去你妹的svn.)

強大的branch

超輕量級的branch建立.(實際只是建立文件指針).推薦根據的git workflow的開發流程.將workspace分成幾區.master dev feature hotfix區等.開發層次就出來了.

merge工具的強力

git根據commit ticket依次再進行一次merge.提高了merge成功率.避免svn merge中的難堪.即使merge失敗.也不會生成亂七八糟的版本文件.簡單修改後.commit就是.

神奇的git gc

由於git本身不保存文件之前的差異文件.只保存每個文件的快照.所以在頻繁修改大文件的情況下會造成git目錄變得肥大不堪.git早就有了解決方案.git gc後,會在.git目錄下生成一個packfile與idx文件.只保存文件差異.滿塞!.

清爽實用的cli

嗯,我在離開"烏龜"之後是徹底就不會用svn了.看來應該還是內心在抵觸.沒有學習.

計算機世界所有的問題都可以通過添加一個間接層來實現

git確實增加了一層間接層,實現了去中心化scm工具.當然增加了一點學習的成本.初次接觸可能不知道push跟pull的作用.set origin的意義.當然只在本地做管理的話,是基本沒有所謂成本的.

github

github作為新一代的程序員靠實力,憑作品交流的sns+code host平台.將geek精神貫徹整站.cool!.相對而言google code則正在走下坡路.

可能還有一些好處或者弊端.沒看到一個產品的弊端說明你沒真正理解它?我可能也只是單純的崇拜.這篇還有待繼續編輯.待我有了更多的經驗.或許這篇文章會變成"git為什麼這麼爛?"也說不定.

to be continue...

toka.


svn,git,hg都用過,目前再使用hg,主要是因為bitbucket支持私有庫,大家在選擇版本控制工具的時候,可以考慮下hg,如果用windows的話,那hg比git更加值得推薦,hg的windows客戶端比git的要好,並且googlecode也支持使用hg進行版本控制


svn 是中央集權,沒了伺服器就都沒了。git是分散式,沒了伺服器,自己本地也能查看歷史記錄,分支操作什麼的。


  • 輕量, 大多數情況下無需等待伺服器的響應
  • 每一台設備都是一個 repo
  • 自由增減 remote repo
  • 離線工作

git有一個殺手級特性,兩級提交,由於這個特性,所以接受了git(很不忍心放棄svn)

在全球範圍類合作開發,或者有潔癖的開發者,必然要求提交的日誌需要乾淨,整齊,有節奏,有意義,所以不能隨便提交,只有整理到一定程度,再一次提交上去,git的兩級提交機制,滿足了這個功能。相比svn,我以前都是現在本地建一個私有的svn,搞的差不多了,再merge到公司的svn里,現在想想,這非常麻煩。

至於其他的一些特性,比如本地開分支,離線開發,都是這個兩級提交的衍生而已。

反對一個說法是:git沒有中心


版本管理的核心還在管理而不是工具。從這個角度,只能說git比svn更加原生的支持了分散式,而分散式是我們決定有必要引入的一種版本管理策略。


我覺得GIT最實用的就是離線工作功能了。你在火車上都可以commit...


在我看來,兩者是非常相似的,區別只是git相當於在svn的客戶端增加了一個本地倉庫,也就是說它實現了一個二級倉庫模型。不同的細節的設計策略,使得git在離線模式下表現更好。


推薦閱讀:

TAG:版本控制系統 | 軟體開發 | Git | SVN(Subversion) |