一、git reset 实现分支重置
即改变分支引用文件的内容。master 分支在版本库的引用目录.gif/refs中体现为一个引用文件.git/refs/heads/master,当有新文件提交时,引用refs/heads/master便指向新的提交。此外,可通过git reset将引用指向任一个存在的提交ID,该引用类似游标,且可人为更改。
- git reset --hard HEAD^ 将 master重置到上一个老的提交上(HEAD的父提交);--hard参数:破坏工作区未提交的改动,慎用。
- git reset --hard 47dc5eb 重置到某个提交ID
- git log --graph --oneline (--oneline参数:显示短小的提交ID;Git 1.6.3前可采用--pretty=oneline --abbrev-commit替代)
- cat .git/refs/heads/master 查看master分支的引用文件内容
二、git reflog挽救错误重置
git提供一个挽救机制,通过.git/logs目录下日志文件记录了分支的变更。默认非裸版本库(存在工作区)均提供分支日志功能,因为带有工作区的版本库有如下设置:git config core.logallrefupdates 。
- git reflog show master | head -5
- git reset --hard master@{1}
- 后者最新改变的信息放在末尾;
- 前者最新改变的信息放在最前,只显示每次改变的最终SHA1哈希值;此外,提供方便易记表达式:<refname>@{<n>},即引用<refname>之前第<n>次改变时的SHA1哈希值。
三、git reset详解
命令:
<commit>:可选项,可使用引用或提交ID,省略则表示使用了HEAD的指向作为提交ID
1)包含路径,避免路径与引用同名而发生冲突,可在路径前加两个连续的短线;
2)不会重置引用,不会改变工作区;
3)用指定提交状态(<commit>)下的文件(<paths>)替换掉暂存区中的文件;
4)如git reset HRAD <paths> === 取消之前执行的git add <paths>命令时改变的暂存区。
用法2:git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
1)不包含路径的用法会引起重置引用;
2)根据不同选项可对暂存区或工作区进行重置;
3)参数--hard:git reset --hard <commit> ,执行以下步骤
- 替换引用的指向:引用指向新的提交ID。
- 替换暂存区:暂存区的内容和引用指向的目录树一致。
- 替换工作区:工作区的内容变得和暂存区一致,也与HEAD所指向的目录树内容相同。
- 替换引用的指向:引用指向新的提交ID。即只更改引用的指向,不改变暂存区和工作区。
- 替换引用的指向:引用指向新的提交ID。
- 替换暂存区:暂存区的内容和引用指向的目录树一致。
- 即更改引用的指向及重置暂存区,但是不改变工作区。
- 仅用HEAD指向的目录树重置暂存区,工作区不会受到影响=== 将之前用git add命令更新到暂存区的内容撤出暂存区。
- 引用未改变=重置到HEAD
- 仅将文件filename的改动撤出暂存区,其他文件不改变=== git add filename的反向操作
- 工作区和暂存区不改变,引用向前回退一次。
- git commit --amend 修补提交命令=== $ git reset --soft HEAD^ $ git commit -e -F .git/COMMIT_EDITMSG
- 工作区不改变,暂存区会回退到上一次提交之前,引用也会回退一次。
- 彻底撤销最近提交。引用回退到前一次,且工作区和暂存区均回退到上一次提交状态。
- 自上一次以来的提交全部丢失。