6. Git版本处理

前言

该文章只是记录了一些自己的见解,可能并不准确,只是为了学习时的一些记录,不喜勿喷,谢谢

该文章主要记录版本回退的几种方式

  1. git reset
  2. git checkout

1. 初始化仓库

首先我们先初始化一个仓库,然后创建多个版本,方便后续演示

下面, 我们来演示一下该命令,首先,我们将原有仓库清除,从新开始,更加清晰。如下图:

[root@huangzb mygit]#
[root@huangzb mygit]# git init
Initialized empty Git repository in /root/mygit/.git/
[root@huangzb mygit]# git config --local user.name huangzb
[root@huangzb mygit]# git config --local user.email [email protected]
[root@huangzb mygit]#
[root@huangzb mygit]# echo 'hello 1' > a.txt
[root@huangzb mygit]# git add .
[root@huangzb mygit]# git commit -m '第一次提交'
[master (root-commit) 99e413a] 第一次提交
1 file changed, 1 insertion(+)
create mode 100644 a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# echo 'hello 2' >> a.txt
[root@huangzb mygit]# git commit -am '第二次提交'
[master d60e201] 第二次提交
1 file changed, 1 insertion(+)
[root@huangzb mygit]# echo 'hello 3' >> a.txt
[root@huangzb mygit]# git commit -am '第三次提交'
[master 54d34d9] 第三次提交
1 file changed, 1 insertion(+)
[root@huangzb mygit]# echo 'hello 4' >> a.txt
[root@huangzb mygit]# git commit -am '第四次提交'
[master 027bfbd] 第四次提交
1 file changed, 1 insertion(+)
[root@huangzb mygit]#
[root@huangzb mygit]# echo 'hello 5' >> a.txt
[root@huangzb mygit]# git commit -am '第五次提交'
[master 493c360] 第五次提交
1 file changed, 1 insertion(+)
[root@huangzb mygit]# git log
commit 493c360fb9b9e2b0e03fdaac92421155035497a5
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:45 2020 +0800
 
    第五次提交
 
commit 027bfbd142a073f6c8e0ac2d9978964b98dfc0ed
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:20 2020 +0800
 
    第四次提交
 
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]#
 

上述图中,我们创建了一个文件 a.txt,且提交了五次,每次提交追加一条记录,那么此时当前分支master的提交节点图应该如下:

2. git reset

通过 git reset 可以回到指定版本时候的记录

这里借助于他人博客(https://segmentfault.com/a/1190000006185954)中的一段介绍,很有用

git reset配合不同的参数,对这三个区域会产生不同的影响。

reset实际上有3个步骤,根据不同的参数可以决定执行到哪个步骤(--soft, --mixed, --hard)。

  1. 改变HEAD所指向的commit(--soft)
  2. 执行第1步,将Index区域更新为HEAD所指向的commit里包含的内容(--mixed)
  3. 执行第1、2步,将Working Directory区域更新为HEAD所指向的commit里包含的内容(--hard)

所以,我们一般使用 git reset 命令回滚版本的时候会使用 --hard

而且,需要注意的是,这种方式回退时,指针HEAD和分支指针master同步移动,即HEAD始终执行分支master(当前分支)

现在,我们根据上图的版本图来看,此时我们回到之前的版本,通过 git reset 也有多种方式,如下:

  1. git reset --hard HEAD^ --------------------------- 使用 ^ 来表示向前一个版本,可以用多个 ^^
  2. git reset --hard HEAD~1 ---------------------------- 使用 ~ ,注意这是波浪号,而不是 减号,后面的数字表示向前走几个版本,该方式用于避免使用了太多的 ^
  3. git reset --hard commit_id ---------------------- 当提交版本太多后,使用 ^ 和 ~ 都需要来数一下,不太方便,此时 可以直接通过提交记录的 commit_id 直接回到指定版本

下面我们来分别演示一下

2.1 git reset --hard HEAD^

使用 ^ 来表示向前一个版本,可以用多个 ^^

现在,假设我们想要回到第四个版本,如何操作呢,如下图:

[root@huangzb mygit]# git reset --hard HEAD^
HEAD is now at 027bfbd 第四次提交
[root@huangzb mygit]# git log
commit 027bfbd142a073f6c8e0ac2d9978964b98dfc0ed
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:20 2020 +0800
 
    第四次提交
 
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]# cat a.txt
hello 1
hello 2
hello 3
hello 4
[root@huangzb mygit]#
 

