三年 Git 使用心得 & 常見問題整理

作者丨秋天不落葉

https://juejin。im/post/5ee649。。。

Git 流程圖

三年 Git 使用心得 & 常見問題整理

Workspace:工作區

Index / Stage:暫存區

Repository:倉庫區(或本地倉庫)

Remote:遠端倉庫

配置 Git

# 配置全域性使用者$ git config ——global user。name “使用者名稱”$ git config ——global user。email “git賬號”# 配置別名$ git config ——global alias。co checkout$ git config ——global alias。ss status$ git config ——global alias。cm commit$ git config ——global alias。br branch$ git config ——global alias。rg reflog# 這裡只是美化 log 的輸出,實際使用時可以在 git lg 後面加命令引數,如:git lg -10 顯示最近10條提交$ git config ——global alias。lg “log ——color ——graph ——pretty=format:‘%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset’ ——abbrev-commit”# 刪除全域性配置$ git config ——global ——unset alias。xxx$ git config ——global ——unset user。xxx

檢視 Git 資訊

# 檢視系統配置$ git config ——list# 檢視使用者配置$ cat ~/。gitconfig# 檢視當前專案的 git 配置$ cat 。git/config# 檢視暫存區的檔案$ git ls-files# 檢視本地 git 命令歷史$ git reflog# 檢視所有 git 命令$ git ——help -a# 檢視當前 HEAD 指向$ cat 。git/HEAD# git 中 D 向下翻一行 F 向下翻頁 B 向上翻頁 Q 退出# 檢視提交歷史$ git log ——oneline ——grep=“關鍵字” ——graph ——all ——author “username” ——reverse -num -p ——before= 1 day/1 week/1 “2019-06-06” ——after= “2019-06-06” ——stat ——abbrev-commit ——pretty=format:“xxx” # oneline -> 將日誌記錄一行一行的顯示# grep=“關鍵字” -> 查詢日誌記錄中(commit提交時的註釋)與關鍵字有關的記錄# graph -> 記錄圖形化顯示 !!!# all -> 將所有記錄都詳細的顯示出來# author “username” -> 查詢這個作者提交的記錄# reverse -> commit 提交記錄順序翻轉# before -> 查詢規定的時間(如:1天/1周)之前的記錄# num -> git log -10 顯示最近10次提交 !!!# stat -> 顯示每次更新的檔案修改統計資訊,會列出具體檔案列表 !!!# abbrev-commit -> 僅顯示 SHA-1 的前幾個字元,而非所有的 40 個字元 !!!# pretty=format:“xxx” -> 可以定製要顯示的記錄格式 !!!# p -> 顯示每次提交所引入的差異(按 補丁 的格式輸出)!!!

git reflog

「顯示的是一個 HEAD 指向發生改變的時間列表」

。在你切換分支、用 git commit 進行提交、以及用 git reset 撤銷 commit 時,HEAD 指向會改變,但當你進行 git checkout —— 撤銷或者 git stash 儲存檔案等操作時,HEAD 並不會改變,這些修改從來沒有被提交過,因此 reflog 也無法幫助我們恢復它們。

git reflog 不會永遠保持,Git 會定期清理那些 “用不到的” 物件,不要指望幾個月前的提交還一直在那裡。

git log 點線圖

「git 中一條分支就是一個指標,新建一條分支就是基於當前指標新建一個指標」

「切換至某個分支 ,就是將 HEAD 指向某條分支(指標)」

「切換至某個 commit ,就是將 HEAD 指向某個 commit」

符號解釋:

*表示一個 commit|表示分支前進/表示分叉\表示合入|/表示新分支

Git 常用命令

# 檢視工作區和暫存區的狀態$ git status# 將工作區的檔案提交到暫存區$ git add 。# 提交到本地倉庫$ git commit -m “本次提交說明”# add和commit的合併,便捷寫法(未追蹤的檔案無法直接提交到暫存區/本地倉庫)$ git commit -am “本次提交說明”# 將本地分支和遠端分支進行關聯$ git push -u origin branchName# 將本地倉庫的檔案推送到遠端分支$ git push# 拉取遠端分支的程式碼$ git pull origin branchName# 合併分支$ git merge branchName# 檢視本地擁有哪些分支$ git branch# 檢視所有分支(包括遠端分支和本地分支)$ git branch -a# 切換分支$ git checkout branchName# 臨時將工作區檔案的修改儲存至堆疊中$ git stash# 將之前儲存至堆疊中的檔案取出來$ git stash pop

Git 常用命令詳解

add

將工作區的檔案新增到暫存區

