參考網(wǎng)站:learn_git
1.直接進(jìn)入沙盒
在 URL 后頭加上 ?NODEMO 就可以了
2. 本地操作相關(guān)篇節(jié)
2.1 基礎(chǔ)篇
-
Git Commeit
- 提交記錄: 保存的是你的目錄下所有文件的快照,就是ctrl+c,但是更優(yōu)雅、輕便
- 可以做到的結(jié)果:可以快速地在這些提交記錄之間切換
- hide goal命令關(guān)閉窗口
-
Git Branch
分支:早建分支!多用分支!
-
與上面的提交記錄結(jié)合起來
- 一種結(jié)合方法:新創(chuàng)建的分支 newImage 指向的是提交記錄
- 切換新分支:
git checkout newImage;git commit并且修改保存到新分支中 - 簡潔的切換方法(創(chuàng)建新分支并切換新分支):
git checkout -b <your-branch-name>
- 切換新分支:
- 一種結(jié)合方法:新創(chuàng)建的分支 newImage 指向的是提交記錄
創(chuàng)建分支示意圖
切換分支提交記錄 -
Git Merge
-
用處:兩個(gè)分支都是獨(dú)立但是沒有整體,如果需要整體的提交記錄這時(shí)候就可以采用合并分支這一個(gè)命令
git merge bugFix
-
合并分支的幾個(gè)步驟:先切換到a節(jié)點(diǎn),接著合并到b節(jié)點(diǎn)
-
合并的規(guī)則就是:正常情況是jiu
git branch bugFix git commit git checkout master git merge bugFix 隨時(shí)用objective打開對(duì)話框 合并分支示意圖:
-
-


