一些常規操作
一、分支操作
1.1、拉取遠程的某個分支的幾種方式
拉取之前,可以使用git branch -a查看所有分支(或者使用git branch -r 查看所有遠程分支)。
- git checkout -b lBranch origin/rBranch 【在本地新建名爲 lBranch 的分支,並追蹤遠程的 rBranch 分支】
- git checkout --t origin/rBranch 【在本地新建名爲 rBranch 的分支,並追蹤到遠程的 rBranch 分支,其中的-t,是 -track 的縮寫】
- git fetch之後,git checkout 遠程分支
目前來說,我使用的比較多的是最後一種,這種方式可以直接在本地建立一個與遠程分支同名的本地分支,並追蹤到遠程分支
1.2、本地新建分支並提交到遠程
git checkout -b feature/my-feature
git push origin feature/my-feature
1.3、刪除本地分支並推送到遠程
git branch -d feature/my-feature
git push origin --delete feature/my-feature
1.4、分支合併
1.4.1、git merge的三種用法以及缺陷
- git merge branchName【fast-forward 方式】
將當前分支 與 本地 叫“branchName”分支的代碼合併(branchName代碼合併到當前分支),這種方式下,會將feature所有的commit點加到baseline上,不會額外生成一個merge 的commit點; - git merge --no-ff branchName
將當前分支 與 本地 叫“branchName”分支的代碼合併(branchName代碼合併到當前分支),並且顯示合併細節,這種方式下,會將feature所有的commit點加到baseline上,但會額外生成一個merge 的commit點; - git merge --squash branchName
合併新分支代碼時, 只將分支新改動放入暫存區,然後baseline提交一個新的commit點。
兩次 squash merge:
git merge 和 git merge --no-ff的區別:
默認情況下,git執行"快進式合併"(fast-farward merge),會直接將master分支指向dev分支。使用–no-ff參數後,會執行正常合併,在master分支上生成一個新節點.
三種方式的缺點:
- fast-forward merge會將所有feature上的commit點完整的呈現在baseline,如果feature上commit非常冗雜,將會導致baseline的commit信息爆炸多
- none-fast-forward merge會丟失merge 信息
- git merge --squash branchName 會將多個壓縮點合併成baseline上的一個commit點,且會丟失feature分支上所有的提交信息(提交人變成git倉庫的container)
1.4.2、git rebase + git merge方式(僅做了解,日常工作中並未做過rebase操作,目前只知道如果在本地倉庫單人時,非常好用,如果多人,需要倉庫管理員統一rebase,然後通知所有開發人員,刪除該分支,重新拉取,否則會很麻煩)
rebase會把你當前分支的 commit 放到公共分支的最後面,所以叫變基。就好像你從公共分支又重新拉出來這個分支一樣。
舉個栗子:
以一般的gitflow中feature分支的操作爲例子:
全部使用merge方式:
- 從分支master新建兩個分支 f1 和 f2。
- f1 修改test.txt文件並提交
- master merge --no-ff f1
- f2 merge --no-ff master
- f2修改test.txt並提交
- master merge --no-ff f2
使用merge+rebase方式:
- 從分支master新建兩個分支 f1 和 f2。
- f1 修改test.txt文件並提交
- master merge --no-ff f1
- f2 rebase master
- f2修改test.txt並提交
- master merge --no-ff f2
兩種方式相比,明顯後者的提交信息更加清爽。
rebase的工作原理可以看下git官方文檔:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
核心原理就是將feature的提交點放在baseline的最後面。
rebase的黃金守則:
絕不要在公共的分支上使用它!
在你運行 git rebase 之前,一定要問問你自己「有沒有別人正在這個分支上工作?」。如果答案是肯定的,那就不能rebase
個人理解:只對尚未推送或分享給別人的本地修改執行變基操作清理歷史;從不對已推送至別處的提交執行變基操作
git rebase的缺點:
- 安全性,如果你違反了 rebase 黃金法則,重寫項目歷史可能會給你的協作工作流帶來災難性的影響
- 可跟蹤性,rebase 不會有合併提交中附帶的信息——你看不到 feature 分支中併入了上游的哪些更改
1.5、撤銷提交
由於日常開發中,爲了提交方便,一般直接使用idea進行commit操作,而idea會直接將文件提交到暫存區和本地倉庫。所以,這裏討論的是,如何把將工作區撤銷到某個 commit 點。
1.5.1、如果提交沒有push到遠程
- git reset --hard 某個commit點 git reset 可以直接將 head 指針指向這個commit點(–hard 是將暫存區和工作區都重置到指定的 commit 點 --soft 將暫存區重置到指定的 commit 點,工作區不受影響)
- git checkout head . 將工作區所有文件撤銷到本地倉庫最新的一次提交
1.5.2、git revert撤銷已經push到遠程的commit
因爲已經push到遠程倉庫了,有可能別人已經拉取了最新的 commit 點,這個時候就不能使用 checkout 或者 reset 命令直接撤銷commit點了(這樣 push 的時候會衝突),這個時候我們可以用git revert方法,revert會提交一個新的commit點,用來撤銷我們選擇的 commit 點的內容。
git revert HEAD 撤銷前一次 commit
git revert HEAD^ 撤銷前前一次 commit
git revert fa042ce57 撤銷指定的版本,撤銷也會作爲一次提交進行保存。
下面附張圖:
1.6、git statsh 工作區暫存
如果,開發到一半,突然需要切換到另外一個分支,提交代碼,但是當前分支代碼又沒完成,怎麼辦?使用 git stash ! git stash 操作會將 工作區 和 暫存區 的改動放到 工作現場。
一般使用順序是:
- git stash save “這些是註釋啦”
- 切換到其他分支處理
- 其他分支代碼處理完後,切換到git statsh 操作所在分支
- git stash pop / git stash apply
1.7、重寫歷史
以下需要重寫的歷史 commit 都默認爲未 push 到遠程的本地commit歷史。
1.7.1、git commit --amend 修改最後一次提交
修改最後一次提交的message
git commit --amend 後,通過文本編輯器來修改
最後一次提交,忘記提交了文件
如果你已經完成提交,又因爲之前提交時忘記添加一個新創建的文件,想通過添加或修改文件來更改提交的快照,也可以通過類似的操作來完成。 通過修改文件然後運行 git add 一個已追蹤的文件,隨後運行 git commit --amend 拿走當前的暫存區域並使其做爲新提交的快照。
git add 需要add的文件
git commit --amend
注意事項
使用這個技巧的時候需要小心,因爲修正會改變提交的 SHA-1 校驗和。 它類似於一個小的變基——如果已經推送了最後一次提交就不要修正它。
1.7.2、git rebase -i 修改提交歷史中較遠的提交
選中當前頭指針之前的3個提交
git rebase -i HEAD~3
進入交互界面:
這張圖,可以分兩個部分看:
- 主要內容:選定的提交們,以及對它們的處理。(編輯區默認的提交順排列序是按提交歷史上的順序排列的,由前到後,順序執行)
- 帶#的註釋內容:關於對這些提交你能操作的命令,理解了它們,就可以開心地爲所欲爲了。
先看註釋內容,理論知識大概掌握先:
- p,pick
使用該提交,也是默認操作,這個從上面的編輯區域可以看出。這個命令的含義是拿到這個命令,但是什麼都不做。 - r,reword
拿到提交,修改提交的提交信息。 - e,edit
拿到提交,修改這個提交的內容。使用這個命令的時候,rebase 操作會停在操作提交處,等待修改完畢,使用git add .和 git commit --amend修改提交,git rebase --continue繼續 rebase 進程。 - s,squash
合併到前一個commit上面去。 - f,fixup
和 squash 命令的作用一樣,不同的是,squash 命令會把融合的提交的提交信息都保存融合後的提交信息中,但是 fixup 會放棄被融合的提交。 - d,drop
刪除提交
交互步驟:
- 對需要修改的歷史 commit ,設置操作
- 保存退出
- 如果中間出現衝突,解決衝突後,進行 git rebase --continue.
- 如果中間任何一個換件出現問題,均可以使用 git rebase --abort 放棄此次變基
1.8、一些tips
1.8.1、每次commit代碼時,首先從遠程拉取下代碼
這是因爲,如果遠程倉庫如果有新的 commit ,本地倉庫也有新的 commit ,這個時候如果git pull,本地會多一個 merge 的 commit 點。這種情況,其實可以通過 git pull --rebase 來解決,但考慮到變基操作學習成本較高,故不做介紹。
二、日常開發中,你需要記住下面的基礎命令(包含參數)
2.1、git branch命令
用戶分支的管理工作
- git branch branch1 在當前分支(本地)下,創建branch1分支
- git branch -d branch1 刪除本地的branch1分支
- git branch 列出本地分支
- git branch -a 列出本地分支和遠程分支
- git branch -r 列出遠程分支
2.2、git checkout 命令
git checkout主要有下面兩個用處:
- 工作區的文件回退;(從暫存區、從本地倉庫)
- 切換分支(包括新建、切換)
回退文件時的常用命令:
- git checkout – a.txt 【用 暫存區 的 a.txt 文件,替換工作區的 a.txt 文件】
- git checkout – . 【用暫存區的所有文件,替換工作區的文件】
- git checkout head a.txt 【用 本地倉庫 的a.txt 文件,替換工作區的 a.txt 文件】
- git checkout head . 【用 本地倉庫 的所有文件,替換工作區的文件】
分支操作時的常用命令
分支切換:
- git checkout branch1 將分支切換到本地分支branch1
本地新建分支:
- git checkout -b dev 在本地新建名爲dev的分支,並切換過去,如果本地已經存在dev分支,則會報錯
相當於git branch dev 和 git checkout dev兩個命令
本地新建分支,並track到遠程分支:
- git checkout -b lBranch origin/rBranch 【在本地新建名爲 lBranch 的分支,並追蹤遠程的 rBranch 分支】
- git checkout --t origin/rBranch 【在本地新建名爲 rBranch 的分支,並追蹤到遠程的 rBranch 分支,其中的-t,是 -track 的縮寫】
2.3、git pull
- git pull
拉取與當前分支關聯的遠程分支代碼(並自動合併當前改動的代碼, 如本地已有commit會產生一個新的commit) - git pull --rebase
拉取與當前分支關聯的遠程分支代碼(並自動合併當前改動的代碼, 如本地已有commit不會產生新的commit)
2.4、git add
- git add .
提交當前路徑下的所有文件到暫存區(包括子目錄,但不包括父級以上目錄) - git add -A
最常用的git 指令, 提交所有 新增、刪除、修改到暫存區(包括子目錄,且包括父級以上目錄)
2.5、git commit
- git commit -m
提交暫存區
2.6、git push
- git push
推送代碼至與當前分支關聯的遠程分支 - git push -f
將當前分支的commit強制推送到遠程分支(不處理 更新、合併等, 非常危險的指令,謹慎操作) - git push origin --delete [branch-name]
刪除遠程分支
2.7、git stash
- git stash
- git stash save “這些是註釋啦”
新增工作現場(將當前的所有改動全部放入工作現場), git stash的默認註釋爲當前分支上一次commit的註釋 - git stash list
顯示工作現場列表 - git stash apply
- git stash apply --index stash@{0}
恢復工作現場的代碼(不刪除),默認恢復最新工作現場:git stash apply = git stash apply --index stash@{0}, --index 參數:不僅恢復工作區,還恢復暫存區
2.8、 git merge
- git merge branchName
將當前分支 與 本地 叫“branchName”分支的代碼合併(branchName代碼合併到當前分支); - git merge --no-ff branchName
將當前分支 與 本地 叫“branchName”分支的代碼合併(branchName代碼合併到當前分支),並且顯示合併細節,具體表現在 提交線路圖會出現交叉線; - git merge --squash branchName
合併新分支代碼時, 只將分支新改動放入暫存區,不產生commit;(合併分支減少commit)
2.9、git log
- git log
查看commit提交歷史, 查看commit id方便回退; - git log --oneline --graph --decorate --all
查看分支樹
2.10、git revert
- git revert
撤銷某個提交帶來的修改
2.11、git clone
- git clone https://github.com/xxxxx
此方式拷貝項目不需密碼;
但以後使用git pull 、git push指令都得輸入賬號密碼;
2.12、git config
- git config --global alias.co checkout
設置別名,這樣可以直接使用 git co 來 代替 git checkout
三、插件&工具
3.1、一個支持交互的git checkout 分支切換工具
https://github.com/royeo/git-checkout-branch
安裝命令(本地需要安裝git):
curl -sSL https://github.com/royeo/git-checkout-branch/releases/download/v0.4.0/git-checkout-branch-`uname -s`-`uname -m` -o /usr/local/bin/git-checkout-branch && chmod +x /usr/local/bin/git-checkout-branch
git config --global alias.cb checkout-branch
使用:
- git倉庫目錄下,直接鍵入git cb即可選擇相關分支,↑、↓可以選擇,←、→可以翻頁。
- git cb 執行後,按 “/”,支持模糊搜索
- control + c 退出交互
四、引用 & 常用鏈接
- https://git-scm.com/book/zh/v2/Git-%E5%9F%BA%E7%A1%80-%E6%92%A4%E6%B6%88%E6%93%8D%E4%BD%9C
- git常用命令大全 https://www.kancloud.cn/wteamxq/git_rank/277268