Git初始設(shè)置
設(shè)置使用Git時(shí)需要的用戶名和郵箱
$ git config --global user.name 'Firstname Lastname'
$ git config --global user.email "your_email@example.com"
初始化倉(cāng)庫(kù)
$ mkdir myApp
$ cd myApp
$ git init
Initialized empty Git repository in /Users/INST/Desktop/myApp/.git/
如果初始化成功煤杀,執(zhí)行了 git init命令的目錄下就會(huì)生成 .git 目 錄树绩。這個(gè) .git 目錄里存儲(chǔ)著管理當(dāng)前目錄內(nèi)容所需的倉(cāng)庫(kù)數(shù)據(jù)。
在 Git 中,我們將這個(gè)目錄的內(nèi)容稱為“附屬于該倉(cāng)庫(kù)的工作樹(shù)”。 文件的編輯等操作在工作樹(shù)中進(jìn)行,然后記錄到倉(cāng)庫(kù)中因篇,以此管理文件 的歷史快照。如果想將文件恢復(fù)到原先的狀態(tài),可以從倉(cāng)庫(kù)中調(diào)取之前 的快照竞滓,在工作樹(shù)中打開(kāi)咐吼。開(kāi)發(fā)者可以通過(guò)這種方式獲取以往的文件。 具體操作指令我們將在后面詳細(xì)解說(shuō)商佑。
查看倉(cāng)庫(kù)的工作狀態(tài)
$ git status
On branch master
Initial commit
結(jié)果顯示了我們當(dāng)前正處于 master 分支下锯茄。關(guān)于分支我們會(huì)在不久 后講到,現(xiàn)在不必深究茶没。接著還顯示了沒(méi)有可提交的內(nèi)容肌幽。所謂提交
(Commit),是指“記錄工作樹(shù)中所有文件的當(dāng)前狀態(tài)”抓半。 尚沒(méi)有可提交的內(nèi)容喂急,就是說(shuō)當(dāng)前我們建立的這個(gè)倉(cāng)庫(kù)中還沒(méi)有記 錄任何文件的任何狀態(tài)。
向暫存區(qū)中添加文件
如果只是用 Git 倉(cāng)庫(kù)的工作樹(shù)創(chuàng)建了文件笛求,那么該文件并不會(huì)被記 入 Git 倉(cāng)庫(kù)的版本管理對(duì)象當(dāng)中廊移。因此我們用 git status命令查看 README.md 文件時(shí),它會(huì)顯示在 Untracked files 里涣易。
要想讓文件成為 Git 倉(cāng)庫(kù)的管理對(duì)象画机,就需要用 git add命令將其 加入暫存區(qū)(Stage 或者 Index)中冶伞。暫存區(qū)是提交之前的一個(gè)臨時(shí)區(qū)域新症。
$ git add README.md
$ git status
# On branch master
將 README.md 文件加入暫存區(qū)后,git 果發(fā)生了變化响禽⊥降可以看到,README.md文件顯示在Changes to be committed 中了芋类。
保存?zhèn)}庫(kù)中的歷史記錄
git commit命令可以將當(dāng)前暫存區(qū)中的文件實(shí)際保存至歷史記錄中隆嗅,通過(guò)這些記錄,我們可以從工作樹(shù)中復(fù)原文件
$ git commit -m "First commit"
[master (root-commit) c968230] First commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
-m 參數(shù)后的 "First commit"稱作提交信息侯繁,是對(duì)這個(gè)提交的概述胖喳。
記述詳細(xì)提交信息
剛才我們只簡(jiǎn)潔地記述了一行提交信息,如果想要記述得更加詳細(xì)贮竟,請(qǐng)不加- m丽焊,直接執(zhí)行g(shù)itcommit命令。執(zhí)行后編輯器就會(huì)啟動(dòng)咕别,并顯示如下結(jié)果技健。
$ git commit
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master #
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage) #
# new file: README.md
#
在編輯器中記述提交信息的格式如下:
- 第一行:用一行文字簡(jiǎn)述提交的更改內(nèi)容
- 第二行:空行
- 第三行以后:記述更改的原因和詳細(xì)內(nèi)容
只要按照上面的格式輸入,今后便可以通過(guò)確認(rèn)日志的命令或工具 看到這些記錄惰拱。
在以 #(井號(hào))標(biāo)為注釋的 Changes to be committed(要提 交的更改)欄中雌贱,可以查看本次提交中包含的文件。將提交信息按格式 記述完畢后,請(qǐng)保存并關(guān)閉編輯器欣孤,以 #(井號(hào))標(biāo)為注釋的行不必刪 除馋没。隨后,剛才記述的提交信息就會(huì)被提交降传。
查看提交日志
git log命令可以查看以往倉(cāng)庫(kù)中提交的日志披泪,包括什么人什么時(shí)候進(jìn)行了提交和合并,以及操作之后有何區(qū)別搬瑰。
$ git log
commit 2c2ee0223f54c7512245f7ab3da5ad7e1bbfb30a
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:37:56 2017 +0800
第一行簡(jiǎn)單文字描述
//空格
只是一個(gè)小小的測(cè)試
文本
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:30:42 2017 +0800
First commit
INSTdeiMac:myApp Andy$ git log --pretty=short // 只顯示提交信息的第一行
commit 2c2ee0223f54c7512245f7ab3da5ad7e1bbfb30a
Author: Firstname Lastname <your_email@example.com>
第一行簡(jiǎn)單文字描述
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
$ git log README.md // 只顯示單個(gè)文件款票、目錄日志
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:30:42 2017 +0800
First commit
顯示文件的改動(dòng)
如果想要查看提交所帶來(lái)的改動(dòng),可以加上參數(shù)- p,文件的前后差別就會(huì)顯示在提交信息中
$ git log -p README.md
commit c968230beadd590903ee2645387d833596fb0fca
Author: Firstname Lastname <your_email@example.com>
Date: Fri Aug 11 09:30:42 2017 +0800
First commit
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..421ac42
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# git教程
\ No newline at end of file
查看暫存區(qū)和工作樹(shù)之間的差別
git diff
diff --git a/README.md b/README.md index e69de29..cb5dc9f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@ +# Git教程
由于我們尚未用git只會(huì)顯示工作樹(shù)與最新提交狀態(tài)之間的差別泽论。
add命令向暫存區(qū)添加任何東西艾少,所以程序只會(huì)顯示工作樹(shù)與最新提交狀態(tài)之間的差別。
查看工作樹(shù)和最新提交的差別
如果現(xiàn)在執(zhí)行 git diff命令翼悴,由于工作樹(shù)和暫存區(qū)的狀態(tài)并無(wú) 差別缚够,結(jié)果什么都不會(huì)顯示。要查看與最新提交的差別鹦赎,請(qǐng)執(zhí)行以下 命令谍椅。
$ git diff HEAD
diff --git a/README.md b/README.md index e69de29..cb5dc9f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@
+# Git教程
不妨養(yǎng)成這樣一個(gè)好習(xí)慣:在執(zhí)行 g i t
git diff HEAD命令,查看本次提交與上次提交之間有什么差別古话,等 確認(rèn)完畢后再進(jìn)行提交雏吭。這里的 HEAD 是指向當(dāng)前分支中最新一次提交 的指針。
分支操作
顯示分支一覽表
```
$ git branch
* master //當(dāng)前只有master分支
```
創(chuàng)建和切換分支
```
$ git checkout -b Feature-A
$ git branch
* Feature-A
master
```
切換回上一個(gè)分支
```
$ git checkout -
Switched to branch 'master'
```
像上面這樣用“-”(連字符)代替分支名陪踩,就可以切換至上一個(gè)分 支杖们。當(dāng)然,將“-”替換成 feature-A 同樣可以切換到 feature-A 分支肩狂。
feature-A 分支左側(cè)標(biāo)有“*”摘完,表示當(dāng)前分支為 feature-A。在這個(gè)狀 態(tài)下像正常開(kāi)發(fā)那樣修改代碼傻谁、執(zhí)行 g i t a d d命令并進(jìn)行提交的話孝治, 代碼就會(huì)提交至 feature-A 分支。像這樣不斷對(duì)一個(gè)分支(例如 feature-A)進(jìn)行提交的操作审磁,我們稱為“培育分支”谈飒。
分支合并
接下來(lái),我們假設(shè) feature-A 已經(jīng)實(shí)現(xiàn)完畢力图,想要將它合并到主干分 支 master 中步绸。首先切換到 master 分支。
```
$git checkout - //回到主分支
Switched to branch 'master'
```
然后合并 feature-A 分支吃媒。為了在歷史記錄中明確記錄下本次分支合 并瓤介,我們需要?jiǎng)?chuàng)建合并提交吕喘。因此,在合并時(shí)加上 --no-ff參數(shù)刑桑。
```
$ git merge --no-ff feature-A
```
以圖標(biāo)的方式查看分支
$ git log --graph
-
更改提交的操作氯质,回溯歷史版本
Git 的另一特征便是可以靈活操作歷史版本。借助分散倉(cāng)庫(kù)的優(yōu)勢(shì)祠斧, 可以在不影響其他倉(cāng)庫(kù)的前提下對(duì)歷史版本進(jìn)行操作闻察。要讓倉(cāng)庫(kù)的 HEAD、暫存區(qū)琢锋、當(dāng)前工作樹(shù)回溯到指定狀態(tài)辕漂,需要用 到git rest --hard命令。只要提供目標(biāo)時(shí)間點(diǎn)的哈希值A(chǔ)吴超,就可以完全恢復(fù)至該時(shí)間點(diǎn)的狀態(tài)钉嘹。事不宜遲,讓我們執(zhí)行下面的命令
$ git reset --hard fd0cbf0d4a25f747230694d95cac1be72d33441d
HEAD is now at fd0cbf0 Add index
查看當(dāng)前倉(cāng)庫(kù)執(zhí)行了哪些操作
$ git reflog
1e4e49d HEAD@{0}: reset: moving to 1e4e49d843f9e23c9665015c520349ec03cf0406
0638c04 HEAD@{1}: reset: moving to HEAD
0638c04 HEAD@{2}: merge feature-A: Merge made by the 'recursive' strategy.
2c2ee02 HEAD@{3}: checkout: moving from Feature-A to master
1e4e49d HEAD@{4}: checkout: moving from master to Feature-A
2c2ee02 HEAD@{5}: checkout: moving from Feature-A to master
1e4e49d HEAD@{6}: commit: Add feature-A
2c2ee02 HEAD@{7}: checkout: moving from master to Feature-A
2c2ee02 HEAD@{8}: checkout: moving from Feature-A to master
2c2ee02 HEAD@{9}: checkout: moving from master to Feature-A
2c2ee02 HEAD@{10}: commit: 第一行簡(jiǎn)單文字描述
c968230 HEAD@{11}: commit (initial): First commit
消除沖突
$ git merge --no-ff fix-B
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Recorded preimage for 'README.md'
Automatic merge failed; fix conflicts and then commit the result.
查看沖突部分并將其解決
# Git教程
<<<<<<< HEAD - feature-A
=======
- fix-B
>>>>>>> fix-B
======= 以上的部分是當(dāng)前 HEAD 的內(nèi)容鲸阻,以下的部分是要合并 的 fix-B 分支中的內(nèi)容跋涣。我們?cè)诰庉嬈髦袑⑵涓某上胍臉幼印?
# Git教程
- feature-A
- fix-B
壓縮歷史
```
$ git checkout -b feature-C
Switched to a new branch 'feature-C'
```
推送至遠(yuǎn)程倉(cāng)庫(kù)
添加遠(yuǎn)程倉(cāng)庫(kù)
$ git remote add origin git@github.com:github-book/git-tutorial.git
按照上述格式執(zhí)行g(shù)it remote add命令之后,Git會(huì)自動(dòng)將 git@github.com:github-book/git-tutorial.git遠(yuǎn)程倉(cāng)庫(kù)的 名稱設(shè)置為 origin(標(biāo)識(shí)符)鸟悴。
推送至遠(yuǎn)程倉(cāng)庫(kù)
推送至 master 分支
如果想將當(dāng)前分支下本地倉(cāng)庫(kù)中的內(nèi)容推送給遠(yuǎn)程倉(cāng)庫(kù)陈辱,需要用到 git push命令。現(xiàn)在假定我們?cè)趍aster分支下進(jìn)行操作细诸。
$ git push -u origin master
像這樣執(zhí)行g(shù)it push命令沛贪,當(dāng)前分支的內(nèi)容就會(huì)被推送給遠(yuǎn)程倉(cāng)庫(kù) origin 的 master 分支。-u參數(shù)可以在推送的同時(shí)揍堰,將 origin 倉(cāng)庫(kù)的 master 分 支設(shè)置為本地倉(cāng)庫(kù)當(dāng)前分支的 upstream(上游)鹏浅。添加了這個(gè)參數(shù)嗅义,將來(lái) 運(yùn)行 git pull命令從遠(yuǎn)程倉(cāng)庫(kù)獲取內(nèi)容時(shí)屏歹,本地倉(cāng)庫(kù)的這個(gè)分支就可 以直接從 origin 的 master 分支獲取內(nèi)容,省去了另外添加參數(shù)的麻煩之碗。執(zhí)行該操作后蝙眶,當(dāng)前本地倉(cāng)庫(kù) master 分支的內(nèi)容將會(huì)被推送到 GitHub 的遠(yuǎn)程倉(cāng)庫(kù)中。在 GitHub 上也可以確認(rèn)遠(yuǎn)程 master 分支的內(nèi)容和本地 master 分支相同褪那。
其他分支也是一樣
注意:這個(gè)時(shí)候肯能會(huì)報(bào)錯(cuò)幽纷,主要原因是遠(yuǎn)程倉(cāng)庫(kù)中的README.md文件不在本地倉(cāng)庫(kù)中。
- 方案一 我們只需加上 -f 參數(shù)即可push成功 git push -f
- 方案二
git pull --rebase origin master
git push -u origin master
獲取遠(yuǎn)程倉(cāng)庫(kù)
$ git clone git@github.com:github-book/git-tutorial.git
執(zhí)行 git clone命令后我們會(huì)默認(rèn)處于 master 分支下博敬,同時(shí)系統(tǒng) 會(huì)自動(dòng)將 origin 設(shè)置成該遠(yuǎn)程倉(cāng)庫(kù)的標(biāo)識(shí)符友浸。也就是說(shuō),當(dāng)前本地倉(cāng)庫(kù) 的 master 分支與 GitHub 端遠(yuǎn)程倉(cāng)庫(kù)(origin)的 master 分支在內(nèi)容上是 完全相同的偏窝。
$ git branch -a * master
remotes/origin/HEAD -> origin/master remotes/origin/feature-D remotes/origin/master
我們用 git branch -a命令查看當(dāng)前分支的相關(guān)信息收恢。添加 -a 參數(shù)可以同時(shí)顯示本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)的分支信息武学。
結(jié)果中顯示了 remotes/origin/feature-D,證明我們的遠(yuǎn)程倉(cāng)庫(kù)中已經(jīng) 有了 feature-D 分支伦意。
獲取遠(yuǎn)程的feature-D分支
$ git checkout -b feature-D origin/feature-D
Branch feature-D set up to track remote branch feature-D from origin. Switched to a new branch 'feature-D'
- b 參數(shù)的后面是本地倉(cāng)庫(kù)中新建分支的名稱火窒。為了便于理解,我 們?nèi)詫⑵涿麨?feature-D驮肉,讓它與遠(yuǎn)程倉(cāng)庫(kù)的對(duì)應(yīng)分支保持同名熏矿。新建 分支名稱后面是獲取來(lái)源的分支名稱。例子中指定了 origin/feature-D离钝, 就是說(shuō)以名為 origin 的倉(cāng)庫(kù)(這里指 GitHub 端的倉(cāng)庫(kù))的 feature-D 分 支為來(lái)源票编,在本地倉(cāng)庫(kù)中創(chuàng)建 feature-D 分支。
推送 feature-D 分支
$ git push
Counting objects: 5, done.
Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes, done. Total 3 (delta 1), reused 0 (delta 0)
To git@github.com:github-book/git-tutorial.git
ca0f98b..ed9721e feature-D -> feature-D
從遠(yuǎn)程倉(cāng)庫(kù)獲取 feature-D 分支卵渴,在本地倉(cāng)庫(kù)中提交更改栏妖,再將 feature-D 分支推送回遠(yuǎn)程倉(cāng)庫(kù),通過(guò)這一系列操作奖恰,就可以與其他開(kāi)發(fā) 者相互合作吊趾,共同培育 feature-D 分支,實(shí)現(xiàn)某些功能
獲取最新的遠(yuǎn)程倉(cāng)庫(kù)分支
現(xiàn)在我們放下剛剛操作的目錄瑟啃,回到原先的那個(gè)目錄下论泛。這邊的本
地倉(cāng)庫(kù)中只創(chuàng)建了 feature-D 分支,并沒(méi)有在 feature-D 分支中進(jìn)行任何提交蛹屿。然而遠(yuǎn)程倉(cāng)庫(kù)的 feature-D 分支中已經(jīng)有了我們剛剛推送的提交屁奏。 這時(shí)我們就可以使用git pull命令,將本地的feature-D分支更新到最新 狀態(tài)错负。當(dāng)前分支為 feature-D 分支坟瓢。
$ git pull origin feature-D
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 1), reused 3 (delta 1) Unpacking objects: 100% (3/3), done.
From github.com:github-book/git-tutorial
* branch feature-D -> FETCH_HEAD
First, rewinding head to replay your work on top of it... Fast-forwarded feature-D to ed9721e686f8c588e55ec6b8071b669f411486b8.
GitHub 端遠(yuǎn)程倉(cāng)庫(kù)中的 feature-D 分支是最新?tīng)顟B(tài),所以本地倉(cāng)庫(kù) 中的 feature-D 分支就得到了更新犹撒。今后只需要像平常一樣在本地進(jìn)行提 交再 push 給遠(yuǎn)程倉(cāng)庫(kù)折联,就可以與其他開(kāi)發(fā)者同時(shí)在同一個(gè)分支中進(jìn)行 作業(yè),不斷給 feature-D 增加新功能识颊。
如果兩人同時(shí)修改了同一部分的源代碼诚镰,push 時(shí)就很容易發(fā)生沖 突。所以多名開(kāi)發(fā)者在同一個(gè)分支中進(jìn)行作業(yè)時(shí)祥款,為減少?zèng)_突情況的發(fā) 生清笨,建議更頻繁地進(jìn)行 push 和 pull 操作
- 刪除本地倉(cāng)庫(kù)
就是刪除文件夾下面的.git文件
find . -name ".git" | xargs rm -Rf
學(xué)習(xí)資料
1.《Github入門與實(shí)踐》