Git & Github 常見(jiàn)命令與概念

Git 速查表(摘自 AI有道)

一、常見(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ū)的文件。
  • 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ū)。
工作區(qū)、暫存區(qū)與 HEAD 參考:http://rogerdudler.github.io/git-guide/index.zh.html

在實(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í)際目錄中,三種狀態(tài)的聯(lián)系 參考:https://www.liaoxuefeng.com

與此同時(shí),History 保存著所有分支信息,HEAD 指針指向當(dāng)前分支。

三種狀態(tài)的聯(lián)系(更詳細(xì)版)[3]
三種狀態(tài)之間的轉(zhuǎn)換及其命令 [3]

上述命令有待驗(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_rsaid_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)目中,一般步驟是:

  1. 在 github 創(chuàng)建 test 項(xiàng)目
  2. 在 test2 目錄中輸入 git remote add origin git@github.com:xxxx/test.git 將本地 test2 項(xiàng)目與 github 的 test 項(xiàng)目關(guān)聯(lián)起來(lái)
  3. git push origin master

合并操作:merge & rebase

git merge branch_agit 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 與 SVN 對(duì)比

Git 屬于分布式版本控制系統(tǒng),而 SVN 屬于集中式。集中式版本控制只有中心服務(wù)器擁有一份代碼,而分布式版本控制每個(gè)人的電腦上就有一份完整的代碼。

參考:

  1. stormzhang 從 0 開(kāi)始學(xué)習(xí) GitHub 系列
  2. git - 簡(jiǎn)明指南
  3. CS-Notes Github
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容