- Git Rebase(另外一種合并方案)
本質(zhì):實(shí)際上就是取出一系列的提交記錄,“復(fù)制”它們,然后在另外一個(gè)地方逐個(gè)的放下去(有當(dāng)前節(jié)點(diǎn)和其他節(jié)點(diǎn),rebase就是復(fù)制當(dāng)前節(jié)點(diǎn)到其指定的其他節(jié)點(diǎn)后面——也就是繼承自其他節(jié)點(diǎn))
-
代碼實(shí)現(xiàn):
git checkout -b bugFix 新建并切換回bugFix git commit 提交一次 git checkout master 切換回master git commit 再提交一次 git checkout bugFix 切換回bugFix git rebase master 把master合并到當(dāng)前分支
-
合并示意圖:
rebase之前rebase之后
- 樹上進(jìn)行移動(dòng)
-
HEAD
分離的 HEAD 就是讓其指向了某個(gè)具體的提交記錄而不是分支名
一個(gè)對(duì)當(dāng)前檢出記錄的符號(hào)引用 —— 也就是指向你正在其基礎(chǔ)上進(jìn)行工作的提交記錄。
總是指向當(dāng)前分支上最近一次提交記錄,修改提交樹也是針對(duì)head開始的;
對(duì)提交做的一些更改,可以通過其看到。
可以通過 cat .git/HEAD 查看head指向;
-
指向的是一個(gè)引用,還可以用 git symbolic-ref HEAD 查看它的指向
git checkout C1; git checkout master; git commit; git checkout C2; HEAD示意圖:
未檢出HEAD檢出HEAD -
分離的 HEAD
- ==讓其指向了某個(gè)具體的提交記錄而不是分支名==
- 待解決的問題:
- 想完成此關(guān),從
bugFix分支中分離出 HEAD 并讓其指向一個(gè)提交記錄。 - 通過哈希值指定提交記錄。每個(gè)提交記錄的哈希值顯示在代表提交記錄的圓圈中。
- 想完成此關(guān),從
- 示意圖與1部分示意圖一致。
-
- 相對(duì)引用:
通過指定提交記錄哈希值的方式在 Git 中移動(dòng)不太方便,在git中只需要提供能夠唯一標(biāo)識(shí)提交記錄的前幾個(gè)字符即可。
-
2個(gè)非常有用的操作:
a.使用
^向上移動(dòng) 1 個(gè)提交記錄b.使用
~<num>向上移動(dòng)多個(gè)提交記錄,如 ~3-
代碼構(gòu)成:
git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^;
-
示意圖:
相對(duì)引用之前進(jìn)行相對(duì)引用之后 強(qiáng)制修改分支位置
-
直接使用 -f 選項(xiàng)讓分支指向另一個(gè)提交:
git branch -f master HEAD~3- 示意圖(`git branch -f master C6`):  
-
撤銷變更:
-
組成部分:底層部分(暫存區(qū)的獨(dú)立文件或者片段)和上層部分(變更到底是通過哪種方式被撤銷的)
- 我們關(guān)注的是后者:上層部分
-
兩種撤銷更改指令:
-
git reset(本地),(git reset HEAD^1----->數(shù)字1就是指定回退到的位置)示意圖如下:git reset之前git reset之后 -
git revert(遠(yuǎn)程)(git revert HEAD,注意當(dāng)前節(jié)點(diǎn)應(yīng)該是在所要操作的節(jié)點(diǎn)上):用一個(gè)新提交來消除一個(gè)歷史提交所做的任何修改,示意圖如下:git revert之前git revert之后
-
-
完成的任務(wù):
- 分別撤銷 local 分支和 pushed 分支上的最近一次提交。共需要撤銷兩個(gè)提交(每個(gè)分支一個(gè))。
- 記住 pushed 是遠(yuǎn)程分支,local 是本地分支 —— 這么說你應(yīng)該知道用分別哪種方法了吧?
-
2.2 處理復(fù)雜問題
2.2.1 修改提交樹
- 自由修改提交樹
git cherry-pick清楚知道所需要提交的記錄
提交記錄插入分支的指向,指定記錄插入當(dāng)前分支
-
示意圖如下(
git cherry-pick C2 C4):修改之前修改之后
- 交互式的
rebase從一系列的提交記錄中找到想要的記錄,可以調(diào)整順序、刪除、合并操作
rebase --interactive(-i)
-
示意圖(git rebase -i HEAD~4):
調(diào)整之前調(diào)整之后
2.3 雜項(xiàng)
- 本地自由棧式提交
針對(duì)各個(gè)不同分支有一些調(diào)試或者打印的提交記錄:復(fù)制解決問題的那幾個(gè)提交就是(只提交一個(gè)分支)
-
提交的技巧
- 先用
git rebase -i將提交重新排序,然后把我們想要修改的提交記錄挪到最前 - 然后用
commit --amend來進(jìn)行一些小修改- 會(huì)合并當(dāng)前提交和上一次的提交,如果當(dāng)前提交有注釋,則以當(dāng)前的注釋為合并后的提交的注釋,若當(dāng)前提交沒有注釋,則以上一次提交的注釋作為合并后的提交的注釋
- 接著再用
git rebase -i來將他們調(diào)回原來的順序 - 最后我們把
master移到修改的最前端(用你自己喜歡的方法),就大功告成啦!
- 先用
-
關(guān)卡代碼實(shí)現(xiàn):
git rebase -i C3~2 git commit --amend 針對(duì)當(dāng)前分支修改提交內(nèi)容 git rebase caption master
-
示意圖:
未修改修改之后
-
與1實(shí)現(xiàn)同樣的功能:將提交樹上任何地方的提交記錄取過來追加到 HEAD 上
實(shí)現(xiàn)代碼:
git cherry-pick C2-
示意圖:
未修改修改之后
-
永遠(yuǎn)地指向某一個(gè)提交記錄分支或者提供類似功能(標(biāo)簽)
-
標(biāo)簽,對(duì)應(yīng)關(guān)系:標(biāo)簽→錨點(diǎn)
-
git tag 標(biāo)簽 實(shí)際節(jié)點(diǎn)- 主要區(qū)別就是:不會(huì)隨著分支的移動(dòng)而移動(dòng);
-
-
示意圖(git tag v1 c1):
沒打標(biāo)簽打上標(biāo)簽 -
describe,用于描述最近的錨點(diǎn)
-
git describe <ref>- 與
git bisect(一個(gè)查找產(chǎn)生 Bug 的提交記錄的指令)一起結(jié)合使用 - 輸出結(jié)果:
<tag>_<numCommits>_g<hash>,tag是指的離ref最近的tag標(biāo)簽
- 與
-
示意圖:
describe
-
-
-
高級(jí)操作
-
多次rebase
把多個(gè)分支rebase到master,按照規(guī)定的順序;
-
主要關(guān)注的是一種特殊情況,如下所示:
rebase的特殊注意情況
-
選擇父提交節(jié)點(diǎn)
-
操作符 ^ 與 ~ 符一樣,后面也可以跟一個(gè)數(shù)字。他們意義不同:
- ^指定合并提交記錄的某個(gè)父提交(針對(duì)有多個(gè)父節(jié)點(diǎn)的時(shí)候),~就是返回多少代。
git branch bugWork master^^2^
- ^指定合并提交記錄的某個(gè)父提交(針對(duì)有多個(gè)父節(jié)點(diǎn)的時(shí)候),~就是返回多少代。
-
示意圖:
未選擇選擇后
-
-
糾纏不清的分支:多個(gè)分支都需要做不同的操作或者提交
三個(gè)分支:one 需要重新排序并刪除 C5,two 僅需要重排排序,而 three 只需要提交一次
-
關(guān)卡代碼實(shí)現(xiàn):
git checkout one git cherry-pick c4 c3 c2 git checkout two git cherry-pick c5 c4 git branch -f three c2 -
示意圖:
處理之前處理之后
-
3. 遠(yuǎn)程操作相關(guān)篇章
3.1 push && pull----git遠(yuǎn)程倉庫
- clone一個(gè)遠(yuǎn)程倉庫
-
git clone
-
本地多的遠(yuǎn)程分支:o/master(遠(yuǎn)程分支有一些特殊的屬性)
- 遠(yuǎn)程分支反映了遠(yuǎn)程倉庫(在你上次和它通信時(shí))的狀態(tài)
- 遠(yuǎn)程分支有一個(gè)特別的屬性:檢出時(shí)自動(dòng)進(jìn)入分離 HEAD 狀態(tài)。所以做法是:(更新了遠(yuǎn)程分支之后)再用遠(yuǎn)程分享你的工作成果。
- o代表遠(yuǎn)程倉庫默認(rèn)為origin
- 遠(yuǎn)程倉庫的命名規(guī)則:
<remote name>/<branch name>
- 遠(yuǎn)程倉庫的命名規(guī)則:
-
示意圖:
git clonegit commit之后進(jìn)入分離狀態(tài)
-
-
git fetch: 向遠(yuǎn)程倉庫傳輸數(shù)據(jù)以及從遠(yuǎn)程倉庫獲取數(shù)據(jù)。
git fetch 通常通過互聯(lián)網(wǎng)(使用 http:// 或 git:// 協(xié)議) 與遠(yuǎn)程倉庫通信。
本質(zhì):將本地倉庫中的遠(yuǎn)程分支更新成了遠(yuǎn)程倉庫相應(yīng)分支最新的狀態(tài)
會(huì)更新本地沒有的記錄而不會(huì)更新更新本地倉庫狀態(tài)(這點(diǎn)尤其需要注意),以及將指針指向
o/master-
關(guān)卡代碼實(shí)現(xiàn)
git fetch origin bugFix git checkout master git fetch origin master git checkout bugFix -
示意圖:
git fetch關(guān)卡初始圖關(guān)卡過關(guān)圖
-
git pull:將變化的內(nèi)容更新到本地
-
等同于兩個(gè)命令:
git fetch;git merge o/master-
git pull --rebase就是fetch和rebase的簡寫!
-
示意圖:
git pull之前git pull之后
-
-
模擬團(tuán)隊(duì)協(xié)作:
- 模擬提交:
git fakeTeamwork foo 3
- 模擬提交:
-
git push:與git pull相對(duì),將本地上傳到遠(yuǎn)程數(shù)據(jù)庫
==推送之前需要先clone==
git push 負(fù)責(zé)將你的變更上傳到指定的遠(yuǎn)程倉庫;同時(shí)本地master與o/master也被更新;
git push 不帶任何參數(shù)時(shí)的行為與 Git 的一個(gè)名為 push.default 的配置有關(guān),使用的時(shí)候最好進(jìn)行檢查。
-
示意圖:
git push之前git push之后
-
偏離的提交記錄
具體原因造成:成員更改了API,你是基于原本的API進(jìn)行開發(fā)
-
通過rebase進(jìn)行解決
git fetch;git rebase o/master;git push;- 簡化代碼:
git pull --rebase;git push;
-
也可以使用merge,只要告訴git當(dāng)前提交已經(jīng)包含了遠(yuǎn)程分支的所有狀況
git fetch;git merge o/master;git push;- 簡化代碼:
git pull;git push;
-
示意圖(通過rebase處理,本地根據(jù)遠(yuǎn)程分支o/master操作了一步,但是遠(yuǎn)程是在o/master之后還有c2):
偏離前對(duì)偏離進(jìn)行合并處理后
-
遠(yuǎn)程服務(wù)器拒絕!(
Remote Rejected)(鎖定的Master(Locked Master))必須使用pull request來更新這個(gè)分支(在團(tuán)隊(duì)中合作可能會(huì)進(jìn)行相關(guān)master鎖定)
-
相應(yīng)流程:
- 新建一個(gè)分支;
- reset你的master分支和遠(yuǎn)程服務(wù)器保持一致;
- 重置操作:
git reset --hard o/master;(這種是硬重置,一般默認(rèn)是--mixed)
- 重置操作:
- 推送(push)這個(gè)分支并申請(qǐng)pull request;
-
流程代碼:
git reset --hard o/master; git checkout -b feature C2; git push origin feature; -
示意圖:
未處理協(xié)同時(shí)鎖定的master處理后
3.2 關(guān)于 origin 和它的周邊 —— Git 遠(yuǎn)程倉庫高級(jí)操作
-
推送主分支
-
完成兩個(gè)操作:
- 將特性分支集成到 master 上;
- 推送并更新遠(yuǎn)程分支;
-
實(shí)現(xiàn)過程
git fetch git rebase o/master side1 git rebase side1 side2 git rebase side2 side3 git rebase side3 master 要注意最后push之前要把當(dāng)前分支合并到想要遠(yuǎn)程的分支(比如master) 快速前進(jìn)。。。 git push -
示意圖:
未推送前推送之后
-
-
合并遠(yuǎn)程倉庫
-
rebase與merge之間的區(qū)別:
- 優(yōu)點(diǎn):Rebase 使你的提交樹變得很干凈, 所有的提交都在一條線上
- 缺點(diǎn):Rebase 使你的提交樹變得很干凈, 所有的提交都在一條線上
- 喜歡保留提交歷史,更偏愛 merge;喜歡干凈的提交樹,偏愛 rebase;因此使用什么根據(jù)自己習(xí)慣就行。
實(shí)現(xiàn)過程:
git checkout master; git pull; git merge side1; git merge side2; git merge side3; git push;-
過程圖:
合并之前的原圖
合并之后的結(jié)果圖
-
-
遠(yuǎn)程追蹤
-
本地分支與遠(yuǎn)程分支之間的關(guān)聯(lián)(通過push以及pull):
- pull:提交記錄會(huì)被先下載到 o/master 上,之后再合并到本地的 master 分支
- push:把工作從 master 推到遠(yuǎn)程倉庫中的 master 分支(同時(shí)會(huì)更新遠(yuǎn)程分支 o/master)
- 分支的
remote tracking(遠(yuǎn)程跟蹤)屬性決定,并且git clone的時(shí)候就已經(jīng)進(jìn)行設(shè)定了,注意提示語句:local branch "master" set totrack remote branch"o/master"- 自己指定鎖定屬性:分支會(huì)像 master 分支一樣得到隱含的 push 目的地以及 merge 的目標(biāo)。
- 可以在分支 totallyNotMaster 上執(zhí)行 git push,將工作推送到遠(yuǎn)程倉庫的 master 分支上
-
git checkout -b totallyNotMaster o/master(第一種方法)檢出一個(gè)分支跟蹤o/masters(totallyNotMaster分支是通過創(chuàng)建出來的) - git branch -u o/master foo(當(dāng)前就在 foo 分支上, 還可以省略 foo,foo分支是本來存在的)
- 自己指定鎖定屬性:分支會(huì)像 master 分支一樣得到隱含的 push 目的地以及 merge 的目標(biāo)。
-
示意圖:
遠(yuǎn)程跟蹤
-
-
git push的參數(shù)1-
基本格式語法:
git push <remote> <place>- 具體實(shí)例:
git push origin master——切到本地倉庫中的“master”分支,獲取所有的提交,再到遠(yuǎn)程倉庫“origin”中找到“master”分支,將遠(yuǎn)程倉庫中沒有的提交記錄都添加上去,搞定之后告訴我。- 過指定參數(shù)告訴了 Git 所有它需要的信息, 所以它就忽略了我們所檢出的分支的屬性
- 有一種情況就是:將某一記錄節(jié)點(diǎn)檢出之后,直接git push就會(huì)失敗,這時(shí)候就需要需要指定本地分支以及遠(yuǎn)程分支
- 具體實(shí)例:
-
關(guān)卡問題:本關(guān)我們要更新遠(yuǎn)程倉庫中的
foo和master, 但是git checkout被禁用了!git push origin master
-
示意圖:
git push<遠(yuǎn)程><位置>
-
-
git push的參數(shù)2-
==來源與去向名稱不一致==,比如:想把本地的
foo分支推送到遠(yuǎn)程倉庫中的bar分支- 解決方案:同時(shí)為源、目的地指定地址:
git push origin <source>:<destination>- 注意:
source可以是git能夠識(shí)別的任意地址 -
git push origin master:newBranch(<u>目的分支不存在的話,git就會(huì)新創(chuàng)建一個(gè)</u>)
- 注意:
- 解決方案:同時(shí)為源、目的地指定地址:
-
示意圖:
push之前push之后
-
-
git fetch的參數(shù)-
git fetch的參數(shù)和git push極其相似,只是方向反了,一個(gè)是上傳一個(gè)是下載提交記錄;git fetch origin foo--->到遠(yuǎn)程foo上下載所有不存在的節(jié)點(diǎn)記錄,但是需要注意的是:提交的記錄只是放在了o/foo上面,并沒有提交到foo上面,這就是fetch特殊的地方;
git fetch origin foo~1:bar------>結(jié)果就是將foo~的記錄提交到bar上,如果分支bar不存在就新建一個(gè)。git fetch:就是把遠(yuǎn)程的所有都更新到本地中
-
代碼實(shí)現(xiàn)過程:
git fetch origin master~:foo git fetch origin foo:master git checkout foo git merge master -
示意圖:
git fetch origin foo指定位置的fetch之前
指定位置的fetch之后
-
-
沒有source的
source-
奇怪的用法:
- 可以在 git push 或 git fetch 時(shí)不指定任何
source,也就是source留空- git push origin :side---->如果空的上傳遠(yuǎn)程倉庫,就是把0賦值給某一個(gè)分支,就是刪除
side分支 - git fetch origin :bugFix----->表示可能從遠(yuǎn)程下載分支,自然就是創(chuàng)建一個(gè)新分支
bugFix
- git push origin :side---->如果空的上傳遠(yuǎn)程倉庫,就是把0賦值給某一個(gè)分支,就是刪除
- 可以在 git push 或 git fetch 時(shí)不指定任何
-
示意圖:
-
push空source
push空之前
push空之后 -
fetch空source
fetch空之前
fetch空之后
-
-
-
git pull的參數(shù)實(shí)質(zhì)意義就是:用同樣的參數(shù)執(zhí)行 git fetch,然后再 merge 你所抓取到的提交記錄;
-
幾個(gè)等價(jià)的代碼:
等價(jià)1: git pull origin foo; git fetch origin foo;git merge o/foo; 等價(jià)2: git pull origin bar~;bugFix; git fetch origin bar~:bugFix;git mergbe bugFix; 同理git pull也可以用
source:destination;-
示意圖:
-
git pull origin mastergit pull origin master之前
git pull origin master之后 -
git pull origin master:foogit pull origin master:foo之前
git pull origin master:foo之后
-



























































