git常用命令收藏
這個(gè)教程將介紹如何將一個(gè)新的項(xiàng)目導(dǎo)入到 git 之中,如何修改項(xiàng)目并如何將這些變更與其他開發(fā)者分享。
如果你更感興趣如何用 git 取出一個(gè)項(xiàng)目,比如,測(cè)試軟件的最新版本,你可能更應(yīng)該看看The Git User’s Manual的前兩章。
首先,記住你可以用 man 來(lái)獲取 git 的文檔,比如 "git diff" 的文檔可以用如下命令察看:
$ man git-diff在做任何改動(dòng)之前,最好把自己的名字和 email 地址介紹給大家,最簡(jiǎn)單的方法就是:
$ git config --global user.name "Your Name Comes Here"$ git config --global user.email you@yourdomain.example.com導(dǎo)入一個(gè)新項(xiàng)目
假設(shè)你有一個(gè)名為 project.tar.gz 的 tarball 作為項(xiàng)目的初始內(nèi)容。你可以如下操作來(lái)把它至于 git 版本控制之下。
$ tar xzf project.tar.gz$ cd project$ git initGit 將會(huì)如下回復(fù):
Initialized empty Git repository in .git/現(xiàn)在,你已經(jīng)初始化了工作目錄——你可能已經(jīng)注意到了名為 ".git" 的一個(gè)新目錄了。
下一步就是使用 git-add(1) 命令告訴 git 當(dāng)前目錄的所有文件 (注意這個(gè)點(diǎn):.) 全是項(xiàng)目的一個(gè)快照:
$ git add .這個(gè)快照目前存放在一個(gè)臨時(shí)區(qū)域之中,在 git 中稱為 "index"(索引)。使用 git-commit(1) 命令,你可以把 index 的所有內(nèi)容永久性地存放到軟件倉(cāng)庫(kù)之中:
$ git commit這條命令會(huì)向你提示輸入版本變更信息。這樣,你的項(xiàng)目的第一個(gè)版本就已經(jīng)存入 git 之中了。
進(jìn)行修改
修改一些文件之后,你可以將更新這些內(nèi)容到 index 之中:
$ git add file1 file2 file3現(xiàn)在,你已經(jīng)準(zhǔn)備就緒,可以提交了。現(xiàn)在你可以使用 git-diff(1) 命令的 –cache 參數(shù):
$ git diff --cached(如果不使用 –cached 參數(shù),git-diff(1)會(huì)顯示所有還沒(méi)添加進(jìn) index 的已經(jīng)做出的改動(dòng)。) 你也可以使用 git-status(1)來(lái)獲得一些當(dāng)前狀況的概要信息:
$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## modified: file1# modified: file2# modified: file3#如果你需要進(jìn)行更多改動(dòng),現(xiàn)在就可以進(jìn)行,然后可以添加到 index 之中。最后,使用如下命令提交改動(dòng):
$ git commit這將再次要求你輸入關(guān)于這次改動(dòng)內(nèi)容的描述性信息,之后記錄下的項(xiàng)目新版本。
此外,如果想省掉提交之前的git add命令,你可以直接用
$ git commit -a這樣會(huì)自動(dòng)檢測(cè)所有修改過(guò)的文件 (不包括新文件) ,并一氣呵成地將它們添到 index 之中,并提交。
關(guān)于提交的描述信息: 雖然這個(gè)信息不是必須的,但提交信息描述最好以一行不超過(guò)50個(gè)字符的概要性信息來(lái)開頭,在一個(gè)空行之后再進(jìn)行更多的描述。比如那些將 commit 轉(zhuǎn)化為 email 的工具就會(huì)把這個(gè)第一行作為郵件標(biāo)題,其余的提交內(nèi)容則放在郵件內(nèi)部。
Git 跟蹤內(nèi)容而不是文件
很多版本控制系統(tǒng)提供了一個(gè) "add" 命令用來(lái)記錄一個(gè)新文件。而 git 的 "add" 命令更加簡(jiǎn)單也更加強(qiáng)大: git add既用于新文件也用于新近改動(dòng)的文件,在所有這些情況下,它在 index 中對(duì)所有的文件與狀態(tài)進(jìn)行一次快照,這樣就可以在下一次 commit 命令中進(jìn)行提交。
Viewing project history
在任何時(shí)候,你都可以如下查看所有你進(jìn)行過(guò)的改動(dòng)
$ git log你可能還想看到每一步改進(jìn)中的所有完整的 diff ,這可以使用如下命令
$ git log -p瀏覽改動(dòng)的概要對(duì)于獲得每一步修改的情況常常是比較有用的,可以使用如下命令
$ git log --stat --summary管理分支
一個(gè) git 倉(cāng)庫(kù)可以包含多個(gè)開發(fā)分支。使用如下命令可以建立一個(gè)稱為 "experimental" 的新分支
$ git branch experimental如果你運(yùn)行命令
$ git branch你將可以得到類似下面的已有分支的列表
experimental* master"experimental" 就是你剛剛建立的那個(gè)分支,而 "master" 分支則是建立倉(cāng)庫(kù)的時(shí)候自動(dòng)創(chuàng)建的缺省分支,里面的星號(hào)表示你當(dāng)前所在的分支;輸入命令
$ git checkout experimental就可以切換到 experimental 分支。現(xiàn)在修改一個(gè)文件,并提交改變,然后重新回到 master 分支:
(edit file)$ git commit -a$ git checkout master你會(huì)發(fā)現(xiàn),剛才的變更已經(jīng)不可見了,這是因?yàn)檫@個(gè)改變是發(fā)生于 experimental 分支的,而你現(xiàn)在已經(jīng)回到 master 分支了。
現(xiàn)在,你可以在 master 分支上做一些不同的變更:
(edit file)$ git commit -a這里,兩個(gè)分支已經(jīng)產(chǎn)生不同了,每個(gè)分支上都發(fā)生了不同的改動(dòng)。要把 experimental 中的改變也合并到 master 之中,運(yùn)行命令
$ git merge experimental如果兩者的改變并不沖突,那么就算是完成了。而如果這里有沖突,有問(wèn)題的文件左邊會(huì)顯示出標(biāo)記,以表明這個(gè)文件發(fā)生了沖突;
$ git diff上述命令將會(huì)列出具體的沖突。一旦你編輯文件解決了沖突,
$ git commit -a這個(gè)命令將把合并的結(jié)果提交。最終,
$ gitk會(huì)顯示出漂亮的圖標(biāo)以展示歷史變革。
這里你可以使用如下命令刪除 experimental 分支。
$ git branch -d experimental這個(gè)命令會(huì)確定 experimental 中的所有改動(dòng)已經(jīng)在當(dāng)前分支當(dāng)中了。
如果你在 crazy-idea 分支中進(jìn)行開發(fā),然后又后悔了,你可以用如下命令刪除分支
$ git branch -D crazy-idea分支操作十分簡(jiǎn)單而且代價(jià)低廉,所以適合于嘗試一些東西。
使用 git 進(jìn)行協(xié)作
假設(shè) Alice 在 /home/alice/project 中的 git 倉(cāng)庫(kù)啟動(dòng)了一個(gè)新項(xiàng)目,而在本機(jī)中也擁有 home 目錄的 Bob 想要貢獻(xiàn)一些代碼。
他可以以如下工作開始:
$ git clone /home/alice/project myrepo這會(huì)新建一個(gè)名為 "myrepo" 的目錄,里面包含了 Alice 的倉(cāng)庫(kù)的一份克隆。這份克隆與原始項(xiàng)目完全一致,可以處理自己的一份原始項(xiàng)目歷史。
之后,Bob 進(jìn)行了一些變更并提交了這些變動(dòng):
(edit files)$ git commit -a(repeat as necessary)當(dāng)他完成的時(shí)候,他告訴 Alice 將 /home/bob/myrepo 之中的變動(dòng)導(dǎo)入到原始倉(cāng)庫(kù)之中。她使用如下命令來(lái)完成這一工作:
$ cd /home/alice/project$ git pull /home/bob/myrepo master這會(huì)合并 Bob 的 "master" 分支到 Alice 的當(dāng)前分支。如果 Alice 也已經(jīng)修改了某些內(nèi)容,她需要手工修復(fù)沖突。(注意,"master" 參數(shù)實(shí)際上并不是必要的,因?yàn)檫@是缺省分支。)
"pull" 命令包括兩個(gè)操作: 從遠(yuǎn)端分支中取出改動(dòng),然后合并到當(dāng)前分支之中。
當(dāng)你只在一個(gè)很小的小組里工作的時(shí)候,通常不會(huì)頻繁地訪問(wèn)同一個(gè)倉(cāng)庫(kù)。通過(guò)定義倉(cāng)庫(kù)的快捷方式,可以讓訪問(wèn)遠(yuǎn)程倉(cāng)庫(kù)更方便一些:
$ git remote add bob /home/bob/myrepo這樣,Alice 可以如下用 "git fetch" 命令僅取出改動(dòng),而不把它們合并到當(dāng)前分支之中:
$ git fetch bob和長(zhǎng)格式不同,當(dāng) Alice 使用 git remote設(shè)置的快捷方式從 Bob 的倉(cāng)庫(kù)中獲取內(nèi)容的時(shí)候,取出的內(nèi)容存儲(chǔ)在一個(gè) remote tracking 分支之中,在本例中是 bob/master。所以,如下操作:
$ git log -p master..bob/master將會(huì)列出從 Bob 從 Alice 的主分支中分支出去以后的所有改動(dòng)。
檢查了這些變動(dòng)之后,Alice 可以將這些變動(dòng)合并到自己的 master 分支中:
$ git merge bob/master這個(gè)合并也可以通過(guò)從自己的 remote tracking 分支中 pull 來(lái)做到,如:
$ git pull . remotes/bob/master注意,git pull 總是合并進(jìn)當(dāng)前的分支,不論命令行給出的是什么。
之后,Bob 可以如下使用 Alice 的最近改動(dòng)更新自己的倉(cāng)庫(kù)
$ git pull這里,他不需要給出 Alice 的倉(cāng)庫(kù)的位置;當(dāng) Bob 克隆了 Alice 的倉(cāng)庫(kù)的時(shí)候,git 在倉(cāng)庫(kù)設(shè)置中保存了她的倉(cāng)庫(kù)的位置,即 pull 所使用的位置:
$ git config --get remote.origin.url/home/alice/project(git-clone 創(chuàng)建的完整配置信息可以用 "git config -l" 獲得,git-config(1)的 man page 解釋了所有選項(xiàng)的含義。)
Git 也在 "origin/master" 分支保存了一份 Alice 的主分支的原始拷貝:
$ git branch -r origin/master如果其后 Bob 決定轉(zhuǎn)到另一臺(tái)主機(jī)上工作,他還可以通過(guò) ssh 來(lái)克隆原始倉(cāng)庫(kù):
$ git clone alice.org:/home/alice/project myrepo此外,git 本身也有遠(yuǎn)程協(xié)議,并且可以使用 rsync 或 http,詳細(xì)情況可以查看 git-pull(1)的 man page。
Git 也可以使用類似 CVS 的工作方式,使用一個(gè)中心倉(cāng)庫(kù),所有用戶將改動(dòng)推送到倉(cāng)庫(kù)之中,相關(guān)內(nèi)容可以查閱 git-push(1)的手冊(cè)頁(yè)或git for CVS users。
瀏覽歷史
Git 的歷史是通過(guò)一系列相互關(guān)聯(lián)的 commit 構(gòu)成的。我們已經(jīng)通過(guò) git log 命令看到了這些提交的列表。注意,每個(gè) git log 條目的第一行是那次提交的名稱:
$ git logcommit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7Author: Junio C Hamano <junkio@cox.net>Date: Tue May 16 17:18:22 2006 -0700merge-base: Clarify the comments on post processing.把這個(gè)名稱用于 git show 命令,可以得到提交的詳情。
$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7不過(guò)還有其他辦法來(lái)指代這次提交。你可以只使用名稱的開始部分,只要它足夠長(zhǎng),保證在所有提交中是惟一的就行了:
$ git show c82a22c39c # the first few characters of the name are # usually enough$ git show HEAD # the tip of the current branch$ git show experimental # the tip of the "experimental" branch每一次提交通常都有一次提交作為 "parent" ,它是項(xiàng)目的前一個(gè)狀態(tài):
$ git show HEAD^ # to see the parent of HEAD$ git show HEAD^^ # to see the grandparent of HEAD$ git show HEAD~4 # to see the great-great grandparent of HEAD要注意,合并提交可能會(huì)有多個(gè) "parent":
$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)$ git show HEAD^2 # show the second parent of HEAD你還可以給你的提交一個(gè)名字; 命令
$ git-tag v2.5 1b2e1d63ff讓你可以使用 "v2.5" 來(lái)指代 1b2e1d63ff。如果你想把這個(gè)名字與他人共享 (比如標(biāo)記一個(gè)發(fā)布版本),你應(yīng)該建立一個(gè) "tag" 對(duì)象,可能還需要簽署它; 詳情請(qǐng)查看 git-tag(1)的 man page。
任何 git 命令都可以使用上述任何一種名字。比如:
$ git diff v2.5 HEAD # compare the current HEAD to v2.5$ git branch stable v2.5 # start a new branch named "stable" based # at v2.5$ git reset --hard HEAD^ # reset your current branch and working # directory to its state at HEAD^小心使用上述最后一個(gè)命令: 這將丟失工作目錄中的所有改動(dòng),他還會(huì)清除本分支內(nèi)隨后的所有提交。如果這個(gè)分支是包含這些提交的惟一分支,它們將永遠(yuǎn)地丟失了。此外,不要對(duì)一個(gè)公眾可見的、有其他開發(fā)者從中 pull 內(nèi)容的分支使用 "git reset" 命令,這將導(dǎo)致一些不必要的合并來(lái)清除其他開發(fā)者的歷史信息。如果你需要取消已經(jīng)推送的改動(dòng),可以使用git-revert(1)命令。
git grep 可以在項(xiàng)目的所有版本歷史中尋找字符串,如下命令
$ git grep "hello" v2.5會(huì)在版本 v2.5 中尋找所有 "hello" 的蹤跡。
如果你不提供 commit 名稱,git grep 會(huì)在你當(dāng)前的目錄中搜索所有由 git 管理的文件。于是,如下命令
$ git grep "hello"是搜索 git 跟蹤的所有文件的便捷的方式。
很多 git 命令可以處理一組提交,可以通過(guò)多種方式來(lái)指定版本。這里是一些 git log 的例子:
$ git log v2.5..v2.6 # commits between v2.5 and v2.6$ git log v2.5.. # commits since v2.5$ git log --since="2 weeks ago" # commits from the last 2 weeks$ git log v2.5.. Makefile # commits since v2.5 which modify # Makefile你給出的范圍的上下邊界不一定是嚴(yán)格的時(shí)間先后關(guān)系,比如,"stable-release" 分支可能會(huì)在 "master" 分支之后相當(dāng)長(zhǎng)一段時(shí)間才會(huì)引入同一個(gè)提交內(nèi)容,這樣
$ git log stable..experimental將會(huì)列出 expermental 分支之中已經(jīng)有的,而 stable 分支卻還沒(méi)有的提交,而命令
$ git log experimental..stable將會(huì)列出 stable 中已有、但 experimental 卻沒(méi)有的提交。
"git log" 命令有一個(gè)弱點(diǎn):必須將所有提交在一個(gè)列表中呈現(xiàn)出來(lái)。當(dāng)項(xiàng)目歷史中有多個(gè)不同開發(fā)分支并最終合并到一起時(shí),"git log" 中呈現(xiàn)出來(lái)的順序可能沒(méi)什么意義。
大部分有大量開發(fā)者的項(xiàng)目 (比如 linux kernel 或 git 本身) 都經(jīng)常合并分支,gitk 可以更好地將這些合并變化展示出來(lái)。比如,
$ gitk --since="2 weeks ago" drivers/這個(gè)命令允許你瀏覽過(guò)去兩個(gè)星期中在 "drivers" 目錄之中的任意提交。(注意: 你可以按住 ctrl 鍵然后用 "-" 和 "+" 來(lái)調(diào)整 gitk 的字體大小。)
最后,大部分命令可以帶有文件名,這可以用于指定某次提交中的某個(gè)文件,從而指定某個(gè)文件的某個(gè)版本:
$ git diff v2.5:Makefile HEAD:Makefile.in你還可以用 "git show" 命令去查看任意文件的任意版本:
$ git show v2.5:Makefile轉(zhuǎn)載于:https://www.cnblogs.com/cobbliu/archive/2011/11/30/2389003.html
總結(jié)
- 上一篇: [转]编程电子书
- 下一篇: ArcMap 水文分析 部分功能