由上图可知,我们使用了命令 git reset --hard HEAD^ 回到了上一个版本,使用 git log 后会发现丢失了最后一次的提交记录,且 a.txt 文件内容回到了第四次提交的时候。

同时 ^ 可以进行叠加,有几个 ^ 表示向前移动几个版本,如下图演示:

[root@huangzb mygit]# git reset --hard HEAD^^^
HEAD is now at 99e413a 第一次提交
[root@huangzb mygit]# git log
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]# cat a.txt
hello 1
[root@huangzb mygit]#
 

由上图可以看到,我们连续使用了 ^^^ 标识符,在第四个版本的基础上,向前移动3个版本,就只想了现在的第一个版本了。

注意,又可以很明显的看到了,当我们回退到第一个版本的时候,只有一条提交记录了,此时之前的四次提交在git log 命令中已然看不到,而 ^ 标识符只有向前移动,没有向后移动的,如何解决该问题呢,先不着急,往后看,后续会讲到

这里可以先偷偷体现下,因为后续需要进行 git reset --hard HEAD~n 命令的演示

下面使用 git reflog 命令找到最后一次提交记录的节点id,然后使用命令 git reset --hard commit_id 回到指定节点,如下图演示:

[root@huangzb mygit]# git reflog
99e413a HEAD@{0}: reset: moving to HEAD^^^
027bfbd HEAD@{1}: reset: moving to HEAD^
493c360 HEAD@{2}: commit: 第五次提交
027bfbd HEAD@{3}: commit: 第四次提交
54d34d9 HEAD@{4}: commit: 第三次提交
d60e201 HEAD@{5}: commit: 第二次提交
99e413a HEAD@{6}: commit (initial): 第一次提交
[root@huangzb mygit]#
[root@huangzb mygit]# git reset --hard 493c360
HEAD is now at 493c360 第五次提交
[root@huangzb mygit]# git log
commit 493c360fb9b9e2b0e03fdaac92421155035497a5
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:45 2020 +0800
 
    第五次提交
 
commit 027bfbd142a073f6c8e0ac2d9978964b98dfc0ed
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:20 2020 +0800
 
    第四次提交
 
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]#
 

通过上图可以看到,已经回到了最后一次提交的节点了。git reflog 命令记录了我们对于所有分支的操作记录,因此可以通过该命令来完成时空穿梭。

但是上述的使用 ^ 的方式,有点缺点,那就是当移动版本量较少时,比较方便,如果想回到前20个,前100个等等,那么岂不是需要写 20个^ 吗,还是仔细的数一数,很麻烦,因此,如果已知需要回退多少个版本的情况下,我们可以使用命令 git reset --hard HEAD~n 的方式来使用,下面来试试

2.2 git reset --hard HEAD~n

我们使用 ~ 标识符,来进行指定数量的向前移动

现在我们在最新的提交节点,同样的,如果想要回到第一个版本,需要向前移动4个版本,因此,我们可以使用 git reset --hard HEAD~4 来进行操作,如下图:

[root@huangzb mygit]# git reset --hard HEAD~4
HEAD is now at 99e413a 第一次提交
[root@huangzb mygit]# git log
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]# cat a.txt
hello 1
[root@huangzb mygit]#
 

