開發中的常見git操作【很全】

一些常規操作

一、分支操作

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 操作會將 工作區 和 暫存區 的改動放到 工作現場。

一般使用順序是:

  1. git stash save “這些是註釋啦”
  2. 切換到其他分支處理
  3. 其他分支代碼處理完後,切換到git statsh 操作所在分支
  4. 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

進入交互界面:
在這裏插入圖片描述
這張圖,可以分兩個部分看:

  1. 主要內容:選定的提交們,以及對它們的處理。(編輯區默認的提交順排列序是按提交歷史上的順序排列的,由前到後,順序執行)
  2. 帶#的註釋內容:關於對這些提交你能操作的命令,理解了它們,就可以開心地爲所欲爲了。

先看註釋內容,理論知識大概掌握先:

  • 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
    刪除提交

交互步驟:

  1. 對需要修改的歷史 commit ,設置操作
  2. 保存退出
  3. 如果中間出現衝突,解決衝突後,進行 git rebase --continue.
  4. 如果中間任何一個換件出現問題,均可以使用 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章