開局一張圖
大家好,我是沐華,可能大家或多或少的有遇到過類似圖檔這種情況,這是不是很煩,一個檔案還能這麼湊合,如果是多檔案,比如一個項目成千上萬個檔案,還可能多人修改,要是都這麼維護,就算不考慮占用存儲空間那也絕對是地獄級難度,是以
Git
出現了
本文将從 Git 入門到進階、由淺入深,從常用指令、分支管理、送出規範、vim 基本操作、進階指令、沖突預防、沖突處理等多方面展開,足以輕松應對工作中遇到的各種疑難雜症,如果覺得有所幫助,還望看官高擡貴手給個贊呗,感謝
雖說現在工作中使用 Git 都會用一些圖形化管理工具來提高開發效率。可事實上使用圖形管理化工具的前提,也是基于對指令都基本了解。還有比如我平時用的工具
GithubDesktop
因為不帶第三方合并工具,隻能手動解決沖突,而且有的功能沒有,隻能配合自己手動敲指令。
即使是工具也沒有那麼完美的工具,掌握指令才是
漁
,工具隻是
魚
。其他的 Git 可視化管理工具比如:小烏龜、SourceTree、還有我們開發用的 IDE 內建的,本期就不過多介紹了
基本概念
Git 是一個開源的,也是目前最主流的分布式版本控制系統。
Git 的作用與好處是:
可以幫我們儲存檔案的所有修改記錄,并且使用版本号進行區分,讓我們随時可以浏覽曆史版本、對比不同版本的差異、還原到指定版本,起到恢複和保護作用的同時,還能和其他人同時修改,然後通過 Git 來合并修改的部分檔案,超級友善
不熟的同學别和 Github 搞混了,Git 是工具,Github 是平台,沒有什麼必然的聯系,就像 Java 和 JavaScript 也沒有什麼必然聯系一樣
Github 是一個主流的代碼托管平台。可以了解為存放和管理代碼的網盤,可以把自己的代碼傳上去進行共享和維護
安裝配置
安裝位址:Git - Downloads (git-scm.com)
安裝好後,指令行黑視窗是使用
Git Bash
、
CMD
、
Powershell
、
終端
、或者編譯器内置的,這個就看個人喜歡了
接着可以再配置下預設使用者名和郵箱,比如配置全局的就用如下兩條指令,替換成自己的使用者名和郵箱,以後所有的項目都會預設這裡配置的使用者資訊
git config --global user.name 'xxxx'
git config --global user.email '[email protected]'
如果隻需要在某個特定的項目中用其他的名字和郵箱,不用全局的,就把上面指令中的
--global
去掉在項目下執行即可,或者不執行指令,直接在項目下的
.git/config
檔案裡添加如下,也可以
# xxx 指的是填你自己的使用者名和郵箱,不是真的寫 xxxx 上去
[user]
name = xxxx
email = [email protected]
基本操作
先了解一下幾個基本概念:
- 工作區:開發的地方,開發過程就是對工作區的操作
- 暫存區:執行
指令後,會把目前修改過的檔案添加到暫存區git add xxx
- 本地倉庫:執行
指令完成後,會把目前暫存區的檔案放入本地倉庫git commit
- 遠端倉庫:就是用來托管代碼的伺服器(如:Github、Gitee、GitLab、工蜂、Bitbucket..),執行
指令後,會把本地倉庫的檔案送出到遠端倉庫git push
常見選項
再認識一下幾個後面會用到多次的指令,之後就不一一解釋了
指令 | 縮寫 | 意思 |
--all | -a | 全部 |
--force | -f | 強制 |
--delete | -d | 删除 |
--delete --force | -D | 強制删除 |
--move | -m | 移動或重命名 |
--move --force | -M | 強制移動或重命名 |
-u | 設定預設遠端分支 |
拉取遠端項目
拉取遠端項目到本地,先複制遠端項目連結,再在本地執行如下指令
# 拉項目
git clone https://xxxx
# 拉項目的同時自動初始化并更新項目中的每一個子子產品
git clone --recursive https://xxxx
上傳本地項目
本地建立的項目,還沒有送出到遠端倉庫,就需要先關聯遠端倉庫。先在遠端建立一個空項目,并複制該項目的連結,然後在本地項目根目錄依次執行下面指令即可
git init // 初始化本地 Git 倉庫,會生成一個 .git 隐藏檔案夾
git remote add origin https://xxxx // 将本地項目關聯遠端倉庫,後面的 https://xxxx 就是複制的遠端倉庫的連結
git pull --rebase origin master // 上傳之前更新一下,確定沒有沖突,master 為分支名稱,--rebase 後面有介紹
git add . // 添加目錄下所有發生改變的檔案
git commit -m 'xxx' // 添加注釋資訊
git push -u origin master // 送出到 master 分支
其中
git remote add origin https://xxxx
,就是往
.git/config
檔案裡添加下面這一段,手動添加也可以,意思就是與遠端倉庫建立關聯。其他的幾條指令後面有介紹,我們先認識下
origin
為後面做鋪墊;
[remote "origin"]
url = https://github.com/wmuhua/xxxx.git
fetch = +refs/heads/*:refs/remotes/origin/*
指令裡的
origin
類似變量命名,這是預設的而已,沒什麼特别的意思,可以随便寫,假如改成
abc
,後面的
git push origin xxx
改成
git push abc xxx
即可,友善區分遠端倉庫的
由此可得出一個結論,就是一個項目可以關聯多個遠端倉庫,命不同的名就行了
沒錯
git remote -v
可以快速檢視目前已經關聯的遠端倉庫清單
關聯多個遠端倉庫
可以使用
git remote add xxx
添加多個,或者直接動在
.git/config
檔案裡添加。
比如一個項目同時關聯一個
Github
倉庫和一個
Gitee
倉庫,添加一個
remote
就是了,比如如下:
[remote "github"]
url = https://github.com/wmuhua/xxxx.git
fetch = +refs/heads/*:refs/remotes/github/*
[remote "gitee"]
url = https://gitee.com/xxxx/xxxx.git
fetch = +refs/heads/*:refs/remotes/gitee/*
[remote "all"]
url = https://github.com/wmuhua/xxxx.git
url = https://gitee.com/xxxx/xxxx.git
fetch = +refs/heads/*:refs/remotes/all/*
這樣當我們送出代碼的時候,想送出到
Github
就用
git push github master
,想同時送出到
Github
和
Gitee
的倉庫,隻需要
git push all master
即可
以指令的方法在某個
remote
下添加
url
如下,比如在上面
remote github
下再添加一個
url
:
git remote set-url --add github https:/xxxx.git
常用指令 add/commit/fetch/merge/pull/push
git add
# 添加一個檔案 test.js 到暫存區,多個檔案以空格隔開
git add test.js
# 添加全部檔案到暫存區
git add .
git commit
# 會打開 vim 編輯器,vim 編輯器操作在下面展開說明
git commit
# 送出暫存區的檔案到本地倉庫,并備注目前 commit 記錄
git commit -m '備注資訊'
# 相當于 git add . 加上 git commit -m 'xxxx'
git commit -am 'xxxx'
# 用本地送出替換上次送出,比如不想保留上一次送出或者上一次送出描述資訊寫錯了之類的
git commit --amend
git fetch
# 擷取 remote origin 對應遠端倉庫指定 master 分支的變更,但是不和本地的合并
git fetch origin master
# 意思一個樣,拉預設的分支而已
git fetch origin
# 也是,等效于 git fetch origin master:master,就是分支配置的預設值
git fetch
# 擷取預設遠端倉庫所有分支的變更
git fetch -a
git merge
# 把本地的 test 分支分并到我目前分支
git merge test
# 合并 remote origin 對應遠端倉庫的 master 分支到目前分支
git merge origin/master
# --on-ff 是 no-fast-forward簡寫,合并并且會在分支上重新生成一個新的 commit 節點
git merge --on-ff origin/master
# 加入 --squash 表示合并,但是不生成 commit 記錄,通常用于把本地分支合入遠端分支
git merge test --squash
# 取消合并
git merge --abort
git pull
pull
和
fetch
都是下載下傳遠端分支,差別是
pull
會和目前分支合并,
fetch
不會
# 拉取 remote origin 對應的遠端倉庫的 master 分支合并到本地的 test 分支
git pull origin master:test
# 這種同理就不解釋了
git pull origin
# git pull --merge 的簡寫,預設是 --merge 模式
# 等于 git fetch 加上 git merge,拉遠端預設分支到目前分支
git pull
# 把合并模式切換成 rebase,等于 git fetch 加上 git rebase,rebase 後面進階有介紹
git pull --rebase origin master
git push
# 推送本地 test 分支到 remote origin 對應的遠端倉庫的 master 分支
git push origin test:master
# 上面同理,推送到遠端預設分支
git push origin test
# 縮寫,同理,用預設分支
git push origin
git push
# 相當于 git push origin master 加上 git branch --set-upstream master origin/master
# 推送并設定預設遠端分支
git push -u origin master
# 強制推送,就算本地和遠端有差異也推上去
git push -f origin master
# 删除遠端主機的 master 分支
git push origin -d master
vim 基本操作
一點點小插曲
比如
git commit
就會打開一個
vim
的終端編輯器,讓我們寫送出說明,新手很容易在這個編輯器上面踩坑,不知道怎麼輸入,不知道怎麼退出,最後隻能關閉終端視窗,這也沒辦法,
vim
的操作确實有些反人類。
vim
打開預設是不能輸入的,要按
a
或者
i
進入編輯模式,輸入完成後,再按
Esc
退出編輯模式,這時左下角會有輸入框,輸入如下英文字元,注意冒号别打成中文字元,回車即可退出
vim
回到終端:
-
:儲存:w
-
:退出:q
-
:儲存并退出:wq
-
:強制的意思,不能儲存時 !
強制儲存,不能退出時 :w!
或 :q!
強制退出:wq!
我們繼續 git
分支管理 branch/switch/checkout
一個人玩,可能分支的作用沒那麼大,但是團隊協作,離不開分支管理。
比如本文開頭圖檔那樣一個版本一個分支多友善,是吧
或者現有一個新需求一個頁面分為多個子產品,配置設定給多個人負責,每人做一個子產品,最後合并成一個完整的頁面,如果都在同一個分支上開發,各種邏輯互相穿插,那沖突真的是人都要搞麻了,如果每個人都建立一個分支,開發自己負責的那個功能,最後再合并到同一個分支上去就非常友善了
然後因為多人協作肯定不是在一台電腦上,是以就需要一個伺服器,來搭建一個 Git 倉庫服務,或者用公共的雲伺服器倉庫存儲,常見的代碼托管平台有比如:
Github
、
碼雲(Gitee)
、
騰訊工蜂
、
GitLab
、
Bitbucket
...,關于這個本篇文章不過多展開
建立分支
# 建立本地分支 test,但不切換
git branch test
# 建立 test 分支,并切換到 test 分支
git branch -M test
# 建立 test 分支,并切換到 test 分支
git checkout -b test
# 建立 test 分支,并切換到 test 分支
git switch -c test
# 建立本地與遠端對應的 test 分支,并切換到 test 分支,全稱最好一緻
git checkout -b test origin/test
檢視分支
# 檢視所有本地分支
git branch
# 檢視所有遠端分支
git branch -r
# 檢視本地和遠端所有分支
git branch -a
切換分支
checkout
和
switch
的共同點是都能切換分支,不同點是:
-
語義上好點switch
-
僅僅用于切換和建立并切換,switch
還能用來還原工作區,後面進階那有介紹checkout
# 切換到 test 分支
git checkout test
# 建立 test 分支,并切換到 test 分支
git checkout -b test
# 切換到 test 分支
git switch test
# 建立 test 分支,并切換到 test 分支
git switch -c test
删除分支
# 删除本地 test 分支
git branch -d test
# 删除遠端主機的 master 分支
git push origin -d master
重命名分支
# 把本地的 master 分支重命名為 test
git branch -m master test
# 遠端分支沒法直接重命名,隻能删了重建,主要分幾步
# 1. git push origin --delete test 删除遠端分支
# 2. git push origin newtest 上傳新的遠端分支
# 3. 把修改後的本地分支關聯遠端分支
git branch --set-upstream-to origin/newtest
合并分支
其實就是上面的
git merge
。比如要把
test
分支合并到
master
分支,就:
# 先切換到 master 分支
git checkout master
# 拉一下,看有沒有更新
git pull
# 把 test 分支合進來
git merge test
# 檢視狀态,看有沒有沖突的,有就打開 IDE 解決一下
git status
# 然後 add、commit、push 幾個指令來一輪就 ok 了
git commit 送出規範
git commit
送出規範指的就是
git commit -am 'xxxx'
裡的
xxxx
的書寫規範,比如我在工作中開發了一個新功能送出的時候一般這麼寫:
-
git commit -am 'feat: 添加掃碼登入
-
,或者加個範圍說明是添加哪方面的功能git commit -am 'feat(mobile):添加掃碼登入
feat
就是添加新功能的時候用,更多說明如下:
-
:添加新功能feat
-
:修複問題/BUGfix
-
:注意不是指CSS,而是修改了如空格、縮進、逗号等代碼風格相關,且不影響運作結果的style
-
:優化相關的,比如功能優化、性能提升、提升體驗等perf
-
:代碼重構,沒有加新功能或者修複 bugrefactor
-
:撤消編輯,復原到上一個版本、撤銷上一次的 commit 之類的revert
-
:測試相關,比如單元測試、內建測試等test
-
:修改文檔/注釋,比如 README、CHANGELOG、CONTRIBUTE 等docs
-
:依賴更新/腳手架配置修改等,比如有改變建構流程、或者增加依賴庫、工具之類的chore
-
:工作流程改進workflow
-
:持續內建ci
-
:類型定義檔案更改types
到這裡,基礎部分内容就結束了
問個問題:
git branch -M ac
是啥意思?不許翻上面
進階操作
常用指令
裝*神器 alias
指令難記?沒有關系
咱們除了會寫一些别人看不懂的代碼,也可以敲一些别人看不懂的指令
alias
這個單詞想必大家就熟悉了,和項目中建立路徑别名類似,在
Git
裡是用來建立指令别名的,比如執行如下這指令後
// 配置全局 branch 指令别名為 b
git config --global alias.b branch
然後比如想建立一個名為
test
的本地分支,如下即可
git b test
好像有點邪教了,了解一下吧~
繼續工作中用到的
檢出 git checkout/git restore
# 四個都是:撤銷 test.js 從上次送出之後的所有修改
git checkout -- test.js
git checkout - test.js
git checkout test.js
git restore test.js
# 隻把 test.js 還原成上一個版本的,HEAD^表示上一個版本,HEAD^^上上一個版本
git checkout HEAD^ - test.js
# 隻把 test.js 重置到某個指定版本
git checkout commitID test.js
# 把 master 分支的 test.js 拿過來替換目前分支的 test.js
git checkout master - test.js
# 都是撤銷上一次 commit 之後的所有檔案的所有修改
git checkout -- *
git checkout -- .
git checkout .
git restore .
# 把暫存區的 test.js 重新放回工作區,和下面的 git reset HEAD test.js 作用一樣
git restore --staged test.js
重置 git reset
git reset
通常用來把代碼重置到過去的某個版本,有五種模式(
--mixed
、
--soft
、
--hard
、
--merge
),注意看注釋有說明差別。
另外
git reset
比較暴力,要慎用,比如現在送出五次了,然後使用這個指令重置到第一次,那麼第二三四五次送出記錄會全部沒了的,找不回來的,這種情況記得建立個分支來執行這種操作就沒事了,或者使用
git revert
# 後面一長串就是我複制的 commitID 或者說是 hash,長得就是這樣子的
# 等同于 git reset commitID,因為 --mixed 是預設模式,是以可以不寫
# 重置并撤銷 git commit 以及 git add,保留編輯器中所有修改
git reset --mixed afcfbcb940164de24cc4f8c866e1da3a18382e10
# 重置并撤銷 git commit,但不撤銷 git add,保留編輯器中所有修改
git reset --soft commitID
# 重置并撤銷 git commit 以及 git add,并且删除編輯器中所有修改
git reset --hard commitID
# 取消某次合并
git reset --merge commitID
git reset --keep commitID
# 把暫存區所有檔案退回到工作區,相當于撤銷 git add .
git reset HEAD
# 把暫存區的 test.js 重新放回工作區,和 git restore --staged test.js 作用一樣
git reset HEAD test.js
# 重置到上一個版本
git reset --hard HEAD^
# 重置到上上一個版本,以此類推
git reset --hard HEAD^^
# 重置到指定版本
git reset --hard commitID
commitID
可以通過三種方法檢視
- 執行
指令能看到目前分支本地所有送出記錄,上面每一條記錄都有對應一個 git log
commitID
- 去遠端代碼倉庫檢視曆史送出記錄,那裡每一條送出記錄都有一個對應的
commitID
-
檢視标簽清單,如果有的話,再 git tag
檢視标簽詳情,裡面也會有 git show 标簽名
commitID
# 檢視目前分支所有送出記錄,詳細清單,一條記錄有幾行資訊
git log
# 檢視目前分支所有送出記錄,簡要清單,一條記錄一行
git log --pretty=oneline
#
git log --oneline -n5
另外關于叫法本地倉庫一般說重置、還原、撤銷都行,遠端倉庫一般叫復原
還原 git revert
git revert
和
git reset
有點類似,隻是比
reset
稍微溫柔一點,沒那麼暴力。
上面介紹了假如現在是第五版,用
reset
在重置回第一版本的時候,二三四五版全都會沒了,而
revert
重置回第一版的時候,隻是新增一條送出記錄“第六版”,代碼變成第一版的代碼,原本的一二三四五版記錄都會有
另外 revert 還要分兩種情況,一種是還原正常的 commit,也就是 git commit 送出的 commit,另一種是用 merge 合并的 commit,如下
# 第一種檢視正常送出的 commit,如下
git show 68be9e548
commit 68be9e548dadbe7b9677874b705662a8f95efd21
# 第二種檢視 merge 合并的 commit 如下,多了一行 Merge,後面指的是從哪兩個 commit 合并過來的
git show 9c810c1db
commit 9c810c1dbf72627dbff10d621c2974b32ed6d929
Merge: 3f6acb587 68be9e548
# 撤銷正常送出的 commit
git revert commitID
# 撤銷 merge 的 commit 送出需要加參數來區分撤銷哪一個分支上的内容
# 也就是指定上面 Merge: 3f6acb587 68be9e548,這兩個 id 中的哪一個
# -m 接收一個參數是數字,取值 1 或 2,表示 Merge 的第一個還是第二個 id
git revert -m 1 9c810c1db
# 删除最後一次遠端送出
git revert HEAD
git push origin master
或
git reset --hard HEAD^
git push origin master -f
# 還原某次送出
git revert commitID
挑揀 git cherry-pick
比如有兩個分支 master 和 test,在 test 上修改了,并且送出了 commit 之後,這時候想把這次的送出也給弄到 master 上,就可以複制 test 的 commitID,再換到 master 分支後執行
git cherry-pick commitID
就可以了
what?這不就是 merge?
和 merge 不同的是:
cherry-pick
合并的是某一次
commit
送出的檔案,
merge
合并的是整個分支。且
merge
會額外多一條
merge commit
的記錄,而
cherry-pick
不會。
而且
cherry-pick
更加靈活,在需要把某個/或多個分支中的 commit,合入其他分支的時候都可以用,示例如下
# 這樣就把其他分支的一個 commit 合入目前分支了
git cherry-pick commitID
# 如果需要把多個 commit 合過來如下,這多個 commitID 可以是來自不同分支的
git cherry-pick commitID1 commitID2 commitID3
變基 git rebase
git rebase
和
git merge
的差別
git merge 和 git rebase 都是可以合并分支,合并用法也是一樣,不同的一個是在 commit 記錄的處理上:
-
會建立一條新的 commit,然後兩個分支以前的 commit 記錄都指向這個新 commit 記錄。這種方法會保留之前每個分支的 commit 曆史。git merge
-
會先找到兩個分支的第一個共同的 commit 祖先記錄,然後将提取目前分支這之後的所有 commit 記錄,放到目标分的最新送出後面。經過這個合并後,兩個分支合并後的 commit 記錄就變為了線性的記錄了。git rebase
這麼說可能不太好了解,看如下示例:
# 如下,需要把本地 test 分支合入 dev
# 為友善了解,字母表示commit記錄,數字表示送出時間順序,可以了解為1就是1點送出的
dev -> A1 -> B3 -> 這一行是遠端 dev 分支的commit記錄,A1/B3是你同僚送出的
↘ X2 -> Y4↗ 這一行是拉取了 dev 分支後在本地的 test 分支 commit 記錄
# 現在需要把你本地的分支合并到遠端的分支去
# 用merge合并後,dev 分支看到的記錄是這樣的,M為merge記錄的commit
dev -> A1 -> X2 -> B3 -> Y4 -> M
# 用rebase合并後,dev 分支看到的記錄是這樣的,注意順序,且沒有合并記錄的commit
# 簡單說就是直接把 test 分支的所有新的 commit 拿出來直接拼到 dev 分支末尾,不管送出時間先後
dev -> A1 -> B3 -> X2 -> Y4
- 然後是解決沖突的問題上,merge 是解決一次沖突就行了,rebase 需要一次一次地解決,如上示例的記錄順序也能看出來
- 再就是
可以合并多次 commit。比如本地分支送出了三個 commit,但沒有 push 到遠端,最後想送出到遠端的時候,為了簡潔,我們希望把本地的三個 commit 合并成一個 commit 再送出到遠端,遠端隻産生一條 commit 記錄,就可以用 rebase
處理下先,這指令可以删除指定記錄,或者合并多個 commit,對 commit 消息編輯等git rebase -i
# 删除某次送出,^表示 commitID 的前一次送出
git rebase -i 'commitID'^
# 修改多個送出資訊
git rebase -i HEAD~3
貯藏 git stash
git stash
常用于把修改儲存起來,需要的時候再取出來。常用于:
- 切換分支并且需要保留修改的時候
- 切換分支并且需要把修改帶到新的分支的時候
# 把目前分支的修改儲存起來,兩個一樣的
git stash
git stash save
# 存儲并添加備注,友善查找
git stash save '備注資訊'
# 檢視儲存清單
git stash list
# 取出儲存中最近一次的修改并删除儲存記錄
git stash pop
# 取出儲存中的指定部分修改,stash@{0} 0是預設的不寫也行,是啥隻要檢視儲存清單你就知道了
git stash apply stash@{0}
# 删除指定儲存
git stash drop stash@{1}
# 删除所有的儲存
git stash clear
# 建立一個新分支 test,并恢複儲存工作時所在的送出到該分支上,并扔掉儲藏
git stash branch test stash@{1}
# 不儲存暫存區的,也就是 git add 了的
git stash --keep-index
清理 git clean
和
git reset
的差別是:reset 删除的是己跟蹤的檔案,并且将已 commit 的回退。clean 删除的是未跟蹤的檔案/目錄
# 顯示如果執行後面删除的指令将會删除的檔案和目錄,相當于給提前給我們确認下
git clean -n
# 删除工作目錄中所有沒被追蹤的檔案(-f)以及空的子目錄(-d),一起就是 -df
git clean -df
差異 git diff
用來找出倉庫或者檔案之間的差異,可以用來預測或者阻止可能産生沖突的合并
# 工作區 vs 暫存區
git diff
# 工作區 vs 版本庫
git diff head
# 暫存區 vs 版本庫
git diff –cached
問題預防
- 不要對已經送出到遠端倉庫的 commit 進行 rebase 變基操作,除非是你一個人玩的分支
- 在切換分支,或者合并分支,或者重置/復原之前,最好不要有未
的檔案,如果有并且不想送出就用 commit
先存起來,再執行操作,如果用指令操作的話,取出之後記得清理git stash
- 遠端倉庫復原前記得做好備份,比如拉一個分支在本地。并且需要通知團隊其他成員,不要悄摸摸地就搞了
解決問題
切換分支保留修改
有時候比如我們在 test 分支上開發了一半,由于某些原因需要切換到 master 分支,但現在又不想送出,又想保留修改并且不帶到 master 分支上去,就可以這樣:
# 把目前分支的修改儲存起來
git stash
# 切換到其他分支幹你的事
git checkout master
# 幹完了
# 切換回 test 分支
git checkout test
# 取出儲存中所有的修改
git stash pop
# 删除所有的儲存
git stash clear
切換分支轉移修改
有的時候我們需要在 test 分支上開發,但是忘記了,活快幹完了才發現目前原來是 master 分支,可是已經開發了,這時候就需要切換分支到 test,并且把已經開發的部分内容也從 master 分支帶到 test 分支來,就可以這樣:
# 儲存修改
git stash
# 切換到 test 分支
git checkout test
# 取出儲存中的全部修改
git stash pop
# 或者
# 檢視儲存清單
git stash list
# 取出儲存中的指定部分修改,stash@{0} 是啥隻要檢視儲存清單你就知道了
git stash apply stash@{0}
# 再清掉儲存
git stash clear
合并時發生沖突用
git merge abort
或
git reset --merge
都可以取消合并
比如把不想要的代碼 commit 了,但是沒有 push
比如剛更新的代碼出問題了,需要還原這次送出的代碼
比如某次送出了不想送出的東西,需要清除掉它
revert 之後重新上線 diff 丢失
- 比如在 dev 分到開發了個功能,送出後會産生一條 commit 記錄,為了友善了解,我們先把這次送出标記為 a
- 然後合并到 master 後,我們把這次合并記錄标記為 b
- 結果出現了 bug 需要撤銷合并,使用 revert b 撤銷了,這會産生了一條新的記錄 我們标記為 c
- 然後繼續在 dev 分支開發完成送出,送出記錄标記為 d
- 這時候再合并到 master 上去,此時合并後的内容不會包含 a 的送出,因為 a 被 revert 丢棄過,不會參與 diff,如果需要包含 a,需要先 revert c 意思是撤銷某一次的撤銷,再來合并,就 ok 了
合并沖突不想合并了
合并時、或者拉取時等,發現有沖突,可能是其他同僚送出的,自己不知道怎麼沖突怎麼選擇,或者其他原因,總之不想合并了,都可以用
--abort
取消,比如合并的時候發現有沖突不想合并了
git merge --abort
取消合并即可
解決沖突
有的時候合并分支沖突是由于本地主分支沒有更新導緻,或者有時
git pull
的時候沖突,隻需要掉本地主分支,再重新拉一下遠端分支就好了。
# 隻保留 test 的修改
git checkout --theirs test.js
# 隻保留 master 的修改
git checkout --ours test.js
# 都保留
git checkout --ours/theirs test.js
# 檢視沖突,都行
git diff --theirs
git diff --ours
# 這個 --theirs 和 --ours 是啥?比如沖突的時候是這樣的
# <<<<<<<<< HEAD
# console.log('master') // 這個就是 --ours
# =========
# console.log('test') // 這個就是 --theirs
# >>>>>>>>> test