由上图可知,在已知需要移动多少版本的情况下,使用 ~n 的表达方法明显比 ^ 更加清晰,但是同样的缺点,如果版本提交比较多,想要回到其中的某一个版本还需要一个个的数,比较麻烦,此时应该可以使用第三种方式,指定某一个 commit_id ,直接锁定版本更加快速。下面,我们来看看

2.3 git reset --hard commit_id

直接指定 commit_id 来进行指定版本回退

由于上述已经使用过了 git reflog 的使用,这里就不再重复演示,我先将版本还原到最新的版本,然后下面将演示如何使用 commit_id 回到第一个版本

[root@huangzb mygit]#
[root@huangzb mygit]# git reset --hard 493c360
HEAD is now at 493c360 第五次提交
[root@huangzb mygit]# git log
commit 493c360fb9b9e2b0e03fdaac92421155035497a5
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:45 2020 +0800
 
    第五次提交
 
commit 027bfbd142a073f6c8e0ac2d9978964b98dfc0ed
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:20 2020 +0800
 
    第四次提交
 
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]#
[root@huangzb mygit]# git reset --hard 99e413a1
HEAD is now at 99e413a 第一次提交
[root@huangzb mygit]# git log
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]#
 

由上图可知,使用了 commit_id 的方式,直接回到了第一个版本了。

2.4 git reset 效果图

假设使用 git reset 时看看效果

当我们切换到第一个提交后,就如上图,最新分支指向的第一次提交,后续的历史都不在保留,假设我们就在第一个版本再次开发,那么之前的记录再与我们无关了。

3. git checkout

也可以使用 git checkout commit_id 来选择到指定分支,但是与 git reset 有区别

假想我们回到了最新的版本,然后假如想在第三个版本中修改文件怎么办?

此时,我们可以使用 git checkout commit_id 回到第三个版本,此时HEAD指针不再指向master,而是指向commit_id 所在节点,但是master指针依然指向最新的提交。如下图:

如何操作呢,如下图:

[root@huangzb mygit]# git log
commit 493c360fb9b9e2b0e03fdaac92421155035497a5
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:45 2020 +0800
 
    第五次提交
 
commit 027bfbd142a073f6c8e0ac2d9978964b98dfc0ed
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:20 2020 +0800
 
    第四次提交
 
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]# git checkout 54d34d9ef3
Note: checking out '54d34d9ef3'.
 
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
 
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
 
  git checkout -b new_branch_name
 
HEAD is now at 54d34d9... 第三次提交
[root@huangzb mygit]#
[root@huangzb mygit]#
[root@huangzb mygit]# git log
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]# cat a.txt
hello 1
hello 2
hello 3
[root@huangzb mygit]#
 

由上图可知,使用了 git checkout commit_id 命令后,虽然切换成功了,但是有一段提示,如下:

Note: checking out '54d34d9ef3'.
 
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
 
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
 
  git checkout -b new_branch_name
 
HEAD is now at 54d34d9... 第三次提交
 

翻译下来就是:

注意:请查看“54d34d9ef3”。
 
 
 
你处于“独立的分支”状态。你可以四处看看,做实验
 
更改并提交它们,您可以放弃在此中所做的任何提交
 
通过执行另一个签出而不影响任何分支的状态。
 
 
 
如果要创建新分支以保留创建的提交,可以
 
再次将-b与checkout命令一起使用(现在或以后)。例子:
 
 
 
git签出-b新分支名称
 
 
 
头部现在在54d34d9。。。第三次提交

从上面的翻译中,可以提炼出两点,如下:

  1. 目前使用 git checkout 后,HEAD指针指向的节点属于游离节点,而master分支任然执行最新的节点
  2. 可以在当前节点进行对文件的操作,但是如果想要保留这些操作,需要新创建一个分支来进行保存

此时,我们再看看分支情况:

[root@huangzb mygit]# git branch
* (detached from 54d34d9)
  master
[root@huangzb mygit]#
 

由上图可知,可以看到多出来了一个不知名的分支,且当前指向了它,因此可以更加证明HEAD和master指针不再指向同一个节点了。此时就叫做游离分支

