git重要的三个命令stash, checkout, reset的一些总结
最近学习了git的一些重要命令的使用,总结出来跟大家分享:
使用git的几种常见情形:
(1)正常的情形,修改工作区的文件然后add,commit,我使用git一般的流程是:
git status ——> git stash save "message..."——> git pull --> git stash pop ——> git add . 或 git add filename ——> git commit -m 'message...' ——> git push
其中 . 表示所有的文件。
(2)只需要撤销工作区的文件修改,即用暂存区的文件覆盖工作区中的文件
git checkout -- filename
(3)当修改的文件已经add到暂存区,需要撤销这次添加,即撤销上一次git add filename 操作:
git reset -- filename / git reset HEAD filename
撤销暂存区内所有的文件改动:
git reset / git reset HEAD
(4)当对上次提交不满意,可以让HEAD指针回退,而暂存区和工作区可以不用动
git reset --soft HEAD^
(5)如果让工作区不改变,而暂存区和引用(HEAD指针)回退一次
git reset --mixed HEAD^
(6)当需要彻底撤销最近的提交,HEAD指针、暂存区、工作区都回到上次的提交状态,自上一次以来的提交全部丢失
git reset --hard HEAD^
1、git stash 用于保存和恢复工作进度。
git stash
保存当前的工作进度。会分别对暂存区和工作区的状态进行保存。
git stash list
显示进度列表。此命令显然暗示了git stash 可以多次保存工作进度,并用在恢复时候选择。
git stash drop [
其他:
git stash pop [--index] [
--index 参数:不仅恢复工作区,还恢复暂存区
<stash> 指定恢复某一个具体进度。如果没有这个参数,默认恢复最新进度
如:以下命令恢复编号为0的进度的工作区和暂存区
# git stash pop --index stash@{0}
(1)如果不使用任何参数,会恢复最新保存的工作进度,并将恢复的工作进度从存储的工作进度列表中清除。
(2)如果提供<stash>参数(来自git stash list显示的列表),则从该<stash>中恢复。恢复完毕也将从进度列表中删除<stash>。
(3)选项--index除了恢复工作区的文件外,还尝试恢复暂存区。这也就是为什么恢复进度的时候显示的状态和保存进度前的略有不同。
git stash [save [--patch] [-k|--[no]keep-index] [-q|--quiet] [
这条命令实际上是git stash命令的完整版。
(1)save,即如果需要在保存工作进度的时候使 用指定的说明,必须使用如下格式:
git stash save “message...”
(2)使用参数--patch会显示工作区和HEAD的差异,通过对差异文件的编辑决定在进度中 最终要保存的工作区的内容,通过编辑差异文件可以在进度中排除无关内容。
(3)使用-k或者--keep-index参数,在保存进度后不会将暂存区重置。默认会将暂存区和工 作区强制重置。
git stash apply [--index] [
除了不删除恢复的进度之外,其余和git stash pop 命令一样。
2、检出命令git checkout是git最常用的命令之一,同时也是一个很危险的命令,因为这条命令会重写工作区。
检出命令的用法如下:
用法一:git checkout [-q] [
注:
<1> 为了避免路径和引用(或者提交ID)同名而发生冲突,可以在
(1)省略commit:用暂存区的文件覆盖工作区的文件。
(2)加上commit:用指定提交中的文件覆盖暂存区和工作区中的文件。
<3>在用法二中,会改变HEAD头指针
(1)加上<branch>:因为只有HEAD切换到一个分支才可以对提交进行跟踪,否则仍然会进入“分离头指针”的状态。在“分离头指针”状态下的提交不能被引用关联到,从而可能丢失。
所以用法二(加上
<4>在用法三中,主要是创建和切换到新的分支(
下图所示的版本库模型图描述了git checkout实际完成的操作。
使用:
git checkout branch
检出branch分支。要完成图中的三个步骤,更新HEAD以指向branch分支,以及用branch 指向的树更新暂存区和工作区。
git checkout / git checkout HEAD
汇总显示工作区、暂存区与HEAD的差异。
git checkout -- filename
用暂存区中filename文件来覆盖工作区中的filename文件。相当于撤销自上次执行git add filename以来(如果执行过)的本地修改。
git checkout -- . / git checkout .
这条命令最危险!会撤销所有本地的修改(相对于暂存区)。相当于用暂存区的所有文件直接覆盖本地文件,不给用户任何确认的机会!
3、git reset是Git最常用的命令之一,也是最危险最容易误用的命令。
用法一:git reset [-q] [
注:
(1)第一种用法(包含了路径
例如:git reset HEAD
(2)第二种用法(不使用路径
参照下面的版本库模型图,可以看不同的参数对第二种重置语法的影响。
命令格式:git reset [--soft | --mixed | --hard] [
(1)使用参数--soft,如 git reset --soft
(2)使用参数--mixed或者不使用参数(默认为--mixed),如 git reset
(3)使用参数--hard,如git reset --hard
使用:
git reset / git reset HEAD
仅用HEAD指向的目录树重置暂存区,工作区不会受到影响,相当于将之前用git add命令更新到暂存区的内容撤出暂存区。引用也未改变,因为引用重置到HEAD相当于没有重置。
git reset -- filename / git reset HEAD filename
仅将文件filename 的改动撤出暂存区,暂存区中其他文件不改变。相当于命令git add filename 的反射操作。
git reset --soft HEAD^
工作区和暂存区不改变,但是引用向前回退一次。当对最新的提交说明或者提交的更改不满意时,撤销最新的提交以便重新提交。
之前提到过修补提交命令git commit --amend,用于对最新的提交进行重新提交以修补错误的提交说明或者错误的提交文件。修补提交命令实际上相当于执行了下面两条命令。(注:文件.git/COMMIT_EDITMSG保存了上次的提交日志)
git reset --soft HEAD^
git commit -e -F .git/COMMIT_EDITMSG
git reset HEAD^ / git reset --mixed HEAD^
工作区不改变,但是暂存区会回退到上一次提交之前,引用也会回退一次。
git reset --hard HEAD^
彻底撤销最近的提交。引用回退到前一次,而且工作区和暂存区都会回退到上一次提交的状态。自上一次以来的提交全部丢失。