# 新增指定檔案到暫存區(追蹤新增的指定檔案)$ git add [file1] [file2] 。。。# 新增指定目錄到暫存區,包括子目錄$ git add [dir]# 添加當前目錄的所有檔案到暫存區(追蹤所有新增的檔案)$ git add 。# 刪除工作區/暫存區的檔案$ git rm [file1] [file2] 。。。# 停止追蹤指定檔案,但該檔案會保留在工作區$ git rm ——cached [file]# 改名工作區/暫存區的檔案$ git mv [file-original] [file-renamed]# Git 2。0 以下版本#只作用於檔案的新增和修改$ git add 。#只作用於檔案的修改和刪除$ gti add -u#作用於檔案的增刪改$ git add -A# Git 2。0 版本$ git add 。 等價於 $ git add -A

「git add .」

「操作的物件是“當前目錄”所有檔案變更」

,“。” 表示當前目錄。會監控工作區的狀態樹,使用它會把工作區的

「所有變化提交」

到暫存區,包括檔案內容修改(modified)以及新檔案(new),但

「不包括被刪除的檔案」

「git add -u」

「操作的物件是整個工作區已經跟蹤的檔案變更,無論當前位於哪個目錄下」

。僅監控

「已經被 add 的檔案」

(即

「tracked file」

),它會將被修改的檔案(包括檔案刪除)提交到暫存區。git add -u 不會提交新檔案(

「untracked file」

)。(

「git add --update」

的縮寫)

「git add -A」

「操作的物件是“整個工作區”所有檔案的變更,無論當前位於哪個目錄下」

。是上面兩個功能的合集(git add ——all 的縮寫)。

status

# 檢視工作區和暫存區的狀態$ git status

commit

# 將暫存區的檔案提交到本地倉庫並新增提交說明$ git commit -m “本次提交的說明”# add 和 commit 的合併,便捷寫法# 和 git add -u 命令一樣,未跟蹤的檔案是無法提交上去的$ git commit -am “本次提交的說明”# 跳過驗證繼續提交$ git commit ——no-verify$ git commit -n# 編輯器會彈出上一次提交的資訊,可以在這裡修改提交資訊$ git commit ——amend# 修復提交,同時修改提交資訊$ git commit ——amend -m “本次提交的說明”# 加入 ——no-edit 標記會修復提交但不修改提交資訊,編輯器不會彈出上一次提交的資訊$ git commit ——amend ——no-edit

git commit ——amend 既可以修改上次提交的檔案內容,也可以修改上次提交的說明。會用一個新的 commit 更新並替換最近一次提交的 commit 。如果暫存區有內容,這個新的 commit 會把任何修改內容和上一個 commit 的內容結合起來。如果暫存區沒有內容,那麼這個操作就只會把上次的 commit 訊息重寫一遍。

「永遠不要修復一個已經推送到公共倉庫中的提交,會拒絕推送到倉庫」

push & pull

分支推送順序的寫法是

「<來源地>:<目的地>」

# 將本地倉庫的檔案推送到遠端分支# 如果遠端倉庫沒有這個分支,會新建一個同名的遠端分支# 如果省略遠端分支名,則表示兩者同名$ git push <遠端主機名> <本地分支名>:<遠端分支名>$ git push origin branchname# 如果省略本地分支名,則表示刪除指定的遠端分支# 因為這等同於推送一個空的本地分支到遠端分支。$ git push origin :master# 等同於$ git push origin ——delete master# 建立當前分支和遠端分支的追蹤關係$ git push -u origin master# 如果當前分支與遠端分支之間存在追蹤關係# 則可以省略分支和 -u$ git push# 不管是否存在對應的遠端分支,將本地的所有分支都推送到遠端主機$ git push ——all origin# 拉取所有遠端分支到本地映象倉庫中$ git pull# 拉取併合並專案其他人員的一個分支$ git pull origin branchname# 等同於 fetch + merge$ git fetch origin branchName$ git merge origin/branchName# 如果遠端主機的版本比本地版本更新,推送時 Git 會報錯,要求先在本地做 git pull 合併差異,# 然後再推送到遠端主機。這時,如果你一定要推送,可以使用 –-force 選項# (儘量避免使用)$ git push ——force origin | git push -f origin

branch

# 檢視本地分支$ git branch | git branch -l# 檢視遠端分支$ git branch -r# 檢視所有分支(本地分支+遠端分支)$ git branch -a# 檢視所有分支並帶上最新的提交資訊$ git branch -av# 檢視本地分支對應的遠端分支$ git branch -vv# 新建分支# 在別的分支下新建一個分支,新分支會複製當前分支的內容# 注意:如果當前分支有修改,但是沒有提交到倉庫,此時修改的內容是不會被複制到新分支的$ git branch branchname# 切換分支(切換分支時,本地工作區,倉庫都會相應切換到對應分支的內容)$ git checkout branchname# 建立一個 aaa 分支,並切換到該分支 (新建分支和切換分支的簡寫)$ git checkout -b aaa# 可以看做是基於 master 分支建立一個 aaa 分支,並切換到該分支$ git checkout -b aaa master# 新建一條空分支(詳情請看問題列表)$ git checkout ——orphan emptyBranchName$ git rm -rf 。# 刪除本地分支,會阻止刪除包含未合併更改的分支$ git brnach -d branchname# 強制刪除一個本地分支,即使包含未合併更改的分支$ git branch -D branchname# 刪除遠端分支# 推送一個空分支到遠端分支,其實就相當於刪除遠端分支$ git push origin :遠端分支名# 或者$ git push origin ——delete 遠端分支名# 修改當前分支名$ git branch -m branchname