下面我们在当前游离的分支进行数据的操作,看看有什么问题,如下图:

下面的操作我们分以下几种场景分析:

  1. 在游离分支,添加了文件后,未追加到git中,然后切换到master分支,看看效果

3.1 追加文件,不被git跟踪,切换到master

现在,我们新创建一个文件,什么都不操作,然后切换到master分支,看看状态

[root@huangzb mygit]# echo 'hello 游离分支' > b.txt
[root@huangzb mygit]# git status
# HEAD detached at 54d34d9
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout master
Previous HEAD position was 54d34d9... 第三次提交
Switched to branch 'master'
[root@huangzb mygit]# git branch
* master
[root@huangzb mygit]# git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
 

由上图可知,当我们在游离分支,新添加了文件,然后没有使用 git add 来让git追踪该文件,且随后切换到了master,可以看到 使用 git status 命令后,任然可以看到该文件,这种情况在之前切换分支操作里也会出现,因为不管是再哪个分支,添加了未跟踪的文件,都是对于工作空间的修改,不管在哪个分支,都可以感知到。

3.2 追加文件,且被追踪,再切换到master

现在,我们再次回到第三个版本中,然后将创建的文件使用 git add 让git跟踪,再切换到 master 看看效果

操作如下图:

[root@huangzb mygit]# git checkout 54d34d9ef3
Note: checking out '54d34d9ef3'.
 
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
 
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
 
  git checkout -b new_branch_name
 
HEAD is now at 54d34d9... 第三次提交
[root@huangzb mygit]#
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 24 Mar 27 15:35 a.txt
-rw-r--r-- 1 root root 19 Mar 27 15:28 b.txt
[root@huangzb mygit]# git status
# HEAD detached at 54d34d9
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@huangzb mygit]#
[root@huangzb mygit]# git add .
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout master
A       b.txt
Previous HEAD position was 54d34d9... 第三次提交
Switched to branch 'master'
[root@huangzb mygit]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b.txt
#
[root@huangzb mygit]#
 

由上图可知,即使在游离分支中,使用了 git add 被 git跟踪,切换分支后,其余分支任然可以感知到,效果同3.1一样。

3.3 追加文件,且commit,再切换到master

现在,我们回到第三个版本,将新创建的文件提交,然后再看看能否切换,操作如下图:

[root@huangzb mygit]# git checkout 54d34d9ef3
A       b.txt
Note: checking out '54d34d9ef3'.
 
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
 
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
 
  git checkout -b new_branch_name
 
HEAD is now at 54d34d9... 第三次提交
[root@huangzb mygit]# git status
# HEAD detached at 54d34d9
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b.txt
#
[root@huangzb mygit]# git commit -m 'create b.txt'
[detached HEAD 43d986d] create b.txt
1 file changed, 1 insertion(+)
create mode 100644 b.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
 
  43d986d create b.txt
 
If you want to keep them by creating a new branch, this may be a good time
to do so with:
 
git branch new_branch_name 43d986d
 
Switched to branch 'master'
[root@huangzb mygit]#
[root@huangzb mygit]# git status
# On branch master
nothing to commit, working directory clean
[root@huangzb mygit]#
 

由上图结果可知,当我们在游离分支中,将新创建的文件进行了commit,此时在游离分支中同样会多处一个新的提交节点,然后切换到master后,会弹出一个警告,但是还可以切换过来,但是此时master分支中是不存在b.txt文件的,那么我们我们之前游离分支所作的操作在切换到游离分支后,还会存在吗,我们试试:

[root@huangzb mygit]# git checkout 54d34d9ef3
Note: checking out '54d34d9ef3'.
 
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
 
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
 
  git checkout -b new_branch_name
 
HEAD is now at 54d34d9... 第三次提交
[root@huangzb mygit]# git log
commit 54d34d9ef36956b47b4b8e9a73f4261307e9c853
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:36:01 2020 +0800
 
    第三次提交
 
