亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                Git從入門到精通,Git命令大全

                Git從入門到精通,Git命令大全

                原文:Git從入門到精通,Git命令大全-友人a的筆記丶

                Git入門

                資料來源:https://www.runoob.com/git/git-tutorial.html、http://git-scm.com/docs

                查看Git命令的幫助信息,git –help

                1.Git 工作區(qū)、暫存區(qū)和版本庫(以本地舉例)、遠(yuǎn)程倉庫

                • 工作區(qū):就是你在電腦里能看到的目錄。
                • 暫存區(qū):英文叫 stage 或 index。一般存放在 .git 目錄下的 index 文件(.git/index)中,所以我們把暫存區(qū)有時也叫作索引(index)。
                • 版本庫:工作區(qū)有一個隱藏目錄 .git,這個不算工作區(qū),而是 Git 的版本庫。

                Git 工作區(qū)、暫存區(qū)和版本庫

                • 圖中左側(cè)為工作區(qū),右側(cè)為版本庫。在版本庫中標(biāo)記為 “index” 的區(qū)域是暫存區(qū)(stage/index),標(biāo)記為 “master” 的是 master 分支所代表的目錄樹。
                • 圖中我們可以看出此時 “HEAD” 實際是指向 master 分支的一個”游標(biāo)”。所以圖示的命令中出現(xiàn) HEAD 的地方可以用 master 來替換。
                • 圖中的 objects 標(biāo)識的區(qū)域為 Git 的對象庫,實際位于 “.git/objects” 目錄下,里面包含了創(chuàng)建的各種對象及內(nèi)容。
                • 當(dāng)對工作區(qū)修改(或新增)的文件執(zhí)行 git add 命令時,暫存區(qū)的目錄樹被更新,同時工作區(qū)修改(或新增)的文件內(nèi)容被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區(qū)的文件索引中。
                • 當(dāng)執(zhí)行提交操作(git commit)時,暫存區(qū)的目錄樹寫到版本庫(對象庫)中,master 分支會做相應(yīng)的更新。即 master 指向的目錄樹就是提交時暫存區(qū)的目錄樹。
                • 當(dāng)執(zhí)行 git reset HEAD 命令時,暫存區(qū)的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區(qū)不受影響。
                • 當(dāng)執(zhí)行 git rm –cached 命令時,會直接從暫存區(qū)刪除文件,工作區(qū)則不做出改變。
                • 當(dāng)執(zhí)行 git checkout . 或者 git checkout — 命令時,會用暫存區(qū)全部或指定的文件替換工作區(qū)的文件。這個操作很危險,會清除工作區(qū)中未添加到暫存區(qū)中的改動。
                • 當(dāng)執(zhí)行 git checkout HEAD . 或者 git checkout HEAD 命令時,會用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區(qū)和以及工作區(qū)中的文件。這個命令也是極具危險性的,因為不但會清除工作區(qū)中未提交的改動,也會清除暫存區(qū)中未提交的改動。

                2.Git文件狀態(tài)

                在Git中文件大概分為四種狀態(tài):已修改(modified)、已暫存(staged)、已提交(committed)、未追蹤(Untrack)

                • .gitignore內(nèi)的文件,不會擁有任何一種狀態(tài),被git徹底無視。
                • 處于ignore列表的文件,無法被add添加;但是可以強(qiáng)制添加
                • 空目錄、以及子目錄全部是空目錄的目錄不會有Untrack狀態(tài),也無法通過add改變狀態(tài)(無效)
                • 工作目錄新增文件時,只要不處于ignore目錄,都會變成Untrack狀態(tài);
                • 沒有add過的文件或者被restore(不帶–staged)的文件,處于Untrack狀態(tài);
                • 初次add和被add后產(chǎn)生修改的文件,會處于modifed狀態(tài)。
                • 處于modified狀態(tài)的文件,最開始可以進(jìn)行add和restore兩種操作,此時的add操作叫做 更新要提交的內(nèi)容,add后變?yōu)閟taged狀態(tài),restore(不加staged標(biāo)記)后變?yōu)閁ntrack;
                • add后變?yōu)閟taged狀態(tài)的文件,可用restore –staged 變回modified狀態(tài);這個staged狀態(tài)的內(nèi)容可以用來恢復(fù)內(nèi)容。沒有被add的modified狀態(tài)文件內(nèi)容沒有被記錄(雖然有撤回,但是本質(zhì)不一樣);
                • 處于staged狀態(tài)的文件,在沒有commit之前再次產(chǎn)生修改時,會同時具有staged和modified兩個狀態(tài)(可以把statged狀態(tài)的內(nèi)容拉回來,覆蓋。);但是commit時會使用內(nèi)容最新的那個狀態(tài);
                • commit會提交所有staged狀態(tài)的文件,所以commit可以理解有一個modified到staged狀態(tài)的過程(實際可能不存在,因為暫存區(qū)本來就有變動的記錄);所以暫存狀態(tài)不能理解為處于暫存區(qū),應(yīng)當(dāng)指的是被納入下一次提交的文件;任何被追蹤的產(chǎn)生修改的文件都會在暫存區(qū)被記錄;成為下一次提交的一部分;
                • 未被追蹤的文件被刪除時,不會產(chǎn)生git狀態(tài)。處于modofy未add時,會變成deleted狀態(tài);處于staged狀態(tài)會保持暫存狀態(tài);
                • 已經(jīng)被刪除的(deleted狀態(tài))被追蹤的文件,恢復(fù)后會變成modified狀態(tài);

                提示:add的作用是將文件添加到暫存區(qū),只有被add的文件才會被追蹤

                暫存區(qū)

                (1)所謂的暫存區(qū)只是一個簡單的索引文件而已。(2)暫存區(qū)這個索引文件里面包含的是文件的目錄樹,像一個虛擬的工作區(qū),在這個虛擬工作區(qū)的目錄樹中,記錄了文件名、文件的時間戳、文件長度、文件類型以及最重要的SHA-1值,文件的內(nèi)容并沒有存儲在其中,所以說 它像一個虛擬的工作區(qū)。(3)索引指向的是.Git/objects下的文件。(4)暫存區(qū)的作用:除非是繞過暫存區(qū)直接提交,否則Git想把修改提交上去,就必須將修改存入暫存區(qū)最后才能commit。每次提交的是暫存區(qū)所對應(yīng)的文件快照。

                拓展:status提示信息

                Changes not staged for commit: (use “git add …” to update what will be committed) (use “git checkout — …” to discard changes in working directory)

                • 既然是Changes not staged for commit,就說明出現(xiàn)這個提示下的所有文件改動,都是存在于工作區(qū)的。stage是暫存區(qū)的意思,not stage說明都不在暫存區(qū),那么說明在工作區(qū)。
                • (use “git add …” to update what will be committed)。執(zhí)行這條命令就可以工作區(qū)里面的改變加入到暫存區(qū)??梢詧?zhí)行g(shù)it add .把當(dāng)前目錄下所有改動加入暫存區(qū)。
                • (use “git checkout – …” to discard changes in working directory)。執(zhí)行這條命令將丟棄在工作區(qū)的改動??梢詧?zhí)行g(shù)it checkout *把當(dāng)前目錄下所有工作區(qū)的改動丟棄掉

                Untracked files: (use “git add …” to include in what will be committed)

                • Untracked files,就說明出現(xiàn)這個提示下的所有文件都是當(dāng)前HEAD沒有被加入過的文件。這種改動也屬于工作區(qū)。
                • (use “git add …” to include in what will be committed)。把Untracked files加入暫存區(qū)。

                On branch masterYour branch is ahead of ‘origin/master’ by 1 commit. (use “git push” to publish your local commits)

                • 當(dāng)前分支比遠(yuǎn)程分支多了一次commit

                Your branch and ‘origin/master’ have perged, and have 1 and 1 different commits each, respectively

                pull報錯了,查看狀態(tài)顯示這個,先留著待解決吧

                3.HEAD是什么

                HEAD是Git中非常重要的一個概念,你可以稱它為指針或者引用,它可以指向任意一個節(jié)點,并且指向的節(jié)點始終為當(dāng)前工作目錄,換句話說就是當(dāng)前工作目錄(也就是你所看到的代碼)就是HEAD指向的節(jié)點。

                4.git重命名檢測

                Git 采用了不同的方法:它沒有選擇去存儲與文件移動操作相關(guān)的信息,而是采用了重命名檢測算法。在該算法中,如果一個文件在某一次提交中消失了,它依然會存在于其前次提交,而如果某個擁有相同名字或相似內(nèi)容的文件出現(xiàn)在了另一個位置,Git 就會自動檢測到。如果是這種情況,Git 就會假定該文件被移動過了。

                Git項目文件說明

                Git init后主要有兩個重要的文件和目錄:.git目錄和.gitignore

                1. .gitignore

                .gitignore文件存在于根目錄(與.git同級的目錄)用于在將文件提交到git暫存區(qū)時,指定將哪些文件排除;

                有時候你想添加(git add)一個文件到Git,但發(fā)現(xiàn)添加不了,多半原因是這個文件被.gitignore忽略了

                git add .不會添加被.gitignore忽視的文件,而git add -f . 強(qiáng)制添加所有文件,即使是.gitignore忽視的文件也添加。

                當(dāng).gitignore文件不是你編寫的,但是它編寫的不符合實際需求,你可以使用git check-ignore命令進(jìn)行檢查,看是哪一個規(guī)則有問題了

                #檢測 git check-ignore -v App.class#結(jié)果.gitignore:3:*.classApp.class

                .gitignore只能忽略那些原來沒有被track的文件,如果某些文件已經(jīng)被納入了版本管理中,則修改.gitignore是無效的。解決方法就是先把本地緩存刪除(改變成未track狀態(tài)),然后再提交。

                git rm -r –cached .git add .git commit -m ‘update .gitignore’

                也可以手動指定一個文件作為git忽略文件

                git config core.excludesfile ***

                對于全局Git配置,可以使用如下命令對全部倉庫進(jìn)行配置。

                git config –global core.excludesfile **/.gitignore(文件相對或絕對位置)

                忽略規(guī)則如下:

              1. 空格不匹配任意文件,可作為分隔符,可用反斜杠轉(zhuǎn)義
              2. #開頭的文件標(biāo)識注釋,可以使用反斜杠進(jìn)行轉(zhuǎn)義
              3. ! 開頭的模式標(biāo)識否定,該文件將會再次被包含,如果排除了該文件的父級目錄,則使用 ! 也不會再次被包含。可以使用反斜杠進(jìn)行轉(zhuǎn)義
              4. / 結(jié)束的模式只匹配文件夾以及在該文件夾路徑下的內(nèi)容,但是不匹配該文件
              5. / 開始的模式匹配項目跟目錄
              6. 如果一個模式不包含斜杠,則它匹配相對于當(dāng)前 .gitignore 文件路徑的內(nèi)容,如果該模式不在 .gitignore 文件中,則相對于項目根目錄
              7. ** 匹配多級目錄,可在開始,中間,結(jié)束
              8. ? 通用匹配單個字符
              9. [] 通用匹配單個字符列表
              10. 各種項目的gitignore

                參考地址:https://github.com/github/gitignore

                2. .git目錄

                任意文件夾中,用 git init 命令初始化倉庫,即可在此文件夾下創(chuàng)建 .git 文件夾(.打頭為隱藏文件夾,所以平時可能看不到)。這個文件夾之外的部分叫做工作區(qū)(Working Directory),.git 文件夾我們稱做 Git倉庫 (Git Repository)。 通常會有7個文件5個目錄,常見目錄如下:

                COMMIT_EDITMSGHEADORIG_HEADFETCH_HEADconfigdescriptionindexhooks/info/logs/objects/refs/

                1. 文件 COMMIT_EDITMSG

                此文件是一個臨時文件,存儲最后一次提交的信息內(nèi)容,git commit 命令之后打開的編輯器就是在編輯此文件,而你退出編輯器后,git 會把此文件內(nèi)容寫入 commit 記錄。

                實際應(yīng)用: git pull 遠(yuǎn)程倉庫后,新增了很多提交,淹沒了本地提交記錄,直接 cat .git/COMMIT_EDITMSG 就可以弄清楚最后工作的位置了。

                2. HEAD

                此文件永遠(yuǎn)存儲當(dāng)前位置指針,就像 linux 中的 $PWD 變量和命令提示符的箭頭一樣,永遠(yuǎn)指向當(dāng)前位置,表明當(dāng)前的工作位置。在 git 中 HEAD 永遠(yuǎn)指向當(dāng)前正在工作的那個 commit。(孤立HEAD?????)

                HEAD 存儲一個分支的 ref,Linux中運行:cat .git/HEAD 通常會顯示:

                ref: refs/heads/master

                這說明你目前正在 master 分支工作。此時你的任何 commit,默認(rèn)自動附加到 master 分支之上

                git cat-file -p HEAD, 顯示詳細(xì)的提交信息:

                tree 4cbb261560348e1727b5137f3ab6eceae8e1f34dparent 22c457fe24f737505356edfb8696c7e50fd9d971author Evan You 1654857613 +0800committer Evan You 1654857613 +0800chore: test pass

                孤立head,不指向任何commit

                3. ORIG_HEAD

                正因為 HEAD 比較重要,此文件會在你進(jìn)行危險操作時備份 HEAD,如以下操作時會觸發(fā)備份

                git resetgit mergegit rebasegit pull

                此文件應(yīng)用示例

                # 回滾到上一次的狀態(tài)(慎用!!!)git reset –hard ORIG_HEAD

                4. FETCH_HEAD

                這個文件作用在于追蹤遠(yuǎn)程分支的拉取與合并,與其相關(guān)的命令有 git pull/fetch/merge,而git pull 命令相當(dāng)于執(zhí)行以下兩條命令:

                $ git fetch$ git merge FETCH_HEAD# 顯示如下>>>From https://github.com/xxx/xxxx* branch master -> FETCH_HEADUpdating f785638..59db1b2

                此時會默默備份 HEAD 到 ORIG_HEAD

                5. config

                此文件存儲項目本地的 git 設(shè)置,典型內(nèi)容如下:

                [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true[remote “origin”] url = git@gitlab.xxxx.com/xxx.git fetch = +refs/heads/*:refs/remotes/origin/*[branch “master”] remote = origin merge = refs/heads/master[branch “v2.6.0”] remote = origin merge = refs/heads/v2.6.0[branch “v2.8.0”] remote = origin merge = refs/heads/v2.8.0

                [core] 段的內(nèi)容跟 git config 命令對應(yīng)

                執(zhí)行以下命令:

                git config user.name abcgit config user.email abc@abc.com

                會在 config 文件中追加以下內(nèi)容:

                … …[user]name = abcemail = abc@abc.com

                git config –global 影響的則是全局配置文件 ~/.gitconfig。

                [remote] 段表示遠(yuǎn)程倉庫配置

                [branch] 段表示分支同步設(shè)置

                假設(shè)當(dāng)前在 master 分支,執(zhí)行 git pull 若出現(xiàn)以下提示:

                There is no tracking information for the current branch.Please specify which branch you want to merge with.See git-pull(1) for details.

                git pull 就說明 .git/config 文件缺少對應(yīng)的 [branch “master”] 字段。

                解決方案為:

                git branch -u origin/master master# 或者執(zhí)行一次 pushgit push -u origin master

                會出現(xiàn)提示:

                Branch ‘master’ set up to track remote branch ‘master’ from ‘origin’.

                其實就是生成以下內(nèi)容在 .git/config中:

                [branch “master”]remote = originmerge = refs/heads/master

                手動編輯 .git/config,效果一樣。這就是 upstream 的真正含義,即生成 config 中的這段配置。

                6. description

                說明這個文件主要用于 GitWeb 的描述,如果要啟動 GitWeb 可用如下命令:

                # 確保lighttpd已安裝: brew install lighttpd$ git instaweb –start

                默認(rèn)會啟動 lighttpd 服務(wù)并打開瀏覽器 http://127.0.0.1:1234 (試著改成對外IP并分享給別人?)

                以下顯示當(dāng)前的 git 倉庫名稱以及描述,默認(rèn)的描述如下:

                默認(rèn)描述

                上面這段話就是默認(rèn)的 description 文件的內(nèi)容,編輯這個文件來讓你 GitWeb 描述更友好。

                7. hooks/目錄

                存放 git hooks,用于在 git 命令前后做檢查或做些自定義動作。運行 ls -F1 .git/hooks

                prepare-commit-msg.sample # git commit 之前,編輯器啟動之前觸發(fā),傳入 COMMIT_FILE,COMMIT_SOURCE,SHA1commit-msg.sample # git commit 之前,編輯器退出后觸發(fā),傳入 COMMIT_EDITMSG 文件名pre-commit.sample # git commit 之前,commit-msg 通過后觸發(fā),譬如校驗文件名是否含中文pre-push.sample # git push 之前觸發(fā)pre-receive.sample # git push 之后,服務(wù)端更新 ref 前觸發(fā)update.sample # git push 之后,服務(wù)端更新每一個 ref 時觸發(fā),用于針對每個 ref 作校驗等post-update.sample # git push 之后,服務(wù)端更新 ref 后觸發(fā)pre-rebase.sample # git rebase 之前觸發(fā),傳入 rebase 分支作參數(shù)applypatch-msg.sample # 用于 git am 命令提交信息校驗pre-applypatch.sample # 用于 git am 命令執(zhí)行前動作fsmonitor-watchman.sample # 配合 core.fsmonitor 設(shè)置來更好監(jiān)測文件變化

                參考

                https://git-scm.com/docs/githooks

                如果要啟用某個 hook,只需把 .sample 刪除即可,然后編輯其內(nèi)容來實現(xiàn)相應(yīng)的邏輯。

                比如要校驗每個 commit message 至少要包含兩個單詞,否則就提示并拒絕提交,將 commit-msg.sample 改為 commit-msg 后,編輯如下:

                #!/bin/shgrep -q ‘Ss+S’ $1 || { echo ‘提交信息至少為兩個單詞’ && exit 1; }

                這樣當(dāng)提交一個 commit 時,會執(zhí)行 bash 命令: .git/hooks/commit-msg .git/COMMIT_EDITMSG,退出值不為 0,就拒絕提交。

                8. info/目錄

                此文件夾基本就有兩個文件:

              11. 文件 info/exclude 用于排除規(guī)則,與 .gitignore 功能類似。
              12. 可能會包含文件 info/refs ,用于跟蹤各分支的信息。此文件一般通過命令 git update-server-info 生成,內(nèi)容通常如下:94e1a0d952f577fe1348d828d145507d3709e11e refs/heads/master # object hash # branch reference
              13. 這表示 master 分支所指向的文件對象 hash 值為:94e1a0d952f577fe1348d828d145507d3709e11e,運行 git cat-file -p 94e1a0d952f577fe1348d828d145507d3709e11e,可以看到 master 分支最后提交的記錄信息。同時:cat .git/objects/94/e1a0d952f577fe1348d828d145507d3709e11e 可以看到最后提交文件的二進(jìn)制內(nèi)容表示。
              14. 文件 info/refs 對于 搭建 git 服務(wù)器 來說至關(guān)重要。
              15. 9. logs/目錄

                記錄了操作信息,git reflog 命令以及像 HEAD@{1} 形式的路徑會用到。如果刪除此文件夾(危險?。敲匆蕾囉?reflog 的命令就會報錯。

                文件夾 objects/

                此文件夾簡單說,就是 git的數(shù)據(jù)庫,運行 tree .git/objects,可以看到目錄結(jié)構(gòu):

                .git/objects/|– 0c| `– d370696b581c38ee01e62b148a759f80facc2d|– 59| `– 3d5b490556791212acd5a516a37bbfa05d44dd|– 61| `– be44eedde61d723e5761577a2b420ba0fc2794|– 64| `– c0aed8ddcbb546bdcec2848938fc82348db227|– d4| `– 9904676ce8ddde276bdbfa9bbec313e90e0f50|– info`– pack |– pack-75e3f2aa378752ec93a8e9f375f01204d498605b.idx `– pack-75e3f2aa378752ec93a8e9f375f01204d498605b.pack

                這些文件分兩種形式:pack壓縮包 形式放在 pack/ 目錄下,除此之外都是 hash文件 形式,被叫做 loost objects。

                這個文件夾以及相應(yīng)的算法,我沒找到獨立的名稱,就叫它 hash-object 體系吧。因為確實有個 git hash-object 命令存在,是一個底層的負(fù)責(zé)生成這些 loost objects 文件,如果要看到這些文件各自的含義,執(zhí)行以下命令:

                git cat-file –batch-check –batch-all-objects

                可以看到

                04c87c65f142f33945f2f5951cf7801a32dfa240 commit 194098217953a6ca169bed33d2be8a07d584fcdaf30 tree 310cd370696b581c38ee01e62b148a759f80facc2d commit 2452a810017bfc85d7db2627f4aabdaa1583212bda3 blob 193920a07c1d5694df6b8658592b0939241d70e9e5 tree 93593d5b490556791212acd5a516a37bbfa05d44dd tag 14861be44eedde61d723e5761577a2b420ba0fc2794 tree 154… …

                但你會發(fā)現(xiàn)這個列表里有些值在文件夾中并不存在,因為除了 loost objects 它還匯總了 pack 文件中的內(nèi)容。

                hash文件

                又稱為 loose object,文件名稱共由40字符的 SHA-1 hash 值組成,其中前兩個字符為文件夾分桶,后38個字符為文件名稱。

                按文件內(nèi)容可分為四種類型:commit, tree, blob, tag,若執(zhí)行以下命令會生成所有四種類型:

                echo -en ‘xx’ > xx # 共 3 個字符git add .git commit -m ‘update xx’git tag -a ‘v1.0’ -m ‘release: 1.0.0’

                經(jīng)過以上操作后,對比一下文件樹,發(fā)現(xiàn)多了四個 hash文件:

                |– 0c| `– d370696b581c38ee01e62b148a759f80facc2d|– 18| `– 143661f96845f11e0b4ab7312bdc0f356834ce|– 30| `– 20feea86d222d83218eb3eb5aa9f58f73df04d|– 59| `– 3d5b490556791212acd5a516a37bbfa05d44dd|– 61| `– be44eedde61d723e5761577a2b420ba0fc2794|– 64| `– c0aed8ddcbb546bdcec2848938fc82348db227|– ad| `– f4c9afac7afae3ff3e95e6c4eefe009d547f00|– cc| `– c9bd67dc5c467859102d53d54c5ce851273bdd|– d4| `– 9904676ce8ddde276bdbfa9bbec313e90e0f50|– info`– pack|– pack-75e3f2aa378752ec93a8e9f375f01204d498605b.idx`– pack-75e3f2aa378752ec93a8e9f375f01204d498605b.pack

                這四個 hash文件 分別是:

                cc/c9bd67dc5c467859102d53d54c5ce851273bdd # blob30/20feea86d222d83218eb3eb5aa9f58f73df04d # commitad/f4c9afac7afae3ff3e95e6c4eefe009d547f00 # tree18/143661f96845f11e0b4ab7312bdc0f356834ce # tag

                其實這些文件都經(jīng)過了壓縮,壓縮形式為 zlib。先安裝一下解壓工具 macOS 版 brew install pigz 或 windows 版 pigz,后執(zhí)行:

                $ pigz -d >>>(注意xx后有個)blob 3xx$pigz -d >>>commit 248tree adf4c9afac7afae3ff3e95e6c4eefe009d547f00parent 0cd370696b581c38ee01e62b148a759f80facc2dauthor jamesyang.yjm 1562044880 +0800committer jamesyang.yjm 1562044880 +0800update xx$ pigz -d >>>tree 154100644 abc*???]}?bJ??X2??100644 asdf???CK?)?wZ???S?100644 iou???CK?)?wZ???S?100644 xx??g?FxY-S?L?Q’;?100644 yy???CK?)?wZ???S?$ pigz -d >>>tag 155object 3020feea86d222d83218eb3eb5aa9f58f73df04dtype committag v1.0tagger jamesyang.yjm 1562045942 +0800release: 1.0.0

                會發(fā)現(xiàn),顯示結(jié)果都是 type size+內(nèi)容 形式,這就是 object 文件的存儲格式:

                [type] [size][NULL][content]

                type 可選值:commit, tree, blob, tag,NULL 就是C語言里的字符結(jié)束符:,size 就是 NULL后內(nèi)容的字節(jié)長度。

                type 的幾種類型可以使用 git cat-file -t hash 看到,內(nèi)容可以用 git cat-file -p hash 看到。

                git cat-file -t ccc9bd67dc5c467859102d53d54c5ce851273bdd# 顯示結(jié)果為>>>>blobgit cat-file -p ccc9bd67dc5c467859102d53d54c5ce851273bdd# 顯示結(jié)果為>>>>xx

                所以 blob 文件就是對原文件內(nèi)容的全量拷貝,同時前面加了 blob size,而文件名稱的 hash 值計算是計算整體字符的 SHA-1 值:

                echo -en ‘blob 3xx’ | shasum# 顯示結(jié)果為>>>>ccc9bd67dc5c467859102d53d54c5ce851273bdd –

                知道原理后,其它類型格式請自行參考 斯坦福 Ben Lynn 所著的 GitMagic。

                所以,當(dāng)我們 git show 3020feea86d222d83218eb3eb5aa9f58f73df04d 時,會發(fā)生些什么?

                找到 3020feea86d222d83218eb3eb5aa9f58f73df04d 這個 commit,顯示出來找到此 commit 關(guān)聯(lián)的 tree object: adf4c9afac7afae3ff3e95e6c4eefe009d547f00,拉取相應(yīng)的 blob 文件,并與當(dāng)前工作區(qū)內(nèi)的文件做 diff,然后顯示出來

                這就是 objects/ 文件夾作為 git數(shù)據(jù)庫 被使用的真實例子。

                pack文件

                為什么會有 .pack 文件?

                由于每次 commit 都會生成許多 hash文件,并且由于 blob 文件都是全量存儲的,導(dǎo)致 git 效率下降,于是有了 pack-format,優(yōu)勢:

                對于大倉庫存儲效率高利于網(wǎng)絡(luò)傳輸,便于備份增量存儲,優(yōu)化磁盤空間將 .git/objects 下的部分文件打包成 pack格式

                $ tree .git/objects/ | wc -l311$ git gcEnumerating objects: 288, done.Counting objects: 100% (288/288), done.Delta compression using up to 4 threadsCompressing objects: 100% (287/287), done.Writing objects: 100% (288/288), done.Total 288 (delta 131), reused 90 (delta 0)$ tree .git/objects/ | wc -l12

                可以看到文件數(shù)量減小了不少,其中大部分文件被打到一個 .pack 包中,并且是增量存儲,有部分變更的文件只存儲 基礎(chǔ)hash 變更內(nèi)容,磁盤空間優(yōu)化很明顯。

                git gc 其實運行了兩條命令:git repack 用來打包 和 git prune-packed 用來移除已打包的 hash文件;

                11.文件夾refs

                refs 可以理解成文件系統(tǒng)中的 symbol link,看下結(jié)構(gòu):

                $ tree .git/refs/.git/refs|– heads| `– master`– tags`– v1.0$ cat .git/refs/heads/master5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5$ cat .git/refs/tags/v1.05978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5$ git cat-file -t 5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5commit

                可以看到 master 和 v1.0 都指向 5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 這個 commit。

                refs/heads/ 文件夾內(nèi)的 ref 一般通過 git branch 生成。git show-ref –heads 可以查看。

                refs/tags/ 文件夾內(nèi)的 ref 一般通過 git tag 生成。git show-ref –tags 可以查看。

                如下:

                $ git branch abc$ tree .git/refs/.git/refs/|– heads| |– abc| `– master`– tags`– v1.0$ cat .git/refs/heads/abc5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5

                說明新建分支其實就是生成了一個指向某個 commit 的 symbol link,當(dāng)然在這里叫做 ref。

                而 git tag 命令本質(zhì)與 git branch 相同,只生成一個 ref 放在 tags 目錄下,所以被稱為 lightweight tag。

                而 git tag -a xx 命令會首先生成一個類型為 tag 的 hash文件 放到 objects/ 目錄,然后生成 ref 放到 tags 目錄下指向那個文件。這就叫做 annotated tag,好處是可包含一些元信息如 tagger 和 message,被 git 的 hash-object 算法管理,可被 GPG 簽名等,所以更穩(wěn)定,更安全。

                使用以下命令來拿到 refs 文件夾存儲的信息:

                $ git show-ref –head –dereference5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 HEAD5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/heads/abc5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/heads/master5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/tags/v1.05e84371048faa20412f5492e6af264a7e1edfec1 refs/tags/xx5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/tags/xx^{}

                我們來看這些信息如何變化的:

                $ touch new_file && git add . && git commit -m ‘add new_file'[master 44b0d05] add new_file1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 new_file$ git show-ref –head –dereference44b0d05ddadaaa8d2cc40d6647cc474b26f5d8d3 HEAD5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/heads/abc44b0d05ddadaaa8d2cc40d6647cc474b26f5d8d3 refs/heads/master5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/tags/v1.05e84371048faa20412f5492e6af264a7e1edfec1 refs/tags/xx5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/tags/xx^{}

                diff 一下可以看到:

                5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 HEAD5978c2c79cd3a4711fb8edd3166c9f9f5c8c97f5 refs/heads/master

                這兩行發(fā)生了變化。也就是每次 commit 時,HEAD 與 heads 都會自動更新。

                12. index文件

                文件保存成二進(jìn)制對象以后,還需要通知 Git 哪些文件發(fā)生了變動。所有變動的文件,Git 都記錄在一個區(qū)域,叫做”暫存區(qū)”(英文叫做 index 或者 stage)。等到變動告一段落,再統(tǒng)一把暫存區(qū)里面的文件寫入正式的版本歷史。

                git update-index命令用于在暫存區(qū)記錄一個發(fā)生變動的文件。

                $ git update-index –add –cacheinfo 100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad test.txt

                上面命令向暫存區(qū)寫入文件名test.txt、二進(jìn)制對象名(哈希值)和文件權(quán)限。

                git ls-files命令可以顯示暫存區(qū)當(dāng)前的內(nèi)容。

                $ git ls-files –stage100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0 test.txt

                上面代碼表示,暫存區(qū)現(xiàn)在只有一個文件test.txt,以及它的二進(jìn)制對象名和權(quán)限。知道了二進(jìn)制對象名,就可以在.git/objects子目錄里面讀出這個文件的內(nèi)容。

                git status命令會產(chǎn)生更可讀的結(jié)果。

                $ git status要提交的變更: 新文件: test.txt

                上面代碼表示,暫存區(qū)里面只有一個新文件test.txt,等待寫入歷史。

                資料來源

                參考:https://developer.aliyun.com/article/716483

                Git遠(yuǎn)程倉庫

                Git 并不像 SVN 那樣有個中心服務(wù)器。目前我們使用到的 Git 命令都是在本地執(zhí)行,如果你想通過 Git 分享你的代碼或者與其他開發(fā)人員合作。 你就需要將數(shù)據(jù)放到一臺其他開發(fā)人員能夠連接的服務(wù)器上。

                1.添加遠(yuǎn)程倉庫

                git remote add [shortname] [url] #添加遠(yuǎn)程倉庫git remote rm name # 刪除遠(yuǎn)程倉庫git remote rename old_name new_name # 修改倉庫名

                2.查看遠(yuǎn)端倉庫

                $ git remoteorigin$ git remote -vorigin git@github.com:tianqixin/runoob-git-test.git (fetch)origin git@github.com:tianqixin/runoob-git-test.git (push)

                3.獲取遠(yuǎn)端倉庫代碼 git fetch

                # 只能fetch到一個空白的分支,然后可以手動merge$ git fetch :

                不填的話都是默認(rèn)

                4.拉取 git pull

                git pull :# 允許合并不相關(guān)的分支 $ git pull –allow-unrelated-histories

                git pull操作其實是git fetch 與 git merge 兩個命令的集合。 git fetch 和 git merge FETCH_HEAD 的簡寫。

                相關(guān)文檔:https://www.runoob.com/git/git-remote-repo.html

                5.推送 git push

                # 基本$ git push :# 強(qiáng)制推送$ git push –force origin master# 刪除遠(yuǎn)程分支$ git push origin –delete master# 允許合并不相關(guān)的分支$ git push –allow-unrelated-histories

                提示

                如果另一個開發(fā)者在我們之前已經(jīng)做過一次 push 操作,此次 push 命令就會被拒絕傳送提交。這時候,我們必須要先做一次 pull 操作,將其他人新上載的更新取回,并本地合并。

                如果本地分支名與遠(yuǎn)程分支名相同,則可以省略冒號,帶上-u 參數(shù)相當(dāng)于記錄了push到遠(yuǎn)端分支的默認(rèn)值,這樣當(dāng)下次我們還想要繼續(xù)push的這個遠(yuǎn)端分支的時候推送命令就可以簡寫成git push即可。

                Git 分支

                1.創(chuàng)建分支命令 git branch

                # 創(chuàng)建分支$ git branch # 創(chuàng)建分支并跟蹤遠(yuǎn)程分支$ git branch -u o/master foo

                2.切換分支命令 git checkout

                第一作用是切換分支,第二個是撤銷修改。

                # 切換指定分支$ git checkout ||# 創(chuàng)建一個的分支,它跟蹤遠(yuǎn)程分支$ git checkout -b 本地分支名x origin/遠(yuǎn)程分支名x# 從暫存區(qū)恢復(fù)到工作區(qū)$ git checkout .

                提示

                當(dāng)你切換分支的時候,Git 會用該分支的最后提交的快照替換你的工作目錄的內(nèi)容, 所以多個分支不需要多個目錄。

                實際測試:

                假設(shè)分支1 a文件未提交,分支2 a文件已提交。切換到到分支2時會替換 分支1的a文件。1切換到2時也會替換a文件;

                兩個分支都已經(jīng)提交的 切換時會互相替換。一個提交一個沒提交時,從a到b,b會保持a的暫存區(qū)和工作區(qū)

                3.合并分支命令 git merge

                # 合并指定分支到當(dāng)前分支$ git merge

                4.刪除分支 git branch -d

                # 刪除指定分支$ git branch -d

                5.分支列表 git branch

                # 列出所有分支$ git branch# 查看遠(yuǎn)程所有分支$ git branch -r# 查看本地和遠(yuǎn)程所有分支$ git branch -a

                列出分支時,帶*號的分支為當(dāng)前活動分支

                5.重命名分支 git branch -M

                # 重命名指定分支# 不填old默認(rèn)重命名當(dāng)前分支$ git branch -m old new# 強(qiáng)制重命名指定分支$ git branch -M old new

                git rebase 變基

                1.介紹

                Git rebase,通常被稱作變基或衍合, 可以理解為另外一種合并的方式,與merge 會保留分支結(jié)構(gòu)和原始提交記錄不同,rebase 是在公共祖先的基礎(chǔ)上,把新的提交鏈截取下來,在目標(biāo)分支上進(jìn)行重放,逐個應(yīng)用選中的提交來完成合并。

                不同公司,不同情況有不同使用場景,不過大部分情況推薦如下:

                自己單機(jī)的時候,拉公共分支最新代碼的時候使用rebase,也就是git pull -r或git pull –rebase。這樣的好處很明顯,提交記錄會比較簡潔。但有個缺點就是rebase以后我就不知道我的當(dāng)前分支最早是從哪個分支拉出來的了,因為基底變了嘛,所以看個人需求了。

                往公共分支上合代碼的時候,使用merge。如果使用rebase,那么其他開發(fā)人員想看主分支的歷史,就不是原來的歷史了,歷史已經(jīng)被你篡改了。舉個例子解釋下,比如張三和李四從共同的節(jié)點拉出來開發(fā),張三先開發(fā)完提交了兩次然后merge上去了,李四后來開發(fā)完如果rebase上去(注意李四需要切換到自己本地的主分支,假設(shè)先pull了張三的最新改動下來,然后執(zhí)行,然后再git push到遠(yuǎn)端),則李四的新提交變成了張三的新提交的新基底,本來李四的提交是最新的,結(jié)果最新的提交顯示反而是張三的,就亂套了。

                正因如此,大部分公司其實會禁用rebase,不管是拉代碼還是push代碼統(tǒng)一都使用merge,雖然會多出無意義的一條提交記錄“Merge … to …”,但至少能清楚地知道主線上誰合了的代碼以及他們合代碼的時間先后順序

                2.原理

                變基操作的工作原理很簡單:Git 會讓我們想要移動的提交序列在目標(biāo)分支上按照相同的順序重新再現(xiàn)一遍。這就相當(dāng)于我們?yōu)楦鱾€原提交做了個副本,它們擁有相同的修改集、同一作者、日期以及注釋信息。

                3.命令

                # 可以是commit 版本號、分支名稱,合并多個提交到一個版本$ git rebase -i [startpoint] [endpoint] # 變基發(fā)生沖突時,解決后繼續(xù)變基$ git rebase –continue# 無視沖突,繼續(xù)變基操作$ git rebase –skip # 發(fā)生沖突時中斷變基$ git rebase –abort”

                -i的意思是–interactive,即彈出交互式的界面讓用戶編輯完成合并操作,[startpoint] [endpoint]則指定了一個編輯區(qū)間,如果不指定[endpoint],則該區(qū)間的終點默認(rèn)是當(dāng)前分支HEAD所指向的commit(注:該區(qū)間指定的是一個前開后閉的區(qū)間)。

                Git 標(biāo)簽

                Git 中的tag指向一次commit的id,通常用來給開發(fā)分支做一個標(biāo)記,如標(biāo)記一個版本號。

                1.添加標(biāo)簽

                git tag -a version -m “note”

                注解:git tag 是打標(biāo)簽的命令,-a 是添加標(biāo)簽,其后要跟新標(biāo)簽號,-m 及后面的字符串是對該標(biāo)簽的注釋。

                2.提交標(biāo)簽到遠(yuǎn)程倉庫

                git push origin -tags

                注解:就像git push origin master 把本地修改提交到遠(yuǎn)程倉庫一樣,-tags可以把本地的打的標(biāo)簽全部提交到遠(yuǎn)程倉庫。

                3.刪除標(biāo)簽

                git tag -d version

                注解:-d 表示刪除,后面跟要刪除的tag名字

                4.刪除遠(yuǎn)程標(biāo)簽

                git push origin :refs/tags/version

                注解:就像git push origin :branch_1 可以刪除遠(yuǎn)程倉庫的分支branch_1一樣, 冒號前為空表示刪除遠(yuǎn)程倉庫的tag。

                5.查看標(biāo)簽

                git tag或者git tag -l

                Git存儲

                git stash將本地未提交代碼作為一個本地緩存。作用范圍為本地工作區(qū)以及本地暫存區(qū)。

                1.使用場景

                • 當(dāng)正在dev分支上開發(fā)某個項目,這時項目中出現(xiàn)一個bug,需要緊急修復(fù),但是正在開發(fā)的內(nèi)容只是完成一半,還不想提交,這時可以用git stash命令將修改的內(nèi)容保存至堆棧區(qū),然后順利切換到hotfix分支進(jìn)行bug修復(fù),修復(fù)完成后,再次切回到dev分支,從堆棧中恢復(fù)剛剛保存的內(nèi)容。
                • 由于疏忽,本應(yīng)該在dev分支開發(fā)的內(nèi)容,卻在master上進(jìn)行了開發(fā),需要重新切回到dev分支上進(jìn)行開發(fā),可以用git stash將內(nèi)容保存至堆棧中,切回到dev分支后,再次恢復(fù)內(nèi)容即可。

                2.git stash

                # 保存當(dāng)前工作區(qū)、暫存區(qū)的所有未提交代碼# 執(zhí)行存儲時,添加備注,方便查找# git stash

                只有g(shù)it stash 也是可以的,但查找時不方便識別。

                3.查看stash列表

                # 查看stash了哪些存儲$ git stash list

                4.恢復(fù)緩存

                git stash pop

                命令恢復(fù)之前緩存的工作目錄,將緩存堆棧中的對應(yīng)stash刪除,并將對應(yīng)修改應(yīng)用到當(dāng)前的工作目錄下,默認(rèn)為第一個stash,即stash@{0},如果要應(yīng)用并刪除其他stash,命令:

                git stash pop stash@{$num}

                比如應(yīng)用并刪除第二個:

                git stash pop stash@{1}

                5.git apply

                使用apply命令恢復(fù),stash列表中的信息是會繼續(xù)保留的,而使用pop命令進(jìn)行恢復(fù),會將stash列表中的信息進(jìn)行刪除。參數(shù)同pop

                6.刪除緩存

                git stash drop stash@{num}

                刪除某個保存,num是可選項,通過git stash list可查看具體值

                7.刪除所有緩存

                # 刪除所有緩存的stash $ git stash clear

                Git常用命令,基于使用步驟

                使用步驟

                提示:正常步驟應(yīng)該是:先commit 然后pull 再 push ;

                1.git config,配置Git

                用于查看和修改Git配置信息,當(dāng)安裝Git后首先要做的事情是設(shè)置用戶名稱和email地址。這是非常重要的,因為每次Git提交都會使用該用戶信息

                #設(shè)置用戶信息git config –global user.name “未進(jìn)化的程序猿”git config –global user.email “486566947@qq.com”#讀取配置信息git config –listgit config user.name

                • /etc/gitconfig 文件:系統(tǒng)中對所有用戶都普遍適用的配置。若使用 git config 時用 –system 選項,讀寫的就是這個文件。
                • ~/.gitconfig 文件:用戶目錄下的配置文件只適用于該用戶。若使用 git config 時用 –global 選項,讀寫的就是這個文件。
                • 當(dāng)前項目的 Git 目錄中的配置文件(也就是工作目錄中的 .git/config 文件):這里的配置僅僅針對當(dāng)前項目有效。每一個級別的配置都會覆蓋上層的相同配置,所以 .git/config 里的配置會覆蓋 /etc/gitconfig 中的同名變量。

                提示

                PHPstorm中使用Git時的賬號密碼同樣是Git配置中使用的賬號密碼

                2.初始化倉庫,git init

                Git 使用 git init 命令來初始化一個 Git 倉庫,Git 的很多命令都需要在 Git 的倉庫中運行,所以 git init 是使用 Git 的第一個命令。

                在執(zhí)行完成 git init 命令后,Git 倉庫會生成一個 .git 目錄,該目錄包含了資源的所有元數(shù)據(jù),其他的項目目錄保持不變。

                使用當(dāng)前目錄作為 Git 倉庫,我們只需使它初始化。

                git init

                該命令執(zhí)行完后會在當(dāng)前目錄生成一個 .git 目錄。

                使用我們指定目錄作為Git倉庫。

                git init newrepo

                初始化后,會在 newrepo 目錄下會出現(xiàn)一個名為 .git 的目錄,所有 Git 需要的數(shù)據(jù)和資源都存放在這個目錄中。

                3.將文件納入版本控制 ,git add

                如果當(dāng)前目錄下有幾個文件想要納入版本控制,需要先用 git add 命令告訴 Git 開始對這些文件進(jìn)行跟蹤,然后提交:

                # 當(dāng)前目錄下.c結(jié)尾的所有文件(通配符)$ git add *.c # 指定README等多個文件文件$ git add README README.md# .git add all無論在哪個目錄執(zhí)行都會提交相應(yīng)文件。$ git add –all # .git add .只能夠提交當(dāng)前目錄或者它后代目錄下相應(yīng)文件。$ git add .

                4. 提交文件 ,git commit

                注意

                注: 在 Linux 系統(tǒng)中,commit 信息使用單引號 ‘,Windows 系統(tǒng),commit 信息使用雙引號 “。

                所以在 git bash 中 git commit -m ‘提交說明’ 這樣是可以的,在 Windows 命令行中就要使用雙引號 git commit -m “提交說明”。

                暫存區(qū)保留本次變動的文件信息,等到修改了差不多了,就要把這些信息寫入歷史,這就相當(dāng)于生成了當(dāng)前項目的一個快照(snapshot)。

                項目的歷史就是由不同時點的快照構(gòu)成。Git 可以將項目恢復(fù)到任意一個快照。快照在 Git 里面有一個專門名詞,叫做 commit,生成快照又稱為完成一次提交。

                提示

                每一次commit都會產(chǎn)生一個新的版本。產(chǎn)生一個代表版本號的散列值

                git commit -m ‘初始化項目版本,記錄提交信息’git commit -am “新增提交說明”

                設(shè)置了用戶名和 Email,保存快照的時候,會記錄是誰提交的。

                Git文件生命周期

                5. 克隆倉庫,git clone

                我們使用 git clone 從現(xiàn)有 Git 倉庫中拷貝項目,Git倉庫一般是一個遠(yuǎn)程連接

                git clone

                • repo:Git 倉庫。
                • directory:本地目錄。

                6. 當(dāng)前提交狀態(tài),git status

                git status 命令用于查看在你上次提交之后是否有對文件進(jìn)行再次修改。

                $ git statusOn branch masterInitial commitChanges to be committed: (use “git rm –cached …” to unstage) new file: README new file: hello.php

                通常我們使用 -s 參數(shù)來獲得簡短的輸出結(jié)果:

                $ git status -sAM READMEA hello.php

                AM 狀態(tài)的意思是這個文件在我們將它添加到緩存之后又有改動。

                7. git diff,比較差異

                git diff 命令比較文件的不同,即比較文件在暫存區(qū)和工作區(qū)的差異。(-c 上下文格式的diff、-u 合并格式diff)

                git diff 命令顯示已寫入暫存區(qū)和已經(jīng)被修改但尚未寫入暫存區(qū)文件的區(qū)別。

                git diff 有兩個主要的應(yīng)用場景。

                • 尚未緩存的改動:git diff
                • 查看已緩存的改動: git diff –cached
                • 查看已緩存的與未緩存的所有改動:git diff HEAD
                • 顯示摘要而非整個 diff:git diff –stat

                顯示暫存區(qū)和工作區(qū)的差異:

                $ git diff [file]

                顯示兩次提交之間的差異:

                $ git diff –cached [file]或$ git diff –staged [file]

                顯示暫存區(qū)和上一次提交(commit)的差異:

                $ git diff [first-branch]…[second-branch]

                分支比較

                # 直接將兩個分支上最新的提交做diff$ git diff topic master$ #或 $ git diff topic..master# 輸出自topic和master分別開發(fā)以來,master分支上的變更。$ git diff topic…master# 查看簡單的diff結(jié)果,可以加上–stat參數(shù)# –name-only輸出時只顯示文件名

                8. 回退版本,git reset

                git reset 命令用于回退版本,可以指定退回某一次提交的版本。只對本地分支有效,對遠(yuǎn)程分支無效

                git reset [–soft | –mixed | –hard] [HEAD]

                –mixed 為默認(rèn),可以不用帶該參數(shù),用于重置暫存區(qū)的文件與上一次的提交(commit)保持一致,工作區(qū)文件內(nèi)容保持不變。

                git reset [HEAD]

                git reset HEAD

                執(zhí)行 git reset HEAD 以取消之前 git add 添加,但不希望包含在下一提交快照中的緩存。

                實例:

                $ git reset HEAD^ # 回退所有內(nèi)容到上一個版本$ git reset HEAD^ hello.php # 回退 hello.php 文件的版本到上一個版本$ git reset 052e # 回退到指定版本

                –soft 參數(shù)用于回退到某個版本:

                $ git reset –soft HEAD~3 # 回退上上上一個版本

                –hard 參數(shù)撤銷工作區(qū)中所有未提交的修改內(nèi)容,將暫存區(qū)與工作區(qū)都回到上一次版本,并刪除之前的所有信息提交:

                $ git reset –hard HEAD~3 # 回退上上上一個版本 $ git reset –hard bae128 # 回退到某個版本回退點之前的所有信息。 $ git reset –hard origin/master # 將本地的狀態(tài)回退到和遠(yuǎn)程的一樣

                • HEAD 表示當(dāng)前版本
                • HEAD^ 上一個版本
                • HEAD^^ 上上一個版本
                • HEAD^^^ 上上上一個版本HEAD~0 表示當(dāng)前版本
                • HEAD~1 上一個版本
                • HEAD^2 上上一個版本
                • HEAD^3 上上上一個版本

                9.刪除文件,git rm

                將文件從暫存區(qū)和工作區(qū)中刪除:

                git rm

                如果想把文件從暫存區(qū)域移除,但仍然希望保留在當(dāng)前工作目錄中,換句話說,僅是從跟蹤清單中刪除,使用 –cached 選項即可:

                git rm –cached

                可以遞歸刪除,即如果后面跟的是一個目錄做為參數(shù),則會遞歸刪除整個目錄中的所有子目錄和文件:

                git rm –r *

                10. 移動目錄、文件,git mv

                git mv 命令用于移動或重命名一個文件、目錄或軟連接。

                git mv [file] [newfile]

                如果新文件名已經(jīng)存在,但還是要重命名它,可以使用 -f 參數(shù):

                git mv -f [file] [newfile]

                11.查看提交歷史git log、git blame

                # 所有歷史記錄$ git log # 簡潔版$ git log –oneline# 拓?fù)鋱D版$ git log –graph# 反向顯示$ git log –reverse # 指定提交者$ git log –author=lius# 時間范圍$ git log –before={3.weeks.ago} –after={2010-04-18}# 反向顯示$ git log –reverse # 指定文件# git blame

                以上多種參數(shù)可以組合使用

                12. git show

                # 查看分支最后一次提交或版本在代碼層面的改動$ git show |

                13. git reflog

                reflog是reference log的縮寫,含義是引用日志,它會記錄下HEAD節(jié)點和分支引用所指向的歷史??梢允褂胓it reflog命令來查看引用日志

                14. git gc

                gc 命令(gc 指的是垃圾回收)可用于清理版本庫,移除所有不屬于當(dāng)前分支的提交對象。

                15. git ls-files

                查看一下git跟蹤了哪些文件,此命令就可以列出所有g(shù)it正在跟蹤的文件

                12. 撤銷文件 git restore

                # 將在 工作區(qū) 但是 不在暫存區(qū) 的文件撤銷更改 $ git restore # 作用是將 暫存區(qū)的文件從暫存區(qū)撤出,但不會更改文件 $ git restore –staged

                問題記錄

                1.push和commit的區(qū)別

                git commit操作的是本地庫,git push操作的是遠(yuǎn)程庫。

                git commit是將本地修改過的文件提交到本地庫中。git push是將本地庫中的最新信息發(fā)送給遠(yuǎn)程庫。

                如果本地不commit的話,修改的紀(jì)錄可能會丟失,而有些修改當(dāng)前是不需要同步至服務(wù)器的,所以什么時候同步過去由用戶自己選擇。什么時候需要同步再push到服務(wù)器

                2. pull requests 和 merge requests

                github可以對不同的用戶賦予不同的分支權(quán)限,例如Gitlab中的:

                • Guest:可以創(chuàng)建issue、發(fā)表評論,不能讀寫版本庫
                • Reporter:可以克隆代碼,不能提交,QA、PM可以賦予這個權(quán)限
                • Developer:可以克隆代碼、開發(fā)、提交、push,RD可以賦予這個權(quán)限
                • Master:可以創(chuàng)建項目、添加tag、保護(hù)分支、添加項目成員、編輯項目,核心RD負(fù)責(zé)人可以賦予這個權(quán)限
                • Owner:可以設(shè)置項目訪問權(quán)限 – Visibility Level、刪除項目、遷移項目、管理組成員,開發(fā)組leader可以賦予這個權(quán)限

                github基于fork的模式下,PR用于請求分支管理員 合并自己提交的代碼(理解為請求拉取自己的代碼),merge requests同理;

                3. fetch和pull的區(qū)別

                git在本地會保存兩個版本的倉庫,分為本地倉庫和遠(yuǎn)程倉庫。

                fetch 只能更新遠(yuǎn)程倉庫的代碼為最新的,本地倉庫的代碼還未被更新,我們需要通過 git merge origin/master 來合并這兩個版本,你可以把它理解為合并分支一樣的。

                pull 操作是將本地倉庫和遠(yuǎn)程倉庫(本地的)更新到遠(yuǎn)程的最新版本。fetch+merge,自動進(jìn)行合并

                4.checkout和reset時的變化

                簽出切換分支、版本、標(biāo)簽時文件的變化

                • 當(dāng)執(zhí)行 git reset HEAD 命令時,暫存區(qū)的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區(qū)不受影響。加上–hard時會強(qiáng)制替換工作區(qū)、暫存區(qū)的內(nèi)容;
                • git restore會清除暫存區(qū)的修改內(nèi)容,例如修改了test.vue ,會變?yōu)槲葱薷臅r的內(nèi)容;
                • 當(dāng)執(zhí)行 git rm –cached 命令時,會直接從暫存區(qū)刪除文件,工作區(qū)則不做出改變。

                5. 保存遠(yuǎn)程時輸入的賬號密碼

                在 git bash 里輸入命令:

                git config –global credential.helper store

                然后執(zhí)行 git 操作,輸入一遍密碼后就會記錄密碼,以后就不用輸入了。

                要更改記錄的用戶名和密碼,只需要更改用戶目錄下的 .git-credentials 文件即可。

                6.移除文件的版本控制

              16. 還沒有g(shù)it add,在 .gitignore中添加
              17. 已經(jīng)git add,先 git rm -r –cached 文件,然后在 .gitignore中添加
              18. 已經(jīng)加到版本控制中,先 git rm -r –cached 文件,然后在 .gitignore中添加,最后 gti commit -m ‘提交.gitignore’
              19. 7.Git問題解決記錄

              20. git config –global credential.helper store,解決SSl連接錯誤
              21. 克隆一個指定目錄:https://blog.csdn.net/constant_rain/article/details/124913407
              22. 8.Github常規(guī)目錄說明:

              23. dist 是指編譯后的文件,可以理解為壓縮發(fā)布版
              24. src 源碼文件,適合動手能力強(qiáng)的童鞋
              25. docs 文檔
              26. examples 示例文件
              27. test 測試腳本
              28. .gitignore 告訴git哪些文件不要上傳到 GitHub,比如數(shù)據(jù)庫配置文件等
              29. LICENSE.txt 授權(quán)協(xié)議
              30. README.md 自述文件,整個項目的簡介、使用方法等
              31. bower.json Bower 包管理器配置文件
              32. package.json npm 包管理器配置文件
              33. 設(shè)置某個分支的權(quán)限(保護(hù)分支)

                1. 管理員身份登錄GitHub,找到項目2. Settings–>Branches–>Protected branches—>Choose a branch… ,選擇需要保護(hù)的分支,然后點擊edit按鈕,3. Branch protection for 所選的分支名 –> 勾選Restrict who can push to this branch People and teams with push access若不選擇任何人,則任何人都沒有push代碼到該分支的權(quán)限。

                9. git做不到一個文件一個分支有一個分支沒有

                例如一個數(shù)據(jù)庫配置文件,本地和線索不一樣,把它從暫存區(qū)拉出來,取消追蹤變成deleted狀態(tài),本地文件實際還存在,同步到分支,遠(yuǎn)程分支當(dāng)前版本已經(jīng)沒有這個文件了。

                10. Git拉取指定分支

                git clone 倉庫地址 //默認(rèn)master分支git clone -b 分支名 倉庫地址 //指定分支

                11. git 常見的輸出內(nèi)容

                # 已經(jīng)提交的改變$ Changes to be committed: # 暫未提交的改變$ Changes not staged for commit:# 常見狀態(tài)deleted、modified

                12.報錯non-fast-forward

                non-fast-forward

                Dealing with “non-fast-forward” errors:(From time to time you may encounter this error while pushing)To prevent you from losing history, non-fast-forward updates were rejected. Merge the remote changes before pushing again. See the ‘non-fast forward’ section of ‘git push –help’ for details.This error can be a bit overwhelming at first, do not fear. Simply put, git cannot make the change on the remote without losing commits, so it refuses the push. Usually this is caused by another user pushing to the same branch. You can remedy this by fetching and merging the remote branch, or using pull to perform both at once.In other cases this error is a result of destructive changes made locally by using commands like git commit –amend or git rebase. While you can override the remote by adding –force to the push command, you should only do so if you are absolutely certain this is what you want to do. Force-pushes can cause issues for other users that have fetched the remote branch, and is considered bad practice. When in doubt, don’t force-push.

                以上時較為官方的解釋,簡單說就是push之前需要先同步遠(yuǎn)程版本。pull會自動合并,所以要改為fetch手動合并;

                問題分析

                可以這樣理解這個問題就是:別人上傳到遠(yuǎn)程倉庫后,你沒有及時的同步(、拉?。┑奖镜兀悄阃瑫r又添加了一些內(nèi)容(提交),以致于你在提交時,它會檢測到你之前從遠(yuǎn)程倉庫拉取的時候的倉庫狀態(tài)和現(xiàn)在的不一樣。于是,它為了安全起見拒絕了你的提交(然后就報了這個錯誤)。

                “不能快速前進(jìn)”的原因是因為路不一樣了,變得不好走了;體現(xiàn)在git里面就是提交歷史出現(xiàn)分叉,主線不再是一條直線,而是在前端出現(xiàn)了分叉,git不知道該如何前進(jìn),所以報錯了,讓你來覺得走哪條路!說的簡單點,就是遠(yuǎn)程倉庫和本地倉庫不同步了

                解決問題

                1.先合并之前的歷史,再進(jìn)行提交——提倡使用

                先把git的東西fetch到你本地然后merge后再push,(如果有沖突就要解決沖突后再合并,沖突問題比較復(fù)雜,這里就不詳細(xì)說了),這樣就可以使遠(yuǎn)程倉庫和你本地倉庫一致了,然后就可以提交修改了。

                $ git fetch origin master$ git merge origin FETCH_HEAD# 提示:這2句命令等價于,但是使用git fetch + git merge 更加安全。$ git pull origin master# 然后執(zhí)行,重新定基,可以使得歷史更加統(tǒng)一,即提交歷史趨向于一條直線。 $ git pull –rebase origin master

                2.丟棄之前的歷史,強(qiáng)推(謹(jǐn)慎使用)

                利用強(qiáng)覆蓋方式用你本地的代碼替代git倉庫內(nèi)的內(nèi)容,遠(yuǎn)程倉庫的東西會被本地倉庫覆蓋?。?!

                $ git push -f 或者 $ git push –force

                官方文檔提示:This flag disables these checks, and can cause the remote repository to lose commits; use it with care.(即:此標(biāo)志禁用這些檢查,并可能導(dǎo)致遠(yuǎn)程存儲庫丟失提交;小心使用。)

                不僅在此處,在平時使用時,也要非常注意,除非你真的是想覆蓋遠(yuǎn)程倉庫,不然最好不要強(qiáng)制執(zhí)行。

                13.徹底清理歷史版本

                先創(chuàng)建一個分支,添加所有文件,刪除其他所有分支。

                14.回退遠(yuǎn)程倉庫的版本

                先把遠(yuǎn)程倉庫指定分支拉下來,手動回退,然后再強(qiáng)制推送上去(拉回來的遠(yuǎn)程版本庫同時帶了這個分支的所有歷史版本);

                Gitee和Github

                1.查看fork的子倉

                • github點擊 Insights -> fork
                • gitee點擊fork邊上的數(shù)字

                2.保護(hù)分支

                • github默認(rèn)只有分支創(chuàng)建者和倉庫管理員有push的權(quán)限,其他人可以提交PR
                • gitee需要自己設(shè)置分支為保護(hù)分支,并在保護(hù)分支的設(shè)置內(nèi)設(shè)置相應(yīng)的保護(hù)級別和權(quán)限。
                • github可以邀請別人成為協(xié)作者,個人倉庫的協(xié)作者可以拉取(讀?。﹤}庫的內(nèi)容并向倉庫推送(寫入)更改。
                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年7月11日 18:47
                下一篇 2022年7月11日 21:03

                相關(guān)推薦

                • 原神3.1版本前瞻匯總,散兵的“高達(dá)”有點帥,原神動畫化確定!

                  我已經(jīng)有過一次旅行。所以,你也要像我一樣抵達(dá)終點,才能在自己的眼中,留下這個世界的沉淀。大家好,我是boyue,感謝打開這篇原神游戲文。boyue會經(jīng)常分享一些原神資訊與攻略給大家…

                  2022年11月27日
                • 短視頻策劃內(nèi)容的3個要點(短視頻策劃內(nèi)容怎么做)

                  短視頻在制作時,內(nèi)容框架非常重要。如果直奔主題,然后結(jié)束,聚卓告訴你,這樣的短視頻已經(jīng)過時了。現(xiàn)在的短視頻需要框架的,但不是任何框架,它需要一種易于理解和消化的框架。而且,現(xiàn)在大多…

                  2022年11月27日
                • cad連續(xù)標(biāo)注快捷鍵(cad連續(xù)標(biāo)注快捷鍵)

                  本文主要講的是cad連續(xù)標(biāo)注快捷鍵,以及和cad連續(xù)標(biāo)注快捷鍵相關(guān)的知識,如果覺得本文對您有所幫助,不要忘了將本文分享給朋友。 cad中連續(xù)標(biāo)注快捷鍵 CAD尺寸標(biāo)準(zhǔn)快捷命令:DL…

                  2022年11月27日
                • 妻子發(fā)微信:“我老公不在,快來”,同事:“下了班就來找你”

                  在現(xiàn)如今網(wǎng)絡(luò)如此發(fā)達(dá)的時代,大家可以從各個地方了解到全國大事小事,正所謂世界之大無奇不有,每天都發(fā)生著奇奇怪怪的事情,今天小編突然看到這樣一件事,看完之后都不知道說什么好了。 王某…

                  2022年11月26日
                • 京東快遞跨省幾天能到(京東一般多久到貨)

                  由于覺得京東平臺的物流效勞十分的不錯,而且商品的質(zhì)量都比擬有保證。在京東平臺購物的話,普通多久時間會到貨?下面的內(nèi)容停止引見。 京東普通多久到貨? 詳細(xì)要看發(fā)貨地址和你所在的地址的…

                  2022年11月26日
                • 抖音帶貨怎么做入門(抖音帶貨怎么做入門教學(xué))

                  相信很多小伙伴都有注意到,現(xiàn)在抖音已經(jīng)成為大家最常光顧的一個平臺了,作為一個日活破億的流量池,如今抖音上的用戶數(shù)量極大。因此,現(xiàn)在在抖音上帶貨、賣貨的人也是越來越多了,那么想在抖音…

                  2022年11月25日
                • 《云頂之弈》s8什么時候上線國服?s8國服上線時間介紹

                  云頂之弈的s8版本為怪物來襲版本,現(xiàn)已正式在美測服上線了。很多小伙伴可能還不清楚該版本什么時候在國服上線吧,今天小編給大家?guī)碓祈斨膕8國服上線時間介紹,快來看一下吧。 s8國服…

                  2022年11月25日
                • 《寶可夢朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

                  寶可夢朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

                  2022年11月25日
                • 《樂隊的海邊》第二場live秀開啟 趙夢為鄭秀妍寫中文歌詞

                  今日(11月25日),芒果TV女性經(jīng)營勵志奮斗真人秀《樂隊的海邊》第二期即將上線。張儷、趙夢、鄭秀妍、于文文、劉戀、張?zhí)鞇墼诤D鲜…偤J薪?jīng)營的“炸廚”音樂餐廳蒸蒸日上,收獲顧客滿滿…

                  2022年11月25日
                • 地靈絕魂劍(地靈絕魂劍像素)

                  今天小編給各位分享地靈絕魂劍的知識,其中也會對地靈絕魂劍像素進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! dnf地靈絕魂劍怎么計算 地靈絕魂劍的附加攻擊是…

                  2022年11月25日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息