亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

git 使用詳解

系統 2466 0

考慮到 CVS 的一些局限性,最近和同事在公司推行 Git

其實,如果推行 SVN 的化,可能推行的難度會降低很多。不過 lark 說既然推行一個新的版本管理工具,總要花費一定的時間進行培訓、部署、轉換。而推行 Git SVN 的代價不如想象中差距那么大。因此,不如就多花些精力推行 Git , 可以帶來更多的好處。 這個想法說服了我。 然后就開始籌備了。 我發現網上很多 git 教程對一些基礎命令(比如 git-reset )的介紹還是不夠清楚。另外,介紹 git1.5 的少,介紹 git1.4 的多。此外,對于如何基于 Git 合作開發,介紹的內容也是少之又少。因此,決定寫一份教程,以減少在公司推廣 Git 的培訓代價。

其實我也是一個 Git 的新手。 寫這份教程也是我自己學習和摸索 git 的過程,其中基于 Git 進行合作開發的模式參考了 CVS ,應該是很初級的合作模式。但是當前自己也只能做到這一步了。 教程所述都是自己通過試驗驗證的。至少可以滿足公司基本的合作開發。教程寫完后,謝欣說可以放到blog 與大家共享。我覺得是個不錯的主意。一方面我覺得這個文檔應該可以給 git 的新手一些幫助,另一方面也歡迎 git 的大牛指點。 這里要感謝《 Git 中文教程》的作者。還有概述中關于 git 的優點描述拷貝了網絡上某位大牛的原話,但是拷貝的出處也是轉載的,就在這里謝謝那位我不知名大牛了。

下面就開始了。

1. 概述
對于軟件版本管理工具,酷訊決定摒棄CVS而轉向Git了。
為什么要選擇Git? 你真正學會使用Git時, 你就會覺得這個問題的回答是非常自然的。然而當真正需要用文字來回答時,卻覺得文字好像不是那么夠用。 咳,該則么回答呢?
其實,關鍵的問題不在于如何回答這個問題。 問題的關鍵是公司已經決定使用它了。那么,我們的程序員們! 請開動你們的瀏覽器,請拿出你的搜索引擎工具,去自己發掘答案吧。在這里,我只能給你們一個最朦朧的感覺。
Git和 CVS、SVN不同,是一個分布式的源代碼管理工具。Linux內核的代碼就是用Git管理的。它很強,也很快。它給我們帶來的直接好處有:
1. 傻瓜都會的初始化,git init, git commit -a, 就完了。對于隨便寫兩行代碼就要放到代碼管理工具里的人來說,再合適不過。也可以拿git做備份系統,或者同步兩臺機器的文檔,都很方便。
2. 絕大部分操作在本地完成,不用和集中的代碼管理服務器交互,終于可以隨時隨地大膽地check in代碼了。 只有最終完成的版本才需要向一個中心的集中的代碼管理服務器提交。
3. 每次提交都會對所有代碼創建一個唯一的commit id。不像CVS那樣都是對單個文件分別進行版本的更改。所以你可以一次性將某次提交前的所有代碼check出來,而不用考慮到底提交過那些文件。(其實SVN也可以做到這點)
4. branch管理容易多了,無論是建立新的branch,還是在branch之間切換都一條命令完成,不需要建立多余的目錄。
5. branch之間merge時,不僅代碼會merge在一起,check in歷史也會保留,這點非常重要。
6. … 太多了
當然,Git也會帶給我們一些困難,首先,你想要使用好git,就要真正明白它的原理,理解它的觀念, 對以那些CVS的熟手來說,改變你已經固有的純集中式源代碼管理的觀念尤為重要,同時也會讓你覺得有些困難。在使用git的初期,你可能會覺得有些困難,但等你逐漸明白它時,你絕對會喜歡上它。這是一定的,就像我問你“喜歡一個溫吞如水、毫無感覺的主婦,還是喜歡一個奔放如火,讓你愛的癡狂恨的牙癢的情人”一樣毋庸置疑。
下面,就讓我們進入學習Git之旅…
請記住,這只是一個非常簡單而且初級的教程, 想要成為git的專家,需要各位同事不斷的自己深入挖掘。
2. Git基礎命令

