?
This document uses PHP Chinese website manual Release
gittutorial - Git 的教程介紹
git *
本教程介紹了如何將新項(xiàng)目導(dǎo)入 Git,對(duì)其進(jìn)行更改以及與其他開(kāi)發(fā)人員共享更改。
如果您主要對(duì)使用 Git 獲取項(xiàng)目感興趣,例如,要測(cè)試最新版本,您可能更愿意從 “Git用戶手冊(cè)” 的前兩章開(kāi)始。
首先,請(qǐng)注意,您可以獲取命令的文檔,例如git log --graph
:
$ man git-log
或者:
$ git help log
使用后者,您可以使用您選擇的手動(dòng)查看器; 請(qǐng)參閱 git-help [1] 了解更多信息。
在進(jìn)行任何操作之前,向 Git 介紹自己的姓名和公共電子郵件地址是一個(gè)好主意。最簡(jiǎn)單的方法是:
$ git config --global user.name "Your Name Comes Here"$ git config --global user.email you@yourdomain.example.com
假設(shè)你的初始工作有一個(gè) tarball project.tar.gz 。您可以按如下方式將它放在 Git 修訂控件下。
$ tar xzf project.tar.gz $ cd project $ git init
Git 回復(fù)
Initialized empty Git repository in .git/
您現(xiàn)在已初始化工作目錄 - 您可能會(huì)注意到創(chuàng)建了一個(gè)名為 “.git” 的新目錄。
接下來(lái),告訴 Git 為當(dāng)前目錄下的所有文件的內(nèi)容創(chuàng)建一個(gè)快照(注意.
)git add
:
$ git add .
此快照現(xiàn)在存儲(chǔ)在 Git 稱為“索引”的臨時(shí)區(qū)域中。您可以使用git commit
命令將索引的內(nèi)容永久存儲(chǔ)在存儲(chǔ)庫(kù)中:
$ git commit
這會(huì)提示你輸入提交信息。您現(xiàn)在已經(jīng)將您的項(xiàng)目的第一個(gè)版本存儲(chǔ)在 Git 中。
修改一些文件,然后將其更新的內(nèi)容添加到索引中:
$ git add file1 file2 file3
您現(xiàn)在已準(zhǔn)備好提交。您可以使用git diff
--cached 選項(xiàng)查看要提交的內(nèi)容:
$ git diff --cached
(不使用 - 緩存,git diff
會(huì)顯示您已做出但未添加到索引的任何更改。)您還可以通過(guò)以git status
方式獲得情況的簡(jiǎn)要摘要:
$ git status On branch master Changes to be committed:Your branch is up-to-date with 'origin/master'. (use "git reset HEAD <file>..." to unstage) modified: file1 modified: file2 modified: file3
如果您需要進(jìn)一步調(diào)整,請(qǐng)立即執(zhí)行此操作,然后將任何新修改的內(nèi)容添加到索引中。最后,通過(guò)以下方式進(jìn)行修改:
$ git commit
這將再次提示您輸入描述更改的消息,然后記錄該項(xiàng)目的新版本。
或者,不要事先運(yùn)行git add
,您可以使用
$ git commit -a
它會(huì)自動(dòng)注意到任何已修改(但不是新增)的文件,將它們添加到索引中,然后全部一步完成。
關(guān)于提交消息的注釋:雖然不是必需的,但最好先用一個(gè)簡(jiǎn)短(少于50個(gè)字符)的行開(kāi)始提交消息,然后再總結(jié)一個(gè)空行,然后進(jìn)行更全面的描述。直到提交消息中的第一個(gè)空行的文本被視為提交標(biāo)題,并且該標(biāo)題在整個(gè) Git 中使用。例如, git-format-patch [1] 將提交轉(zhuǎn)換為電子郵件,并使用主題行上的標(biāo)題和正文中的其余提交。
許多修訂控制系統(tǒng)提供一個(gè)add
命令,告訴系統(tǒng)開(kāi)始跟蹤對(duì)新文件的更改。Git 的add
命令做了一些更簡(jiǎn)單,更強(qiáng)大的功能:git add
既可用于新文件又可用于新修改的文件,在這兩種情況下,它都會(huì)獲取給定文件的快照并為索引中的內(nèi)容創(chuàng)建階段,以供下一次提交使用。
在任何時(shí)候,您都可以使用查看更改的歷史記錄
$ git log
如果您還想在每個(gè)步驟中看到完整的差異,請(qǐng)使用
$ git log -p
通常情況下,變更的概述對(duì)于了解每一步是很有用的
$ git log --stat --summary
一個(gè) Git 倉(cāng)庫(kù)可以維護(hù)多個(gè)分支的開(kāi)發(fā)。要?jiǎng)?chuàng)建名為 “experimental” 的新分支,請(qǐng)使用
$ git branch experimental
如果你現(xiàn)在運(yùn)行
$ git branch
你會(huì)得到所有現(xiàn)有分支的列表:
experimental* master
"experimental" 分支是您剛剛創(chuàng)建的分支,“主分支”分支是自動(dòng)為您創(chuàng)建的默認(rèn)分支。星號(hào)標(biāo)記你當(dāng)前所在的分支類型;
$ git checkout experimental
切換到實(shí)驗(yàn)分支?,F(xiàn)在編輯一個(gè)文件,提交更改并切換回主分支:
(edit file)$ git commit -a $ git checkout master
檢查您所做的更改是否不再可見(jiàn),因?yàn)樗窃趯?shí)驗(yàn)分支上創(chuàng)建的,而您又回到了主分支上。
您可以在主分支上進(jìn)行不同的更改:
(edit file)$ git commit -a
在這一點(diǎn)上,兩個(gè)分支已經(jīng)發(fā)生了分歧,每個(gè)分支都有不同的變化。要將實(shí)驗(yàn)中所做的更改合并到 master 中,請(qǐng)運(yùn)行
$ git merge experimental
如果更改不沖突,則表示完成。如果有沖突,標(biāo)記將留在顯示沖突的有問(wèn)題的文件中;
$ git diff
會(huì)顯示這一點(diǎn)。一旦你編輯了文件來(lái)解決沖突,
$ git commit -a
將承諾合并的結(jié)果。最后,
$ gitk
將顯示最終的歷史記錄的一個(gè)很好的圖形表示。
在這一點(diǎn)上,你可以刪除實(shí)驗(yàn)分支
$ git branch -d experimental
命令確保實(shí)驗(yàn)分支中的更改已經(jīng)在當(dāng)前分支中。
如果你在一個(gè)分支的思路發(fā)展,然后后悔了,你可以隨時(shí)刪除分支
$ git branch -D crazy-idea
分支機(jī)構(gòu)既便宜又容易,所以這是嘗試一些東西的好方法。
假設(shè) Alice 已經(jīng)在 / home / alice / project 中使用 Git 存儲(chǔ)庫(kù)啟動(dòng)了一個(gè)新項(xiàng)目,并且在同一臺(tái)機(jī)器上有一個(gè)主目錄的 Bob 想要貢獻(xiàn)。
Bob 從以下開(kāi)始:
bob$ git clone /home/alice/project myrepo
這會(huì)創(chuàng)建一個(gè)包含 Alice 存儲(chǔ)庫(kù)克隆的新目錄 “myrepo” ??寺∨c原始項(xiàng)目保持平等,擁有原始項(xiàng)目歷史的副本。
Bob 然后做出一些改變并提交它們:
(edit files)bob$ git commit -a(repeat as necessary)
當(dāng)他準(zhǔn)備好時(shí),他告訴 Alice 從 / home / bob / myrepo 的存儲(chǔ)庫(kù)中提取更改。她這樣做:
alice$ cd /home/alice/project alice$ git pull /home/bob/myrepo master
這將 Bob 的 “master” 分支的更改合并到 Alice 的當(dāng)前分支中。如果 Alice 在此期間做出了自己的更改,那么她可能需要手動(dòng)修復(fù)任何沖突。
因此,“pull” 命令執(zhí)行兩個(gè)操作:它從遠(yuǎn)程分支獲取更改,然后將它們合并到當(dāng)前分支。
請(qǐng)注意,一般來(lái)說(shuō),Alice 會(huì)希望在啟動(dòng)此“拉”之前執(zhí)行其本地更改。如果 Bob 的工作與愛(ài)麗絲自歷史分手以來(lái)所做的工作相沖突,Alice 將使用她的工作樹(shù)和索引來(lái)解決沖突,而現(xiàn)有的本地更改將干擾沖突解決過(guò)程(Git 仍將執(zhí)行提取操作,但會(huì)拒絕合并 - - Alice 將不得不以某種方式擺脫她的本地變化,并在發(fā)生這種情況時(shí)再次pull)。
Alice 可以通過(guò)使用“獲取”命令來(lái)查看 Bob 沒(méi)有合并的情況,這允許 Alice 使用特殊符號(hào) “FETCH_HEAD” 來(lái)檢查 Bob 做了什么,以確定他是否有值得拉的東西,如下所示:
alice$ git fetch /home/bob/myrepo master alice$ git log -p HEAD..FETCH_HEAD
即使 Alice 未提交本地更改,此操作也是安全的。范圍表示法 “HEAD..FETCH_HEAD” 表示 “顯示可從FETCH_HEAD 獲得的所有內(nèi)容,但排除可從 HEAD 獲得的任何內(nèi)容”。Alice 已經(jīng)知道導(dǎo)致她當(dāng)前狀態(tài)的所有信息(HEAD),并且回顧 Bob 在他的狀態(tài)(FETCH_HEAD)中她沒(méi)有看到過(guò)這個(gè)命令。
如果 Alice 想要查看自從他們的歷史分支后 Bob 做了什么,她可以發(fā)出以下命令:
$ gitk HEAD..FETCH_HEAD
使用git log
,我們看到前面的相同的兩點(diǎn)范圍表示法。
Alice 可能想看看自從他們分手以來(lái)他們都做了什么。她可以使用三點(diǎn)形式而不是雙點(diǎn)形式:
$ gitk HEAD...FETCH_HEAD
這意味著“顯示任何一個(gè)都可以訪問(wèn)的東西,但排除任何可以從兩者中獲得的東西”。
請(qǐng)注意,這些范圍表示法可以與 gitk 和 “git log” 一起使用。
在檢查 Bob 做了什么之后,如果沒(méi)有任何緊急事件,Alice可能會(huì)決定繼續(xù)工作而不從 Bob 那里 pull 。如果 Bob的歷史確實(shí)需要 Alice 立即需要的東西,艾麗斯可能會(huì)選擇先擱置她正在進(jìn)行的工作,做一次 “pull”,然后最終在最終的歷史之外取消正在進(jìn)行的工作。
當(dāng)你在一個(gè)緊密團(tuán)結(jié)的小團(tuán)隊(duì)中工作時(shí),一次又一次地與同一個(gè)存儲(chǔ)庫(kù)進(jìn)行交互并不少見(jiàn)。通過(guò)定義remote
存儲(chǔ)庫(kù)速記,可以使其更容易:
alice$ git remote add bob /home/bob/myrepo
有了這個(gè),Alice 可以使用git fetch
命令單獨(dú)執(zhí)行 “pull” 操作的第一部分,而不用將它們與自己的分支合并,使用:
alice$ git fetch bob
與 longhand 形式不同的是,當(dāng) Alice 使用遠(yuǎn)程倉(cāng)庫(kù)快速設(shè)置從 Bob 獲取時(shí)git remote
,在這種情況下,獲取的內(nèi)容存儲(chǔ)在遠(yuǎn)程跟蹤分支中bob/master
。所以在這之后:
alice$ git log -p master..bob/master
顯示了 Bob 從 Alice 的主分支中分支后所做的所有更改的列表。
在檢查這些更改后,Alice 可以將更改合并到她的主分支中:
alice$ git merge bob/master
merge
也可以通過(guò)pulling from her own remote-tracking branch
如下方式完成:
alice$ git pull . remotes/bob/master
注意 git pull 總是合并到當(dāng)前分支中,而不管命令行上給出的是什么。
之后,Bob可以使用Alice的最新更改更新其回購(gòu)
bob$ git pull
請(qǐng)注意,他不需要為 Alice 的存儲(chǔ)庫(kù)提供路徑; 當(dāng) Bob 克隆 Alice 的存儲(chǔ)庫(kù)時(shí),Git 將其存儲(chǔ)庫(kù)的位置存儲(chǔ)在存儲(chǔ)庫(kù)配置中,并且位置用于提?。?/p>
bob$ git config --get remote.origin.url/home/alice/project
(創(chuàng)建的完整配置git clone
使用可見(jiàn)git config -l
,而 git-config [1] 手冊(cè)頁(yè)解釋每個(gè)選項(xiàng)的含義。)
Git 還以 “origin / master” 的名稱保存了 Alice 主分支的原始副本:
bob$ git branch -r origin/master
如果Bob后來(lái)決定從另一個(gè)主機(jī)上工作,他仍然可以使用 ssh 協(xié)議執(zhí)行 clone 和 pull 操作:
bob$ git clone alice.org:/home/alice/project myrepo
另外,Git 有一個(gè)本地協(xié)議,或者可以使用 http ; 有關(guān)詳細(xì)信息,請(qǐng)參閱 git-pull [1]。
Git 也可以用于類似 CVS 的模式,帶有各種用戶推送更改的中央存儲(chǔ)庫(kù); 請(qǐng)參閱 git-push [1] 和 gitcvs-migration [7]。
Git 歷史被表示為一系列相關(guān)的提交。我們已經(jīng)看到git log
命令可以列出這些提交。請(qǐng)注意,每個(gè)
git 日志條目的第一行還提供了提交的名稱:
$ git log commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7 Author: Junio C Hamano <junkio@cox.net>Date: Tue May 16 17:18:22 2006 -0700 merge-base: Clarify the comments on post processing.
我們可以通過(guò)這個(gè)名字來(lái)git show
查看關(guān)于這個(gè)提交的細(xì)節(jié)。
$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
但還有其他方式可以參考提交。您可以使用足夠長(zhǎng)的名稱的任何起始部分來(lái)唯一標(biāo)識(shí)提交:
$ 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
每個(gè)提交通常都有一個(gè)指向項(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
請(qǐng)注意,合并提交可能有多個(gè)父代:
$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)$ git show HEAD^2 # show the second parent of HEAD
你也可以提交你自己的名字; 跑完之后
$ git tag v2.5 1b2e1d63ff
您可以通過(guò)名稱 “v2.5” 來(lái)引用 1b2e1d63ff 。如果你打算與其他人分享這個(gè)名字(例如,識(shí)別發(fā)布版本),你應(yīng)該創(chuàng)建一個(gè)“標(biāo)簽”對(duì)象,并且可能簽名; 有關(guān)詳細(xì)信息,請(qǐng)參閱 git-tag [1] 。
任何需要提交的 Git 命令都可以采用這些名稱中的任何一個(gè)。例如:
$ 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^
請(qǐng)注意最后一條命令:除了在工作目錄中丟失任何更改之外,它還會(huì)從此分支中刪除所有稍后的提交。如果這個(gè)分支是包含這些提交的唯一分支,它們將會(huì)丟失。另外,不要在其他開(kāi)發(fā)者從其公開(kāi)的分支上使用git reset
,因?yàn)檫@會(huì)迫使其他開(kāi)發(fā)人員不必要的合并來(lái)清理歷史記錄。如果您需要撤消您推送的更改,請(qǐng)改為使用git revert
。
git grep
命令可以在任何版本的項(xiàng)目中搜索字符串,所以
$ git grep "hello" v2.5
在v2.5中搜索所有“hello”。
如果省略提交名稱,git grep
將搜索它在當(dāng)前目錄中管理的任何文件。所以
$ git grep "hello"
是一種快速搜索 Git 跟蹤文件的方法。
許多 Git 命令也會(huì)提交一組提交,這些提交可以通過(guò)多種方式指定。以下是一些示例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
你也可以給出git log
一個(gè)“范圍”的提交,其中第一個(gè)不一定是第二個(gè)的父類; 例如,如果分支機(jī)構(gòu)的“穩(wěn)定”和“主機(jī)”的提示早于一個(gè)普通的提交,那么
$ git log stable..master
將列出在主分支中進(jìn)行的提交,但不在穩(wěn)定分支中進(jìn)行提交
$ git log master..stable
將顯示穩(wěn)定分支上的提交列表,但不顯示主分支上的提交列表。
git log
命令有一個(gè)弱點(diǎn):它必須在列表中提交提交。當(dāng)歷史的發(fā)展路線發(fā)生分化,然后合并到一起時(shí),git log
呈現(xiàn)這些提交的順序就沒(méi)有意義了。
大多數(shù)具有多個(gè)貢獻(xiàn)者的項(xiàng)目(如 Linux 內(nèi)核或 Git
本身)經(jīng)常合并,gitk
更好地將其歷史記錄可視化。例如,
$ gitk --since="2 weeks ago" drivers/
允許您瀏覽在 “drivers” 目錄下提交修改文件的最后2周提交的任何提交。(注意:按住“ - ”或“+”鍵的同時(shí)按住控制鍵可以調(diào)整 gitk 的字體。)
最后,大多數(shù)采用文件名的命令可以選擇允許您在提交之前的任何文件名前面指定文件的特定版本:
$ git diff v2.5:Makefile HEAD:Makefile.in
您也可以使用git show
查看任何此類文件:
$ git show v2.5:Makefile
本教程應(yīng)該足以為您的項(xiàng)目執(zhí)行基本的分布式版本控制。但是,要充分理解 Git 的深度和功能,您需要理解它所基于的兩個(gè)簡(jiǎn)單的想法:
對(duì)象數(shù)據(jù)庫(kù)是相當(dāng)優(yōu)雅的系統(tǒng),用于存儲(chǔ)項(xiàng)目的歷史記錄,目錄和提交。
索引文件是目錄樹(shù)狀態(tài)的緩存,用于創(chuàng)建提交,檢出工作目錄,并保存合并中涉及的各種樹(shù)。
本教程的第二部分將介紹對(duì)象數(shù)據(jù)庫(kù),索引文件以及您需要充分利用 Git 所需的其他一些優(yōu)勢(shì)和缺點(diǎn)。你可以在 gittutorial-2 [7] 找到它。
如果您不想立即繼續(xù),那么在這一點(diǎn)上可能有趣的一些其他偏差:
git-format-patch [1],git-am [1]:這些將 git 提交系列轉(zhuǎn)換為電子郵件補(bǔ)丁,反之亦然,這對(duì) Linux 內(nèi)核等依賴電子郵件補(bǔ)丁的項(xiàng)目非常有用。
git-bisect [1]:當(dāng)你的項(xiàng)目出現(xiàn)回歸時(shí),追蹤錯(cuò)誤的一種方法是通過(guò)搜索歷史記錄來(lái)找到應(yīng)該歸咎于的確切提交。Git bisect 可以幫助您執(zhí)行該提交的二進(jìn)制搜索。即使在具有大量合并分支的復(fù)雜非線性歷史的情況下,它也足夠聰明地執(zhí)行接近最優(yōu)的搜索。
gitworkflows [7]:概述推薦的工作流程。
giteveryday [7]:每天 Git 與20個(gè)命令或者如此。
gitcvs-migration [7]:CVS 用戶的 Git。