merge 三種常用合併方法

# 預設 fast-forward ,HEAD 指標直接指向被合併的分支$ git merge# 禁止快進式合併$ git merge ——no-ff$ git merge ——squash

三年 Git 使用心得 & 常見問題整理

fast-forward:會在當前分支的提交歷史中新增進被合併分支的提交歷史(

「得先理解什麼時候會發生快速合併,並不是每次 merge 都會發生快速合併」

);

——no-ff:

「會生成一個新的提交」

,讓當前分支的提交歷史不會那麼亂;

——squash:

「不會生成新的提交」

,會將被合併分支多次提交的內容直接存到工作區和暫存區,由開發者手動去提交,這樣當前分支最終只會多出一條提交記錄,不會摻雜被合併分支的提交歷史

stash

能夠將所有未提交的修改儲存至堆疊中,用於後續恢復當前工作區內容

如果檔案沒有提交到

「暫存區(使用 git add . 追蹤新的檔案)」

,使用該命令會提示 No local changes to save ,無法將修改儲存到堆疊中

「使用場景:」

當你接到一個修復緊急 bug 的任務時候,一般都是先建立一個新的 bug 分支來修復它,然後合併,最後刪除。但是,如果當前你正在開發功能中,短時間還無法完成,無法直接提交到倉庫,這時候可以先把當前工作區的內容 git stash 一下,然後去修復 bug,修復後,再 git stash pop,恢復之前的工作內容。

# 將所有未提交的修改(提交到暫存區)儲存至堆疊中$ git stash# 給本次儲存加個備註,以防時間久了忘了$ git stash save “儲存”# 儲存未追蹤的檔案$ git stash -u# 檢視儲存記錄$ git stash list在 Windows 上和 PowerShell 中,需要加雙引號# 恢復後,stash 記錄並不刪除$ git stash apply “stash@{index}”# 恢復的同時把 stash 記錄也刪了$ git stash pop “stash@{index}”# 刪除 stash 記錄$ git stash drop “stash@{index}”# 刪除所有儲存的進度$ git stash clear# 檢視當前記錄中修改了哪些檔案$ git stash show “stash@{index}”# 檢視當前記錄中修改了哪些檔案的內容$ git stash show -p “stash@{index}”

diff

# 檢視工作區和暫存區單個檔案的對比$ git diff filename# 檢視工作區和暫存區所有檔案的對比$ git diff# 檢視工作區和暫存區所有檔案的對比,並顯示出所有有差異的檔案列表$ git diff ——stat# 注意:# 1。你修改了某個檔案,但是沒有提交到暫存區,這時候會有對比的內容# 一旦提交到暫存區,就不會有對比的內容(因為暫存區已經更新)# 2。如果你新建了一個檔案,但是沒有提交到暫存區,這時候 diff 是沒有結果的# 檢視暫存區與上次提交到本地倉庫的快照(即最新提交到本地倉庫的快照)的對比$ git diff ——cached/——staged# 檢視工作區與上次提交到本地倉庫的快照(即最新提交到本地倉庫的快照)的對比$ git diff branchname# 檢視工作區與 HEAD 指向(預設當前分支最新的提交)的對比$ git diff HEAD# 檢視兩個本地分支中某一個檔案的對比$ git diff branchname。。branchname filename# 檢視兩個本地分支所有的對比$ git diff branchname。。branchname# 檢視遠端分支和本地分支的對比$ git diff origin/branchname。。branchname# 檢視遠端分支和遠端分支的對比$ git diff origin/branchname。。origin/branchname# 檢視兩個 commit 的對比$ git diff commit1。。commit2

remote

# 檢視所有遠端主機$ git remote# 檢視關聯的遠端倉庫的詳細資訊$ git remote -v# 刪除遠端倉庫的 “關聯”$ git remote rm projectname# 設定遠端倉庫的 “關聯”$ git remote set-url origin

tag

常用於釋出版本

# 預設在 HEAD 上建立一個標籤$ git tag v1。0# 指定一個 commit id 建立一個標籤$ git tag v0。9 f52c633# 建立帶有說明的標籤,用 -a 指定標籤名,-m 指定說明文字$ git tag -a v0。1 -m “version 0。1 released”# 檢視所有標籤# 注意:標籤不是按時間順序列出,而是按字母排序的。$ git tag# 檢視單個標籤具體資訊$ git show # 推送一個本地標籤$ git push origin # 推送全部未推送過的本地標籤$ git push origin ——tags# 刪除本地標籤# 因為建立的標籤都只儲存在本地,不會自動推送到遠端。# 所以,打錯的標籤可以在本地安全刪除。$ git tag -d v0。1# 刪除一個遠端標籤(先刪除本地 tag ,然後再刪除遠端 tag)$ git push origin :refs/tags/

