當前分支圖git
切換到以前的某一次提交shell
執行命令bash
$ git checkout de11fa87ea
複製代碼
提示,當前位於「分離頭指針」狀態編輯器
分支圖gitlab
注意測試
使用場景fetch
此處演示分離頭指針丟失commit的狀況和補救措施ui
使用IDE修改文件並提交,忽略全部警告,修改後分支圖以下this
此時接到其餘需求,須要切換分支進行緊急修復spa
執行命令
$ git checkout master
複製代碼
分支切換成功,並彈出提示和告警
Warning: you are leaving 1 commit behind, not connected to any of your branches:
199ac20 遊離狀態修改文件
If you want to keep it by creating a new branch, this may be a good time to do so with:
git branch 199ac20
Switched to branch 'master' Your branch is up to date with 'origin/master'.
此時查看分支圖,剛纔的commit已經不可見
此時發現剛纔的commit十分重要,可根據git的提示進行補救
執行命令
$ git branch hot-fix 199ac20
複製代碼
再次查看分支圖,可見commit已經恢復
如下操做僅適用於本地分支,無遠程分支協同工做的狀況
amend
當前分支圖
執行命令
$ git commit --amend
複製代碼
自動彈出編輯器
修改後保存並關閉編輯器便可,輸出以下
再次查看分支圖
rebase
現計劃修改以下message
使用IDE拷貝其父提交的SHA值
執行命令,-i
表示交互式執行
$ git rebase -i 199ac203c90f881024c6870d56517df9e2080841
複製代碼
自動彈出編輯器
同時包含提示操做
Rebase 199ac20..bfe2b7f onto 199ac20 (3 commands)
Commands: p, pick = use commit r, reword = use commit, but edit the commit message e, edit = use commit, but stop for amending s, squash = use commit, but meld into previous commit f, fixup = like "squash", but discard this commit's log message x, exec = run command (the rest of the line) using shell b, break = stop here (continue rebase later with 'git rebase --continue') d, drop = remove commit l, label
These lines can be re-ordered; they are executed from top to bottom.
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
Note that empty commits are commented out
因而可知「變基」支持不少操做,此處須要使用的是reword
,修改目標提交的命令爲r
保存並關閉編輯器,會自動彈出新編輯器界面
修改後保存並關閉便可,輸出以下
查看分支圖
rebase
現計劃合併3個commit
使用IDE拷貝其父SHA值
執行命令
$ git rebase -i 199ac203c90f881024c6870d56517df9e2080841
複製代碼
此處使用squash
,官方介紹以下
s, squash = use commit, but meld into previous commit
修改內容以下,說明將中間兩個合併進第一個commit中
保存後關閉,會彈出新的編輯器界面,提示能夠輸出合併commit的message
編寫message
保存後關閉,提示修改爲功
查看分支圖
演示不一樣分支合併策略效果,當前的分支圖以下
如今將hot-fix合併進master
merge commit
gitlab默認合併請求使用的策略
因爲沒有衝突,能夠線上直接合並
其對應執行的命令以下
Step 1. Fetch and check out the branch for this merge request
$ git fetch origin $ git checkout -b hot-fix origin/hot-fix 複製代碼
Step 2. Review the changes locally
Step 3. Merge the branch and fix any conflicts that come up
$ git fetch origin $ git checkout origin/master $ git merge --no-ff hot-fix 複製代碼
Step 4. Push the result of the merge to GitLab
$ git push origin master 複製代碼
合併完成
查看分支圖,故當前分支會影響特性分支併產生新的提交
提交合並請求的時候勾選策略Squash commits when merge request is accepted
其對應執行的命令以下(與默認策略一致)
Step 1. Fetch and check out the branch for this merge request
$ git fetch origin $ git checkout -b hot-fix origin/hot-fix 複製代碼
Step 2. Review the changes locally
Step 3. Merge the branch and fix any conflicts that come up
$ git fetch origin $ git checkout origin/master $ git merge --no-ff hot-fix 複製代碼
Step 4. Push the result of the merge to GitLab
$ git push origin master 複製代碼
合併成功
查看分支圖,可見其影響特性分支,會產生新的提交,同時覆蓋特性分支最後一次提交
squash merge
GitHub支持squash merge
合併策略,此處經過命令行執行測試
$ git merge --squash origin/hot-fix
$ git commit -m "squash commit"
複製代碼
查看分支圖,特性分支不變,目標分支合併提交後產生一條提交,效果與GitLab合併提交相似,但命令使用方式不一樣
注意:squash merge
會變動提交者做者信息,這是一個很大的問題,後期問題追溯很差處理
rebase merge
該策略也是GitHub支持的合併策略,可能會產生較多衝突
選擇合併策略,最後一種即變基合併策略
合併成功
查看分支圖,其產生的三次提交即變基合併的結果,不會影響特性分支,也不會變動提交人,相似cherry pick
回滾策略分爲兩種,一種是合併後回滾,一種是普通提交回滾,不一樣回滾策略操做方法不一樣
當前分支圖,計劃回滾最新提交
直接在IDE中執行revert
操做便可
回滾會產生新的提交,回滾結束
此時分支圖,使用merge commit
方式進行過一次合併,此時不想要合併的結果,想恢復到未合併狀態
revert
此時IDE已經不支持經過revert進行回滾合併操做,經過命令行強行執行
查找SHA值
回滾merge
須要加上-m
參數git就知道到底要revert哪個merge
$ git revert -n 25d7b405a4d50fe1b36019d90276973a8ed9160d -m 1
複製代碼
回滾後作一次commit便可,使用默認的message後以下
驗證回滾結果,使用兩個提交進行差別比對
無差別,回滾看似成功了
此時在原分支作了修復後再進行合併
報沒法合併,由於分支已經進行過合併
reset
使用reset操做到上一次提交
使用--hard
參數,丟棄後續的commit
此時繼續進行操做,並支持從新合併
說明:禁止類說明是對開發人員禁止,而該命令在必要時候依然須要由配置管理員使用
push -f
官方使用說明
-f, --force force updates
緣由:
-f
以後,本地分支會強行推送到遠端,若本地分支落後於遠端分支也不會彈出提示,由此致使遠程commit丟失適用場景:
rebase
此處對場景進行模擬,正常狀況下,多位開發者對公共分支common-branch
進行修改,分支圖以下
另外一開發者在本地修改後執行變基操做,此處以修改歷史提交message爲例
變基
錄入變基信息
變基成功
此時查看本地分支圖,可見產生了新的分支路徑,同時遠程message並無變化,故rebase對存在遠程分支的狀況無效
變基後推送到遠端分支,提示須要合併,選擇「合併」
合併後分支圖以下
此時其餘開發者修改文件後並fetch
遠程分支查看變動狀況以下
此時沒法對遠程分支進行push
操做
pull遠程分支在本地合併後從新推送,此時在本地再產生一次合併
此時能夠成功推送
由此一來一回操做致使大量沒必要要的合併操做,並可能致使大量衝突,而且沒有解決問題
reset --hard
官方對reset
操做用法說明
usage: git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [] or: git reset [-q] [] [--] ... or: EXPERIMENTAL: git reset [-q] [--stdin [-z]] [] or: git reset --patch [] [--] [...]
-q, --quiet be quiet, only report errors --mixed reset HEAD and index --soft reset only HEAD --hard reset HEAD, index and working tree --merge reset HEAD, index and working tree --keep reset HEAD but keep local changes --recurse-submodules[=<reset>] control recursive updating of submodules -p, --patch select hunks interactively -N, --intent-to-add record only the fact that removed paths will be added later -z EXPERIMENTAL: paths are separated with NUL character --stdin EXPERIMENTAL: read paths from <stdin> 複製代碼
緣由:
適用場景