个人主页Milestone-里程碑❄️个人专栏: 力扣hot100 CLinuxGitMySQL心向往之行必能至一.Git 版本回退与撤退修改之前我们也提到过Git 能够管理⽂件的历史版本这也是版本控制器重要的能⼒。如果有⼀天你发现之前前的⼯作做的出现了很⼤的问题需要在某个特定的历史版本重新开始这个时候就需要版本回退的功能了。1.1版本回退参数版本库状态暂存区状态工作区状态适用场景注意事项--soft回退到指定版本保持当前状态不变保持当前状态不变仅调整版本库保留暂存 / 工作区内容---mixed回退到指定版本回退到指定版本保持当前状态不变默认选项回退版本库 暂存区无需额外参数默认生效--hard回退到指定版本回退到指定版本回退到指定版本彻底回退所有区域到历史版本工作区有未提交代码时禁止使用会丢失未提交内容HEAD说明◦可直接写成 commit id表⽰指定退回的版本◦HEAD 表⽰当前版本◦HEAD^ 上⼀个版本◦HEAD^^ 上上⼀个版本◦以此类推...•可以使⽤ 〜数字表⽰◦HEAD~0 表⽰当前版本◦HEAD~1 上⼀个版本◦HEAD^2 上上⼀个版本◦以此类推...在上节课我们知道了ReadMe经过了两次提交,日志为lcbhcss-ecs-1cde:~/gitcode$ git log --prettyoneline 9abf140c35ac62624f4170932dc9808ab93fc5e8 (HEAD - master) modify ReadMe d908770ac1a99192cb8f272a3f4cb0ef9397ba99 add 3 files ef866eba4f5a0727c0ce203db456b4e098743da1 add first file我们使用git reset --hard回退到第一次提交,并使用cat 和git config查看,确认lcbhcss-ecs-1cde:~/gitcode$ git reset --hard ef866eba4f5a0727c0ce203db456b4e098743da1 HEAD is now at ef866eb add first file lcbhcss-ecs-1cde:~/gitcode$ la .git ReadMe lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone lcbhcss-ecs-1cde:~/gitcode$ git reflog ef866eb (HEAD - master) HEAD{0}: reset: moving to ef866eba4f5a0727c0ce203db456b4e098743da1结果也确实如此,同时暂存区和工作区也修改了但如果我们后悔了,想进行回退呢?那也是可以的,通过前面的git config拿到最晚修改的ReadMe id进行修改lcbhcss-ecs-1cde:~/gitcode$ git reset --hard 9abf140c35ac62624f4170932dc9808ab93fc5e8 HEAD is now at 9abf140 modify ReadMe lcbhcss-ecs-1cde:~/gitcode$ la file1 file2 file3 .git ReadMe到这里一般回退功能就演示完毕了但是如果我后悔了想再回到 version3 怎么办我们可以继续使用 git reset 命令回退到 version3 版本 但是我们必须拿到 version3 的 commit id 去指定回退版本。但是我们看到了 git log 并不能打印出 version3 的 commit id ,运气好的话我们可以从终端上去找找之前的记录运气不好的话 commit id 就已经被我们搞丢了~~值得一提的是 Git 还提供了一个 git reflog 命令能补救一下该命令用来记录本地的每一次指令。lcbhcss-ecs-1cde:~/gitcode$ git reflog 9abf140 (HEAD - master) HEAD{0}: reset: moving to 9abf140 ef866eb HEAD{1}: reset: moving to ef866eb ef866eb HEAD{2}: reset: moving to ef866eba4f5a0727c0ce203db456b4e098743da1 9abf140 (HEAD - master) HEAD{3}: reset: moving to 9abf140c35ac62624f4170932dc9808ab93fc5e8 9abf140 (HEAD - master) HEAD{4}: reset: moving to 9abf140c35ac62624f4170932dc9808ab93fc5e8 ef866eb HEAD{5}: reset: moving to ef866eba4f5a0727c0ce203db456b4e098743da1 9abf140 (HEAD - master) HEAD{6}: commit: modify ReadMe d908770 HEAD{7}: commit: add 3 files ef866eb HEAD{8}: commit (initial): add first file而每行开头的数字这些就是修改的commit id,而如果想要回到最新的版本,就--hard接上最后modify的,即上面的commit : modify ReadMe这样你就可以很⽅便的找到你的所有操作记录了但d95c13f这个是啥东西这个是version3的commit id的部分。没错Git 版本回退的时候也可以使⽤部分commit id来代表⽬标版本。可往往是理想很丰满现实很⻣感。在实际开发中由于⻓时间的开发了导致commit id早就找不到了可突然某⼀天我⼜想回退到 version3那该如何操作呢貌似现在不可能了。。。补充:值得说的是Git 的版本回退速度⾮常快因为 Git 在内部有个指向当前分⽀此处是master的HEAD 指针refs/heads/master⽂件⾥保存当前master分⽀的最新commit id。当我们在回退版本的时候Git 仅仅是给refs/heads/master 中存储⼀个特定的version可以简单理解成如下⽰意图1.2 撤退修改如果我们在我们的⼯作区写了很⻓时间代码越写越写不下去觉得⾃⼰写的实在是垃圾想恢复到 上⼀个版本,这时就需要根据不同场景进行修改场景一:未git add至暂存区,在工作区git checkout -- [file]命令中的 -- 很重要切记不要省略⼀旦省略该命令就变为其他意思了友情提示千万不要想着用什么git diff xxx找到差异去手动删除那要是改的地方多得删多久啊这不得累麻了//向ReadMe新增一行代码 lcbhcss-ecs-1cde:~/gitcode$ echo It is shift ReadMe lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone Hello world It is shift //回退到上一次的git add / git commit lcbhcss-ecs-1cde:~/gitcode$ git checkout -- ReadMe lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone Hello world场景二:已经git add到暂存区,但还未commitadd 后还是保存到了暂存区怎么撤销呢//向ReadMe新增一行代码 lcbhcss-ecs-1cde:~/gitcode$ echo It is shift ReadMe lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone Hello world It is shift //提交至暂存区并查看状态 lcbhcss-ecs-1cde:~/gitcode$ git add ReadMe lcbhcss-ecs-1cde:~/gitcode$ git status On branch master Changes to be committed: (use git restore --staged file... to unstage) modified: ReadMe那我们该怎么做呢我们来回忆一下之前学过的 git reset 回退命令。该命令如果使用 --mixed 参数可以将暂存区的内容回退到指定的版本内容但工作区文件保持不变我们再接着用上面场景一的方法解决一下不就好了。总的来说就是先将暂存区修改撤销到工作区再丢弃工作区修改//# 先将暂存区修改撤销到工作区--mixed 是默认参数可以省略 lcbhcss-ecs-1cde:~/gitcode$ git reset HEAD ReadMe Unstaged changes after reset: M ReadMe lcbhcss-ecs-1cde:~/gitcode$ git status On branch master Changes not staged for commit: (use git add file... to update what will be committed) (use git restore file... to discard changes in working directory) modified: ReadMe no changes added to commit (use git add and/or git commit -a) //# 类似于场景一丢弃工作区的修改 lcbhcss-ecs-1cde:~/gitcode$ git checkout -- ReadMe lcbhcss-ecs-1cde:~/gitcode$ git status On branch master nothing to commit, working tree clean lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone Hello world场景三:已经add 和commit到版本库(还未推送至远端)直接通过git reset --hard回退到上一个版本即可。注意若已推送push到远程仓库此操作会导致本地与远程版本不一致需谨慎这个远程仓库我们在后面会讲的。//向ReadMe添加一行内容 lcbhcss-ecs-1cde:~/gitcode$ echo haha ReadMe lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone Hello world haha //提交ReadMe lcbhcss-ecs-1cde:~/gitcode$ git add ReadMe lcbhcss-ecs-1cde:~/gitcode$ git commit -m test [master d854e66] test 1 file changed, 1 insertion() //将版本回退到上一个版本 lcbhcss-ecs-1cde:~/gitcode$ git reset --hard HEAD^ HEAD is now at 9abf140 modify ReadMe lcbhcss-ecs-1cde:~/gitcode$ cat ReadMe Hello Milestone Hello world二Git文件删除:彻底删除和误删除在 Git 中删除文件也是一种 “修改操作”需根据需求选择 “彻底删除” 或 “恢复误删文件”2.1 误删工作区文件,需要进行回复lcbhcss-ecs-1cde:~/gitcode$ ls file1 file2 file3 ReadMe lcbhcss-ecs-1cde:~/gitcode$ rm file1直接这样删除其实是没用的反而徒增烦恼git status命令会立刻告诉你那些文件被删除了lcbhcss-ecs-1cde:~/gitcode$ git status On branch master Changes not staged for commit: (use git add/rm file... to update what will be committed) (use git restore file... to discard changes in working directory) deleted: file1 no changes added to commit (use git add and/or git commit -a)此时⼯作区和版本库就不⼀致了要删⽂件⽬前除了要删⼯作区的⽂件还要清除版本库的⽂件.当然我们这里如果是误删可以直接使用git checkout -- file来进行恢复之前讲过(删除也是修改)。lcbhcss-ecs-1cde:~/gitcode$ git checkout -- file1 lcbhcss-ecs-1cde:~/gitcode$ ls file1 file2 file3 ReadMe2.2 确认删除文件同步到版本库//从工作区和暂且区同时删除file1 git rm 文件名 lcbhcss-ecs-1cde:~/gitcode$ git rm file1 rm file1 lcbhcss-ecs-1cde:~/gitcode$ git status On branch master Changes to be committed: (use git restore --staged file... to unstage) deleted: file1 //提交删除操作到版本库 lcbhcss-ecs-1cde:~/gitcode$ git commit -m deleted file1 [master 8c0bf79] deleted file1 1 file changed, 0 insertions(), 0 deletions(-) delete mode 100644 file1 lcbhcss-ecs-1cde:~/gitcode$ git status On branch master nothing to commit, working tree clean