刪除檔案

# 刪除暫存區和工作區的檔案$ git rm filename# 只刪除暫存區的檔案,不會刪除工作區的檔案$ git rm ——cached filename

如果在配置 。gitignore 檔案之前就把某個檔案上傳到遠端倉庫了,這時候想把遠端倉庫中的該檔案刪除,此時你配置 。gitignore 檔案也沒有用,因為該檔案已經被追蹤了,但又不想在本地刪除該檔案後再重新提交到遠端倉庫,這時候可以使用 git rm ——cached filename 命令取消該檔案的追蹤,這樣下次提交的時候,git 就不會再提交這個檔案,從而遠端倉庫的該檔案也會被刪除

版本切換 & 重設 & 撤銷

「checkout 可以撤銷工作區的檔案,reset 可以撤銷工作區/暫存區的檔案」

「reset 和 checkout 可以作用於 commit 或者檔案,revert 只能作用於 commit」

checkout 詳解

# 恢復暫存區的指定檔案到工作區$ git checkout # 恢復暫存區的所有檔案到工作區$ git checkout 。# 回滾到最近的一次提交# 如果修改某些檔案後,沒有提交到暫存區,此時的回滾是回滾到上一次提交# 如果是已經將修改的檔案提交到倉庫了,這時再用這個命令回滾無效# 因為回滾到的是之前自己修改後提交的版本$ git checkout HEAD$ git checkout HEAD —— filename# 回滾到最近一次提交的上一個版本$ git checkout HEAD^# 回滾到最近一次提交的上2個版本$ git checkout HEAD^^# 切換分支,在這裡也可以看做是回到專案「當前」狀態的方式$ git checkout <當前你正在使用的分支># 切換到某個指定的 commit 版本$ git checkout # 切換指定 tag$ git checkout

「在開發的正常階段,HEAD 一般指向 master 或是其他的本地分支,但當你使用 git checkout <commit id> 切換到指定的某一次提交的時候,HEAD 就不再指向一個分支了——它直接指向一個提交,HEAD 就會處於 detached 狀態(遊離狀態)」

切換到某一次提交後,你可以檢視檔案,編譯專案,執行測試,甚至編輯檔案而不需要考慮是否會影響專案的當前狀態,你所做的一切都不會被儲存到主棧的倉庫中。當你想要回到主線繼續開發時,使用 git checkout branchName 回到專案初始的狀態(

「這時候會提示你是否需要新建一條分支用於保留剛才的修改」

)。

「哪怕你切換到了某一版本的提交,並且對它做了修改後,不小心提交到了暫存區,只要你切換回分支的時候,依然會回到專案的初始狀態。(***注意:你所做的修改,如果 commit 了,會被儲存到那個版本中。切換完分支後,會提示你是否要新建一個分支來儲存剛才修改的內容。如果你剛才解決了一個 bug ,這時候可以新建一個臨時分支,然後你本地自己的開發主分支去合併它,合併完後刪除臨時分支***)。」

「一般我都是用 checkout 回退版本,檢視歷史程式碼,測試 bug 在哪」

三年 Git 使用心得 & 常見問題整理

三年 Git 使用心得 & 常見問題整理

三年 Git 使用心得 & 常見問題整理

reset 詳解

git reset [——hard|soft|mixed|merge|keep] [或HEAD]:將當前的分支重設(reset)到指定的 或者 HEAD (預設,如果不顯示指定 ,預設是 HEAD ,即最新的一次提交),並且根據 [mode] 有可能更新索引和工作目錄。mode 的取值可以是 hard、soft、mixed、merged、keep 。

# 從暫存區撤銷特定檔案,但不改變工作區。它會取消這個檔案的暫存,而不覆蓋任何更改$ git reset # 重置暫存區最近的一次提交,但工作區的檔案不變$ git reset# 等價於$ git reset HEAD (預設)# 重置暫存區與工作區,回退到最近一次提交的版本內容$ git reset ——hard# 重置暫存區與工作區,回退到最近一次提交的上一個版本$ git reset ——hard HEAD^# 將當前分支的指標指向為指定 commit(該提交之後的提交都會被移除),同時重置暫存區,但工作區不變$ git reset # 等價於$ git reset ——mixed # 將當前分支的指標指向為指定 commit(該提交之後的提交都會被移除),但保持暫存區和工作區不變$ git reset ——soft # 將當前分支的指標指向為指定 commit(該提交之後的提交都會被移除),同時重置暫存區、工作區$ git reset ——hard

