Git進階使用——git reflog處理代碼丟失 & 協做開發保證git信息簡潔

git reflog 解決提交代碼丟失 detached-head

reflog 是 Git 操做的一道安全保障,它可以記錄幾乎全部本地倉庫的改變。包括全部分支 commit 提交,已經刪除(其實並未被實際刪除)commit 都會被記錄。總結而言,只要 HEAD 發生變化,就能夠經過 reflog 查看到。git

detached-head 代碼丟失找回

背景

平常開發中,切換分支誤操做,形成本地代碼修改丟失。github

此時,能夠藉助 git reflog 找回丟失的代碼修改。segmentfault

丟失產生緣由和步驟

首先在 master 分支上開發,此時線上出現 bug 且回到舊版本的 tag。這時 master 分支上有一部分代碼修改但未提交。緩存

master 分支上執行 git status,有未提交的代碼,以下圖所示安全

master 分支上執行 git tag查看標籤信息,以下圖所示bash

此時有未提交的代碼,而後執行 git checkout v1.0spa

這個時候,提示當前分支爲 detached HEAD命令行

而後再執行 git add ./git commitgit checkout master,切換回 master 分支。這個時候發現 detached HEAD 分支不見了,master 分支上未提交的代碼也不見了。3d

代碼找回

執行 git reflog 查看提交記錄指針

查找對應提交的 commitId247e11b,而後執行下述命令行,找回丟失的代碼

git checkout 247e11b    //檢出對應的提交
git checkout -b diff    //新建一個新的diff分支
git checkout master     //切換到master分支
git merge diff          //將新建的diff分支合併到master分支
複製代碼

刪除全部歷史提交記錄

此處介紹如何刪除全部歷史提交記錄,造成一個全新的倉庫。

  • 1 - Checkout
git checkout --orphan new_branch
複製代碼
  • 2 - Add all the files
git add -A

//等效於 git add --all 或 git add .
複製代碼

git add 中使用參數 -A--all 表示追蹤全部操做,包含新增、修改和刪除

Git 2.0版開始,-A 參數爲默認參數,即 git add . 等效於 git add -Agit add --all

  • 3 - Commit the changes
git commit -am "commit message"
複製代碼
  • 4 - Delete the branch
git branch -D master   //同時刪除本地和遠程分支
複製代碼
  • 5 - Rename the current branch to master
git branch -m master
複製代碼
  • 6 - force update your repository
git push -f origin master
複製代碼

下面對上述步驟進行說明

git checkout --orphan

若是你的某個分支上積累了無數次的無心義的提交,git log 信息滿天飛,那麼可使用 git checkout --orphan <new_branch_name>

  • 基於當前分支建立一個新的「孤兒(orphan)」的分支,沒有任何提交歷史,但包含當前分支全部內容
  • 執行上述命令後,工做區(Workspace)中全部文件均被認爲在該操做中新增(git statue 查看狀態,全部文件狀態均爲 new file,以下圖所示),此時執行 git add . 會把全部文件添加到緩存區(Index

  • 嚴格意義上說,執行 git checkout --orphan <new_branch_name> 後,建立的並非一個分支,由於此時 HEAD 指向的引用中沒有 commit 值。只有在進行一次提交後,它纔算得上真正的分支。

orphan 譯爲「孤兒」,該參數表示建立一個孤立的分支,沒有任何提交歷史,且與當前分支不存在任何關係(查看提交信息,可發現其爲一個孤立的點,以下圖所示)

孤兒(orphan)無父輩信息,同理,建立的分支也不包含任何歷史提交信息

git commit -am

git branch -m

重命名

git push -f origin master

git 項目協做——保證git信息簡潔

同一分支 git pull 使用 rebase

默認狀況下,git pull 使用的是 merge 行爲。多人協做開發時,會產生沒必要要的 merge 提交記錄,形成提交鏈混亂不堪。

推薦在同一個分支更新代碼時,使用 git pull --rebase

# 爲某個分支單獨設置,這裏是設置 dev 分支
git config branch.dev.rebase true
# 全局設置,全部的分支 git pull 均使用 --rebase
git config --global pull.rebase true
git config --global branch.autoSetupRebase always
複製代碼

分支合併使用 merge --no-ff

Usage

  • Fast-Forward:當前分支合併到另外一分支時,若是沒有衝突要解決,就會直接移動文件指針,而且不會產生合併提交記錄。該過程當中,存在git 文件指針快速移動, 所以該過程稱爲 Fast-Forward
  • --no-ff(no fast foward):每一次的合併,都會建立一個新的 commit 記錄。使用 --no-ff,能夠保持原有分支提交鏈的完整性,而且當該分支被刪除時,提交信息依舊存在。

git-merge--no-ff-1

結合上圖分析,在 dev(綠色) 分支上檢出 feature-1 分支(藍色),且 dev 分支不進行任何提交

  • 直接 merge,默認採用 Fast-Forward,兩個分支的提交鏈會合併爲一條直線,不利於後期代碼審查和維護
  • 使用 git merge --no-ff feature-1 合併代碼,會產生一個新的提交,且兩個分支的提交鏈不會重疊,利於後期代碼審查和維護

merge 默認設置

git merge 默認使用 fast-forward,能夠經過以下方式,修改成默認使用 --no-ff

git config --global merge.commit no
git config --global merge.ff no
複製代碼

此外,SourceTree 在設置中也能夠設置 --no-ff

git-merge--no-ff-2
相關文章
相關標籤/搜索