在开发过程中,我们会遇到如下几种情况:
首先明确一点,使用git checkout 进行版本回撤,必须想要将代码提交到仓库中。
1. 代码已经提交过,然后在工作区中进行修改,暂时还没有添加到暂存区中,回撤
# 1. 首先创建beijing.txt文件,并提交到本地仓库
$ vim beijing.txt
$ cat beijing.txt
beijing
$ git status
beijing
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
(use "git push" to publish your local commits)
Untracked files:
(use "git add <file>..." to include in what will be committed)
beijing.txt
nothing added to commit but untracked files present (use "git add" to track)
$ git add beijing.txt
$ git commit -m "添加beijing.txt"
[master cd84708] 添加beijing.txt
1 file changed, 1 insertion(+)
create mode 100644 beijing.txt
zfz:gitlearn zhangfengzhou$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
# 2. 在提交代码后,修改代码内容,并保存在工作区中
$ vim beijing.txt
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: beijing.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 3. 上面的日志提示此时有两种操作方法
# 1:git add <file> 将文件添加到暂存区中
# 2:git checkout -- <file> 将修改的内容撤回,也就是说在工作目录中的修改撤回
# 我们选择撤回
$ git checkout -- beijing.txt
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
# 4. 在工作区进行撤回之后,发现代码又回到代码提交之后,修改之前的状态
$ cat beijing.txt
beijing
2. 代码已经提交过,然后修改并且已经添加到暂存区,然后从暂存区回撤
# 一、首先查看状态 没有可以提交的内容
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
# 二、修改world.txt文件,并添加到暂存区
$ vim world.txt
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: world.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ git add world.txt
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: world.txt
# 三、上面提示我们如果要从暂存区中撤回代码,可以使用 git reset HEAD <file>
# 我们回撤代码,然后发现,暂存区中已经没有可以要提交的代码,代码已经撤回到工作目录中
$ git reset HEAD world.txt
Unstaged changes after reset:
M world.txt
$ cat world.txt
world
添加内容到暂存区
$ git status
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: world.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 四、暂存区中已经没有提交的内容,如果想要撤回代码,可以使用 git checkout --<file>
$ git checkout world.txt
Updated 1 path from the index
# 暂存区的代码已经回撤
$ cat world.txt
world
3. 代码已经提交,然后代码从本地仓库回撤
3.1 使用 git reset 回撤代码,不会创建新的提交记录
reset命令有3种方式:
1. git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息。
2. git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可。
3. git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容。
index 信息是指定track信息??保留index信息的意思就是不用重新 add,添加暂存区操作?
# git reset HEAD^1 本地仓库代码撤回到上一次提交,但是代码不动,仅仅撤回commit信息和index信息
# git reset HEAD^n n 表示撤回最近的 n 次提交
$ vim world.txt
$ git add world.txt
$ git commit -m "第四次提交"
[master 292b89d] 第四次提交
1 file changed, 2 insertions(+)
$ git reset HEAD^1
Unstaged changes after reset:
M world.txt
$ git log
commit bda7af482eff313d49c7ccf6fb1ea64a058a2e88 (HEAD -> master)
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:27:49 2021 +0800
第三次提交
commit 5d6ba7c33d2832a3d8e31e836a9aa0b214a1ea72
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:05:47 2021 +0800
第二次提交
commit cd847086fa4b259f49334e886e217205a562f75b
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 22:28:20 2021 +0800
添加beijing.txt
commit cbf1573cab32a50abb1bed51a9deaa53ee3b45e7
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 22:15:45 2021 +0800
添加world.txt
# 撤回到工作区,但是丢失了commit信息和index信息(即需要重新add到暂存区)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: world.txt
no changes added to commit (use "git add" and/or "git commit -a")
# 撤回到工作区之后,内容不变
$ cat world.txt
world
第二次提交
第三次提交
第四次提交
$ git add world.txt
$ git commit -m "第四次提交"
[master f3c512a] 第四次提交
1 file changed, 2 insertions(+)
# 查看最新的状态
$ git status
On branch master
Your branch is ahead of 'origin/master' by 6 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
# 一、git reset --soft HEAD^1 撤回到最近的一次提交,即回撤到上次的提交
$ git reset --soft HEAD^1
$ git log
commit bda7af482eff313d49c7ccf6fb1ea64a058a2e88 (HEAD -> master)
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:27:49 2021 +0800
第三次提交
commit 5d6ba7c33d2832a3d8e31e836a9aa0b214a1ea72
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:05:47 2021 +0800
第二次提交
commit cd847086fa4b259f49334e886e217205a562f75b
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 22:28:20 2021 +0800
添加beijing.txt
commit cbf1573cab32a50abb1bed51a9deaa53ee3b45e7
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 22:15:45 2021 +0800
添加world.txt
# 二、查看状态,git reset --soft HEAD^1 回撤之后,会撤会提交信息,但是会保留index信息
# 后面如果有需要再次提交,不需要添加暂存区,直接commit就可以
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: world.txt
# 三、查看回撤后的内容,内容依然不变
$ cat world.txt
world
第二次提交
第三次提交
第四次提交
$ git commit -m "第四次提交"
[master 3c49c8d] 第四次提交
1 file changed, 2 insertions(+)
$ git log
commit 3c49c8d5322aad979674d004a0253cf596aa6b96 (HEAD -> master)
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:47:41 2021 +0800
第四次提交
commit bda7af482eff313d49c7ccf6fb1ea64a058a2e88
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:27:49 2021 +0800
第三次提交
commit 5d6ba7c33d2832a3d8e31e836a9aa0b214a1ea72
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:05:47 2021 +0800
第二次提交
commit cd847086fa4b259f49334e886e217205a562f75b
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 22:28:20 2021 +0800
添加beijing.txt
# git reset --hard HEAD^1 表示撤回最近的一次提交,撤回到上一次提交,
# 并且丢失了代码内容和commit信息和index信息
$ git reset --hard HEAD^1
HEAD is now at bda7af4 第三次提交
$ git status
On branch master
Your branch is ahead of 'origin/master' by 5 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
# 查看内容,已经撤回到上一次提交,并且工作区和暂存区都没有保留撤回的内容
$ cat world.txt
world
第二次提交
第三次提交
3.2 使用 git revert 回撤某次提交,会创建新的提交记录
git revert -n commit “反做某个版本”,用来修改已经提交的某个版本的代码,并最终生成一个新的的提交。
# 查看提交日志
$ git log
commit e0987503261505b2f0bd19fab7ca9286790edc35 (HEAD -> master)
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:54:04 2021 +0800
第四次提交
commit bda7af482eff313d49c7ccf6fb1ea64a058a2e88
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:27:49 2021 +0800
第三次提交
commit 5d6ba7c33d2832a3d8e31e836a9aa0b214a1ea72
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:05:47 2021 +0800
第二次提交
commit cd847086fa4b259f49334e886e217205a562f75b
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 22:28:20 2021 +0800
world
添加beijing.txt
# 查看world.txt内容
$ cat world.txt
world
第二次提交
第三次提交
第四次提交
# 针对第二次提交的内容进行修改,可能会遇到冲突,然后解决冲突,然后git add <file>,
# 最后 git commit -m "revert 第二次提交的内容"
# git revert -n commitid “反做某个版本号”
$ git revert -n 5d6ba7c
error: could not revert 5d6ba7c... 第二次提交
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
# 遇到了冲突,然后解决冲突
$ cat world.txt
world
<<<<<<< HEAD
第二次提交
第三次提交
第四次提交
=======
>>>>>>> parent of 5d6ba7c... 第二次提交
# 解决冲突
$ vim world.txt
$ git add world.txt
$ git commit -m "revert 第二次提交"
[master 5e04f53] revert 第二次提交
1 file changed, 1 deletion(-)
$ cat world.txt
world
第二次提交
第三次提交
第四次提交
$ git log # 生成新的提交 revert 第二次提交
commit 5e04f53ab154b3f20787ed20a19b750283aa7e26 (HEAD -> master)
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Sat Aug 28 00:43:14 2021 +0800
revert 第二次提交
commit e0987503261505b2f0bd19fab7ca9286790edc35
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:54:04 2021 +0800
第四次提交
commit bda7af482eff313d49c7ccf6fb1ea64a058a2e88
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:27:49 2021 +0800
第三次提交
commit 5d6ba7c33d2832a3d8e31e836a9aa0b214a1ea72
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:05:47 2021 +0800
第二次提交
3.3 代码已经提交远程仓库,如何撤回版本
如果我们某次修改了某些内容,并且已经commit到本地仓库,而且已经push到远程仓库了,这种情况下,我们想把本地和远程仓库都回退到某个版本,该怎么做呢?前面讲到的git reset只是在本地仓库中回退版本,而远程仓库的版本不会变化。这样,即时本地reset了,但如果再git pull,那么,远程仓库的内容又会和本地之前版本的内容进行merge,这并不是我们想要的东西,这时可以有2种办法来解决这个问题:
1. 直接在远程server的仓库目录下,执行git reset --soft 10efa来回退。
注意:在远程不能使用mixed或hard参数
2. 在本地直接强制rest内容,然后再把reset后的分支内容给强制push上去,这样不会在远程仓库里留下提交记录,如下:
# 一、退回到上一次提交,强制删除了错误的提交
$ git reset --hard HEAD~1
HEAD is now at 5e04f53 revert 第二次提交
# 二、查看提交历史
$ git log
commit 5e04f53ab154b3f20787ed20a19b750283aa7e26 (HEAD -> master)
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Sat Aug 28 00:43:14 2021 +0800
revert 第二次提交
commit e0987503261505b2f0bd19fab7ca9286790edc35
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:54:04 2021 +0800
第四次提交
commit bda7af482eff313d49c7ccf6fb1ea64a058a2e88
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:27:49 2021 +0800
第三次提交
commit 5d6ba7c33d2832a3d8e31e836a9aa0b214a1ea72
Author: zhangfengzhou <zhangfengzhou@qq.com>
Date: Fri Aug 27 23:05:47 2021 +0800
第二次提交
# 三、强制本地仓库推导远程仓库 git push -f origin master # 注意:-f 不能缺少
$ git push -f origin master
Enter passphrase for key '/Users/zhangfengzhou/.ssh/id_ed25519':
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.1]
To gitee.com:happiness365/gitlearn.git
+ 8d52d4d...5e04f53 master -> master (forced update)