git reset 有很多種用法。它可以被用來移除提交快照,儘管它通常被用來撤銷暫存區和工作區的修改。不管是哪種情況,它應該只被用於本地修改——你永遠不應該重設和其他開發者共享的快照。

「當你用 reset 回滾到了某個版本後,那麼在下一次 git 提交時,之前該版本後面的版本會被作為垃圾刪掉。」

「當我們回退到一箇舊版本後,此時再用 git log 檢視提交記錄,會發現之前的新版本記錄沒有了。如果第二天,你又想恢復到新版本怎麼辦?找不到新版本的 commit_id 怎麼辦?」

「我們可以用 git reflog 檢視歷史命令,這樣就可以看到之前新版本的 commit_id ,然後 git reset --hard commit_id 就可以回到之前的新版本程式碼」

雖然可以用 git reflog 檢視本地歷史,然後回覆到之前的新版本程式碼,但是在別的電腦上是無法獲取你的歷史命令的,所以這種方法不安全。萬一你的電腦突然壞了,這時候就無法回到未來的版本。

revert 詳解

# 生成一個撤銷最近的一次提交的新提交$ git revert HEAD# 生成一個撤銷最近一次提交的上一次提交的新提交$ git revert HEAD^# 生成一個撤銷最近一次提交的上兩次提交的新提交$ git revert HEAD^^# 生成一個撤銷最近一次提交的上n次提交的新提交$ git revert HEAD~num# 生成一個撤銷指定提交版本的新提交$ git revert # 生成一個撤銷指定提交版本的新提交,執行時不開啟預設編輯器,直接使用 Git 自動生成的提交資訊$ git revert ——no-edit

git revert命令用來

「撤銷某個已經提交的快照(和 reset 重置到某個指定版本不一樣)」

。它是在提交記錄最後面加上一個撤銷了更改的新提交,而不是從專案歷史中移除這個提交,這避免了 Git 丟失專案歷史。

「撤銷(revert)應該用在你想要在專案歷史中移除某個提交的時候」

。比如說,你在追蹤一個 bug,然後你發現它是由一個提交造成的,這時候撤銷就很有用。

「撤銷(revert)被設計為撤銷公共提交的安全方式,重設(reset)被設計為重設本地更改。」

因為兩個命令的目的不同,它們的實現也不一樣:重設完全地移除了一堆更改,而撤銷保留了原來的更改,用一個新的提交來實現撤銷。

「千萬不要用 git reset 回退已經被推送到公共倉庫上的 提交,它只適用於回退本地修改(從未提交到公共倉庫中)。如果你需要修復一個公共提交,最好使用 git revert」

釋出一個提交之後,你必須假設其他開發者會依賴於它。移除一個其他團隊成員在上面繼續開發的提交在協作時會引發嚴重的問題。當他們試著和你的倉庫同步時,他們會發現專案歷史的一部分突然消失了。一旦你在重設之後又增加了新的提交,Git 會認為你的本地歷史已經和 origin/master 分叉了,同步你的倉庫時的合併提交(merge commit)會使你的同事困惑。

cherry-pick

「將指定的提交 commit 應用於當前分支」

(可以用於恢復不小心撤銷(revert/reset)的提交)

$ git cherry-pick $ git cherry-pick $ git cherry-pick ^。。

git submodule 子模組

有種情況我們經常會遇到:某個工作中的專案需要包含並使用另一個專案。也許是第三方庫,或者你獨立開發的,用於多個父專案的庫。現在問題來了:你想要把它們當做兩個獨立的專案,同時又想在一個專案中使用另一個。如果將另外一個專案中的程式碼複製到自己的專案中,那麼你做的任何自定義修改都會使合併上游的改動變得困難。

「Git 透過子模組來解決這個問題,允許你將一個 Git 倉庫作為另一個 Git 倉庫的子目錄。它能讓你將另一個倉庫克隆到自己的專案中,同時還保持提交的獨立。」

# 在主專案中新增子專案,URL 為子模組的路徑,path 為該子模組儲存的目錄路徑git submodule add [URL] [Path]# 克隆含有子專案的主專案git clone [URL]# 當你在克隆這樣的專案時,預設會包含該子專案的目錄,但該目錄中還沒有任何檔案# 初始化本地配置檔案git submodule init# 從當前專案中抓取所有資料並檢出父專案中列出的合適的提交git submodule update# 等價於 git submodule init && git submodule updategit submodule update ——init# 自動初始化並更新倉庫中的每一個子模組, 包括可能存在的巢狀子模組git clone ——recurse-submodules [URL]

新建一個 Git 專案的兩種方式

1。本地新建好 Git 專案,然後關聯遠端倉庫

# 初始化一個Git倉庫$ git init# 關聯遠端倉庫$ git remote add # 例如$ git remote add origin https://github。com/xxxxxx

2。clone 遠端倉庫

