唉~我以為休息幾天就不會(huì)痛了,看來我還是太天真了佑笋,實(shí)在是閑不住了翼闹,今天重新開始寫筆記吧,讀者們也注意身體蒋纬,不要久坐猎荠。
第四章 通過實(shí)際操作學(xué)習(xí) Git
4.1 基本操作
-
git init ——初始化倉庫
Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello (master) $ mkdir git-tutorial $ cd git-tutorial bash: cd: git-tutorial: No such file or directory Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master) $ git init Initialized empty Git repository in C:/Users/76152/Desktop/PyProjects/GitHub/Hello/git-tutorial/.git/
如果初始化成功了,執(zhí)行了 git init 命令的目錄下會(huì)生成 .git 目錄蜀备。這個(gè)目錄存儲(chǔ)著管理當(dāng)前目錄內(nèi)容所需的倉庫數(shù)據(jù)
-
git?status——查看倉庫的狀態(tài)
$ git status On branch master Initial commit nothing to commit (create/copy files and use "git add" to track)
結(jié)果顯示了我們當(dāng)前正處于 master 分支下关摇,且沒有可提交的內(nèi)容。
接著我們創(chuàng)建 README.md 文件作為管理對象碾阁,為第一次提交做前期準(zhǔn)備输虱。
$ touch README.md Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master) $ git status On branch master Initial commit Untracked files: (use "git add <file>..." to include in what will be committed) README.md nothing added to commit but untracked files present (use "git add" to track)
可以看到在 Untracked files中顯示了 README.md文件。
類似地脂凶, 只要對 Git 的工作樹或倉庫進(jìn)行操作宪睹,git status命令的顯示結(jié)果就 會(huì)發(fā)生變化。
?
-
git?add——向暫存區(qū)中添加文件
$ git add README.md Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master) $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: README.md
將 README.md 文件加入暫存區(qū)后艰猬,使用 git status 命令查看 README.md 文件横堡,顯示結(jié)果已經(jīng)變化。
?
-
git?commit——保存?zhèn)}庫的歷史記錄
git commit命令可以將當(dāng)前暫存區(qū)中的文件實(shí)際保存到倉庫的歷 史記錄中冠桃。通過這些記錄命贴,我們就可以在工作樹中復(fù)原文件。
?
1. 記述一行提交信息
$ git commit -m "First commit" [master (root-commit) 51e40bb] First commit 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md
-m 參數(shù)后的 "First commit" 稱作提交信息,是對這個(gè)提交的概述胸蛛。
?
2. 記述詳細(xì)提交信息
如果想要記述得更加詳 細(xì)污茵,請不加 -m,直接執(zhí)行 git commit命令葬项。
?
-
git?log——查看提交日志
$ git log commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master) Author: Jadon <761529114@qq.com> Date: Wed Apr 18 15:39:19 2018 +0800 First commit
屏幕顯示了剛剛的提交操作泞当。 commit 欄旁邊顯示的 “51e40bb0c……” 是指向這個(gè)提交的哈希值。Git 的其他命令中民珍,在指向提交時(shí)會(huì)用到這個(gè)哈希值襟士。 最后就是該提交的提交信息。
?
1. 只顯示提交信息的第一行
如果只想讓程序顯示第一行的簡述性信息嚷量,可以在 git log 命令后加上 --pretty=short陋桂。
$ git log --pretty=short commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master) Author: Jadon <761529114@qq.com> First commit
?
2. 只顯示指定文件、目錄的日志
只要在 git log 命令后面加上目錄名/文件名蝶溶。便會(huì)顯示相應(yīng)的日志嗜历。
$ git log README.md commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master) Author: Jadon <761529114@qq.com> Date: Wed Apr 18 15:39:19 2018 +0800 First commit
?
3. 顯示文件的改動(dòng)
如果想查看提交所帶來的改動(dòng),可以加上 -p 參數(shù)抖所,文件的前后差 別就會(huì)顯示在提交信息之后梨州。
$ git log -p commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 (HEAD -> master) Author: Jadon <761529114@qq.com> Date: Wed Apr 18 15:39:19 2018 +0800 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29
比如,我們修改 README.md田轧,并執(zhí)行下面的命令暴匠,就可以只查看 README.md 文件的提交日志以及提交前后的差別。
?
$ git log -p README.md commit 95cf441aad40363e03326657aa25667a965078f9 (HEAD -> master) Author: Jadon <761529114@qq.com> Date: Wed Apr 18 16:03:56 2018 +0800 text2 diff --git a/README.md b/README.md index e69de29..f3ca610 100644 --- a/README.md +++ b/README.md @@ -0,0 +1 @@ +你好 \ No newline at end of file commit 51e40bb0c4f7022a47f8cd0b1e1e58dde76ac9f5 Author: Jadon <761529114@qq.com> Date: Wed Apr 18 15:39:19 2018 +0800 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 :
-
git?diff——查看更改前后的差別
git diff命令可以查看工作樹涯鲁、暫存區(qū)巷查、最新提交之間的差別。
?
1. 查看工作樹和暫存區(qū)的差別
我們修改 README.md 文件,并執(zhí)行 git diff 命令抹腿。
$ git diff diff --git a/README.md b/README.md index e69de29..0d34868 100644 --- a/README.md +++ b/README.md @@ -0,0 +1 @@ +# Hello GitHub
由于我們尚未用 git add 命令向暫存區(qū)添加任何東西岛请,所以程序 只會(huì)顯示工作樹與最新提交狀態(tài)之間的差別。
“+”號(hào)標(biāo)出的是新添加的行警绩,被刪除的 行則用“-”號(hào)標(biāo)出崇败。我們可以看到,這次只添加了一行肩祥。
?
2. 查看工作樹和最新提交的差別
$ git add README.md $ git diff HEAD diff --git a/README.md b/README.md index 0d34868..4b4963b 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Hello GitHub
執(zhí)行 git add README.md 后后室,如果現(xiàn)在執(zhí)行 git diff命令,由于工作樹和暫存區(qū)的狀態(tài)并無 差別混狠,結(jié)果什么都不會(huì)顯示岸霹。要查看與最新提交的差別,請執(zhí)行 git diff HEAD 命令将饺。
不妨養(yǎng)成這樣一個(gè)好習(xí)慣:在執(zhí)行 git commit 命令之前先執(zhí)行 git diff HEAD命令贡避,查看本次提交與上次提交之間有什么差別痛黎,等確認(rèn)完畢后再進(jìn)行提交。
這里的 HEAD是指向當(dāng)前分支中最新一次提交的指針刮吧。
?
由于我們剛剛確認(rèn)過兩個(gè)提交之間的差別湖饱,所以直接運(yùn)行g(shù)it commit命令。
$ git commit -m "Add index" [master 65f2814] Add index 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test.txt
保險(xiǎn)起見杀捻,我們查看一下提交日志井厌,確認(rèn)提交是否成功。
$ git log commit 65f2814a20db917f2d71457b3e5db95c377f4af9 (HEAD -> master) Author: Jadon <761529114@qq.com> Date: Wed Apr 18 16:24:56 2018 +0800 Add index
?
4.2 分支操作
在進(jìn)行多個(gè)并行作業(yè)時(shí)致讥,我們會(huì)用到分支仅仆。在這類并行開發(fā)的過程 中,往往同時(shí)存在多個(gè)最新代碼狀態(tài)垢袱。
如下圖所示蝇恶,從master分支創(chuàng)建 feature-A 分支和 fix-B 分支后,每個(gè)分支中都擁有自己的最新代碼惶桐。master 分支是 Git 默認(rèn)創(chuàng)建的分支,因此基本上所有開發(fā)都是以這個(gè)分支為中心進(jìn)行的潘懊。
不同分支中姚糊,可以同時(shí)進(jìn)行完全不同的作業(yè)。等該分支的作業(yè)完成之后再與 master 分支合并授舟。比如 feature-A分支的作業(yè)結(jié)束后與 master 合并救恨,如下圖所示。
-
git?branch——顯示分支一覽表
git branch 命令可以將分支名列表顯示释树,同時(shí)可以確認(rèn)當(dāng)前所在 分支肠槽。
?
-
git?checkout?-b——?jiǎng)?chuàng)建、切換分支
如果想以當(dāng)前的master分支為基礎(chǔ)創(chuàng)建新的分支奢啥,我們需要用到 git checkout -b命令秸仙。
?
1. 切換到 feature-A 分支并進(jìn)行提交
創(chuàng)建并切換到名為 feature-A 的分支
$ git checkout -b feature-A Switched to a new branch 'feature-A'
連續(xù)執(zhí)行下面兩條命令也能收到同樣效果。
$ git branch feature-A $ git checkout feature-A
使用 git branch 命令查看分支一覽表桩盲, “ * ”表示我們當(dāng)前的分支寂纪。
$ git branch * feature-A master
在這個(gè)狀態(tài)下像正常開發(fā)那樣修改代碼、執(zhí)行 git add 命令并進(jìn)行提交的話赌结,代碼就會(huì)提交至 feature-A 分支捞蛋。像這樣不斷對一個(gè)分支(例如 feature-A)進(jìn)行提交的操作,我們稱為“培育分支”柬姚。
修改 README.md
# Hello GitHub - feature-A
提交 README.md 到 feature-A 分支中拟杉。
$ git add README.md Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (feature-A) $ git commit -m "Add feature-A" [feature-A f0adaa3] Add feature-A 1 file changed, 3 insertions(+), 1 deletion(-)
?
2. 切換到 master 分支
?
Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master) $ git checkout master Switched to branch 'master'
打開文件 README.md ,發(fā)現(xiàn)文件并沒有發(fā)生變化量承。
feature-A分支的更改不會(huì)影響到 master分支搬设,這正是在開發(fā)中創(chuàng)建分支的優(yōu)點(diǎn)穴店。
?
3. 切換回上一個(gè)分支
$ git checkout - Switched to branch 'feature-A'
將“-”替換成 feature-A 同樣可以切換到 feature-A 分支。
?
-
特性分支
特性分支顧名思義焕梅,是集中實(shí)現(xiàn)單一特性(主題)迹鹅,除此之外不進(jìn) 行任何作業(yè)的分支。
在日常開發(fā)中贞言,往往會(huì)創(chuàng)建數(shù)個(gè)特性分支斜棚,同時(shí)在此之外再保留一個(gè)隨時(shí)可以發(fā)布軟件的穩(wěn)定分支。穩(wěn)定分支的角色通常 由 master 分支擔(dān)當(dāng)该窗。
?
?
-
主干分支
主干分支是剛才我們講解的特性分支的原點(diǎn)弟蚀,同時(shí)也是合并的 點(diǎn)。
通常人們會(huì)用 master 分支作為主干分支(擁有多個(gè)版本發(fā)布時(shí)酗失,主干分支可以有多個(gè))义钉。主干分支中并沒有開發(fā)到 一半的代碼,可以隨時(shí)供他人查看规肴。
-
git?merge——合并分支
假設(shè) feature-A 已經(jīng)實(shí)現(xiàn)完畢捶闸,想要將它合并到主干分 支 master 中。
首先切換到 master 分支拖刃。
$ git checkout master Switched to branch 'master'
然后合并 feature-A 分支删壮。為了在歷史記錄中明確記錄下本次分支合 并,我們需要?jiǎng)?chuàng)建合并提交兑牡。因此央碟,在合并時(shí)加上 --no-ff參數(shù)。
$ git merge --no-ff feature-A
隨后編輯器會(huì)啟動(dòng)均函,用于錄入合并提交的信息亿虽。
Merge branch 'feature-A' # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
默認(rèn)信息中已經(jīng)包含了是從 feature-A 分支合并過來的相關(guān)內(nèi)容,所 以可不必做任何更改苞也。將編輯器中顯示的內(nèi)容保存洛勉,關(guān)閉編輯器,然后就會(huì)看到下面的結(jié)果如迟。
Merge made by the 'recursive' strategy. README.md | 2 ++ 1 file changed, 2 insertions(+)
這樣一來坯认,feature-A 分支的內(nèi)容就合并到 master 分支中了。
?
注意:
使用 git merge --no-ff feature-A 命令氓涣,會(huì)進(jìn)入到vim 編輯器牛哺。
然后你會(huì)發(fā)現(xiàn)編輯器里你怎么輸入都沒反應(yīng),這是因?yàn)関im處在不可編輯狀態(tài)劳吠,按下字母鍵 c引润,此時(shí)進(jìn)入編輯狀態(tài),可以開始修改注釋信息了痒玩;
再然后你會(huì)發(fā)現(xiàn)你怎么都退出不了淳附,回到 shell 了议慰,此時(shí),按下 ESC 退出編輯狀態(tài)奴曙;
最后連續(xù)按兩次大寫字母鍵 Z别凹,就可以保存信息并退出來了(第一次玩這個(gè),折騰了挺久的)洽糟。
?
-
git?log?--graph——以圖表形式查看分支
用 git log --graph 命令進(jìn)行查看的話炉菲,能很清楚地看到特性 分支(feature-A)提交的內(nèi)容已被合并。
除此以外坤溃,特性分支的創(chuàng)建 及合并也都清楚明了
$ git log --graph * commit a120a5cc58d1665b0b12793b92267a3f4f665491 (HEAD -> master) |\ Merge: 0fcf070 07f5b0a | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 17:43:07 2018 +0800 | | | | Merge branch 'feature-A' | | | * commit 07f5b0a0eb2598964c09082693749d201f905f7c (feature-A) | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 17:40:15 2018 +0800 | | | | Add feature-A | | | * commit ac3e358ca1848a6b1387d376acc3a008e3cb5172 | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 17:27:42 2018 +0800 | | | | Add feature-A | | | * commit 34be8333a59d28ea692e002ff91eb55eed4398ff | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 17:20:46 2018 +0800 | |
4.3 更改提交的操作
-
git?reset——回溯歷史版本
Git的另一特征便是可以靈活操作歷史版本拍霜。借助分散倉庫的優(yōu)勢, 可以在不影響其他倉庫的前提下對歷史版本進(jìn)行操作薪介。
為了讓各位熟悉對歷史版本的操作祠饺,我們先回溯歷史版本,創(chuàng)建一個(gè)名為 fix-B 的特性分支汁政。
?
?
1. 回溯到創(chuàng)建 feature-A 分支前
讓我們先回溯到上一節(jié)feature-A分支創(chuàng)建之前道偷,創(chuàng)建一個(gè)名為 fix-B 的特性分支。
要讓倉庫的HEAD记劈、暫存區(qū)试疙、當(dāng)前工作樹回溯到指定狀態(tài),需要用 到 git rest --hard命令抠蚣。只要提供目標(biāo)時(shí)間點(diǎn)的哈希值 A,就可以完全恢復(fù)至該時(shí)間點(diǎn)的狀態(tài)履澳。
$ git reset --hard 65f2814a20db917f2d71457b3e5db95c377f4af9
HEAD is now at 65f2814 Add index
我們已經(jīng)成功回溯到特性分支(feature-A)創(chuàng)建之前的狀態(tài)嘶窄。由于所有文件都回溯到了指定哈希值對應(yīng)的時(shí)間點(diǎn)上,README.md 文件的 內(nèi)容也恢復(fù)到了當(dāng)時(shí)的狀態(tài)(只有標(biāo)題的狀態(tài))距贷。
?
2. 創(chuàng)建 fix-B 分支
$ git checkout -b fix-B
Switched to a new branch 'fix-B'
修改 README.md
Hello GitHub
- fix-B
提交文件
$ git add README.md
Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (fix-B)
$ git commit -m "Fix-B"
[fix-B dfa4302] Fix-B
1 file changed, 3 insertions(+), 1 deletion(-)
現(xiàn)在的狀態(tài)如圖 4.5 所示柄冲。接下來我們的目標(biāo)是圖 4.6 中所示的狀 態(tài),即主干分支合并 feature-A 分支的修改后忠蝗,又合并了 fix-B 的修改现横。
?
?
?
3. 推進(jìn)至 feature-A 分支合并后的狀態(tài)
?
首先恢復(fù)到 feature-A 分支合并后的狀態(tài)。不妨稱這一操作為“推進(jìn) 歷史”阁最。(什么鬼戒祠?)
git log 命令只能查看以當(dāng)前狀態(tài)為終點(diǎn)的歷史日志。
所以這里 要使用 git reflog 命令速种,查看當(dāng)前倉庫的操作日志姜盈。在日志中找出 回溯歷史之前的哈希值,通過 git reset --hard 命令恢復(fù)到回溯歷 史前的狀態(tài)配阵。
只要不進(jìn)行 Git 的 GC(Garbage Collection馏颂,垃圾回收)示血, 就可以通過日志隨意調(diào)取近期的歷史狀態(tài)。
即便開發(fā)者錯(cuò)誤執(zhí)行了Git操作救拉, 基本也都可以利用 git reflog 命令恢復(fù)到原先的狀態(tài)难审。
$ git checkout -
Switched to branch 'master'
$ git reset --hard a120a5c
HEAD is now at a120a5c Merge branch 'feature-A'
當(dāng)前狀態(tài)為
?
?
-
消除沖突
現(xiàn)在只要合并 fix-B 分支,就可以得到我們想要的狀態(tài)亿絮。
$ git merge --no-ff fix-B Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
這時(shí)告喊,系統(tǒng)告訴我們 README.md 文件發(fā)生了沖突(Conflict)。
系統(tǒng)在合并 README.md 文件時(shí)壹无,feature-A 分支更改的部分與本次想要合并的 fix-B 分支更改的部分發(fā)生了沖突葱绒。
不解決沖突就無法完成合并,所以我們打開 README.md文件斗锭,解決這個(gè)沖突地淀。
?
1. ?查看沖突部分并將其解決
此時(shí)打開 README.md 文件,就會(huì)發(fā)現(xiàn)內(nèi)容變成了下面這個(gè)樣子
# Hello GitHub <<<<<<< HEAD - feature-A ======= - fix-B >>>>>>> fix-B
=======以上的部分是當(dāng)前HEAD的內(nèi)容岖是,以下的部分是要合并 的 fix-B 分支中的內(nèi)容帮毁。我們在編輯器中將其改成想要的樣子(直接改?我還以為有什么高端的操作)豺撑。
# Hello GitHub - feature-A - fix-B
如上所示烈疚,本次修正讓 feature-A 與 fix-B 的內(nèi)容并存于文件之中。
但是在實(shí)際的軟件開發(fā)中聪轿,往往需要?jiǎng)h除其中之一爷肝,所以各位在處理沖突時(shí),務(wù)必要仔細(xì)分析沖突部分的內(nèi)容后再行修改陆错。
?
2. 提交解決后的結(jié)果
$ git add README.md $ git commit -m "Fix conflict" [master 51a829b] Fix conflict
?
?
-
git?commit?--amend——修改提交信息
要修改上一條提交信息灯抛,可以使用 git commit --amend命令。
我們將上一條提交信息記為了 "Fix conflict"音瓷,但它其實(shí)是 fix-B分 支的合并对嚼,解決合并時(shí)發(fā)生的沖突只是過程之一,這樣標(biāo)記實(shí)在不妥绳慎。 于是纵竖,我們要修改這條提交信息。
$ git commit --amend
執(zhí)行上面的命令后杏愤,編輯器就會(huì)啟動(dòng)靡砌。
Fix conflict # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: # (use "git reset HEAD^1 <file>..." to unstage) # # modified: README.md #
編輯器中顯示的內(nèi)容如上所示,其中包含之前的提交信息珊楼。
請將 提交信息的部分修改為 Merge branch 'fix-B'乏奥,然后保存文件,關(guān)閉編輯器(我也不知道是不是這樣改亥曹,結(jié)果一樣)邓了。
?
?
更改后
$ git log --graph * commit 2d9907ae4bc6efccdc647d181346794f65a4fa86 (HEAD -> master) |\ Merge: a120a5c dfa4302 | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 20:26:32 2018 +0800 | | | | Merge branch 'fix-B'
?
-
git?rebase?-i——壓縮歷史
在合并特性分支之前恨诱,如果發(fā)現(xiàn)已提交的內(nèi)容中有些許拼寫錯(cuò)誤等, 不妨提交一個(gè)修改骗炉,然后將這個(gè)修改包含到前一個(gè)提交之中照宝,壓縮成一 個(gè)歷史記錄。這是個(gè)會(huì)經(jīng)常用到的技巧句葵,讓我們來實(shí)際操作體會(huì)一下厕鹃。
?
1. 創(chuàng)建 feature-C 分支
$ git checkout -b feature-C Switched to a new branch 'feature-C'
修改文件,故意拼錯(cuò)
# Hello GitHub - feature-A - fix-B - faeture-C
提交這部分內(nèi)容乍丈。這個(gè)小小的變更就沒必要先執(zhí)行 git add命令 再執(zhí)行 git commit命令了剂碴,我們用 git commit -am命令來一次 完成這兩步操作。
$ git commit -am "Add feature-C" [feature-C ae1dd4a] Add feature-C 2 files changed, 1 insertion(+) delete mode 100644 test.txt
?
2. 修正拼寫錯(cuò)誤
自行修正 README.md 文件轻专。
修正后差別如下:
$ git diff diff --git a/README.md b/README.md index 30e62c5..b77c703 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ - feature-A - fix-B - - faeture-C + - feature-C
進(jìn)行提交
$ git commit -am "Fix typo" [feature-C 75b6433] Fix typo 1 file changed, 1 insertion(+), 1 deletion(-)
錯(cuò)字漏字等失誤稱作 typo忆矛,所以我們將提交信息記為 "Fix typo"。
實(shí)際上请垛,我們不希望在歷史記錄中看到這類提交催训,因?yàn)榻∪臍v史記錄 并不需要它們。如果能在最初提交之前就發(fā)現(xiàn)并修正這些錯(cuò)誤宗收,也就不 會(huì)出現(xiàn)這類提交了漫拭。
?
3. 更改歷史
將 "Fix typo"修正的內(nèi)容與之前一次的提交合并,在歷史記錄中合并為一次完美的提交混稽。為此采驻,我們要用到 git rebase命令。
$ git rebase -i HEAD~2
用上述方式執(zhí)行 git rebase命令匈勋,可以選定當(dāng)前分支中包含 HEAD(最新提交)在內(nèi)的兩個(gè)最新歷史記錄為對象礼旅,并在編輯器中打開。
?
?
如上所示颓影,我們將 Fix typo 的 pick 改為 fixup,這樣就可以把 Fix typo 的歷史記錄壓縮到 Add feature-C 里懒鉴。
$ git rebase -i HEAD~2 Successfully rebased and updated refs/heads/feature-C.
系統(tǒng)顯示 rebase 成功诡挂。也就是將 "Fix typo" 的內(nèi)容合并到了上一個(gè)提交 "Add feature-C" 中,改寫成了一個(gè)新的提交临谱。
$ git log --graph * commit 70e60670827b9c962a2532a421d4c01eb93c90b7 (HEAD -> feature-C) | Author: Jadon <761529114@qq.com> | Date: Wed Apr 18 21:01:11 2018 +0800 | | Add feature-C | * commit 2d9907ae4bc6efccdc647d181346794f65a4fa86 (master) |\ Merge: a120a5c dfa4302 | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 20:26:32 2018 +0800 | | | | Merge branch 'fix-B' | | | * commit dfa4302d449eb325dae383a02e5e152723dbed26 (fix-B) | | Author: Jadon <761529114@qq.com> | | Date: Wed Apr 18 19:53:59 2018 +0800 | | | | Fix-B
這樣一來璃俗,F(xiàn)ix typo 就從歷史中被抹去,也就相當(dāng)于 Add feature-C 中從來沒有出現(xiàn)過拼寫錯(cuò)誤悉默。這算是一種良性的歷史改寫城豁。
?
4.合并至 master 分支
$ git checkout master Switched to branch 'master' Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Hello/git-tutorial (master) $ git merge --no-ff feature-C Merge made by the 'recursive' strategy. README.md | 1 + 1 files changed, 1 insertion(+)
?
4.4 推送至遠(yuǎn)程倉庫
Git 是分散型版本管理系統(tǒng),但我們前面所學(xué)習(xí)的抄课,都是針對單一 本地倉庫的操作唱星。下面雳旅,我們將開始接觸遠(yuǎn)在網(wǎng)絡(luò)另一頭的遠(yuǎn)程倉庫。
遠(yuǎn)程倉庫顧名思義间聊,是與我們本地倉庫相對獨(dú)立的另一個(gè)倉庫攒盈。 讓我們先在 GitHub 上創(chuàng)建一個(gè)倉庫,并將其設(shè)置為本地倉庫的遠(yuǎn)程倉庫哎榴。
在 github 上新建一個(gè)名為 git-tutorial 的倉庫型豁,并且創(chuàng)建時(shí)請不要勾選 Initialize this repository with a README 選項(xiàng)。因?yàn)橐坏┕?選該選項(xiàng)尚蝌,GitHub一側(cè)的倉庫就會(huì)自動(dòng)生成 README 文件迎变,從創(chuàng)建之初便與本地倉庫失去了整合性。
-
git?remote?add——添加遠(yuǎn)程倉庫
$ git remote add origin git@github.com:Jun-Dong/git-tutorial.git
?
-
git?push——推送至遠(yuǎn)程倉庫
1. 推送至 master 分支
使用 git push 將當(dāng)前分支下本地庫的內(nèi)容推送給遠(yuǎn)程倉庫飘言。
$ git push -u origin master Counting objects: 46, done. Delta compression using up to 4 threads. Compressing objects: 100% (28/28), done. Writing objects: 100% (46/46), 3.82 KiB | 0 bytes/s, done. Total 46 (delta 7), reused 0 (delta 0) remote: Resolving deltas: 100% (7/7), done. To github.com:Jun-Dong/git-tutorial.git * [new branch] master -> master Branch master set up to track remote branch master from origin.
像這樣執(zhí)行 git push 命令衣形,當(dāng)前分支的內(nèi)容就會(huì)被推送給遠(yuǎn)程倉庫 origin 的 master 分支。-u參數(shù)可以在推送的同時(shí)热凹,將 origin 倉庫的 master 分支設(shè)置為本地倉庫當(dāng)前分支的 upstream(上游)泵喘。添加了這個(gè)參數(shù),將來 運(yùn)行 git pull 命令從遠(yuǎn)程倉庫獲取內(nèi)容時(shí)般妙,本地倉庫的這個(gè)分支就可以直接從 origin 的 master 分支獲取內(nèi)容纪铺,省去了另外添加參數(shù)的麻煩。
在 github 上可以確認(rèn)遠(yuǎn)程 master 分支的內(nèi)容是否和本地 master 分支相同碟渺。
?
2. 推送至 master 以外的分支
除了master分支之外鲜锚,遠(yuǎn)程倉庫也可以創(chuàng)建其他分支。舉個(gè)例子苫拍,我們在本地倉庫中創(chuàng)建 feature-D 分支芜繁,并將它以同名形式 push 至遠(yuǎn)程倉庫。
$ git checkout -b feature-D Switched to a new branch 'feature-D' $ git push -u origin feature-D Total 0 (delta 0), reused 0 (delta 0) To github.com:Jun-Dong/git-tutorial.git * [new branch] feature-D -> feature-D Branch feature-D set up to track remote branch feature-D from origin.
我們在本地倉庫創(chuàng)建了 feature-D 分支绒极,并將它 push 給遠(yuǎn)程倉庫并保持分支名稱不變骏令。
在 github 上查看 feature-D 分支。
?
4.5 從遠(yuǎn)程倉庫獲取
我們把在 GitHub 上新建的倉庫設(shè)置成了遠(yuǎn)程倉庫垄提,并向 這個(gè)倉庫push了 feature-D 分支±拼現(xiàn)在,所有能夠訪問這個(gè)遠(yuǎn)程倉庫的 人都可以獲取 feature-D 分支并加以修改铡俐。
接下來我們從實(shí)際開發(fā)者的角度出發(fā)凰兑,在另一個(gè)目錄下新建一個(gè)本地倉庫,學(xué)習(xí)從遠(yuǎn)程倉庫獲取內(nèi)容的相關(guān)操作审丘。這就相當(dāng)于我們剛剛執(zhí)行過 push 操作的目標(biāo)倉庫又有了另一名新開發(fā)者來共同開發(fā)吏够。
-
git?clone——獲取遠(yuǎn)程倉庫
1. 獲取遠(yuǎn)程倉庫
首先我們換到其他目錄下,將 GitHub 上的倉庫 clone 到本地。注意不要與之前操作的倉庫在同一目錄下锅知。
$ git clone git@github.com:Jun-Dong/git-tutorial.git Cloning into 'git-tutorial'... remote: Counting objects: 46, done. remote: Compressing objects: 100% (21/21), done. Receiving objects: 100% (46/46), done. Resolving deltas: 100% (7/7), done. remote: Total 46 (delta 7), reused 46 (delta 7), pack-reused 0 Jadon@LAPTOP-QTBB80RR MINGW64 ~/Desktop/PyProjects/GitHub/Helo2 $ cd git-tutorial
執(zhí)行 git clone 命令后我們會(huì)默認(rèn)處于 master 分支下播急,同時(shí)系統(tǒng)會(huì)自動(dòng)將 origin設(shè) 置成該遠(yuǎn)程倉庫的標(biāo)識(shí)符。也就是說喉镰,當(dāng)前本地倉庫 的 master 分支與 GitHub端遠(yuǎn)程倉庫(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í)顯示本地倉庫和遠(yuǎn)程倉庫的分支信息侣姆。
?
2. 獲取遠(yuǎn)程的 feature-D 分支
$ git checkout -b feature-D origin/feature-D Switched to a new branch 'feature-D' Branch feature-D set up to track remote branch feature-D from origin.
-b 參數(shù)的后面是本地倉庫中新建分支的名稱生真。為了便于理解,我們?nèi)詫⑵涿麨?feature-D捺宗,讓它與遠(yuǎn)程倉庫的對應(yīng)分支保持同名柱蟀。新建分支名稱后面是獲取來源的分支名稱。例子中指定了origin/feature-D蚜厉, 就是說以名為 origin的倉庫(這里指 GitHub 端的倉庫)的 feature-D 分支為來源长已,在本地倉庫中創(chuàng)建 feature-D 分支。
?
3. 向本地的 feature-D 分支提交更改
現(xiàn)在假定我們是另一名開發(fā)者昼牛,要做一個(gè)新的提交术瓮。在README. md 文件中添加一行文字,查看更改贰健,并提交胞四。
$ git diff diff --git a/README.md b/README.md index b77c703..4309f62 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,4 @@ - feature-A - fix-B - feature-C + - feature-D $ git commit -am "Add feature-D" [feature-D fe60f80] Add feature-D 1 file changed, 1 insertion(+)
?
4. 推送 feature-D 分支
現(xiàn)在來推送 feature-D 分支
$ git push Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 277 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:Jun-Dong/git-tutorial.git 4275a5a..fe60f80 feature-D -> feature-D
從遠(yuǎn)程倉庫獲取 feature-D 分支,在本地倉庫中提交更改伶椿,再將 feature-D 分支推送回遠(yuǎn)程倉庫辜伟,通過這一系列操作,就可以與其他開發(fā)者相互合作脊另,共同培育 feature-D 分支导狡,實(shí)現(xiàn)某些功能。
?
-
git?pull——獲取最新的遠(yuǎn)程倉庫分支
現(xiàn)在回到原先的那個(gè)目錄下偎痛,這邊的本地倉庫中只創(chuàng)建了 feature-D分支旱捧,并沒有在 feature-D分支中進(jìn)行任何提交。然而遠(yuǎn)程倉庫的 feature-D 分支中已經(jīng)有了我們剛剛推送的提交踩麦。 這時(shí)我們就可以使用 git pull 命令枚赡,將本地的 feature-D 分支更新到最新 狀態(tài)。切換到 feature-D 分支靖榕。
$ git pull origin feature-D remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:Jun-Dong/git-tutorial * branch feature-D -> FETCH_HEAD 4275a5a..fe60f80 feature-D -> origin/feature-D Updating 4275a5a..fe60f80 Fast-forward README.md | 1 + 1 file changed, 1 insertion(+)
GitHub 端遠(yuǎn)程倉庫中的 feature-D 分支是最新狀態(tài)标锄,所以本地倉庫中的 feature-D 分支就得到了更新顽铸。今后只需要像平常一樣在本地進(jìn)行提交再push給遠(yuǎn)程倉庫茁计,就可以與其他開發(fā)者同時(shí)在同一個(gè)分支中進(jìn)行作業(yè),不斷給 feature-D 增加新功能。
如果兩人同時(shí)修改了同一部分的源代碼星压,push 時(shí)就很容易發(fā)生沖突践剂。所以多名開發(fā)者在同一個(gè)分支中進(jìn)行作業(yè)時(shí),為減少?zèng)_突情況的發(fā) 生娜膘,建議更頻繁地進(jìn)行 push 和 pull 操作逊脯。
?
這一章有點(diǎn)長,今天就一章了哈竣贪。