Git常用命令的使用
版本控制是一種記錄若干文件內(nèi)容變化,以便將來查閱特定版本修訂情況的系統(tǒng).
關(guān)于版本控制分為三種:本地版本控制系統(tǒng),如rcs;集中化的版本控制系統(tǒng),如CVS、SVN;分布式版本控制系統(tǒng),如Git。
Git基礎(chǔ)要點(diǎn)
Git和其它版本控制系統(tǒng)的主要差別在于:Git只關(guān)心文件數(shù)據(jù)的整體是否發(fā)生變化,而大多數(shù)其它系統(tǒng)則只關(guān)心文件內(nèi)容的具體差異。
對于任何一個(gè)文件,在Git內(nèi)都只有三種狀態(tài):已提交(committed)、已修改(modified)和已暫存(staged)。已提交表示該文件已經(jīng)被安全地保存在本地?cái)?shù)據(jù)庫中了;已修改表示修改了某個(gè)文件,但還沒有提交保存;已暫存表示把已修改的文件放在下次提交時(shí)要保存的清單中。
每個(gè)項(xiàng)目都有一個(gè)git目錄,它是Git用來保存元數(shù)據(jù)和對象數(shù)據(jù)庫的地方。該目錄非常重要,每次克隆鏡像倉庫的時(shí)候,實(shí)際拷貝的就是這個(gè)目錄里面的數(shù)據(jù)。
所謂的暫存區(qū)域只不過是個(gè)簡單的文件,一般都放在git目錄中。有時(shí)候人們會(huì)把這個(gè)文件叫做索引文件。
基本的Git工作流程:(1)、在工作目錄中修改某些文件;(2)、對這些修改了的文件作快照,并保存到暫存區(qū)域;(3)、提交更新,將保存在暫存區(qū)域的文件快照轉(zhuǎn)儲(chǔ)到git目錄中。
對于已安裝的Git,第一個(gè)要配置的是你個(gè)人的用戶名稱和電子郵件地址。這兩條配置很重要,每次Git提交時(shí)都會(huì)引用這兩條信息,說明是誰提交了更新,所以會(huì)隨更新內(nèi)容一起被永久納入歷史記錄:
$ git config --global user.name "Spring" $ git config --global user.email Spring@163.com
如果用了--global選項(xiàng),那么更改的配置文件就是位于你用戶主目錄的那個(gè),以后你所有的項(xiàng)目都會(huì)默認(rèn)使用這里配置的用戶信息。如果要在某個(gè)特定的項(xiàng)目中使用其他名字或者電郵,只要去掉--global選項(xiàng)重新配置即可,新的設(shè)定保存在當(dāng)前項(xiàng)目的./git/config文件里。
Git常用命令
有兩種取得Git項(xiàng)目倉庫的方法。
第一種是在現(xiàn)存的目錄下,通過導(dǎo)入所有文件來創(chuàng)建新的Git倉庫:(1)、從當(dāng)前目錄初始化:$ git init ,初始化后,在當(dāng)前目錄下會(huì)出現(xiàn)一個(gè)名為.git的目錄,所有Git需要的數(shù)據(jù)和資源都存放在這個(gè)目錄中;(2)、如果當(dāng)前目錄下有幾個(gè)文件想要納入版本控制,需要先用git add命令告訴Git開始對這些文件進(jìn)行跟蹤,然后提交:
$ git add README $ git commit -m 'initial project version'
其中README文件是已經(jīng)存在在當(dāng)前目錄中的。git add后可以接要跟蹤的文件或目錄的路徑。如果是目錄的話,就說明要遞歸跟蹤所有該目錄下的文件。
第二種是從已有的Git倉庫克隆出一個(gè)新的鏡像倉庫來,如:
$ git clone git://github.com/schacon/grit.git
如果希望在克隆的時(shí)候,自己定義要新建的項(xiàng)目目錄名稱,可以在上面的命令最后指定:
$ git clone git://github.com/schacon/grit.git mygrit
唯一的差別就是,現(xiàn)在新建的目錄成了mygrit,其它的都和上邊的一樣。
工作目錄下面的所有文件都不外乎兩種狀態(tài):已跟蹤或未跟蹤。已跟蹤的文件是指本來就被納入版本控制管理的文件,在上次快照中有它們的記錄,工作一段時(shí)間后,它們的狀態(tài)可能是未更新,已修改或者已放入暫存區(qū)。而所有其他文件都屬于未跟蹤文件。
檢查當(dāng)前文件狀態(tài):
$ git status
忽略某些文件:可以創(chuàng)建一個(gè)名為.gitignore的文件,列出要忽略的文件模式。
要查看尚未暫存的文件更新了哪些部分 ,不加參數(shù)直接輸入:
$ git diff
單單git diff不過是顯示還沒有暫存起來的改動(dòng),而不是這次工作和上次提交之間的差異。
如要看已經(jīng)暫存起來的文件和上次提交時(shí)的快照之間的差異,可以用:
$ git diff --cached
每次準(zhǔn)備提交前,先用git status看下,是不是都已經(jīng)暫存起來了,然后在運(yùn)行提交命令:
$ git commit
這種方式會(huì)啟動(dòng)文本編輯器以便輸入本次提交的說明,也可以使用-m參數(shù)后跟提交說明的方式:
$ git commit -m "commit message"
提交時(shí)記錄的是放在暫存區(qū)域的快照,任何還未暫存的仍然保持已修改狀態(tài),可以在下次提交時(shí)納入版本管理。每一次運(yùn)行提交操作,都是對你項(xiàng)目作一次快照,以后可以回到這個(gè)狀態(tài),或者進(jìn)行比較。
提交更新:現(xiàn)在的暫存區(qū)域已經(jīng)準(zhǔn)備妥當(dāng)可以提交了。在此之前,請一定要確認(rèn)還有什么修改過的或新建的文件還沒有g(shù)it add 過,否則提交的時(shí)候不會(huì)記錄這些還沒暫存起來的變化。所以,每次準(zhǔn)備提交前,先用git status 看下,是不是都已暫存起來了,然后再運(yùn)行提交命令git commit。
跳過使用暫存區(qū)域:只要在提交的時(shí)候,給git commit加上-a選項(xiàng),Git就會(huì)自動(dòng)把所有已經(jīng)跟蹤過的文件暫存起來一并提交,從而跳過git add步驟。
移除文件:要從Git 中移除某個(gè)文件,就必須要從已跟蹤文件清單中移除(確切地說,是從暫存區(qū)域移除),然后提交??梢杂胓it rm 命令完成此項(xiàng)工作,并連帶從工作目錄中刪除指定的文件,這樣以后就不會(huì)出現(xiàn)在未跟蹤文件清單中了:
$ git rm README
如果刪除之前修改過并且已經(jīng)放到暫存區(qū)域的話,則必須要用強(qiáng)制刪除選項(xiàng)”-f”,以防誤刪除文件后丟失修改的內(nèi)容。
移動(dòng)文件:要在Git中對文件改名:
$ git mv file_from file_to
其實(shí),運(yùn)行g(shù)it mv就相當(dāng)于運(yùn)行了下面三條命令:
$ mv file_from file_to $ git rm file_from $ git add file_to
查看提交歷史:可以使用
$ git log
默認(rèn)不用任何參數(shù)的話,git log會(huì)按提交時(shí)間列出所有的更新,最近的更新排在最上面。
常用”-p”選項(xiàng)展開顯示每次提交的內(nèi)容差異,用-2則僅顯示最近的兩次更新。”--stat”僅顯示簡要的增改行數(shù)統(tǒng)計(jì)。”--pretty”選項(xiàng),可以指定使用完全不同于默認(rèn)格式的方式展開提交歷史,比如用online將每個(gè)提交放在一行顯示:
$ git log --pretty=oneline
另外還有short、full、fuller和format可以用
git log --pretty=format:"%h - %an, %ar : %s"
下面列出一些其它常用的選項(xiàng)及其釋義:
- “-p”:按補(bǔ)丁格式顯示每個(gè)更新之間的差異。
- “--stat”: 顯示每次更新的文件修改統(tǒng)計(jì)信息。
- “--shortstat”: 只顯示--stat 中最后的行數(shù)修改添加移除統(tǒng)計(jì)。
- “--name-only”: 僅在提交信息后顯示已修改的文件清單。
- “--name-status”:顯示新增、修改、刪除的文件清單。
- “--abbrev-commit”:僅顯示SHA-1 的前幾個(gè)字符,而非所有的40 個(gè)字符。
- “--relative-date”:使用較短的相對時(shí)間顯示(比如,“2 weeks ago”)。
- “--graph”: 顯示ASCII 圖形表示的分支合并歷史。
- “--pretty”: 使用其他格式顯示歷史提交信息。可用的選項(xiàng)包括oneline,short,full,fuller 和format(后跟指定格式)。
- “-(n)”: 僅顯示最近的n 條提交
- --since,--after: 僅顯示指定時(shí)間之后的提交,$ git log --since=2.weeks
- --until,--before: 僅顯示指定時(shí)間之前的提交。
- --author: 僅顯示指定作者相關(guān)的提交。
- --committer”僅顯示指定提交者相關(guān)的提交。
使用圖形化工具查閱提交歷史:gitk,它是用Tcl/Tk寫成的,基本上相當(dāng)于git log命令的可視化版本,凡是git log可以用的選項(xiàng)也都能用在gitk上。在項(xiàng)目工作目錄中輸入
$ gitk
gitk命令后,就會(huì)啟動(dòng)gitk圖形化工具,如果提示沒有安裝,則執(zhí)行以下命令進(jìn)行安裝gitk:
$ sudo apt-get install gitk
撤銷操作:有些操作并不總是可以撤銷的,所以請務(wù)必謹(jǐn)慎小心,一旦失誤,就有可能丟失部分工作成果。
修改最后一次提交:想要撤銷剛才的提交操作,可以使用--amend選項(xiàng)重新提交:
$ git commit --amend
此命令將使用當(dāng)前的暫存區(qū)域快照提交。如果剛才提交完沒有作任何改動(dòng),直接運(yùn)行此命令的話,相當(dāng)于有機(jī)會(huì)重新編輯提交說明,而所提交的文件快照和之前的一樣。啟動(dòng)文本編輯器后,會(huì)看到上次提交時(shí)的說明,編輯它確認(rèn)沒問題后保存退出,就會(huì)使用新的提交說明覆蓋剛才失誤的提交。如果剛才提交時(shí)忘了暫存某些修改,可以先補(bǔ)上暫存操作,然后再運(yùn)行--amend 提交:
$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend
三條命令最終得到一個(gè)提交,第二個(gè)提交命令修正了第一個(gè)的提交內(nèi)容。
取消已經(jīng)暫存的文件:
$ git reset HEAD test.txt
取消對文件的修改:
$ git checkout -- test.txt
這條命令有些危險(xiǎn),所有對文件的修改都沒有了。所以在用這條命令前,請務(wù)必確定真的不再需要保留剛才的修改。
遠(yuǎn)程倉庫的使用:遠(yuǎn)程倉庫是指托管在網(wǎng)絡(luò)上的項(xiàng)目倉庫。管理遠(yuǎn)程倉庫的工作,包括添加遠(yuǎn)程庫,移除廢棄的遠(yuǎn)程庫,管理各式遠(yuǎn)程庫分支,定義是否跟蹤這些分支等。
查看當(dāng)前的遠(yuǎn)程庫:要查看當(dāng)前配置有哪些遠(yuǎn)程倉庫,可以用
$ git remote
它會(huì)列出每個(gè)遠(yuǎn)程庫的簡短名字。在克隆完某個(gè)項(xiàng)目后,至少可以看到一個(gè)名為origin 的遠(yuǎn)程庫,Git 默認(rèn)使用這個(gè)名字來標(biāo)識你所克隆的原始倉庫。也可以加上”-v”選項(xiàng),顯示對應(yīng)的克隆地址。
添加遠(yuǎn)程倉庫:要添加一個(gè)新的遠(yuǎn)程倉庫,可以指定一個(gè)簡單的名字,以便將來引用,運(yùn)行
$ git remote add [shortname] [url]
從遠(yuǎn)程倉庫抓取數(shù)據(jù):
$ git fetch [remote-name]
此命令會(huì)到遠(yuǎn)程倉庫中拉取所有你本地倉庫中還沒有的數(shù)據(jù)。運(yùn)行完成后,你就可以在本地訪問該遠(yuǎn)程倉庫中的所有分支,將其中某個(gè)分支合并到本地,或者只是取出某個(gè)分支。fetch 命令只是將遠(yuǎn)端的數(shù)據(jù)拉到本地倉庫,并不自動(dòng)合并到當(dāng)前工作分支,只有當(dāng)你確實(shí)準(zhǔn)備好了,才能手工合并。如果設(shè)置了某個(gè)分支用于跟蹤某個(gè)遠(yuǎn)端倉庫的分支,可以使用
$ git pull
git pull 命令自動(dòng)抓取數(shù)據(jù)下來,然后將遠(yuǎn)端分支自動(dòng)合并到本地倉庫中當(dāng)前分支。
推送數(shù)據(jù)到遠(yuǎn)程倉庫:
$ git push [remote-name] [branch-name]
只有在所克隆的服務(wù)器上有寫權(quán)限,或者同一時(shí)刻沒有其他人在推數(shù)據(jù),這條命令才會(huì)如期完成任務(wù)。如果在你推數(shù)據(jù)前,已經(jīng)有其他人推送了若干更新,那你的推送操作就會(huì)被駁回。你必須先把他們的更新抓取到本地,并到自己的項(xiàng)目中,然后才可以再次推送。
查看遠(yuǎn)程倉庫信息:
$ git remote show [remote-name]
查看某個(gè)遠(yuǎn)程倉庫的詳細(xì)信息。
遠(yuǎn)程倉庫的刪除和重命名:可以用git remote rename命令修改某個(gè)遠(yuǎn)程倉庫的簡短名稱,比如想把pb改成paul,可以這樣運(yùn)行:
$ git remote rename pb paul
對遠(yuǎn)程倉庫的重命名,也會(huì)使對應(yīng)的分支名稱發(fā)生變化,原來的pb/master 分支現(xiàn)在成了paul/master。碰到遠(yuǎn)端倉庫服務(wù)器遷移,或者原來的克隆鏡像不再使用,又或者某個(gè)參與者不再貢獻(xiàn)代碼,那么需要移除對應(yīng)的遠(yuǎn)端倉庫,可以運(yùn)行g(shù)it remote rm 命令:
$ git remote rm paul
打標(biāo)簽:同大多數(shù)VCS 一樣,Git 也可以對某一時(shí)間點(diǎn)上的版本打上標(biāo)簽。人們在發(fā)布某個(gè)軟件版本(比如v1.0 等等)的時(shí)候,經(jīng)常這么做。
列出已有的標(biāo)簽:
$ git tag
顯示的標(biāo)簽按字母順序排列,所以標(biāo)簽的先后并不表示重要程度的輕重。如果只對某系列的版本感興趣,可以使用:
$ git tag -l 'v1.4.2.*'
新建標(biāo)簽:Git使用的標(biāo)簽有兩種類型,輕量級的(lightweight)和含附注的(annotated)。輕量級標(biāo)簽就像是個(gè)不會(huì)變化的分支,實(shí)際上它就是個(gè)指向特定提交對象的引用。而含附注標(biāo)簽,實(shí)際上是存儲(chǔ)在倉庫中的一個(gè)獨(dú)立對象,它有自身的校驗(yàn)和信息,包含著標(biāo)簽的名字,電子郵件地址和日期,以及標(biāo)簽說明,標(biāo)簽本身也允許使用GNU Privacy Guard (GPG) 來簽署或驗(yàn)證。一般都建議使用含附注型的標(biāo)簽,以便保留相關(guān)信息。
含附注的標(biāo)簽:
$ git tag -a v1.0 -m 'my version 1.0'
而-m選項(xiàng)則指定了對應(yīng)的標(biāo)簽說明,Git會(huì)將此說明一同保存在標(biāo)簽對象中。如果在此選項(xiàng)后沒有給出具體的說明內(nèi)容,Git會(huì)啟動(dòng)文本編輯軟件供你輸入。
可以使用git show命令查看相應(yīng)標(biāo)簽的版本信息,并連同顯示打標(biāo)簽時(shí)的提交對象:
$ git show v1.0
簽署標(biāo)簽:如果你有自己的私鑰,還可以用GPG來簽署標(biāo)簽,只需要把之前的-a改為-s即可。
輕量級標(biāo)簽:輕量級標(biāo)簽實(shí)際上就是一個(gè)保存著對應(yīng)提交對象的校驗(yàn)和信息的文件。要?jiǎng)?chuàng)建這樣的標(biāo)簽,一個(gè)-a,-s 或-m 選項(xiàng)都不用,直接給出標(biāo)簽名字即可
$ git tag v2.0
驗(yàn)證標(biāo)簽:可以使用
$ git tag -v [tag-name]
的方式驗(yàn)證已經(jīng)簽署的標(biāo)簽。此命令會(huì)調(diào)用GPG來驗(yàn)證簽名,所以你需要有簽署者的公鑰,存放在keyring中才能驗(yàn)證。
后期加注標(biāo)簽:可以在后期對早先的某次提交加注標(biāo)簽。只要在打標(biāo)簽的時(shí)候跟上對應(yīng)提交對象的校驗(yàn)和(或前幾位字符)即可:
$ git tag -a v1.3 d06e3de00
分享標(biāo)簽:默認(rèn)情況下,git push并不會(huì)把標(biāo)簽傳送到遠(yuǎn)端服務(wù)器上,只有通過顯式命令才能分享標(biāo)簽到遠(yuǎn)端倉庫,運(yùn)行
$ git push origin [tagname]
即可。如果要一次推送所有(本地新增的)標(biāo)簽上去,可以使用--tags選項(xiàng):
$ git push origin --tags
Git分支
Git中的分支,其實(shí)本質(zhì)上僅僅是個(gè)指向commit 對象的可變指針。Git會(huì)使用master 作為分支的默認(rèn)名字。在若干次提交后,你其實(shí)已經(jīng)有了一個(gè)指向最后一次提交對象的master 分支,它在每次提交的時(shí)候都會(huì)自動(dòng)向前移動(dòng)。
創(chuàng)建一個(gè)新的分支,即創(chuàng)建一個(gè)新的分支指針。比如創(chuàng)建一個(gè)testing分支,可以使用git branch命令:
$ git branch testing
HEAD特別指針,在Git中,它是一個(gè)指向你正在工作中的本地分支的指針。運(yùn)行g(shù)it branch 命令,僅僅是建立了一個(gè)新的分支,但不會(huì)自動(dòng)切換到這個(gè)分支中去。要切換到其它分支,可以執(zhí)行g(shù)it checkout命令:
$ git checkout testing
這樣HEAD就指向了testing分支。每次提交后HEAD隨著分支一起向前移動(dòng)。
$ git checkout -b testing
相當(dāng)于:
$ git branch testing $ git checkout testing
兩條命令。
由于Git中的分支實(shí)際上僅是一個(gè)包含所指對象校驗(yàn)和(40個(gè)字符長度SHA-1字串)的文件,所以創(chuàng)建和銷毀一個(gè)分支就變得非常廉價(jià)。說白了,新建一個(gè)分支就是向一個(gè)文件寫入41 個(gè)字節(jié)(外加一個(gè)換行符)那么簡單,當(dāng)然也就很快了。轉(zhuǎn)換分支的時(shí)候最好保持一個(gè)清潔的工作區(qū)域。Git會(huì)把工作目錄的內(nèi)容恢復(fù)為檢出某分支時(shí)它所指向的那個(gè)commit 的快照。它會(huì)自動(dòng)添加、刪除和修改文件以確保目錄的內(nèi)容和你上次提交時(shí)完全一樣。
分支合并:用git merge命令來進(jìn)行合并,
$ git merge testing
刪除一個(gè)分支:
$ git branch -d testing
沖突的合并:要看看哪些文件在合并時(shí)發(fā)生沖突,可以用
$ git status
查閱。任何包含未解決沖突的文件都會(huì)以未合并(unmerged)狀態(tài)列出。Git會(huì)在有沖突的文件里加入標(biāo)準(zhǔn)的沖突解決標(biāo)記,可以通過它們來手工定位并解決這些沖突。在解決了所有文件里的所有沖突后,運(yùn)行
$ git add
將把它們標(biāo)記為已解決(resolved)。因?yàn)橐坏捍?,就表示沖突已經(jīng)解決。最后再用
$ git commit
來完成這次合并提交。
如果想用一個(gè)有圖形界面的工具來解決沖突,可以運(yùn)行
$ git mergetool
它會(huì)調(diào)用一個(gè)可視化的合并工具并引導(dǎo)你解決所有沖突。
分支管理:git branch命令不僅僅能創(chuàng)建和刪除分支,如果不加任何參數(shù),它會(huì)給出當(dāng)前所有分支的清單。若要查看各個(gè)分支最后一次commit的信息,運(yùn)行,
$ git branch -v
要從該清單中篩選出你已經(jīng)(或尚未)與當(dāng)前分支合并的分支,可以用--merge 和--no-merged選項(xiàng)。比如,
$ git branch --merge
查看哪些分支已被并入當(dāng)前分支。清單中帶有”*”字符的表示當(dāng)前所在的分支。一般來說,列表中沒有”*”的分支通常都可以用git branch -d來刪掉。對于未合并的分支,用git branch -d刪除該分支會(huì)導(dǎo)致失敗。不過,如果你堅(jiān)信你要?jiǎng)h除它,可以用大寫的刪除選項(xiàng)-D 強(qiáng)制執(zhí)行,例如,
$ git branch -D testing
分支式工作流程:長期分支、特性分支
- 特性分支:在任何規(guī)模的項(xiàng)目中都可以使用特性(Topic)分支。一個(gè)特性分支是指一個(gè)短期的,用來實(shí)現(xiàn)單一特性或與其相關(guān)工作的分支。
請務(wù)必牢記這些分支全部都是本地分支,這一點(diǎn)很重要。當(dāng)你在使用分支及合并的時(shí)候,一切都是在你自己的Git倉庫中進(jìn)行----完全不涉及與服務(wù)器的交互。 - 遠(yuǎn)程分支(remote branch):是對遠(yuǎn)程倉庫狀態(tài)的索引。它們是一些無法移動(dòng)的本地分支;只有在進(jìn)行Git的網(wǎng)絡(luò)活動(dòng)時(shí)才會(huì)更新。遠(yuǎn)程分支就像是書簽,提醒著你上次連接遠(yuǎn)程倉庫時(shí)上面各分支的位置。
- 推送:要想和其他人分享某個(gè)分支,你需要把它推送到一個(gè)你擁有寫權(quán)限的遠(yuǎn)程倉庫。你的本地分支不會(huì)被自動(dòng)同步到你引入的遠(yuǎn)程分支中,除非你明確執(zhí)行推送操作。換句話說,對于無意分享的,你盡可以保留為私人分支,而只推送那些協(xié)同工作的特性分支??梢赃\(yùn)行
$ git push (遠(yuǎn)程倉庫名) (分支名)
跟蹤分支:從遠(yuǎn)程分支檢出的本地分支,稱為跟蹤分支(tracking branch)。跟蹤分支是一種和遠(yuǎn)程分支有直接聯(lián)系的本地分支。在跟蹤分支里輸入
$ git push
Git會(huì)自行推斷應(yīng)該向哪個(gè)服務(wù)器的哪個(gè)分支推送數(shù)據(jù)。反過來,在這些分支里運(yùn)行
$ git pull
會(huì)獲取所有遠(yuǎn)程索引,并把它們的數(shù)據(jù)都合并到本地分支中來。
在克隆倉庫時(shí),Git通常會(huì)自動(dòng)創(chuàng)建一個(gè)master分支來跟蹤origin/master。這正是git push和git pull一開始就能正常工作的原因。當(dāng)然,你可以隨心所欲地設(shè)定為其它跟蹤分支,比如origin 上除了master 之外的其它分支,
$ git checkout -b [分支名] [遠(yuǎn)程名]/[分支名]
刪除遠(yuǎn)程分支:如果不再需要某個(gè)遠(yuǎn)程分支了,比如搞定了某個(gè)特性并把它合并進(jìn)了遠(yuǎn)程的master 分支(或任何其他存放穩(wěn)定代碼的地方),可以用這個(gè)非常無厘頭的語法來刪除它:
$ git push [遠(yuǎn)程名]:[分支名]
衍合:把一個(gè)分支整合到另一個(gè)分支的辦法有兩種:merge(合并)和rebase(衍合)。
有了rebase命令,就可以把在一個(gè)分支里提交的改變在另一個(gè)分支里重放一遍。如,
$ git checkout testing $ git rebase master
它的原理是回到兩個(gè)分支(你所在的分支和你想要衍合進(jìn)去的分支)的共同祖先,提取你所在分支每次提交時(shí)產(chǎn)生的差異(diff),把這些差異分別保存到臨時(shí)文件里,然后從當(dāng)前分支轉(zhuǎn)換到你需要衍合入的分支,依序使用每一個(gè)差異補(bǔ)丁文件。衍合能產(chǎn)生一個(gè)更為整潔的提交歷史。如果視察一個(gè)衍合過的分支的歷史記錄,看起來更清楚,仿佛所有修改都是先后進(jìn)行的,盡管實(shí)際上它們原來是同時(shí)發(fā)生的?,F(xiàn)在可以回到master分支然后進(jìn)行一次快進(jìn)合并:
$ git checkout master $ git merge testing $ git rebase master testing
命令會(huì)先檢出特性分支testing,然后在主分支master上重演,然后快進(jìn)主分支master,
$ git checkout master $ git merge testing
永遠(yuǎn)不要衍合那些已經(jīng)推送到公共倉庫的更新。在衍合的時(shí)候,實(shí)際上拋棄了一些現(xiàn)存的commit 而創(chuàng)造了一些類似但不同的新commit。如果你把commit 推送到某處然后其他人下載并在其基礎(chǔ)上工作,然后你用git rebase 重寫了這些commit 再推送一次,你的合作者就不得不重新合并他們的工作,這樣當(dāng)你再次從他們那里獲取內(nèi)容的時(shí)候事情就會(huì)變得一團(tuán)糟。如果把衍合當(dāng)成一種在推送之前清理提交歷史的手段,而且僅僅衍合那些永遠(yuǎn)不會(huì)公開的commit,那就不會(huì)有任何問題。如果衍合那些已經(jīng)公開的commit,而與此同時(shí)其他人已經(jīng)用這些commit 進(jìn)行了后續(xù)的開發(fā)工作,那就麻煩了。
服務(wù)器上的Git
建立一個(gè)大家都可以訪問的共享倉庫,從那里推送和拉取數(shù)據(jù)。我們將把這個(gè)倉庫稱為“Git 服務(wù)器”。遠(yuǎn)程倉庫通常只是一個(gè)純倉庫(bare repository)----一個(gè)沒有當(dāng)前工作目錄的倉庫。因?yàn)樵搨}庫只是一個(gè)合作媒介,所以不需要從一個(gè)處于已從硬盤上檢出狀態(tài)的快照;倉庫里僅僅是Git 的數(shù)據(jù)。簡單的說,純倉庫是你項(xiàng)目里.git 目錄的內(nèi)容,別無他物。
協(xié)議:Git可以使用四種主要的協(xié)議來傳輸數(shù)據(jù):本地傳輸,SSH協(xié)議,Git協(xié)議和HTTP 協(xié)議。
在服務(wù)器部署Git:開始架設(shè)Git 服務(wù)器的時(shí)候,需要把一個(gè)現(xiàn)存的倉庫導(dǎo)出為新的純倉庫----不包含當(dāng)前工作目錄的倉庫。方法非常直截了當(dāng)。把一個(gè)倉庫克隆為純倉庫,可以使用clone 命令的--bare 選項(xiàng)。純倉庫的目錄名以.git 結(jié)尾,如
$ git clone -bare my_project my_project.git
現(xiàn)在在my_project.git中已經(jīng)有了一份Git目錄數(shù)據(jù)的副本。
有了倉庫的純副本以后,剩下的就是把它放在服務(wù)器上并設(shè)定相關(guān)的協(xié)議。假設(shè)一個(gè)域名為git.example.com的服務(wù)器已經(jīng)架設(shè)好,并可以通過SSH 訪問,而你想把所有的Git倉庫儲(chǔ)存在/opt/git 目錄下。只要把純倉庫復(fù)制上去:
$ scp -r my_project.git user@git.example.com:/opt/git
現(xiàn)在,其他對該服務(wù)器具有SSH訪問權(quán)限并可以讀取/opt/git的用戶可以用以下命令克?。?/p>
$ git clone user@git.example.com:/opt/git/my_project.git
假如一個(gè)SSH 用戶對/opt/git/my_project.git 目錄有寫權(quán)限,他會(huì)自動(dòng)具有推送權(quán)限。這時(shí)如果運(yùn)行g(shù)it init 命令的時(shí)候加上--shared 選項(xiàng),Git 會(huì)自動(dòng)對該倉庫加入可寫的組:
$ ssh user@git.example.com $ cd /opt/git/my_project.git $ git init --bare --shared
現(xiàn)在已經(jīng)可以開始在同一個(gè)項(xiàng)目上密切合作了。
Git托管服務(wù):可供選擇的托管服務(wù)數(shù)量繁多,如GitHub。
分布式Git
分布式工作流程:同傳統(tǒng)的集中式版本控制系統(tǒng)(CVCS)不同,開發(fā)者之間的協(xié)作方式因Git 的分布式特性而變得更為靈活多樣。在集中式系統(tǒng)上,每個(gè)開發(fā)者就像是連接在集線器上的節(jié)點(diǎn),彼此的工作方式大體相像。而在Git 網(wǎng)絡(luò)中,每個(gè)開發(fā)者同時(shí)扮演著節(jié)點(diǎn)和集線器的角色,這就是說,每一個(gè)開發(fā)者都可以將自己的代碼貢獻(xiàn)到另外一個(gè)開發(fā)者的倉庫中,或者建立自己的公共倉庫,讓其他開發(fā)者基于自己的工作開始,為自己的倉庫貢獻(xiàn)代碼。于是,Git 的分布式協(xié)作便可以衍生出種種不同的工作流程。
以上內(nèi)容摘自于《Pro Git》
實(shí)際工作中常用命令匯總:
1. 查看遠(yuǎn)程分支:$ git branch -a
2. 查看本地分支:$ git branch
3. 切換分支:$ git checkout 分支名
4. 更新到指定版本:$ git reset --hard 39c9064fe34a1331e3624fbbef33a3f66df8f6ba
5. 更新到上個(gè)版本:$ git reset --hard HEAD^
6. 將遠(yuǎn)程分支下載到本地:$ git checkout -b branch1 origin/branch1
7. 創(chuàng)建新分支,并立即切換到此新分支:$ git checkout -b branchname
8. 從遠(yuǎn)程分支下載指定的分支:$ git pull origin branchname
9. 查看某個(gè)文件作了哪些修改:$ git diff src/a.cpp
10. 在合并進(jìn)倉庫之前,修改上次的提交:$ git commit --amend
11. 撤銷為提交的修改:$ git checkout -- a.cpp
12. 撤銷當(dāng)前目錄下所有文件的修改(慎用):$ git checkout .
13. 查看某個(gè)文件詳細(xì)的修改信息:$ git blame src/a.cpp
14. 刪除本地所有未提交的新增的文件(如果文件已經(jīng)被staged不會(huì)被回退):$ git clean -df
15. 撤銷本地所有未提交的更改(包括已經(jīng)被staged的文件,但不包括新增的文件):$ git reset --hard
16. 修改指定文件的名字,如將a.cpp重命名為b.cpp:$ git mv a.cpp b.cpp
17. 刪除遠(yuǎn)程倉庫中指定的文件src/a.cpp:$ git rm src/a.cpp
18. 刪除遠(yuǎn)程倉庫中指定的目錄src/aa:$ git rm src/aa -r -f
19. 假如之前基于master新建了一個(gè)分支dev,但是后來master有了多于一次的提交,但是dev一直沒有改動(dòng),假如現(xiàn)在想把master的提交更新到dev分支上,因?yàn)閐ev分支一直沒有改動(dòng)過,假如master提交了兩次,除了手動(dòng)調(diào)整改動(dòng)的文件外還可以這樣操作,當(dāng)前在dev分支:$ git merge master , $ git reset HEAD^^,因?yàn)閙aster多于一次的提交,直接git merge master,在git push是不行的
20. 如果一個(gè)項(xiàng)目的提交記錄太多,直接使用git log并不太方便查看提交歷史,此時(shí)可通過tree的方式輸出,執(zhí)行如下命令后,每次查看時(shí)終端執(zhí)行 $ git lg 即可
git config --global alias.lg "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all"
21. 本地執(zhí)行g(shù)it branch -a查看遠(yuǎn)程分支時(shí)出現(xiàn)了一些實(shí)際遠(yuǎn)程倉庫中已不存在的分支,此時(shí)可在本地執(zhí)行:git pull --prune命令清理遠(yuǎn)程倉庫中已不存在的分支
22. 從另一個(gè)分支dev拷貝文件funset.hpp或目錄到現(xiàn)在的分支master,則執(zhí)行:$ git checkout dev funset.hpp ,執(zhí)行后funset.hpp在master分支中默認(rèn)是暫存狀態(tài);若取消暫存,可執(zhí)行: $ get reset HEAD
到此這篇關(guān)于Git常用命令的使用的文章就介紹到這了,更多相關(guān)Git常用命令內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
matlab讀取串口數(shù)據(jù)并顯示曲線的實(shí)現(xiàn)示例
這篇文章主要介紹了matlab讀取串口數(shù)據(jù)并顯示曲線的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Source?Insight?4.0.093?安裝破解詳細(xì)圖文教程
這篇文章主要介紹了Source?Insight?4.0.093?安裝破解詳細(xì)圖文教程,source?insight?4是一款非常強(qiáng)大的程序編輯器,如果你沒有一款合適的代碼編輯器,那么這款軟件不妨試試,可能你會(huì)喜歡2022-08-08ISO-8859-1 、Latin-1 西歐編碼介紹及應(yīng)用
這篇文章主要介紹了ISO-8859-1 、Latin-1 西歐編碼介紹及應(yīng)用,需要的朋友可以參考下2016-06-06使用Visual Studio進(jìn)行文件差異比較的問題小結(jié)
這篇文章主要介紹了使用Visual Studio進(jìn)行文件差異比較,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07刪除SVN三種方法delSvn(windows+linux)
今天想清除目錄下的SVN信息,在網(wǎng)上找了找,說是有三種方法2012-03-03