# 新建好遠端倉庫,然後 clone 到本地$ git clone # 將遠端倉庫下載到(當前 git bash 啟動位置下面的)指定檔案中,如果沒有會自動生成$ git clone

Git 分支管理規範

實際開發的時候,一人一條分支(個人見解:除非是大專案,參與的開發人員很多時,可以採用 feature 分支,否則一般的專案中,一個開發者一條分支夠用了)。除此之外還要有一條 develop 開發分支,一條 test 測試分支,一條 release 預釋出分支。

「develop」

「開發分支」

,開發人員每天都需要拉取/提交最新程式碼的分支;

「test」

「測試分支」

,開發人員開發完並自測通過後,釋出到測試環境的分支;

「release」

「預釋出分支」

,測試環境測試通過後,將測試分支的程式碼釋出到預發環境的分支(

「這個得看公司支不支援預發環境,沒有的話就可以不採用這條分支」

);

「master」

「線上分支」

,預發環境測試通過後,運營/測試會將此分支程式碼釋出到線上環境;

大致流程:

開發人員每天都需要拉取/提交最新的程式碼到

「develop 分支」

開發人員開發完畢,開始

「整合測試」

,測試無誤後提交到

「test 分支」

併發布到測試環境,交由測試人員測試;

測試環境通過後,釋出到

「release 分支」

上,進行預發環境測試;

預發環境通過後,釋出到

「master 分支」

上並打上標籤(tag);

如果線上分支出了 bug ,這時候相關開發者應該基於預釋出分支(

「沒有預發環境,就使用 master 分支」

),新建一個

「bug 分支」

用來臨時解決 bug ,處理完後申請合併到 預釋出 分支。這樣做的好處就是:不會影響正在開發中的功能。

「預釋出環境的作用:」

預釋出環境是正式釋出前最後一次測試。因為在少數情況下即使預釋出通過了,都不能保證正式生產環境可以100%不出問題;預釋出環境的配置,資料庫等都是跟線上一樣;有些公司的預釋出環境資料庫是連線線上環境,有些公司預釋出環境是單獨的資料庫;如果不設預釋出環境,如果開發合併程式碼有問題,會直接將問題釋出到線上,增加維護的成本。

Git 鉤子

Git 基本已經成為專案開發中預設的版本管理軟體,在使用 Git 的專案中,我們可以為專案設定 Git Hooks 來幫我們在提交程式碼的各個階段做一些程式碼檢查等工作

鉤子(Hooks) 都被儲存在 Git 目錄下的 hooks 子目錄中。也就是絕大部分專案中的 。git/hook 目錄

鉤子分為兩大類,客戶端的和伺服器端的

客戶端鉤子主要被提交和合並這樣的操作所呼叫

而伺服器端鉤子作用於接收被推送的提交這樣的聯網操作,這裡主要介紹客戶端鉤子

4。1 pre-commit

pre-commit 就是在程式碼提交之前做些東西,比如程式碼打包,程式碼檢測,稱之為鉤子(hook)

在 commit 之前執行一個函式(callback)。這個函式成功執行完之後,再繼續 commit,但是失敗之後就阻止 commit

在 。git->hooks->下面有個 pre-commit。sample* ,這個裡面就是預設的函式(指令碼)樣本

4。2 安裝 pre-commit

npm install pre-commit ——save-dev

4。3 配置指令碼

「如果沒有在 .git->hooks 目錄下生成 pre-commit 檔案的話,則要手工建立 node ./node_modules/pre-commit/install.js」

“scripts”: { “build”: “tsc”, “eslint”: “eslint src ——ext 。ts”, “eslint:fix”: “eslint src ——ext 。ts ——fix” }, //在提交程式碼之前,先執行 scripts 中的 eslint 命令 “pre-commit”: [ “eslint” ]

4。4 跳過 pre-commit 繼續提交程式碼

# 跳過驗證$ git commit ——no-verify$ git commit -n

更多鉤子:git-scm。com/book/zh/v2/…

常見問題

1、拉取別人的遠端分支合併後,git 會存取這個拉取的記錄,如果你不小心刪了別人的上傳的檔案,這時候想要再拉取別人的分支是沒用的,會顯示 already-up

這時候可以回滾程式碼,重新拉取。

2、以前有過這樣的經歷:前後端、客戶端的程式碼都存放在一個 git 倉庫中,在根目錄下各自新建專案目錄。那麼可以直接在自己的專案目錄下使用 git 提交程式碼並且在各自的專案目錄下配置 。gitignore 檔案,不用在根目錄下配置 。gitignore 檔案,這樣就互不影響了。

3、fatal:refusing to merge unrelated histories 拒絕合併不相關的歷史

在 git 2。9。2 之後,不可以合併沒有相同結點的分支(分支之間自倉庫建立後,從來沒有過互相拉取合併)。如果需要合併兩個不同結點的分支,如下:

