记录git reset、git checkout及git stash的常见用法,参考自《Git权威指南》及Git的官方使用说明

git reset

git reset 命令 可以重置工作区、暂存区和分支指向引用(注意是分支引用,不是HEAD),主要分为两种用法,如下

用法简介

  • git reset [commit] [--] <paths>:该用法不改变工作区和分支引用,但会重置暂存区内指定路径的文件,相当于取消暂存区内git add <paths>产生的改动
  • git reset [--mixed|--soft|--hard|--merge|--keep]:该用法根据指定模式的不同可以在改变分支引用的同时改变暂存区和工作区,以下展示了几种主要模式产生的变化

模式介绍

  • --hard:分支引用指向会改变,暂存区和工作区的内容也会被重置,即工作区的改动和暂存区的改动都会和分支引用改变后的目录树保持一致
  • --soft:分支引用指向会改变,暂存区及工作区内容不改变,git reset --soft HEAD^可帮助回退到上一次提交,适用于提交后对提交说明或提交内容不满意下重新提交
  • --mixed:默认下使用的模式,分支引用会改变,且重置暂存区,但不改变工作区
  • --merge:该模式下工作区和暂存区需保持一致,否则会重置失败,重置后分支引用改变,暂存区和工作区的改动全部被丢弃(???可能有误,官方文档看不懂,中文版的文档又没有介绍╮(╯▽╰)╭)
  • --keep:该模式下工作区和暂存区需保持一致,否则会重置失败,暂存区重置,工作区会在重置后的基础上加上原先的改动,假如重置后冲突则重置失败

以下为各重置模式的效果展示表格:

模式 工作区 暂存区 版本库(分支引用)
soft
mixed
hard
merge
keep ✔+⚪

注: ✔为重置,✘为无变化,⚪为新改动

git checkout

git checkout 命令用于切换分支或恢复工作区(主要)内文件,用法如下

  1. git checkout [-q] [commit] [--] [paths] ...
  2. git checkout [branch]
  3. git checkout [-m] [-b] [new_branch] [start_point]

第一种用法主要用于还原工作区内容,默认是从暂存区还原,指定参数[commit]情况下使用对应提交还原工作区和暂存区。

第二种用法主要用于改变HEAD指针指向。此处的参数[branch]可以是分支名,也可以是某个提交id,需要注意的是只有当HEAD指向一个分支时才能对其进行跟踪,如切换到的是某个具体提交,则此时HEAD处于“分离头指针”状态,该状态下的提交不能被引用关联到,可能会丢失。需要慎用,如省略[branch]时则相当于对当前暂存区进行状态检查。

第三种用法主要用于创建和切换到新的分支上。新分只从指定的[start_point]指向的提交开始,不指定时默认从当前分支的最新提交开始。

以下是上面三种用法的一些常用命令及其产生的效果

命令 效果
git checkout 展示暂存区和分支最新提交间的差异
git checkout -- <paths> 使用暂存区内指定路径文件替换工作区文件,当路径参数为.时为还原所有
git checkout branch -- filename 使用指定分支指向的提交的文件替换当前工作区和暂存区
git checkout -b <branch> <start_point> 从指定的提交id<start_point>开始创建名为<branch>的新分支并切到该分支上

git stash

git stash 命令用于保存和恢复工作区和暂存器的进度

  • git stash save [-k] [-u] [-a] <message>:保存工作区及暂存区进度,并重置暂存区和工作区到分支引用指向的提交,默认只保存跟踪文件的修改,即之前git add过的文件,-u参数可以将未跟踪的文件一起保存,-k参数使保存后暂存区不重置,-a参数将所有修改保存包括被.gitignore文件忽略的文件,<message>为保存进度的说明信息

  • git stash pop [--index] <stash>:将指定的进度恢复到当前分支上,并在恢复成功后删除进度,默认情况下只恢复到工作区,--index参数可以将进度上的改动应用到工作区及暂存区,<stash>可以是stash@{0},即ref/stash的最新指向。

  • git stash apply [--index] <stash>:将指定的进度恢复到当前分支上,恢复后不会删除进度,其他信息参考命令git stash pop

  • git stash show <stash>:展示进度信息与当前工作区间的差异

  • git stash clear:清除所有进度

  • git stash list:列出所有进度

  • git stash drop <stash>:删除指定进度