<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Git : 每一行命令都算數(shù)

          共 10188字,需瀏覽 21分鐘

           ·

          2021-11-04 11:52

          ????關(guān)注后回復(fù) “進群” ,拉你進程序員交流群????


          作者丨sowhat1412

          來源丨sowhat1412


          git思維導圖

          Git工作區(qū)域

          為了說明我們?nèi)粘i_發(fā)中執(zhí)行的一系列Git命令的作用是什么,我們需要了解Git的工作區(qū)域的概念,幾乎每一個常見的Git命令操作都可以通過工作區(qū)域來解釋。

          Git本地有四個工作區(qū)域:

          • 工作區(qū)(Working Directory):在git init之后的本地的文件目錄下,也就是大家寫代碼的地方

          • 暫存區(qū)(Staged/Index):修改了代碼之后,需要先將改動add到暫存區(qū),表示將要提交的改動

          • 本地倉庫(Local Repository):本地Git倉庫,通俗講就是本地隱藏文件.git目錄下,存儲著你的所有改動

          • 遠程倉庫(Remote Repository):遠程Git倉庫,理論上和本地倉庫地位平等,但是主要是用于多個開發(fā)者之間pull/push代碼的倉庫。

          四個工作區(qū)域

          Git 文件狀態(tài)

          接下來我們來看下Git文件的狀態(tài):

          Git 文件狀態(tài)
          • UnTracked: 未跟蹤,此文件在文件夾中,但并沒有加入到git庫,不參與版本控制。通過git add 狀態(tài)變?yōu)镾taged。

          • UnModify: 文件已經(jīng)入庫,未修改, 即版本庫中的文件快照內(nèi)容與文件夾中完全一致。這種類型的文件有兩種去處,如果它被修改,而變?yōu)镸odified。如果使用git rm移出版本庫,則成為UnTracked文件。

          • Modified: 文件已修改,僅僅是修改,并沒有進行其他的操作。這個文件也有兩個去處,通過git add可進入暫存staged狀態(tài),使用git checkout 則丟棄修改過,返回到unmodify狀態(tài),這個git checkout即從庫中取出文件,覆蓋當前修改。

          • Staged: 暫存狀態(tài),執(zhí)行g(shù)it commit則將修改同步到庫中,這時庫中的文件和本地文件又變?yōu)橐恢拢募閁nModify狀態(tài)。執(zhí)行g(shù)it reset 取消暫存,文件狀態(tài)為Modified。

          Git 基本命令

          在了解Git工作區(qū)域、文件狀態(tài)以及本地倉庫的相關(guān)信息之后,相信大家對于日常使用的一些命令都有了更加深刻的理解。接下來,我們一起進行一個常用命令總結(jié):

          • git clone:將遠程倉庫克隆到本地,也就是創(chuàng)建了一個本地倉庫,會出現(xiàn)隱藏文件.git

          • git status:查看狀態(tài),可以看到哪些文件被修改、哪些是未跟蹤的文件

          • git diff:可以看到當前工作區(qū)和暫存區(qū)staged中的文件diff

          • git add:將未跟蹤(新增加)或者修改過的文件從工作區(qū)添加到暫存區(qū)staged中

          • git commit:將暫存區(qū)staged中的內(nèi)容提交到本地Git倉庫中

          • git push:將本地Git倉庫中的內(nèi)容提交到遠程Git倉庫中

          并且如果是單人開發(fā),自己玩的情況下,貌似這些命令就足夠了。但是,在實際的開發(fā)當中,我們往往會面對更加復(fù)雜的場景,需要一些更為復(fù)雜的命令來處理,我們接著往下看。

          git merge

          在當前分支上執(zhí)行g(shù)it merge master可以將master的提交合并merge到當前分支,也就是更新本地分支。我們?nèi)粘i_發(fā)中,將本地代碼推到遠程倉庫,建立Merge Request,然后點擊Merge按鈕其實就是在master分支上merge了開發(fā)分支。

          merge
          git fetch

          git fetch可以將遠程分支拉到本地:

          git fetch 會將所有遠程分支都拉到本地
          git fetch origin sowhat1412  指定拉取遠程origin倉庫的sowhat1412分支到本地
          git pull

          當我們想要更新本地分支代碼的時候,需要將遠程開發(fā)分支或者遠程master分支代碼拉到本地,并且合并到當前開發(fā)分支上。所以git pull = git fetch + git merge
          在當前開發(fā)分sowhat1412上,我們執(zhí)行如下的命令:

          git pull origin master 
          表示將遠程master分支拉到本地并且merge到當前分支sowhat1412上
          git rebase

          rebase會把你當前分支的 commit 放到公共分支的最后面,所以叫變基。就好像你從公共分支又重新拉出來這個分支一樣。
          舉例:如果你從 master 拉了個feature分支出來,然后你提交了幾個 commit,這個時候剛好有人把他開發(fā)的東西合并到 master 了,這個時候 master 就比你拉分支的時候多了幾個 commit,如果這個時候你 rebase master 的話,就會把你當前的幾個 commit,放到那個人 commit 的后面。

          git rebeae

          merge 會把公共分支和你當前的commit 合并在一起,形成一個新的 commit 提交

          git merge
          git cherry-pick

          對于多分支的代碼庫,將代碼從一個分支轉(zhuǎn)移到另一個分支是常見需求。

          這時分兩種情況。一種情況是,你需要另一個分支的所有代碼變動,那么就采用合并(git merge)。另一種情況是,你只需要部分代碼變動(某幾個提交),這時可以采用 Cherry pick。

          git cherry-pick命令的作用,就是將指定的提交(commit)應(yīng)用于其他分支。

          $ git cherry-pick <commitHash>

          上面命令就會將指定的提交commitHash,應(yīng)用于當前分支。這會在當前分支產(chǎn)生一個新的提交,當然它們的哈希值會不一樣。

          舉例來說,代碼倉庫有master和feature兩個分支。

           a - b - c - d       Master
                   \
                     e - f - g Feature

          現(xiàn)在將提交f應(yīng)用到master分支。

          # 切換到 master 分支
          $ git checkout master

          # Cherry pick 操作
          $ git cherry-pick f

          上面的操作完成以后,代碼庫就變成了下面的樣子。

              a - b - c - d - f  Master
                   \
                     e - f - g   Feature

          從上面可以看到,master分支的末尾增加了一個提交f。

          git cherry-pick命令的參數(shù),不一定是提交的哈希值,分支名也是可以的,表示轉(zhuǎn)移該分支的最新提交。

          $ git cherry-pick feature
          上面代碼表示將feature分支的最近一次提交,轉(zhuǎn)移到當前分支。

          Cherry pick 支持一次轉(zhuǎn)移多個提交。

          $ git cherry-pick <HashA> <HashB>

          上面的命令將 A 和 B 兩個提交應(yīng)用到當前分支。這會在當前分支生成兩個對應(yīng)的新提交。

          如果想要轉(zhuǎn)移一系列的連續(xù)提交,可以使用下面的簡便語法。

          $ git cherry-pick A..B 

          上面的命令可以轉(zhuǎn)移從 A 到 B 的所有提交。它們必須按照正確的順序放置:提交 A 必須早于提交 B,否則命令將失敗,但不會報錯。

          注意,使用上面的命令,提交 A 將不會包含在 Cherry pick 中。如果要包含提交 A,可以使用下面的語法。

          $ git cherry-pick A^..B 
          git reset
          • git reset commitId

          該命令執(zhí)行之后,HEAD指針會移動到選中commitId上,并且之前的HEAD ->commitId之間的所有修改的內(nèi)容會被置于工作區(qū),需要重新add、commit。
          • git reset --soft commitId

          該命令執(zhí)行之后,HEAD指針會移動到選中commitId上,并且之前的HEAD ->commitId之間的所有修改的內(nèi)容會被直接置于暫存區(qū)staged中,也就是后續(xù)只需要執(zhí)行commit操作就OK了
          • git reset --hard commitId

          這個--hard很好理解,就是在回滾HEAD指針的時候,很強硬的將所有HEAD ->commitId之間的改動內(nèi)容“全部刪除”!
          為什么加引號?因為前邊我們說了Git不會丟失任何你提交過的內(nèi)容(只要你玩的溜),后續(xù)我們會分析原因。
          git reflog
          1. 新建一個目錄git-test,初始化一下倉庫,做一次簡單的提交

          mkdir git-test  
          cd git-test/  
          git init  
          echo 0 > test  
          git add .  
          git commit -am "init"  
          1. 假設(shè)這幾個星期你做了三次重要代碼的提交:

          linux-geek:/home/tmp/git-test # echo "important code0" >> test  
          linux-geek:/home/tmp/git-test # git commit -am "important code0"  
          [master 03f85a1] important code0  
           1 files changed, 1 insertions(+), 0 deletions(-)  
          linux-geek:/home/tmp/git-test # echo "important code1" >> test     
          linux-geek:/home/tmp/git-test # git commit -am "important code1"  
          [master 83547ba] important code1  
           1 files changed, 1 insertions(+), 0 deletions(-)  
          linux-geek:/home/tmp/git-test # echo "important code2" >> test     
          linux-geek:/home/tmp/git-test # git commit -am "important code2"  
          [master b826ae5] important code2  
           1 files changed, 1 insertions(+), 0 deletions(-)   
          linux-geek:/home/tmp/git-test # cat test  
          0  
          important code0  
          important code1  
          important code2  
          1. 就在這個時候,假設(shè)你頭腦突然短路,用了git reset這條命令:

          linux-geek:/home/tmp/git-test # git reset --hard HEAD~3  
          HEAD is now at 2e71cf6 init 

          再來看一下代碼的情況:

          linux-geek:/home/tmp/git-test # cat test

          有沒有什么辦法補救呢?答案是肯定的!

          1. 用git reflog來看一下

          linux-geek:/home/tmp/git-test # git reflog
          2e71cf6 HEAD@{0}: HEAD~3: updating HEAD
          b826ae5 HEAD@{1}: commit: important code2
          83547ba HEAD@{2}: commit: important code1
          03f85a1 HEAD@{3}: commit: important code0
          2e71cf6 HEAD@{4}: commit (initial): init  

          其中,我們可以清楚地看到HEAD每次移動的情況以及哈希值,于是乎我們再采用git reset去試一下:

          linux-geek:/home/tmp/git-test # git reset --hard HEAD@{1}
          HEAD is now at b826ae5 important code2  
          1. 我們再來看一下代碼的情況:

          linux-geek:/home/tmp/git-test # cat test
          0
          important code0
          important code1
          important code2 
          1. 此時用 git log 或 git log --pretty=oneline 可以看到全部的歷史記錄又恢復(fù)回來了。

          git revert

          revert 是回滾某個 commit ,不是回滾到某個。git revert是用于反做某一個版本,以達到撤銷該版本的修改的目的。比如,我們commit了三個版本(版本一、版本二、 版本三),突然發(fā)現(xiàn)版本二不行(如:有bug),想要撤銷版本二,但又不想影響撤銷版本三的提交,就可以用 git revert 命令來反做版本二,生成新的版本四,這個版本四里會保留版本三的東西,但撤銷了版本二的東西。如下圖所示:

          在這里插入圖片描述
          1. 反做,使用“git revert -n 版本號”命令。如下命令,我們反做版本號為8b89621的版本:

          git revert -n 8b89621019c9adc6fc4d242cd41daeb13aeb9861
          1. 這里可能會出現(xiàn)沖突,那么需要手動修改沖突的文件。而且要git add 文件名來提交

          git commit -m "revert add text.txt"

          手動整理commit

          有這樣一個需求,代碼量不多,但是因為你多次提交,會導致在建立Merge Request的時候,出現(xiàn)了幾十個commitId,比如:“update”、“bug fix”、“fix again”等,不光看起來很丑,也會給大家一種感覺,這小伙到底行不行呀?一百行代碼的開發(fā)量,提交了這么多次才搞定。(尷尬.jpg)
          為了解決這樣的問題,我們可以巧妙的利用git reset。比如當前的commit是這樣的A-1-2-3-4-5-6-7-8,你的第一個提交是1,那么我們執(zhí)行如下的命令:

          git reset --soft A // 重置本地分支HEAD指針
          git commit -m "XXX邏輯開發(fā)"
          git push origin ywq_news_0702 -f // 提交到遠程分支

          -f是什么操作?force的含義,表示強行執(zhí)行本次操作。當我們git reset之后,本地的HEAD指針指向的commitId會比遠程origin對應(yīng)的落后,直接push會被拒絕。通過-f命令可以強行將本地內(nèi)容push到遠程分支上(切記!如果是多人共同合作的開發(fā)分支或者遠程master操作,千萬不能加-f操作!!!)
          經(jīng)過git reset --soft之后,我們提的Merge Request里就是一個commitId了,發(fā)出來的CR會感覺倍兒有面兒。

          Git stash 臨時儲藏

          當我們在當前分支開發(fā)某個需求的時候,遇到了另一個需求的聯(lián)調(diào)問題,需要切換到另一個分支上去解決問題。怎么辦?
          正常情況下,我們應(yīng)該將當前分支工作區(qū)的內(nèi)容add 、commit之后再切換分支。但是問題來了,當前需求開發(fā)了一半,我不想生成一次提交怎么辦?
          放心,這個時候我們的git stash命令可以幫助我們將當前工作區(qū)的內(nèi)容儲藏起來。然后切換其他分支,處理完問題之后,再切換到當前分支,執(zhí)行g(shù)it stash pop取出來就完事。

          git stash list // 查看當前stash里邊的內(nèi)容
          git stash // 將當前工作區(qū)內(nèi)容儲藏起來
          git stash pop // 將stash中棧頂內(nèi)容pop出來,當然也可以根據(jù)順序直接取第n個

          Git 恢復(fù)修改文件

          對于恢復(fù)修改的文件,就是將文件從倉庫中拉到本地工作區(qū),即 倉庫區(qū) ----> 暫存區(qū) ----> 工作區(qū)。

          對于修改的文件有兩種情況:

          • 只是修改了文件,沒有任何 git 操作

          只是修改了文件,沒有任何 git 操作,直接一個命令就可回退:
          $ git checkout -- aaa.txt # aaa.txt為文件名
          • 修改了文件,并提交到暫存區(qū))

          即編輯之后,git add 但沒有 git commit -m ....
          $ git log --oneline    # 可以省略
          $ git reset HEAD    # 回退到當前版本
          $ git checkout -- aaa.txt    # aaa.txt為文件名
          • 修改了文件,并提交到倉庫區(qū)

          即編輯之后,git add 和 git commit -m ....
          $ git log --oneline    # 可以省略
          $ git reset HEAD^    # 回退到上一個版本
          $ git checkout -- aaa.txt    # aaa.txt為文件名

          參考

          • Git十大硬圖:https://zhuanlan.zhihu.com/p/132573100

          • Git分支規(guī)范:https://zhuanlan.zhihu.com/p/108385922

          • Git思維導圖:https://www.jianshu.com/p/e2f553942317

          -End-

          最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

          點擊??卡片,關(guān)注后回復(fù)【面試題】即可獲取

          在看點這里好文分享給更多人↓↓

          瀏覽 24
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91三级在线观看 | 亚洲国产正在播放 | 欧美成人在线视频网站 | 天堂网www啊啊啊啊啊啊 | 青青草在线激情视频 |