$ git pull origin branchName ——allow-unrelated-histories$ git merge branchName ——allow-unrelated-histories

這個功能是可以讓大家不要把倉庫上傳錯了,如果會加上這個程式碼,那麼就是自己確定了上傳。舊版本的 Git 很容易就把程式碼傳錯了,現在可以看到,如果上傳的不是之前的,那麼就需要加程式碼上傳。正常情況下,都是先建立倉庫,然後切多個分支,分支先去拉取合併主分支的內容,然後再各自開發, 如果建立倉庫後,各個分支沒有區拉取主分支的程式碼,之後各個分支之間想要合併時就會報錯。

4、合併分支時出現問題,想要解除合併狀態

error: merge is not possible because you have unmerged files。hint: Fix them up in the work tree, and then use ‘git add/rm ’hint: as appropriate to mark resolution and make a commit。fatal: Exiting because of an unresolved conflict。

當遠端分支和本地分支發生衝突後,git 保持合併狀態,你如果沒有去解決完所有的衝突,那麼 git 會一直保持這個狀態,你就無法再提交程式碼。只有先解除合併狀態後,才能繼續提交。執行命令前最好先備份一下,有可能本地做的修改會被遠端分支覆蓋掉。

# 解除合併狀態$ git merge ——abort

5、不小心把某些檔案上傳到遠端 git 倉庫/想要刪除遠端倉庫中的檔案

# 刪除暫存區和工作區的檔案$ git rm filename# 只刪除暫存區的檔案,不會刪除工作區的檔案$ git rm ——cached filename

如果在配置 。gitignore 檔案之前就把某個檔案上傳到遠端倉庫了,這時候想把遠端倉庫中的該檔案刪除,此時你配置 。gitignore 檔案也沒有用,因為該檔案已經被追蹤了,但又不想在本地刪除該檔案後再重新提交到遠端倉庫,這時候可以使用 git rm ——cached filename 命令取消該檔案的追蹤,這樣下次提交的時候,git 就不會再提交這個檔案,從而遠端倉庫的該檔案也會被刪除

6、將本地新建的專案上傳到新建的遠端倉庫上

之前沒有進行過關聯,即沒有透過 clone 遠端專案到本地再開始做專案,而是先本地新建了一個專案,然後想傳到遠端倉庫上。

# 將本地倉庫和遠端倉庫關聯起來$ git remote add origin 遠端倉庫地址# 將本地的 master 分支推送到 origin 主機,同時指定 origin 為預設主機$ git push -u origin master# 上面的命名執行後,下次再從本地庫上傳內容的時候只需下面這樣就可以了$ git push

7、每次 git push 都要輸入使用者名稱、密碼

step 1:生成公鑰

ssh-keygen -t rsa -C “xxxxx@xxxxx。com”# Generating public/private rsa key pair。。。# 三次回車即可生成 ssh key

step 2:檢視已生成的公鑰

cat ~/。ssh/id_rsa。pub

step3:複製已生成的公鑰新增到 git 伺服器

三年 Git 使用心得 & 常見問題整理

測試 ssh 是否能夠連線成功

$ ssh -T git@github。com

step4:使用 ssh 協議 clone 遠端倉庫 或者 如果已經用 https 協議 clone 到本地了,那麼就重新設定遠端倉庫

三年 Git 使用心得 & 常見問題整理

「使用 ssh 協議」

$ git remote set-url origin git@xxx。com:xxx/xxx。git

step5:建立檔案儲存使用者名稱和密碼

一般為 C:\users\Administrator,也可以是你自己建立的系統使用者名稱目錄,檔名為 。git-credentials。由於在 Windows 中不允許直接建立以 “。” 開頭的檔案,所以用命令列建立該檔案。

$ touch 。git-credentials$ echo “http://{username}:{password}@github。com” >> ~/。git-credentials$ git config ——global credential。helper store

8、git 不允許提交空資料夾

可以在當前目錄下,新增一個 。gitkeep 檔案

9、Another git process seems to be running in this repository, e。g。

三年 Git 使用心得 & 常見問題整理

原因在於 Git 在使用過程中遭遇了奔潰,部分被上鎖資源沒有被釋放導致的。

「解決方案:」

進入專案資料夾下的 。git 檔案中(顯示隱藏資料夾或 rm 。git/index。lock)刪除 index。lock 檔案即可。

10、git commit -am “xxx” 有時候會失效,無法提交所有的修改

git commit -am “xxx” 只會將被

「tracked」

的檔案新增到暫存區並提交,而將檔案新增到 git 管理是要使用 git add 命令,將新的檔案

「tracked」

。(新建了檔案之後,idea 會提示你是否需要加到 git 管理中。選擇記住後,之後 idea 預設都會把新建的檔案

「tracked」

化)

11、git merge ——no-ff 的作用

「禁止快進式(fast-forward)合併,會生成一個新的提交」

