在Git
使用过程中,一种很常见的情况是:发现某个已经提交到仓库里的代码文件有致命的bug
,必须将代码回滚到上一个版本,在这种情况下就显示出了Git
的强大。Git
为每次提交,都保留了日志,根据提交日志,Git
可以方便地进行版本回退。本实训通过介绍Git
日志相关知识和操作,使大家掌握Git
版本回退相关内容。
一、回到前一次提交 git revert
任务描述
如果提交到本地仓库中的代码发现了
bug
,就必须将代码回到上一个版本。而在Git
中,一次提交就对应着一个版本,因此可以根据日志信息进行版本回退。本关任务:将本地仓库回退到上一个版本。
相关知识
强大的git log
在之前,我们已经介绍了
git log
的基本使用方法,这里我们要进一步介绍git log
的使用。
- 查看提交的内容差异
git log
提供了-p
参数,用于查看每次提交之间的内容差异,如下:git log -p
即可显示每次提交之间的变化:- 而如果想限制显示的范围,则可以再添加参数用于限定:
如上,则仅显示最近的两次更新。 如上所示,这一选项附带了每次git log -p -2
commit
的内容变化,这就为代码审查或者浏览某个搭档的修改内容,提供了很好的参考。其他
git log
选项:
单词层面对比
Git
提供了--word-diff
选项,可以显示单词层面的差异。当需要在书籍、论文这种很大的文本文件上,进行对比的时候,这个功能就非常有用。显示简要的增改行数
Git
提供了--stat
选项,则可以仅显示增加或者减少了多少行。
pretty
选项 使用--pretty
选项选项,可以指定不同的显示属性,如oneline
将每个提交放在一行显示。short
,full
和fuller
可以指定展示的信息的多少。git revert实现版本回退
版本回退可以用
git revert
命令。git revert
撤销提交时,会保留所撤销的提交的记录和历史,并将撤销操作做为一次新的提交。即提交一个新的版本,将需要revert
的版本的内容再反向修改回去,版本会递增,不影响之前提交的内容。其具体的使用方法如下:git reset实现版本回退
git reset
也能实现版本回退,但是git revert
和git reset
也存在一定的区别 :
git revert
是用一次新的commit
来回滚之前的commit
,git reset
是直接删除指定的commit
;- 在回滚这一操作上看,效果差不多。但是,在日后继续
merge
以前的老版本时有区别。因为git revert
是用一次逆向的commit
,“中和”之前的提交,因此日后合并老的branch
时,导致这部分改变不会再次出现。但是git reset
是把某些commit
在某个branch
上删除,因而和老的branch
再次merge
时,这些被回滚的commit
应该还会被引入;git reset
是把HEAD
向后移动了一下,而git revert
是HEAD
继续前进,只是新的commit
的内容和要revert
的内容正好相反,能够抵消要被revert
的内容。
git reset
用法如下:
git reset HEAD
回到前一次commit
。也可以用于将错误的文件添加进暂存区后,想回退取消,如:git reset HEAD 文件名
git reset HEAD^
回到前前一次commit
。git reset commit
比如:commit = fa042ce57ebbe5b
,回到指定的版本,撤销也会作为一次提交进行保存。另外
git reset
也可以指定reset
的模式:hard
、soft
、mixed
、merged
、keep
。 这几种模式的差别如下:
--soft
缓存区和工作目录都不会被改变;--mixed
– 默认选项。缓存区和你指定的提交同步,但工作目录不受影响;--hard
– 缓存区和工作目录,都同步到你指定的提交。几种模式的具体使用方法如下:
#直接丢弃工作区和暂存区的修改 git reset --hard HEAD #暂存区内容保留,工作区修改丢弃 git reset --mixed HEAD #暂存区和工作区内容都保留 git reset --soft HEAD
编程要求
平台已准备了本地仓库
gitTraining
,并在master
分支进行了三次提交:
- 第一次提交:添加了
helloGit1
;- 第二次提交:添加了
helloGit2
;- 第三次提交:添加了
helloGit3
。现在发现,
helloGit3
内容有错误,需要撤销第三次提交,即将HEAD
指向第二次提交。 本关的编程任务是,补全右侧代码片段中Begin
至End
中间的脚本,撤销最近一次提交。
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以撤销最近一次提交
#********** Begin **********#
#git reset --hard HEAD~1
git revert HEAD
#********** End **********#
二、回到指定提交
编程要求
平台已准备了本地仓库
gitTraining
,并在master
分支进行了三次提交:
- 第一次提交:添加了
helloGit1
;- 第二次提交:添加了
helloGit2
;- 第三次提交:添加了
helloGit3
。现在发现,
helloGit3
、helloGit2
内容均有错误,需要撤销第三次、第二次提交。即将HEAD
指向第一次提交。 本关的编程任务是,补全右侧代码片段中Begin
至End
中间的脚本,撤销最近两次提交,以回到第一次提交,即将HEAD
指向第一次提交,需要选择--hard
模式。
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以回到第一次提交的版本
#********** Begin **********#
git reset --hard HEAD~2
#********** End **********#
`git reset --hard HEAD~2` **命令用于将当前分支回退到上一个提交(commit),同时清除工作目录和暂存区的改动**。
该命令由三部分组成:
1. `git reset`: 这是Git的一个基本命令,用来重置当前分支的HEAD指针以及工作目录和暂存区的状态。
2. `--hard`: 这个选项告诉Git不仅要移动HEAD指针,还要清除所有相关的改动,包括工作目录和暂存区的更改。
3. `HEAD~2`: 这里的`HEAD`代表当前分支最新的提交,而`~2`表示要回退到当前提交的前两个版本,即祖父级提交。使用这个命令时需要非常小心,因为它会丢弃自指定提交之后的所有工作成果,包括未提交的修改和新增的文件。如果确定要执行这样的操作,建议先备份重要的工作内容,以防万一。
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以回到第一次提交的版本
#********** Begin **********#
git revert HEAD~2..HEAD
#git reset --hard HEAD~2
#********** End **********#
`git revert HEAD~2..HEAD` **命令用于撤销当前分支中最近两个提交的更改**。
该命令由两部分组成:
1. `git revert`: 这是Git的一个基本命令,用来创建一个新的提交,该提交会撤销指定范围内的提交的更改。
2. `HEAD~2..HEAD`: 这里的`HEAD`代表当前分支最新的提交,而`~2`表示要回退到当前提交的前两个版本,即祖父级提交。`..`表示范围,所以`HEAD~2..HEAD`表示从祖父级提交到当前提交的范围。使用这个命令时,Git会自动生成一个新的提交,该提交会撤销指定范围内所有提交的更改。这样做的好处是保留历史记录,并且不会对工作目录和暂存区产生任何影响。但是,如果需要撤销的提交非常多,那么执行这个命令可能会比较耗时。
三、 撤销修改
任务描述
在本地开发中,经常遇到的一个问题是:对一个文件的修改有错误,需要丢弃修改。如何准确地丢弃指定的修改,是一个关键的操作。
本关任务:撤销本地的修改。
相关知识
git reset实现版本回退
当将有错误的文件
add
进暂存区后,可以使用git reset
丢弃修改。即:git reset HEAD 文件名
但此时修改仍旧保留在工作区。
如果尚未
add
进暂存区,则可以使用:git reset --hard HEAD
这样就能彻底丢弃修改,即将修改从暂存区及工作区彻底删除。 #####git checkout丢弃修改 当将错误的文件
add
进暂存区后,使用git checkout
无法将修改从暂存区中撤销,必须要先使用git reset
将修改从暂存区中撤销。git checkout丢弃修改
当将错误的文件
add
进暂存区后,使用git checkout
无法将修改从暂存区中撤销,必须要先使用git reset
将修改从暂存区中撤销。git chekcout -- hello
通过这种方式,就可将
hello
文件自上个commit
之后,尚未add
进暂存区的修改丢弃。编程要求
平台已为你准备了本地仓库
gitTraining
,并在master
分支进行了一次提交,将文件helloGit
提交到了本地仓库。随后,平台又对helloGit
进行了修改,但是尚未添加(即add
)到暂存区。现在发现此修改有错误需要丢弃。本关的编程任务是,补全右侧代码片段中
Begin
至End
中间的脚本,丢弃helloGit
中尚未添加到暂存区的修改。
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以丢弃helloGit的修改
#********** Begin **********#
#git checkout -- helloGit
git reset --hard HEAD
#********** End **********#
四、删除文件
任务描述
在
Git
使用过程中,涉及到撤回的操作,还有从暂存区或者分支删除文件。比如你错误地将测试过程中产生的日志文件提交到了暂存区或者分支上面去了,那么你可能就需要删除文件。本关任务:彻底删除本地仓库中某个文件。
相关知识
删除文件需要用到的命令是
git rm
,且git rm
有参数--cached
。 当我们需要删除暂存区或分支上的文件,同时工作区也不再需要这个文件了,可以使用:git rm 文件路径
当我们需要删除暂存区或分支上的文件,但本地又需要使用, 只是不希望这个文件被提交到版本库,可以使用:
git rm --cached 文件路径
文件已添加至暂存区
如果文件被添加到了暂存区,这种情况下直接使用
git rm file_path
会报错:$ git rm hello.txt error: the following file has changes staged in the index: hello.txt (use --cached to keep the file, or -f to force removal)
根据提示我们可以得知,这个时候,如果不想保留
hello.txt
,则可以使用:git rm hello.txt -f
如果想保留
hello.txt
到工作区则可以使用:git rm --cached hello.txt
文件已提交至分支
如果文件已经被提交到了某个分支,则可以使用如下命令:
#从当前分支中彻底删除‘文件路径’指定的文件 git rm 文件路径
具体使用方法如:
git rm hello.txt
或者:
#从本地版本库中将‘文件路径’指定的文件删除,并保留到工作区 git rm --cached 文件路径
具体使用方法如下:
git rm --cached hello.txt
但是无论使用哪种方式,都相当于在本地做了修改,在
git rm --cached
之后,使用git status
查看版本库状态,可以得到如下输出:因此,还需要通过
git commit
操作将修改提交。通过以上分析可知,从仓库中删除文件的一般过程为:
git rm <--cached> 文件名 git commit -m "提交信息"
编程要求
平台已为你准备了本地仓库
gitTraining
,并在master
分支进行了一次提交,将文件helloGit
提交到了本地仓库。现在需要将helloGit
从版本库删除,但还需要将其保留在工作区。 本关的编程任务是,补全右侧代码片段中Begin
至End
中间的脚本,将helloGit
从本地版本库中删除,但仍保留在工作区。
#进入gitTraining
cd gitTraining
#请在下方Begin至End星号线内填写git命令以丢弃helloGit的修改
#********** Begin **********#
git rm --cached helloGit
#********** End **********#