commit d60e201851187a0f63b76acfc30e84dd07cb3d56
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:47 2020 +0800
 
    第二次提交
 
commit 99e413a174d2e1647cdd034ab064ebacc38771a4
Author: huangzb <[email protected]>
Date:   Thu Mar 26 11:35:33 2020 +0800
 
    第一次提交
[root@huangzb mygit]# ll
total 4
-rw-r--r-- 1 root root 24 Mar 27 15:42 a.txt
[root@huangzb mygit]#
 

可以看到,当我们在游离分支添加了文件,提交了之后,再次切换到游离分支,可以发现之前的操作全部丢失。

而且,在之前,游离分支commit之后,切换到master分支上的时候,有一个警告,我们现在看看改警告

Warning: you are leaving 1 commit behind, not connected to
any of your branches:
 
  43d986d create b.txt
 
If you want to keep them by creating a new branch, this may be a good time
to do so with:
 
git branch new_branch_name 43d986d
 
Switched to branch 'master'

翻译如下:

警告:您将留下1个提交,未连接到
 
您的任何分支机构:
 
 
 
43d986d创建b.txt
 
 
 
如果你想通过创建一个新的分支来保留它们,这可能是一个好时机
 
要这样做:
 
 
 
git branch new_branch_name 43d986d
 
 
 
切换到分支“master”

从这个警告中,我们得知git建议我们在切换之前,需要创建一个新的分支来保留该修改,否则数据将丢失,因此我们可以根据提示 来创建一个分支来保留他们。

操作如下图:

[root@huangzb mygit]# ll
total 4
-rw-r--r-- 1 root root 24 Mar 27 15:42 a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# echo 'hello youli' > b.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git add .
[root@huangzb mygit]# git commit -m 'create b.txt'
[detached HEAD 0dae8a5] create b.txt
1 file changed, 1 insertion(+)
create mode 100644 b.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git branch new_branch 0dae8a54
[root@huangzb mygit]# git branch
* (detached from 54d34d9)
  master
  new_branch
[root@huangzb mygit]# git checkout master
Previous HEAD position was 0dae8a5... create b.txt
Switched to branch 'master'
[root@huangzb mygit]# ll
total 4
-rw-r--r-- 1 root root 40 Mar 27 15:57 a.txt
[root@huangzb mygit]# git checkout new_branch
Switched to branch 'new_branch'
[root@huangzb mygit]# ll
total 8
-rw-r--r-- 1 root root 24 Mar 27 15:57 a.txt
-rw-r--r-- 1 root root 12 Mar 27 15:57 b.txt
[root@huangzb mygit]#
 

由上图可知,我们在游离分支中,添加了文件后,再切换到master之前,使用 git branch 新分支名 最后一次提交节点id 方式来保留了游离分支的操作,然后切换到master中,发现没有新添加的文件,然后切换到新分支后,可以看到新添加的文件。如此甚好。

上述的几点,都是针对新添加的文件来做的操作,下面,我们来看看 针对 master原有的文件,在游离分支中修改存在的文件,此时情况是什么样子得呢?

3.4 修改文件,不提交,再切换到master

注意,这里的修改的文件,是要在master中已存在的

我们来演示一波,如下图:

[root@huangzb mygit]# git checkout 54d34d9ef
[root@huangzb mygit]#
[root@huangzb mygit]# ll
total 4
-rw-r--r-- 1 root root 24 Mar 27 16:03 a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# cat a.txt
hello 1
hello 2
hello 3
[root@huangzb mygit]# echo 'hello youli' >> a.txt
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        a.txt
Please, commit your changes or stash them before you can switch branches.
Aborting
[root@huangzb mygit]#
 

由上图可知,当我们在游离分支修改了文件,且没有提交时,再切换到master时会出现error,提示如下:

error: Your local changes to the following files would be overwritten by checkout:
        a.txt
Please, commit your changes or stash them before you can switch branches.
Aborting