2.1 創建Git庫—git-init
你們曾經創建過CVS的庫么?應該很少有人操作過吧?因為很多人都是從CVS庫里checkout代碼。同樣,在合作開發中,如果你不是一個代碼模塊的發起者,也不會使用到這個命令,更多的是使用git-clone(見2.7節)。 但是,如果你想個人開發一個小模塊,并暫時用代碼管理工具管理起來(其實我就常這么做,至少很多個人開發過程都可以保留下來,以便備份和恢復),創建一個Git庫是很容易和方便的。
對于酷訊來說,當一個代碼的Git庫創建后,會添加代碼文件到庫里,并將這個庫放到公司一個專門用來進行代碼管理的服務器上,使大家可以在以后clone(不明白?沒關系,繼續往后看就明白了)它。對于個人來說,你可以隨便將這個庫放到哪里,只要你能訪問的到就行。

創建一個Git庫是很容易和方便的,只要用命令 git-init 就可以了。在Git1.4之前(包括git1.4)的版本,這個命令是git-init。
a) $ mkdir dir
b) $ cd dir
c) $ git-init
這樣,一個空的版本庫就創建好了,并在當前目錄中創建一個叫 .git 的子目錄。以后,所以的文件變化信息都會保存到這個目錄下,而不像CVS那樣,會在每個目錄和子目錄下都創建一個討厭的CVS目錄。
在.git目錄下有一個config文件, 需要我們添加一下個人信息后才能使用。否則我們不能對其中添加和修改任何文件。
原始的config文件是這樣的,
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
我們需要加入
[user]
name = xxx
emai= xxx@kuxun.cn
現在已經創建好了一個 git 版本庫,但是它是空的,還不能做任何事情,下一步就是怎么向版本庫中添加文件了。如果希望忽略某些文件,需要在git庫根目錄下添加. gitignore文件。
2.2 一條重要的命令 -- git-update-index
在介紹如何向git庫中添加文件前,不得不先介紹git-update-index命令。這條命令可能會使很多熟悉CVS的用戶疑惑, 一般來說,我們向一個源代碼管理庫提交代碼的更改,都會抽象為以下的動作:更改文件;向源碼管理系統標識變化;提交。比如從一個CVS庫里刪除一個文件,需要先刪除文件,然后cvs delete; 最后cvs commit。
因此, git-update-index就是向源碼管理系統標識文件變化的一個抽象操作。說的簡要一些,git-update-index命令就是通知git庫有文件的狀態發生了變化(新添、修改、刪除等待)。這條命令在早期的git版本中是非常常用的。 在新的git版本(1.5版本及以后)已經被其它命令包裝起來,并且不推薦使用了。
git-update-index最常用的方式有以下兩種,更多功能請man git-update-index。
? 方法一:git-update-index --add 文件名列表。 如果文件存在,則這條命令是向git庫標識該文件發生過變化(無論是否該文件確實被修改過),如果文件不存在,則這條命令是向git庫表示需要加入一個新文件。
? 方法二: git-update-index --force-remove 文件名列表。 這表示向git庫表示喲啊從庫中刪除文件。無論該文件是否已經被刪除,這條命令僅僅是通知git庫要從庫中刪除這些文件。這些文件都不會受影響。
因此,git-update-index僅僅是向git庫起到一個通知和標識的作用,并不會操作具體的文件。
2.3 向git庫中添加或刪除文件 – git-add、git-rm
其實,說使用git-add命令向git庫里添加文件是不對的, 或者說至少是不全面的。git-add 命令的本質是命令"git-update-index --add” 的一個包裝。因此,git-add除了可以添加文件,還可以標識文件修改。在調用了git-add后,才可以做commit操作。git-rm 也是一樣, 它是git-update-index --force-remove的一個包裝。
對于git-add來說, 如果在一個目錄下調用了git-add * ,則默認是遞歸將子目錄中所有文件都add到git庫中。對于git-rm來說,也是一樣。 這點和CVS有較大區別。
此外,我們還可以通過命令git-ls-files來查看當前的git庫中有那些文件。

