Git进阶使用——git reflog处理代码丢失 & 协作开发保证git信息简洁

git reflog 解决提交代码丢失 detached-head

reflog 是 Git 操作的一道安全保障,它能够记录几乎所有本地仓库的改变。包括所有分支 commit 提交,已经删除(其实并未被实际删除)commit 都会被记录。总结而言,只要 HEAD 发生变化,就可以通过 reflog 查看到。

detached-head 代码丢失找回

背景

日常开发中,切换分支误操作,造成本地代码修改丢失。

此时,可以借助 git reflog 找回丢失的代码修改。

丢失产生原因和步骤

首先在 master 分支上开发,此时线上出现 bug 且回到旧版本的 tag。这时 master 分支上有一部分代码修改但未提交。

master 分支上执行 git status,有未提交的代码,如下图所示

master 分支上执行 git tag查看标签信息,如下图所示

此时有未提交的代码,然后执行 git checkout v1.0

这个时候,提示当前分支为 detached HEAD

然后再执行 git add ./git commitgit checkout master,切换回 master 分支。这个时候发现 detached HEAD 分支不见了,master 分支上未提交的代码也不见了。

代码找回

执行 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

https://juejin.im/post/5e362f8c51882526163504cf

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论