Git 流程圖
Workspace:作業區Index / Stage:暫存區Repository:倉庫區(或本地倉庫)Remote:遠程倉庫
配置 Git:另外技術是不斷更新的,在此贈送2020最新企業級別Vue3.0/Js/ES6/TS/React/node等實戰視頻教程,想學的可進裙 519293536 免費獲取,小白勿進哦
# 配置全域用戶
$ 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 -- <filename>撤銷或者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
復制代碼
fast-forward:會在當前分支的提交歷史中添加進被合并分支的提交歷史(得先理解什么時候會發生快速合并,并不是每次 merge 都會發生快速合并);--no-ff:會生成一個新的提交,讓當前分支的提交歷史不會那么亂;--squash:不會生成新的提交,會將被合并分支多次提交的內容直接存到作業區和暫存區,由開發者手動去提交,這樣當前分支最終只會多出一條提交記錄,不會摻雜被合并分支的提交歷史
rebase
www.liaoxuefeng.com/wiki/896043…
git-scm.com/book/zh/v2/…
www.jianshu.com/p/4a8f4af4e…
juejin.im/post/5a5438…
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 <newurl>
復制代碼
tag
常用于發布版本
www.liaoxuefeng.com/wiki/896043…
# 默認在 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 <tagname>
# 推送一個本地標簽
$ git push origin <tagname>
# 推送全部未推送過的本地標簽
$ git push origin --tags
# 洗掉本地標簽
# 因為創建的標簽都只存盤在本地,不會自動推送到遠程,
# 所以,打錯的標簽可以在本地安全洗掉,
$ git tag -d v0.1
# 洗掉一個遠程標簽(先洗掉本地 tag ,然后再洗掉遠程 tag)
$ git push origin :refs/tags/<tagname>
復制代碼
洗掉檔案
# 洗掉暫存區和作業區的檔案
$ git rm filename
# 只洗掉暫存區的檔案,不會洗掉作業區的檔案
$ git rm --cached filename
復制代碼
如果在配置 .gitignore 檔案之前就把某個檔案上傳到遠程倉庫了,這時候想把遠程倉庫中的該檔案洗掉,此時你配置 .gitignore 檔案也沒有用,因為該檔案已經被追蹤了,但又不想在本地洗掉該檔案后再重新提交到遠程倉庫,這時候可以使用 git rm --cached filename 命令取消該檔案的追蹤,這樣下次提交的時候,git 就不會再提交這個檔案,從而遠程倉庫的該檔案也會被洗掉
版本切換 & 重設 & 撤銷
- checkout 可以撤銷作業區的檔案,reset 可以撤銷作業區/暫存區的檔案
- reset 和 checkout 可以作用于 commit 或者檔案,revert 只能作用于 commit
checkout 詳解
# 恢復暫存區的指定檔案到作業區
$ git checkout <filename>
# 恢復暫存區的所有檔案到作業區
$ git checkout .
# 回滾到最近的一次提交
# 如果修改某些檔案后,沒有提交到暫存區,此時的回滾是回滾到上一次提交
# 如果是已經將修改的檔案提交到倉庫了,這時再用這個命令回滾無效
# 因為回滾到的是之前自己修改后提交的版本
$ git checkout HEAD
$ git checkout HEAD -- filename
# 回滾到最近一次提交的上一個版本
$ git checkout HEAD^
# 回滾到最近一次提交的上2個版本
$ git checkout HEAD^^
# 切換分支,在這里也可以看做是回到專案「當前」狀態的方式
$ git checkout <當前你正在使用的分支>
# 切換到某個指定的 commit 版本
$ git checkout <commit_id>
# 切換指定 tag
$ git checkout <tag>
復制代碼
- 在開發的正常階段,
HEAD一般指向 master 或是其他的本地分支,但當你使用git checkout <commit id>切換到指定的某一次提交的時候,HEAD就不再指向一個分支了——它直接指向一個提交,HEAD 就會處于 detached 狀態(游離狀態), - 切換到某一次提交后,你可以查看檔案,編譯專案,運行測驗,甚至編輯檔案而不需要考慮是否會影響專案的當前狀態,你所做的一切都不會被保存到主堆疊的倉庫中,當你想要回到主線繼續開發時,使用
git checkout branchName回到專案初始的狀態(這時候會提示你是否需要新建一條分支用于保留剛才的修改), - 哪怕你切換到了某一版本的提交,并且對它做了修改后,不小心提交到了暫存區,只要你切換回分支的時候,依然會回到專案的初始狀態,(注意:你所做的修改,如果 commit 了,會被保存到那個版本中,切換完分支后,會提示你是否要新建一個分支來保存剛才修改的內容,如果你剛才解決了一個 bug ,這時候可以新建一個臨時分支,然后你本地自己的開發主分支去合并它,合并完后洗掉臨時分支),
- 一般我都是用 checkout 回退版本,查看歷史代碼,測驗 bug 在哪
reset 詳解
git reset [--hard|soft|mixed|merge|keep] [<commit>或HEAD]:將當前的分支重設(reset)到指定的 <commit> 或者 HEAD (默認,如果不顯示指定 <commit>,默認是 HEAD ,即最新的一次提交),并且根據 [mode] 有可能更新索引和作業目錄,mode 的取值可以是 hard、soft、mixed、merged、keep ,
# 從暫存區撤銷特定檔案,但不改變工作區,它會取消這個檔案的暫存,而不覆寫任何更改
$ git reset <fileName>
# 重置暫存區最近的一次提交,但作業區的檔案不變
$ git reset
# 等價于
$ git reset HEAD (默認)
# 重置暫存區與作業區,回退到最近一次提交的版本內容
$ git reset --hard
# 重置暫存區與作業區,回退到最近一次提交的上一個版本
$ git reset --hard HEAD^
# 將當前分支的指標指向為指定 commit(該提交之后的提交都會被移除),同時重置暫存區,但作業區不變
$ git reset <commit>
# 等價于
$ git reset --mixed <commit>
# 將當前分支的指標指向為指定 commit(該提交之后的提交都會被移除),但保持暫存區和作業區不變
$ git reset --soft <commit>
# 將當前分支的指標指向為指定 commit(該提交之后的提交都會被移除),同時重置暫存區、作業區
$ git reset --hard <commit>
復制代碼
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 <commit_id>
# 生成一個撤銷指定提交版本的新提交,執行時不打開默認編輯器,直接使用 Git 自動生成的提交資訊
$ git revert <commit_id> --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 <commit_id>
$ git cherry-pick <commit_id> <commit_id>
$ git cherry-pick <commit_id>^..<commit_id>
復制代碼
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 update
git submodule update --init
# 自動初始化并更新倉庫中的每一個子模塊, 包括可能存在的嵌套子模塊
git clone --recurse-submodules [URL]
復制代碼
新建一個 Git 專案的兩種方式
1.本地新建好 Git 專案,然后關聯遠程倉庫
# 初始化一個Git倉庫
$ git init
# 關聯遠程倉庫
$ git remote add <name> <git-repo-url>
# 例如
$ git remote add origin https://github.com/xxxxxx
復制代碼
2.clone 遠程倉庫
# 新建好遠程倉庫,然后 clone 到本地
$ git clone <git-repo-url>
# 將遠程倉庫下載到(當前 git bash 啟動位置下面的)指定檔案中,如果沒有會自動生成
$ git clone <git-repo-url> <project-name>
復制代碼
Git 分支管理規范
blog.csdn.net/LitongZero/…
juejin.im/post/5b4328…
- 實際開發的時候,一人一條分支(個人見解:除非是大專案,參與的開發人員很多時,可以采用 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 <file>'
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、HEAD 指標既可以指向分支(默認指向當前分支),也可以指向快照,當指向的是快照時,這個時候指標的狀態稱之為游離狀態(detached)
8、創建與合并分支的原理
www.liaoxuefeng.com/wiki/896043…
9、每次 git push 都要輸入用戶名、密碼
- step 1:生成公鑰
ssh-keygen -t rsa -C "[email protected]"
# Generating public/private rsa key pair...
# 三次回車即可生成 ssh key
復制代碼
- step 2:查看已生成的公鑰
cat ~/.ssh/id_rsa.pub
復制代碼
- step3:復制已生成的公鑰添加到 git 服務器
測驗 ssh 是否能夠連接成功
$ ssh -T [email protected]
復制代碼
- step4:使用 ssh 協議 clone 遠程倉庫 或者 如果已經用 https 協議 clone 到本地了,那么就重新設定遠程倉庫
使用 ssh 協議
$ git remote set-url origin [email protected]: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
復制代碼
10、git 不允許提交空檔案夾
可以在當前目錄下,添加一個 .gitkeep 檔案
11、有時候復制過來的檔案,使用 git add . 無法進行檔案追蹤,可以使用 git add -A ,這也就是每次提交前都要 git status 的原因
12、同一臺電腦配置多個 git 賬號
github.com/jawil/notes…
13、Another git process seems to be running in this repository, e.g.
原因在于 Git 在使用程序中遭遇了奔潰,部分被上鎖資源沒有被釋放導致的,
解決方案: 進入專案檔案夾下的 .git 檔案中(顯示隱藏檔案夾或 rm .git/index.lock)洗掉 index.lock 檔案即可,
14、git commit -am "xxx" 有時候會失效,無法提交所有的修改
git commit -am "xxx" 只會將被 tracked 的檔案添加到暫存區并提交,而將檔案添加到 git 管理是要使用 git add 命令,將新的檔案 tracked ,(新建了檔案之后,idea 會提示你是否需要加到 git 管理中,選擇記住后,之后 idea 默認都會把新建的檔案 tracked 化)
15、git merge --no-ff 的作用
- 禁止快進式(fast-forward)合并,會生成一個新的提交
從合并后的代碼來看,結果都是一樣的,區別就在于 --no-ff 會讓 git 生成一個新的提交物件,為什么要這樣?通常我們把 master 作為主分支,上面存放的都是比較穩定的代碼,提交頻率也很低,而 feature 是用來開發特性的,上面會存在許多零碎的提交,快進式合并會把 feature 的提交歷史混入到 master 中,攪亂 master 的提交歷史,所以如果你根本不在意提交歷史,也不愛管 master 干不干凈,那么 --no-ff 其實沒什么用,
segmentfault.com/q/101000000…
16、git merge 與 git rebase 的區別
juejin.im/post/5a5438…
blog.csdn.net/liuxiaoheng…
segmentfault.com/a/119000001…
segmentfault.com/a/119000001…
17、git log 無法正常顯示中文
# 試試
$ git -c core.pager=more log
# 如果可以顯示中文的話,把 pager 設定為 more
$ git config --global core.pager more
復制代碼
www.zhihu.com/question/57…
www.playpi.org/2019031901.…
18、git merge -m "xxx" 的時候可以附加資訊
- 默認是 Merge branch branchName
19、git pull 會拉取所有遠程分支的代碼到本地鏡像倉庫中
想要 merge 別人的分支時:
- 如果你的本地倉庫中已經有了他人的分支(直接切換到他人分支,就會在本地生成一條他人的分支),就可以使用 merge branchname;
- 如果你的本地倉庫沒有他人的分支,那么就得使用 merge origin/branchname 來合并
20、git branch -r/-a/-l 查看的都是本地鏡像倉庫中的分支,如果本地鏡像倉庫沒有拉取遠程倉庫的代碼,此時別人新推了一個分支到遠程倉庫,你這時候是查看不到這條新推的分支的
21、git stash 存盤未追蹤的檔案
- 如果我們新建了檔案,但是沒有用
git add .追蹤檔案,那么git stash是無法存盤的
$ git stash -u
復制代碼
22、如何在 github 上 pr 專案
segmentfault.com/a/119000002…
23、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地址,
24、git 輸錯用戶名和密碼,后續的 git 操作一直報錯
remote: Coding 提示: Authentication failed.
remote: 認證失敗,請確認您輸入了正確的賬號密碼,
fatal: Authentication failed for 'https://e.coding.net/xxx.git/'
復制代碼
在控制面板里找到憑據管理器,選中 Windows 憑據,找到 git 的憑據,點擊編輯,輸入所用 github 的正確用戶名和密碼,
25、lint-staged 失敗
可能你的專案名路徑中包含了中文名,需要替換成英文名
26、查看 git 安裝目錄
- Mac: 在命令列中輸入
which git,就會顯示 git 的安裝位置了 - Windows: 打開cmd,輸入
where git,就會顯示 git 的安裝路徑了
27、Git中用vim打開、修改、保存檔案
28、windows10 無法編輯 vimrc
29、Windows下Git Bash中VIM打開檔案中文亂碼
30、如何修改舊的 commit 的 message/如何將多個 commit 合成一個 commit/如何將多個間隔的 commit 合成一個 commit/
git rebase -i
復制代碼
31、如果兩個人都對某個檔案進行了修改,一個是重命名檔案,一個是修改檔案內容,那么會起沖突嗎?git 很智能,會自動合并這些修改
如果兩個人都對同一個檔案重命名,此時會起沖突,git 不會自動處理,需要開發者自身去解決沖突
32、git revert 失敗:error: Commit faulty merge is a merge but no -m option was given、error: option `mainline' expects a number greater than zero
segmentfault.com/a/119000001…
www.jianshu.com/p/3719dae37…
git revert -m 1
復制代碼
33、git 創建一個空的分支
在 Git 中創建分支,是必須有一個父節點的,也就是說必須在已有的分支上來創建新的分支,如果工程已經進行了一段時間,這個時候是無法創建空分支的,但是有時候就是需要創建一個空白的分支,
$ git checkout --orphan emptyBranchName
復制代碼
該命令會生成一個叫 emptybranch 的分支,該分支會包含父分支的所有檔案,但新的分支不會指向任何以前的提交,就是它沒有歷史,如果你提交當前內容,那么這次提交就是這個分支的首次提交,
想要空分支,所以需要把當前內容全部洗掉,用 git 命令
$ git rm -rf . // 注意:最后的‘.’不能少,
復制代碼
34、如何清空一個分支的所有提交
先洗掉該分支,然后再新建一個空的分支(分支名就是洗掉的分支名)~~
以上的都會了嗎? 另外技術是不斷更新的,在此贈送2020最新企業級別Vue3.0/Js/ES6/TS/React/node等實戰視頻教程,想學的可進裙 519293536 免費獲取,小白勿進哦!
本文的文字及圖片來源于網路加上自己的想法,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/60303.html
標籤:JavaScript