2.4 查看版本庫狀態—git-status
通過該命令,我們可以查看版本庫的狀態。可以得知那些文件發生了變化,那些文件還沒有添加到git庫中等等。 建議每次commit前都要通過該命令確認庫狀態。以避免誤操作。
其總,最常見的誤操作是, 修改了一個文件, 沒有調用git-add通知git庫該文件已經發生了變化就直接調用commit操作, 從而導致該文件并沒有真正的提交。如果這時如果開發者以為已經提交了該文件,就繼續修改甚至刪除這個文件,那么修改的內容就沒有通過版本管理起來。如果每次在提交前,使用git-status查看一下,就可以發現這種錯誤。因此,如果調用了git-status命令,一定要格外注意那些提示為“Changed but not updated:”的文件。 這些文件都是與上次commit相比發生了變化,但是卻沒有通過git-add標識的文件。
2.5 向版本庫提交變化 – git-commit
直接調用git-commit命令,會提示填寫注釋。也可以通過如下方式在命令行就填寫提交注釋:git-commit -m "Initial commit of gittutor reposistory"。 注意,和CVS不同,git的提交注釋必須不能為空。否則就會提交失敗。
git-commit還有一個 –a的參數,可以將那些沒有通過git-add標識的變化一并強行提交,但是不建議使用這種方式。
每一次提交,git就會為全局代碼建立一個唯一的commit標識代碼,用戶可以通過git-revert命令恢復到任意一次提交時的代碼。 這比CVS不同文件有不同的版本呢號管理可方便多了。(和SVN類似)
如果提交前,想看看具體那些文件發生變化,可以通過git-diff來查看, 不過這個命令的輸出并不友好。因此建議用別的工具來實現該功能。在提交后,還可以通過git-log命令來查看提交記錄。
2.6 分支管理 – git-branch
我們迎來了git最強大,也是比CVS、SVN強大的多的功能 — 分支管理。
大概每個程序員都會經常遇到這樣的情況:
1. 需要立刻放下手頭的工作,去修改曾經一個版本的bug并上線,然后再繼續當的工作。
2. 本想向中心庫commit一個重要修改,但是由于需要經常備份代碼,最終不得不頻繁的向中心庫commit。從而導致大量無用的commit信息被保留在中心庫中。
3. 將一次修改提交同事進行code review, 但是由于同事code review比較慢, 得到反饋時,自己的代碼已經發生了變化,從而倒是合并異常困難
這些場景,如果用CVS或者SVN來解決,雖說不一定解決不了,但過程之繁瑣,之復雜,肯定另所有人都有生不如死的感覺吧!究其關鍵,就是CVS或者SNV的branch管理太復雜,基本不具可用性。
在 git 版本庫中創建分支的成本幾乎為零,所以,不必吝嗇多創建幾個分支。當第一次執行git-init時,系統就會創建一個名為”master”的分支。 而其它分支則通過手工創建。下面列舉一些常見的分支策略,這些策略相信會對你的日常開發帶來很大的便利。
? 1.創建一個屬于自己的個人工作分支,以避免對主分支 master 造成太多的干擾,也方便與他人交流協作。
? 2.當進行高風險的工作時,創建一個試驗性的分支,扔掉一個爛攤子總比收拾一個爛攤子好得多。
? 3.合并別人的工作的時候,最好是創建一個臨時的分支用來合并,合并完成后在“fatch”到自己的分支(合并和fatch后面有講述,不明白就繼續往下看好了)
2.6.1 查看分支 – git-branch
調用git-branch可以查看程序中已經存在的分支和當前分支
2.6.2 創建分支 – git-branch 分支名
要創建一個分支,可以使用如下方法:
1. git-branch 分支名稱
2. git-checout –b 分支名
使用第一種方法,雖然創建了分支,但是不會將當前工作分支切換到新創建的分支上,因此,還需要命令”git-checkout 分支名” 來切換, 而第二種方法不但創建了分支,還將當前工作分支切換到了該分支上。
另外,需要注意,分支名稱是有可能出現重名的情況的, 比如說,我在master分支下創建了a和b兩個分支, 然后切換到b分支,在b分支下又創建了a和c分支。 這種操作是可以進行的。 此時的a分支和master下的a分支實際上是兩個不同的分支。 因此,在實際使用時,不建議這樣的操作,這樣會帶來命名上的疑惑。
2.6.3 刪除分支 – git-branch –D
git-branch –D 分支名可以刪除分支,但是需要小心,刪除后,發生在該分支的所有變化都無法恢復。
2.6.4 切換分支 – git-checkout 分支名
如果分支已經存在, 可以通過 git-checkout 分支名 來切換工作分支到該分支名
2.6.5 查看分支歷史 –git-show-branch
調用該命令可以查看分支歷史變化情況。 如:
* [dev1] d2
! [master] m2
--
* [dev1] d2
* [dev1^] d1
* [dev1~2] d1
*+ [master] m2
在上述例子中, “--”之上的兩行表示有兩個分支dev1和master, 且dev分支上最后一次提交的日志是“d2”,master分支上最后一次提交的日志是”m2”。 “--”之下的幾行表示了分支演化的歷史,其中 dev1表示發生在dev分支上的最后一次提交,dev^表示發生在dev分支上的倒數第二次提交。dev1~2表示發生在dev分支上的倒數第三次提交。
2.6.6 合并分支 – git-merge
git-merge的用法為:git-merge “some memo” 合并的目標分支 合并的來源分支。如:
git-merge master dev1~2
如果合并有沖突,git會由提示,當前,git-merge已經很少用了, 用git-pull來替代了。
用法為:git-pull 合并的目標分支 合并的來源分支。 如git-pull . dev1^