三年 Git 使用心得 & 常見問題整理

從合併後的程式碼來看,結果都是一樣的,區別就在於 ——no-ff 會讓 git 生成一個新的提交物件。為什麼要這樣?通常我們把 master 作為主分支,上面存放的都是比較穩定的程式碼,提交頻率也很低,而 feature 是用來開發特性的,上面會存在許多零碎的提交,快進式合併會把 feature 的提交歷史混入到 master 中,攪亂 master 的提交歷史。所以如果你根本不在意提交歷史,也不愛管 master 乾不乾淨,那麼 ——no-ff 其實沒什麼用。

12、git log 無法正常顯示中文

# 試試$ git -c core。pager=more log# 如果可以顯示中文的話,把 pager 設定為 more$ git config ——global core。pager more

13、git merge -m “xxx” 的時候可以附加資訊

預設是 Merge branch branchName

三年 Git 使用心得 & 常見問題整理

14、git pull 會拉取所有遠端分支的程式碼到本地映象倉庫中

想要 merge 別人的分支時:

如果你的本地倉庫中已經有了他人的分支(直接切換到他人分支,就會在本地生成一條他人的分支),就可以使用 merge branchname;

如果你的本地倉庫沒有他人的分支,那麼就得使用 merge origin/branchname 來合併

三年 Git 使用心得 & 常見問題整理

15、git stash 儲存未追蹤的檔案

如果我們新建了檔案,但是沒有用 git add 。 追蹤檔案,那麼 git stash 是無法儲存的

$ git stash -u

16、git push 無法提交程式碼

「可能出現的報錯:」

「remote:」

Permission to xxxxx。git denied to xxx。 fatal: unable to access ‘github。com/ xxxxx。git/’: The requested URL returned error: 403

「remote:」

You do not have permission to push to the repository via HTTPS

「fatal:」

Authentication failed for ‘gitee。com/xxx。git/’

# 檢視當前專案的 git 配置$ cat 。git/config

檢視本地專案的 。git/config 設定的倉庫 url 地址和 github 使用的連結地址是否一致。git push 的資料協議有兩種方式:ssh 和 https。如果不一致就需要切換 url 地址。

三年 Git 使用心得 & 常見問題整理

17、git 輸錯使用者名稱和密碼,後續的 git 操作一直報錯

remote: Coding 提示: Authentication failed。remote: 認證失敗,請確認您輸入了正確的賬號密碼。fatal: Authentication failed for ‘https://e。coding。net/xxx。git/’

在控制面板裡找到憑據管理器,選中 Windows 憑據,找到 git 的憑據,點選編輯,輸入所用 github 的正確使用者名稱和密碼。

18、lint-staged 失敗

三年 Git 使用心得 & 常見問題整理

可能你的專案名路徑中包含了中文名,需要替換成英文名

19、檢視 git 安裝目錄

「Mac:」

在命令列中輸入 which git,就會顯示 git 的安裝位置了

「Windows:」

開啟cmd,輸入 where git,就會顯示 git 的安裝路徑了

20、如何修改舊的 commit 的 message/如何將多個 commit 合成一個 commit/如何將多個間隔的 commit 合成一個 commit/

git rebase -i

21、如果兩個人都對某個檔案進行了修改,一個是重新命名檔案,一個是修改檔案內容,那麼會起衝突嗎?git 很智慧,會自動合併這些修改

如果兩個人都對同一個檔案重新命名,此時會起衝突,git 不會自動處理,需要開發者自身去解決衝突

22、git revert 失敗:error: Commit faulty merge is a merge but no -m option was given、error: option `mainline‘ expects a number greater than zero

git revert -m 1

23、git 建立一個空的分支

在 Git 中建立分支,是必須有一個父節點的,也就是說必須在已有的分支上來建立新的分支,如果工程已經進行了一段時間,這個時候是無法建立空分支的。但是有時候就是需要建立一個空白的分支。

$ git checkout ——orphan emptyBranchName

該命令會生成一個叫 emptybranch 的分支,該分支會包含父分支的所有檔案。但新的分支不會指向任何以前的提交,就是它沒有歷史,如果你提交當前內容,那麼這次提交就是這個分支的首次提交。

想要空分支,所以需要把當前內容全部刪除,用 git 命令

$ git rm -rf 。 // 注意:最後的‘。’不能少。

24、如何清空一個分支的所有提交

先刪除該分支,然後再新建一個空的分支(分支名就是刪除的分支名)~~

最後

剛整理 2020 年全套最新精品技術資料免費發給你! (原價最少8999元,超2000G!)

三年 Git 使用心得 & 常見問題整理

三年 Git 使用心得 & 常見問題整理

領取 看看下面!!

1、點贊 + 評論 (勾選 “轉發” )

2、關注小編私信。點選頭像,關注。並私信回覆關鍵詞: 1024