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
相关文章
相关标签/搜索