2.7 遠程獲取一個git庫 git-clone
在2.1節提到過,如果你不是一個代碼模塊的發起者,也不會使用到git-init命令,而是更多的是使用git-clone。通過這個命令,你可以從遠端完整獲取一個git庫,并可以通過一些命令和遠端的git交互。
基于git的代碼管理的組織結構,往往形成一個樹狀結構,開發者一般從某個代碼模塊的管理者的git庫通過git-clone取得開發環境,在本地迭代開發后,再提交給該模塊的管理者,該模塊的管理者檢查這些提交并將代碼合并到自己的庫中,并向更高一級的代碼管理者提交自己的模塊代碼。
對于酷訊來說,公司會有一個中心的git庫, 大家在開發時,都是從中心庫git-clone獲取最新代碼。
git-clone的使用方法如下: git-clone [ssh://]username@ipaddr:path。 其中, “ssh://”可選,也有別的獲取方式,如rsync。 Path是遠端git的根路徑,也叫repository。
通過git-clone獲取遠端git庫后,.git/config中的開發者信息不會被一起clone過來。仍然需要為.git/config文件添加開發者信息。此外,開發者還需要自己添加. gitignore文件
另外,通過git-clone獲取的遠端git庫,只包含了遠端git庫的當前工作分支。如果想獲取其它分支信息,需要使用”git-branch –r” 來查看, 如果需要將遠程的其它分支代碼也獲取過來,可以使用命令” git checkout -b 本地分支名 遠程分支名”,其中,遠程分支名為git-branch –r所列出的分支名, 一般是諸如“origin/分支名”的樣子。如果本地分支名已經存在, 則不需要“-b”參數。

2.8 從遠程獲取一個git分支 – git-pull
與git-clone不同, git-pull可以從任意一個git庫獲取某個分支的內容。用法如下:
git-pull username@ipaddr : 遠端repository名 遠端分支名:本地分支名。這條命令將從遠端git庫的遠端分支名獲取到本地git庫的一個本地分支中。其中,如果不寫本地分支名,則默認pull到本地當前分支。
需要注意的是,git-pull也可以用來合并分支。 和git-merge的作用相同。 因此,如果你的本地分支已經有內容,則git-pull會合并這些文件,如果有沖突會報警。

2.9 將本地分支內容提交到遠端分支 – git-push
git-push和git-pull正好想反,是將本地某個分支的內容提交到遠端某個分支上。用法:
git-push username@ipaddr : 遠端repository名 本地分支名:遠端分支名。這條命令將本地git庫的一個本地分支push到遠端git庫的遠端分支名中。

需要格外注意的是,git-push好像不會自動合并文件。這點我的試驗表明是這樣,但我不能確認是否是我用錯了。因此,如果git-push時,發生了沖突,就會被后push的文件內容強行覆蓋,而且沒有什么提示。 這在合作開發時是很危險的事情。
2.10 庫的逆轉與恢復 – git-reset
庫的逆轉與恢復除了用來進行一些廢棄的研發代碼的重置外,還有一個重要的作用。比如我們從遠程clone了一個代碼庫,在本地開發后,準備提交回遠程。但是本地代碼庫在開發時,有功能性的commit,也有出于備份目的的commit等等。總之,commit的日志中有大量無用log,我們并不想把這些log在提交回遠程時也提交到庫中。 因此,就要用到git-reset。
Git-reset的概念比較復雜。它的命令形式:git-reset [--mixed | --soft | --hard] [<commit-ish>]
命令的選項:
--mixed
這個是默認的選項。 如git-reset [--mixed] dev1^(dev1^的定義可以參見2.6.5)。它的作用僅是重置分支狀態到dev1^, 但是卻不改變任何工作文件的內容。即,從dev1^到dev1的所有文件變化都保留了,但是dev1^到dev1之間的所有commit日志都被清除了,而且,發生變化的文件內容也沒有通過git-add標識,如果您要重新commit,還需要對變化的文件做一次git-add。 這樣,commit后,就得到了一份非常干凈的提交記錄。
--soft
相當于做了git-reset –mixed,后,又對變化的文件做了git-add。如果用了該選項, 就可以直接commit了。
--hard
這個命令就會導致所有信息的回退, 包括文件內容。 一般只有在重置廢棄代碼時,才用它。 執行后,文件內容也無法恢復回來了。

2.11 更多的操作
之前的10節只簡要介紹了git的基本命令,更多的細節可以去linux下man git的文檔。此外, http://www.linuxsir.org/main/doc/git/gittutorcn.htm 也有不少更詳細的介紹。

3. 基于git的合作開發
對于酷訊來說,當我們采用了Git,如何進行合作開發呢? 具體步驟如下:
3.1 獲取最新代碼

酷訊會準備一個中心git代碼庫。首先,我們將整理好的代碼分模塊在git中心庫中建立git庫。并將文件add到中心庫中。 接下來,開發者通過git-clone將代碼從中心庫clone到本地開發環境。
對于較大的項目,我們還建議每個組選擇一個負責人,由這個負責人負責從中心庫獲取和更新最新的代碼,其它開發者從這個負責人的git代碼庫中clone代碼。此時,對開發者來說,這個負責人的git庫就是中心庫了。

git 使用詳解

3.2 開發者在本地進行迭代開發

當用戶將代碼clone到本地后, 就可以進行本地的迭代開發,建議用戶不要在master分支上開發,而是建立一個開發分支進行開發。 在本地開發中,用戶可以隨意的創建臨時分支,隨意commit。

git 使用詳解

3.3 開發者請其它同事進行code review

當本地開發完畢,可以請其它同事進行code review。過程為:
1. user2通通過git-pull命令,將開發者(user1)的開發分支(dev)pull到user2本地的一個tmp分支,并切換工作分支到該分支上進行code review。
2. 完成code review后, user2切換回其原有開發分支繼續開發,并告知user1已經修改完畢。
3. User1將user2的tmp分支git-pull到本地tmp分支,并和dev分支進行merge。最終得到一個code review后的dev分支。
當然,user2也可以直接坐在user1旁邊在他的代碼上進行review。而不需要走上述步驟。(圖中第7步,不是git-pull,而是直接在dev分支上和user1邊review邊modify)

git 使用詳解



3.4 和中心庫進行代碼合并

使用過CVS的人都知道, 在commit之前,都要做一次cvs update,以避免和中心庫沖突。Git也是如此。
現在我們已經經過了code review, 準備向中心庫提交變化了, 在開發的這段時間,也許中心庫發生了變化, 因此,我們需要在向中心庫提交前,再次將中心庫的master分支git-pull到本地的master分支上。并且和dev分支做合并。最終,將合并的代碼放入master分支。
如果開發過程提交日志過多,可以考慮參照2.10節的介紹做一次git-reset。
此外,如果發現合并過程變化非常多, 出于代碼質量考慮,建議再做一次code review


3.5 提交代碼到中心庫

此時,已經完全準備好提交最終的代碼了。 通過git-push就可以了。


3.6 合作流程總結
大家可以看到,使用git進行合作開發,這一過程和CVS有很多相似性,同時,增強了以下幾個環節:
1. 開發者在本地進行迭代開發,可以經常的做commit操作且不會影響他人。 而且即使不在線也可以進行開發。只需要最后向中心庫提交一次即可。
2. 大家都知道,如果CVS管理代碼,由于我們會常常做commit操作。但是在commit之前cvs update時常會遇到將中心庫上的其它最新代碼checkout下來的情況,此時,一旦出現問題,就很難確認到底是自己開發的bug還是其它用戶的代碼帶來了影響。 而使用git則避免了用戶間的開發互相影響。
3. 更有利于在代碼提交前做code review。 以往用cvs, 都是代碼提交后才做code view。如果發生問題, 也無法避免服務器上有不好的代碼。 但是用git, 真正向中心庫commit前,都是在本地開發,可以方便的進行code review, 然后才提交到中心庫。更有利于代碼質量。而且, 大家應該可以感到,使用git的過程中,更容易對代碼進行code review,因為影響因素更小。
4. 創建多分支,更容易在開發中進行多種工作,而使工作間不會互相影響。 比如user2對user1的代碼進行code review時,就可以非常方便的保留當時的開發現場,并切換到user1的代碼分支,在code review完畢后,也可以非常方便的切換會曾經被中斷的工作現場。

誠然,帶來這些好處的同時,確實也使得操作比CVS復雜了一些。但我們覺得和前面所能獲得的好處相比,這些麻煩是值得的。 當大家用慣了之后會發現,這并不增加多大的復雜性, 而且開發流程會更加自然。

請大家多動手,多嘗試! 去體驗git的魅力所在吧!let’s enjoy it!

git 使用詳解


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 一级特级毛片 | 国产欧美日韩精品高清二区综合区 | 欧美另类69xxxxx 视频 | 国产亚洲一区二区精品 | 久久精品免视看国产明星 | 欧美一级毛片在线一看 | 一级有奶水毛片免费看 | 久久久亚洲欧洲国产 | 亚洲人妖女同在线播放 | 成人激情免费视频 | 91大神在线精品视频一区 | 欧美交换乱理伦片120秒 | 亚洲国产韩国一区二区 | 国产精品国产三级国产 | 亚洲天堂一区在线 | 男人天堂视频在线观看 | 亚洲精品国产男人的天堂 | 羞羞视频免费在线观看 | 一区二区午夜 | 免费国产午夜高清在线视频 | 绿色视频在线看 | 天天综合色天天综合网 | 国产高清在线精品免费 | 日韩一区二区三区不卡视频 | 久久久久久久久久久福利观看 | 久久国产免费一区 | 国产精品日本一区二区在线看 | 欧美成人午夜影院 | 精品96在线观看影院 | 天天射网站| 成人在线短视频 | 一区二区三区欧美日韩 | 国产视频久久久 | 亚洲欧美久久精品一区 | 国产一区二区在线视频观看 | 97高清国语自产拍免费 | 日本热久久 | 国产在线小视频 | 亚洲高清中文字幕综合网 | 97久久综合精品久久久综合 | 欧美一区二区三区国产精品 |