1. 安裝 git
Mac上可以在終端上輸入:
git --version
來查看git是否安裝,以及當前git的版本號。
以下內(nèi)容,均為在Mac電腦上使用為前提。git在Mac上的常用的圖形化工具一般是:SourceTree 。 本文主要介紹git 的命令行模式, SourceTree 的使用,見下方參考資料中的 GUI for git|SourceTree|入門基礎(chǔ)
2. 初次運行前 git的配置
當安裝完 Git 應(yīng)該做的第一件事就是設(shè)置你的用戶名稱與郵件地址。 這樣做很重要,因為每一個 Git 的提交都會使用這些信息,并且它會寫入到你的每一次提交中,不可更改:
git config -- global user.name "chenxi"
git config -- global user.email chenxi@01game
如果使用了 --global 選項,那么該命令只需要運行一次,因為之后無論你在該系統(tǒng)上做任何事情, Git 都會使用這些信息。
通過如下命令檢查配置信息
git config --list
3. 獲取git倉庫
3.1 在現(xiàn)有目錄中初始化倉庫
如果你打算使用 Git 來對現(xiàn)有的項目進行管理,你只需要進入該項目目錄并輸入:
git init
該命令將創(chuàng)建一個名為 .git 的子目錄,這個子目錄含有你初始化的 Git 倉庫中所有的必須文件,這些文件是 Git 倉庫的骨干。 但是,在這個時候,我們僅僅是做了一個初始化的操作,你的項目里的文件還沒有被跟蹤。
如果你是在一個已經(jīng)存在文件的文件夾(而不是空文件夾)中初始化 Git 倉庫來進行版本控制的話,你應(yīng)該開始跟蹤這些文件并提交。 你可通過 git add 命令來實現(xiàn)對指定文件的跟蹤,然后執(zhí)行 git commit 提交:
git add <filename>
git commit -m "提交信息"
3.2 從遠端克隆一份已經(jīng)存在的倉庫
執(zhí)行如下命令:
git clone /path/to/repository
git 工作流介紹:
你的本地倉庫由git維護的三棵“樹”組成。第一個是你的 工作目錄,它持有實際文件; 第二個是 暫存區(qū)(Index) ,它像個緩存區(qū)域,臨時保存你的改動;最后是 HEAD ,它指向你最后一次提交的結(jié)果
4.添加和提交
4.1 使用如下命令,把本地文件添加到暫存區(qū)。
git add filename
一次性提交所有的變化
git add -A
4.2 使用如下命令,提交實際改動部分:
git commit -m "代碼提交信息"
現(xiàn)在,本地的改動已經(jīng)提交到了HEAD,但是還沒有到遠端倉庫。
5.推送
使用如下命令,提交到遠端倉庫
git push origin master
默認是master分支,當然你可以把master切換到任何想要推送的分支
當然也可以使用如下命令:
git push -u origin master
-u
告訴git記住這次push的參數(shù),下次運行 git push
的時候,git就知道該怎么做了。
6.更新與合并
使用如下命令更新本地倉庫到最新的改動:
git pull
他相當于 獲取(fetch)
并且 合并(merge)
遠端的改動
7. 替換本地改動
使用如下命令替換掉本地改動:
git checkout -- readme.txt
命令 git checkout -- readme.txt
意思就是,把 readme.txt
文件在工作區(qū)的修改全部撤銷,這里有兩種情況:
一種是
readme.txt
自修改后還沒有被放到暫存區(qū),現(xiàn)在,撤銷修改就回到和版本庫一模一樣的狀態(tài);一種是
readme.txt
已經(jīng)添加到暫存區(qū)后,又作了修改,現(xiàn)在,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)。
總之,就是讓這個文件回到最近一次git commit
或 git add
時的狀態(tài)
注意此命令中的 --
非常重要, 如果沒有,就變成了切換分支的命令了。
**假如你想丟棄你在本地的所有改動與提交,可以到服務(wù)器上獲取最新版本歷史,并將你本地主分支指向它:**
git fetch origin
git reset --hard origin/master
當然還可以使用 `git revert` 命令來撤銷某次操作。此次操作之前和之后的` commit` 和`history`都會保留,并且把這次撤銷作為一次最新的提交
git revert HEAD 撤銷前一次 commit
git revert HEAD^ 撤銷前前一次commit
git revert commit-id (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)撤銷指定的版本,撤銷也會作為一次提交進行保存。
git revert是提交一個新的版本,將需要revert的版本的內(nèi)容再反向修改回去,版本會遞增,不影響之前提交的內(nèi)容
8.刪除文件
在Git中,刪除也是一個修改操作。例如先添加一個新文件test.txt 到git并提交:
git add test.txt
git commit -m "add test.txt"
一般情況下,我們通常在文件管理器中直接把文件刪了,或者使用 rm
命令:
rm test.txt
這個時候,我們有兩種選擇,一是確實要從庫版本中刪除該文件,那就使用 git rm
命令:
git rm test.txt
git commit -m "remove test.txt"
git pull --rebase
git push origin master
第一條命令: 從庫版本中刪除test.txt
第二條命令: 提交信息
第三條命令:推送之前,先拉取信息,并且使用變基命令來代替合并
第四條命令:推送到遠端倉庫 <br />
另一種情況是,刪錯了,因為庫版本里面還有,所以可以很輕松的把誤刪的文件恢復(fù)到最新版本:
git checkout -- test.txt
刪除文件夾的操作類似:例如已經(jīng)在git中添加了second文件夾,刪除執(zhí)行如下指令
git rm second -r
或者是強制刪除second文件夾極其下所有的文件
git rm second -r -f
9.忽略文件
一般我們總會有些文件無需納入 Git 的管理,也不希望它們總出現(xiàn)在未跟蹤文件列表。 通常都是些自動生成的文件,比如日志文件,或者編譯過程中創(chuàng)建的臨時文件等。 在這種情況下,我們可以創(chuàng)建一個名為 .gitignore 的文件,列出要忽略的文件模式。
文件 .gitignore 的格式規(guī)范如下:
所有空行或者以 # 開頭的行都會被 Git 忽略。
可以使用標準的 glob 模式匹配。
匹配模式可以以(/)開頭防止遞歸。
匹配模式可以以(/)結(jié)尾指定目錄。
要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(!)取反。
10. git分支
分支是用來將特性開發(fā)絕緣開來的。在你創(chuàng)建倉庫的時候,master是默認的分支。在其他分支上進行開發(fā),完成后再將它們合并到主分支上。
創(chuàng)建分支:
git branch testing
創(chuàng)建一個叫做“feature_x”的分支,并切換過去:
git checkout -b feature_x
切換回主分支:
git checkout master
再把新創(chuàng)建的分支刪掉:
git branch -d feature_x
將分支推送到遠端倉庫,不然該分支就是不為他人所見的:
git push origin <branch>
查看每個分支的最后一次提交:
git branch -v
查看哪些分支已經(jīng)合并到當前分支:
git branch --merged
分支前的 *
表示當前分支
查看所有包含未合并工作的分支:
git branch --no-merged
合并分支:
git merge <branchName>
11. git 分支-變基
在 Git 中整合來自不同分支的修改主要有兩種方法: merge
以及 rebase
。
整合分支最容易的方法是 merge
命令。 它會把兩個分支的最新快照 以及二者最近的共同祖先進行三方合并,合并的結(jié)果是生成一個新的快照(并提交)。
其實,還有一種方法:可以提取 新建分支
中引入的補丁和修改, 然后在 master
分支的基礎(chǔ)上再應(yīng)用一次。 在git上,這種操作就叫做 變基
。 可以使用 rebase
命令將提交到某一分支上得所有修改都移至道另一分支上,就好像重新播放一樣。如下所示:
git checkout experiment
git rebase master
它的原理是首先找到這兩個分支(即當前分支 experiment
、 變基操作的目標基底分支 master
) 的最近共同祖先(假如叫做 c2
),然后對比當前分支相對于該祖先分支的歷次提交,提取相應(yīng)地修改并存為臨時文件,然后將當前分支指向目標基底,最后以此將之前另存為臨時文件的修改依序應(yīng)用。
現(xiàn)在回到 master
分支上,進行一次快進合并。
git checkout master
git merge experiment
這兩種整合方法的最終結(jié)果沒有任何區(qū)別, 但是變基使得提交歷史更加整潔。你在查看一個經(jīng)過變基的分支的歷史記錄時會發(fā)現(xiàn),盡管實際的開發(fā)工作是并行的,但是他們看上去就像是先后串行的一樣,提交歷史是一條直線沒有分叉。
一般我們這么做的目的是為了確保在向遠程分支推送時能保持提交歷史的整潔——例如向某個別人維護的項目貢獻代碼時。 在這種情況下,你首先在自己的分支里進行開發(fā),當開發(fā)完成時你需要先將你的代碼變基到 origin/master 上,然后再向主項目提交修改。 這樣的話,該項目的維護者就不再需要進行整合工作,只需要快進合并便可。
變基的風(fēng)險
變基也并非完美無缺,要用它得遵循一條準則:
不要對在你的倉庫外有副本的分支執(zhí)行變基。
變基操作的實質(zhì)是丟棄一些現(xiàn)有的提交,然后相應(yīng)地新建一些內(nèi)容一樣但實際上不同的提交。如果有人依賴那些丟棄的提交,會產(chǎn)生問題。
如果沒有分支的情況下,我們拉取數(shù)據(jù)的時候,最好還是按如下指令進行:
git pull --rebase
在我們使用圖形化工具sourceTree 的時候,當我們拉取數(shù)據(jù)的時候,最好勾選上 用變基代替合并
這一選項。如下圖所示
只要你把變基命令當作是在推送前清理提交使之整潔的工具,并且只在從未推送至共用倉庫的提交上執(zhí)行變基命令,你就不會有事。
12. git 子模塊
有種情況我們經(jīng)常會遇到:某個工作中的項目需要包含并使用另一個項目。 也許是第三方庫,或者你獨立開發(fā)的,用于多個父項目的庫。 現(xiàn)在問題來了:你想要把它們當做兩個獨立的項目,同時又想在一個項目中使用另一個。
Git 通過子模塊來解決這個問題。 子模塊允許你將一個 Git 倉庫作為另一個 Git 倉庫的子目錄。 它能讓你將另一個倉庫克隆到自己的項目中,同時還保持提交的獨立。
**12.1 將一個已存在的 Git 倉庫添加為正在工作的倉庫的子模塊,以aonesdk倉庫來舉例 **
git submodule add git@192.168.7.181:core_developers/pub_protocols.git
默認情況下,子模塊會將子項目放到一個與倉庫同名的目錄中,本例中是“protocols”。如果需要放在其他地方,可以在命令結(jié)尾添加一個不同的路徑。
添加完,子模塊之后,會生成一個.gitmodules文件。該文件保存了項目的URL和與已經(jīng)大區(qū)的本地目錄之間的映射. 可以使用如下命令來查看:
cat .gitmodules
12.2 克隆含有子模塊的項目
使用 git clone /path/to/repository
來克隆項目時,默認會包含該子模塊目錄,但其中還沒有任何文件。
必須使用 git submodule init
來初始化本地配置文件, 之后使用 git submodule update
從該項目中抓取所有數(shù)據(jù)并檢出父項目中列出的合適的提交。
更簡單的方式是,使用 --recursive
選項,它會自動初始化并更新倉庫中的每一個子模塊。例如使用如下命令:
git clone --recursive http://192.168.7.181/sdk_developers/aonesdk.git
12.3 在包含子模塊的項目上工作
拉取上游修改
在項目中使用子模塊的最簡模型,就是只使用子項目并不時地獲取更新,而并不在你的檢出中進行任何更改。
如果想要在子模塊中查看新工作,可以進入到子模塊的目錄中運行 git fetch
與 git merge
,合并上游分支來更新本地代碼。
如果不想在子目錄中手動抓取與合并,還有鐘更容易的方式。運行 git submodule update --remote
, git 將會進入子模塊然后抓取并更新。例如:
git submodule update --remote protocols
此命令默認會假定你想要更新并檢出子模塊倉庫的 master 分支。
為了確保這不會發(fā)生,你可以讓 Git 在推送到主項目前檢查所有子模塊是否已推送。 git push
命令接受可以設(shè)置為 “check” 或 “on-demand” 的 --recurse-submodules
參數(shù)。 如果任何提交的子模塊改動沒有推送那么 “check” 選項會直接使 push 操作失敗。例如:
git push --recurse-submodules=check
如果子模塊沒有更新,會推送失敗,并給出提示。簡單的方法是進入每一個子模塊中然后手動推送到遠程倉庫,確保他們能被外部訪問到,之后再次嘗試這次推送
另一個選項是使用 on-demand
值, 它會嘗試為你這么做。例如:
git push --recurse-submodules=on-demand
合并子模塊改動:
如果你其他人同時改動了一個子模塊引用,那么可能會遇到一些問題。 也就是說,如果子模塊的歷史已經(jīng)分叉并且在父項目中分別提交到了分叉的分支上,那么你需要做一些工作來修復(fù)它。
使用 git diff
命令來查看不同分支中的提交記錄
一般的解決步驟如下:
- 首先解決沖突
- 然后返回到主項目目錄中
- 再次檢查SHA-A值
- 解決沖突的子模塊記錄
- 提交我們的合并
13. git 其他命令
幫助命令
git help
查看當前文件狀態(tài)
git status
查看提交歷史
git log
查看不同
git diff
14. git 使用經(jīng)驗總結(jié)
14.1 每次使用git命令進行操作時,都需要輸入用戶名和密碼
解決方法:
GitHub獲得遠程庫時,有ssh方式和https方式。兩個方式的url地址不同,認證方式也不同。使用ssh時保存密鑰對以后可以不再輸入帳號密碼,而https卻不能。所以如果想要不再輸入帳號密碼,一種方式就是在git clone的時候使用ssh方式,另一種方式就是去修改已有項目.git目錄下的config文件中的url。更改為ssl的地址。
14.2 sourceTree 使用錯誤
新買的Mac使用sourceTree克隆代碼的時候報錯:
warning: templates not found /usr/local/git/share/git-core/templates
問題的原因: 意思是在Mac上找不到模板
解決方法: 在終端上面輸入:
open /usr/local/
依次輸入下列命令:
sudo mkdir /usr/local/git(這一條命令后面需要輸入用戶密碼)
sudo mkdir /usr/local/git/share
sudo mkdir /usr/local/git/share/git-core
sudo mkdir /usr/local/git/share/git-core/templates
sudo chmod -R 755 /usr/local/git/share/git-core/templates
前四條創(chuàng)建目錄,最后一條給修改目錄添加權(quán)限. 注意 sudo 創(chuàng)建目錄需要輸入當前 Mac 用戶的密碼
** 14.3 克隆HTTP 錯誤 **
出現(xiàn)如下錯誤信息:
原因:代碼太大,克隆不下來
解決辦法: 配置clone的文件,分批次下載。 或者使用SSH 下載。