一、常見(jiàn)命令
-
git init
: 初始化 git 倉(cāng)庫(kù),即將一個(gè)文件夾初始化為一個(gè) git 倉(cāng)庫(kù)。具體的操作是創(chuàng)建一個(gè).git
隱藏文件夾 -
git status
: 查看倉(cāng)庫(kù)的狀態(tài) -
git add <file>
: 將文件提交到暫存區(qū) -
git commit -m <代碼提交信息>
: 將暫存區(qū)的文件提交到倉(cāng)庫(kù)中,并附帶說(shuō)明信息 -
git log
: 查看所有產(chǎn)生的 commit 記錄 -
git config -l
: 查看自己的配置,默認(rèn)配置都在.git/config
文件中
1.2 分支相關(guān)的命令
-
git branch <branch_name>
: 如果不加上<branch_name>
,查看當(dāng)前分支情況。如果加上,就是創(chuàng)建一個(gè)分支。 -
git checkout <branch_name>
: 切換到<branch_name>
的分支上 -
git checkout -b <branch_name>
: 創(chuàng)建一個(gè)分支并切換到這個(gè)分支上,效果相當(dāng)于合并上面 2 個(gè)命令。 -
git merge <branch_name>
: 將<branch_name>
分支合并到當(dāng)前所在的分支上 -
git branch -d <branch_name>
: 將<branch_name>
分支刪除 -
git branch -D <branch_name>
: 將<branch_name>
分支強(qiáng)制刪除。如果<branch_name>
分支存在未合并的代碼時(shí),那么用-d
是刪除不了。
1.3 標(biāo)簽相關(guān)的命令
-
git tag
: 查看歷史 tag 記錄。 -
git tag <tag_name> <commit_id>
: 在指定提交 id 上創(chuàng)建一個(gè) tag。如果不寫(xiě)<commit_id>
,那就在最新的 commit 上創(chuàng)建一個(gè) tag。 -
git checkout <tag_name>
: 切換到<tag_name>
標(biāo)簽 -
git show <tag_name>
: 查看標(biāo)簽信息 -
git tad -d <tag_name>
: 刪除標(biāo)簽 -
git push origin <tag_name>
: 將某個(gè)標(biāo)簽推送到遠(yuǎn)程倉(cāng)庫(kù) -
git push origin :refs/tags/<tag_name>
: 可以刪除一個(gè)遠(yuǎn)程標(biāo)簽。
1.4 SSH
提前申明, windows 系統(tǒng)并不自帶 SSH, 但是安裝的 Git 中帶有 SSH。所以以下命令請(qǐng)?jiān)?Git bash 下執(zhí)行。
-
ssh-keygen -t rsa
: 指定 rsa 算法生成密鑰。 -
ssh -T git@github.com
: 測(cè)試 ssh 是否成功添加到 github 中
1.5 Github 操作
-
git clone ...
: 將 github 項(xiàng)目復(fù)制到本地的當(dāng)前目錄 -
git push origin <本地分支>:<遠(yuǎn)程分支>
: 把本地分支中本地代碼同步到遠(yuǎn)程分支 -
git pull orgin <branch_name>
: 把遠(yuǎn)程 <branch_name> 分支的最新的代碼同步到本地當(dāng)前分支中 -
get remote add origin git@github.com:xxx/xxxx.git
: 將當(dāng)前本地倉(cāng)庫(kù)與遠(yuǎn)程進(jìn)行聯(lián)接 -
git remote -v
: 查看我們當(dāng)前項(xiàng)目有哪些遠(yuǎn)程倉(cāng)庫(kù)
1.6 補(bǔ)充命令
-
alias 別名
-
git config --global alias.<別名> "<原命令>"
。比如git config --global alias.c "checkout"
,之后git c
==git checkout
-
-
diff
-
git diff
: 比較工作區(qū)文件和暫存區(qū)文件差異。如果加上文件名,就僅比較這個(gè)文件在工作區(qū)與暫存區(qū)的區(qū)別 -
git diff <commit_id1> <commit_id2>
: 比較兩次提交之間的差異
-
-
checkout
- 作用 1 :切換分支、標(biāo)簽以及 commit。本質(zhì)是「用某個(gè) HEAD 中的最新內(nèi)容替換掉你的工作區(qū)中的文件」。切換時(shí),暫存區(qū)的內(nèi)容不受影響但相當(dāng)于在切換前執(zhí)行了
git stash
- 作用 2 :撤銷(xiāo)還沒(méi)進(jìn)入暫存區(qū)的修改的作用。舉個(gè)例子,假設(shè)我們?cè)谝粋€(gè)分支開(kāi)發(fā)一個(gè)小功能,剛寫(xiě)完一半,這時(shí)候需求變了,而且是大變化,之前寫(xiě)的代碼完全用不了了,好在你剛寫(xiě),甚至都沒(méi)有 git add 進(jìn)暫存區(qū),這個(gè)時(shí)候很簡(jiǎn)單的一個(gè)操作就直接把原文件還原:
git checkout a.md
,本質(zhì)上是將 HEAD 內(nèi)容覆蓋掉工作區(qū)的內(nèi)容。注意,checkout 命令只能撤銷(xiāo)還沒(méi)有 add 進(jìn)暫存區(qū)的文件。
- 作用 1 :切換分支、標(biāo)簽以及 commit。本質(zhì)是「用某個(gè) HEAD 中的最新內(nèi)容替換掉你的工作區(qū)中的文件」。切換時(shí),暫存區(qū)的內(nèi)容不受影響但相當(dāng)于在切換前執(zhí)行了
-
stash
- 作用:把當(dāng)前分支中的工作區(qū)的所有修改先暫存到棧上。
- 運(yùn)用場(chǎng)景:假設(shè)我們正在一個(gè)新的分支做新的功能,這個(gè)時(shí)候突然有一個(gè)緊急的bug需要修復(fù),而且修復(fù)完之后需要立即發(fā)布。當(dāng)然你說(shuō)我先把剛寫(xiě)的一點(diǎn)代碼進(jìn)行提交不就行了么?這樣理論上當(dāng)然是ok的,但是這會(huì)產(chǎn)品垃圾commit,原則上我們每次的commit都要有實(shí)際的意義,你的代碼只是剛寫(xiě)了一半,還沒(méi)有什么實(shí)際的意義是不建議就這樣commit的,那么就用
git stash
保留。 -
git stash
: 把當(dāng)前分支所有沒(méi)有 commit 的代碼先暫存起來(lái) -
git stash list
: 查看所有 stash 記錄 -
git stash apply
: 將暫存的代碼還原 -
git stash drop
: 把最近一條 stash 記錄刪除。注意:每次還原代碼后,最好刪除這條 stash 記錄 -
git stash pop
==git stash apply
+git stash drop
- 注意:執(zhí)行了
git add
的數(shù)據(jù)在切換分支時(shí),會(huì)自動(dòng)暫存一起。本質(zhì)上是因?yàn)榍袚Q分支不影響暫存區(qū)的數(shù)據(jù)。但需要手動(dòng)恢復(fù)。
二、常用概念
2.1 工作區(qū)、暫存區(qū)與 HEAD
- 工作區(qū)就是你還沒(méi)有執(zhí)行
git add
的文件,它持有實(shí)際文件; - 暫存區(qū)就是你執(zhí)行了
git add
但沒(méi)執(zhí)行git commit
的文件,它像個(gè)緩存區(qū)域,臨時(shí)保存你的改動(dòng); - HEAD 就是你執(zhí)行完
git commit
,它指向你最后一次提交的結(jié)果并且清空暫存區(qū)。
在實(shí)際中,工作區(qū)有一個(gè)隱藏目錄 .git
,它不屬于工作區(qū),而是 Git 的版本庫(kù)。Git 的版本庫(kù)里存了很多東西,其中最重要的就是稱(chēng)為 stage(或者叫 index )的暫存區(qū),還有 Git 為我們自動(dòng)創(chuàng)建的第一個(gè)分支
master ,以及指向master的一個(gè)指針叫 HEAD。
與此同時(shí),History 保存著所有分支信息,HEAD 指針指向當(dāng)前分支。
上述命令有待驗(yàn)證。
2.2 分支 branch
stormzhang 從0開(kāi)始學(xué)習(xí) GitHub 系列之「團(tuán)隊(duì)合作利器 Branch」
2.3 標(biāo)簽 tag
本質(zhì):標(biāo)簽作用于提交上,可以看成是某個(gè)提交的別稱(chēng)。
運(yùn)用:主要用于標(biāo)記軟件的版本號(hào)。
2.4 SSH
簡(jiǎn)單點(diǎn)說(shuō),SSH是一種網(wǎng)絡(luò)協(xié)議,用于計(jì)算機(jī)之間的加密登錄。目前是每一臺(tái) Linux 電腦的標(biāo)準(zhǔn)配置。而大多數(shù) Git 服務(wù)器都會(huì)選擇使用 SSH 公鑰來(lái)進(jìn)行授權(quán),所以想要在 GitHub 提交代碼的第一步就是要先添加 SSH key 配置。
命令生成的密鑰會(huì)存放在兩個(gè)文件 id_rsa 和 id_rsa.pub ,而 id_rsa 是私鑰,id_rsa.pub 就是公鑰。這兩文件默認(rèn)分別在如下目錄里生成:
Linux/Mac 系統(tǒng) 在 ~/.ssh
下,win系統(tǒng)在 /c/Documents and Settings/<username>/.ssh
下,都是隱藏文件,相信你有辦法查看的。
接下來(lái)要做的是把 id_rsa.pub 的內(nèi)容添加到 GitHub 上,這樣你本地的 id_rsa 私鑰跟 GitHub 上的 id_rsa.pub 公鑰進(jìn)行配對(duì),授權(quán)成功才可以提交代碼。
2.5 Github 操作
Push
如果你本地代碼有更新,那么就需要把本地代碼推到遠(yuǎn)程倉(cāng)庫(kù),這樣本地倉(cāng)庫(kù)跟遠(yuǎn)程倉(cāng)庫(kù)就可以保持同步了。
Pull
如果遠(yuǎn)程倉(cāng)庫(kù)有更新,那么需要把遠(yuǎn)程倉(cāng)庫(kù)的最新代碼更新到本地,然后保證兩端代碼的同步。一般我們?cè)?push 之前都會(huì)先 pull ,這樣不容易沖突。
先有遠(yuǎn)程倉(cāng)庫(kù),后有本地倉(cāng)庫(kù):Clone
使用 git clone
命令,將遠(yuǎn)程倉(cāng)庫(kù)復(fù)制到本地中。然后,修改本地倉(cāng)庫(kù)并進(jìn)行 git commit
。然后,git pull orgin <遠(yuǎn)程分支>
建立本地倉(cāng)庫(kù)和遠(yuǎn)程倉(cāng)庫(kù)之間聯(lián)系以及保持同步。最后,git push origin <本地分支>:<遠(yuǎn)程分支>
將本地倉(cāng)庫(kù)的修改提交到遠(yuǎn)程倉(cāng)庫(kù)中
通過(guò) git clone
命令復(fù)制的倉(cāng)庫(kù),不需要使用 git init
初始化,同時(shí)也不需要聲明與遠(yuǎn)程倉(cāng)庫(kù)關(guān)聯(lián)(因?yàn)橐呀?jīng)聲明了)。
先有本地倉(cāng)庫(kù),后有遠(yuǎn)程倉(cāng)庫(kù):關(guān)聯(lián)本地已有項(xiàng)目
如果我們本地已經(jīng)有一個(gè)完整的 git 倉(cāng)庫(kù),并且已經(jīng)進(jìn)行了很多次 commit ,我們想將本地倉(cāng)庫(kù)提交到 github 上。
假設(shè)本地倉(cāng)庫(kù) test2,要提交到 github test 項(xiàng)目中,一般步驟是:
- 在 github 創(chuàng)建 test 項(xiàng)目
- 在 test2 目錄中輸入
git remote add origin git@github.com:xxxx/test.git
將本地 test2 項(xiàng)目與 github 的 test 項(xiàng)目關(guān)聯(lián)起來(lái) git push origin master
合并操作:merge & rebase
git merge branch_a
與 git rebase branch_a
的效果是一樣,都是將 branch_a
分支合并到當(dāng)前的分支中。但兩者合并方式不同:rebase 跟 merge 的區(qū)別你們可以理解成有兩個(gè)書(shū)架,你需要把兩個(gè)書(shū)架的書(shū)整理到一起去,
- 第一種做法是 merge ,比較粗魯暴力,就直接騰出一塊地方把另一個(gè)書(shū)架的書(shū)全部放進(jìn)去,雖然暴力,但是這種做法你可以知道哪些書(shū)是來(lái)自另一個(gè)書(shū)架的;
- 第二種做法就是 rebase ,他會(huì)把兩個(gè)書(shū)架的書(shū)先進(jìn)行比較,按照購(gòu)書(shū)的時(shí)間來(lái)給他重新排序,然后重新放置好,這樣做的好處就是合并之后的書(shū)架看起來(lái)很有邏輯,但是你很難清晰的知道哪些書(shū)來(lái)自哪個(gè)書(shū)架。
合并沖突
如果兩個(gè)分支 a,b 同時(shí)修改了同一個(gè)位置時(shí),合并到 master 時(shí)就會(huì)報(bào)沖突。不管兩個(gè)分支合并的先后順序、中間是否還合并了其他的分支(即任何情況下),都會(huì)報(bào)沖突。發(fā)生沖突的地方,Git 會(huì)在發(fā)生沖突的位置使用 <<<<< 、======、>>>>> 標(biāo)記出不同分支的內(nèi)容。如
<<<<<<< HEAD # HEAD 內(nèi)容
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1 # feature1 分支的內(nèi)容
此時(shí),你需要手動(dòng)地進(jìn)行正確的合并后,再 git add .
與 git commit
就可以了。
2.6 Git 與 SVN 對(duì)比
Git 屬于分布式版本控制系統(tǒng),而 SVN 屬于集中式。集中式版本控制只有中心服務(wù)器擁有一份代碼,而分布式版本控制每個(gè)人的電腦上就有一份完整的代碼。