翻译如下:

错误:checkout 操作将覆盖对以下文件的本地更改:
 
a.txt
 
请在切换分支之前提交或保存更改。
 
中止

可以看出,对于这种情况下,git不允许我们修改了文件,直接切换分支,除非 先提交或者保存修改。那么下面我们来分别试试 提交和保存修改两种情况.

3.5 修改文件,且提交,再切换到master

因为在3.4中,没有切换到master成功,所以再次基础上,直接操作,操作如下:

[root@huangzb mygit]# git status
# HEAD detached at 54d34d9
# 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:   a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]# git add .
[root@huangzb mygit]#
[root@huangzb mygit]# git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        a.txt
Please, commit your changes or stash them before you can switch branches.
Aborting
[root@huangzb mygit]#
 

上述的是先演示 只 git add ,而不提交的情况,看看是否如提示那样,结果证实,仅仅只 git add 的话,任然不能切换分支,现在在提交它,操作如下:

[root@huangzb mygit]# git commit -m 'update a.txt'
[detached HEAD 57dba1e] update a.txt
1 file changed, 1 insertion(+)
[root@huangzb mygit]# git checkout master
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
 
  57dba1e update a.txt
 
If you want to keep them by creating a new branch, this may be a good time
to do so with:
 
git branch new_branch_name 57dba1e
 
Switched to branch 'master'
[root@huangzb mygit]# cat a.txt
hello 1
hello 2
hello 3
hello 4
hello 5
[root@huangzb mygit]#
 

由上图可知,虽然我们commit了之后,成功切换到了 master,但是同 3.3一样,出现同样的问题,就是在游离分支的操作,即使commit了,再切换分支之后,之前的游离分支的操作都不在存在,即会丢失在游离分支的操作。

所以,需要根据提示在 切换之前创建新的分支后在切换,其操作 同3.3 一致,不再重复,下面我们看看git给我们的第二个简易

3.6 修改文件,且保存,再切换到master

这里的保存意思是将当前分支的修改先保存起来,下次再回到该分支,可以使用pop来还原数据

这里的保存的操作,需要用到了命令 git stash, 该命令其余文章再介绍,这里只介绍版本处理,因为现在已经切换到了master分支,因此下面会先切换到游离分支,然后修改文件一系列操作,最后看看使用 git stash 命令后的效果,操作如下图:

[root@huangzb mygit]# git checkout 54d34d9ef
[root@huangzb mygit]# echo 'hello youli' >> a.txt
[root@huangzb mygit]# git status
# HEAD detached at 54d34d9
# 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:   a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@huangzb mygit]# git stash
Saved working directory and index state WIP on (no branch): 54d34d9 第三次提交
HEAD is now at 54d34d9 第三次提交
[root@huangzb mygit]# git status
# HEAD detached at 54d34d9
nothing to commit, working directory clean
[root@huangzb mygit]# git checkout master
Previous HEAD position was 54d34d9... 第三次提交
Switched to branch 'master'
[root@huangzb mygit]# cat a.txt
hello 1
hello 2
hello 3
hello 4
hello 5
[root@huangzb mygit]#
 

从上图可以看出,我们使用了 git stash命令后,再次使用 git status 可以看到工作空间已经干净,此时就可以切换到master分支了,而修改的数据已经被我们暂时保存到其余地方了,当我们再次回到游离分支时,可以使用命令将其还原回来,操作如下:

[root@huangzb mygit]# git checkout 54d34d9ef
[root@huangzb mygit]# git stash pop
# HEAD detached at 54d34d9
# 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:   a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (1ff59e1834eb8ab5a04b374a5e624ae45ffb4cb2)
[root@huangzb mygit]# cat a.txt
hello 1
hello 2
hello 3
hello youli
[root@huangzb mygit]#
 

使用 git stash pop 命令将最近的保存的修改还原

猜你喜欢

转载自www.cnblogs.com/duguxiaobiao/p/12691395.html