假如我们现在正在 dev2
分支上进行开发,开发到一半,突然发现 master
分支上面有 bug,需要解决。
bug
都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。可现在 dev2
的代码在工作区中开发了一半,还无法提交,怎么办?例如:
lighthouse@VM-8-10-ubuntu:gitcode$ git branch
* dev2
master
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d
I am coding...
lighthouse@VM-8-10-ubuntu:gitcode$ git status
On branch dev2
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: book
no changes added to commit (use "git add" and/or "git commit -a")
Git 提供了 git stash
命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来。
lighthouse@VM-8-10-ubuntu:gitcode$ git stash
Saved working directory and index state WIP on dev2: 2bd7b8b modify Readme
lighthouse@VM-8-10-ubuntu:gitcode$ git status
On branch dev2
nothing to commit, working tree clean
用 git status
查看工作区,就是干净的(除非有没有被 Git 管理的文件),因此可以放心地创建分支来修复bug。
储藏 dev2 工作区之后,由于我们要基于 master
分支修复 bug,所以需要切回 master
分支,再新建临时分支来修复 bug,示例如下:
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout -b fix_bg # 新建并切换
Switched to a new branch 'fix_bg'
lighthouse@VM-8-10-ubuntu:gitcode$ vim book
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
lighthouse@VM-8-10-ubuntu:gitcode$ git add book
lighthouse@VM-8-10-ubuntu:gitcode$ git commit -m "fix bug"
[fix_bg c0637e0] fix bug
1 file changed, 1 insertion(+), 1 deletion(-)
修复完成后,切换到 master
分支,并完成合并,最后删除 fix_bg
分支
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout master
Switched to branch 'master'
lighthouse@VM-8-10-ubuntu:gitcode$ git merge --no-ff -m "merge fix_bug branch" fix_bg
Merge made by the 'ort' strategy.
book | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
至此,bug的修复工作已经做完了,我们还要继续回到 dev2 分支进行开发。切换回 dev2
分支:
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout dev2
Switched to branch 'dev2'
lighthouse@VM-8-10-ubuntu:gitcode$ git status
On branch dev2
nothing to commit, working tree clean
工作区是干净的,刚才的工作现场存到哪去了?用 git stash list
命令看看:
lighthouse@VM-8-10-ubuntu:gitcode$ git stash list
stash@{0}: WIP on dev2: 2bd7b8b modify Readme
工作现场还在,Git 把 stash 内容存在某个地方了,但是需要恢复一下,如何恢复现场呢?我们可以使用 git stash pop
命令,恢复的同时会把 stash 也删了,示例如下:
lighthouse@VM-8-10-ubuntu:gitcode$ git stash pop
On branch dev2
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: book
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (e2dfd6d0312e2454d1a7a4a3eb65cf3e28f333af)
再次查看的时候,我们已经发现已经没有现场可以恢复了
lighthouse@VM-8-10-ubuntu:gitcode$ git stash list
lighthouse@VM-8-10-ubuntu:gitcode$
另外,恢复现场也可以采用 git stash apply
恢复,但是恢复后,stash内容并不删除,你需要用 git stash drop
来删除;
stash
,恢复的时候,先用 git stash list
查看,然后恢复指定的 stash
,用命令git stash apply stash@{o}
恢复完代码之后我们便可以继续完成开发,开发完成后便可以进行提交,例如:
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d
I am coding... Done
lighthouse@VM-8-10-ubuntu:gitcode$ git add .
lighthouse@VM-8-10-ubuntu:gitcode$ git commit -m "modify book"
[dev2 ccb0f97] modify book
1 file changed, 1 insertion(+)
但我们注意到了,修复 bug的内容,并没有在 dev2 上显示。此时的状态图为:
Master
分支目前最新的提交,是要领先于新建 dev2
时基于的 master
分支的提交的,所以我们在 dev2 中当然看不见修复 bug 的相关代码。
master
合并 dev2 分支的,那么正常情况下我们切回 master
分支直接合并即可,但这样其实是有一定风险的原因:在合并分支时可能会有冲突,而代码冲突需要我们手动解决(在 master上解决)
master
上。此时的状态为:
解决这个问题的一个好的建议就是:最好在自己的分支上合并下 master
,再让 master
去合并dev ,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master
此时的状态为:
对应的实操演示如下,要说明的是,以下演示的merge操作,没有使用 --no-ff
,但上述的图示是禁用 Fast forward
了模式后得出的,主要是为了方便解释问题。
# dev 合并 master
lighthouse@VM-8-10-ubuntu:gitcode$ git branch
* dev2
master
lighthouse@VM-8-10-ubuntu:gitcode$ git merge master
Auto-merging book
CONFLICT (content): Merge conflict in book
Automatic merge failed; fix conflicts and then commit the result.
# 发送冲突
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
<<<<<<< HEAD
a,b,c,d
I am coding... Done
=======
a,b,c,d,e
>>>>>>> master
# 解决冲突并重新提交
lighthouse@VM-8-10-ubuntu:gitcode$ vim book
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
I am coding... Done
lighthouse@VM-8-10-ubuntu:gitcode$ git add .
lighthouse@VM-8-10-ubuntu:gitcode$ git commit -m "merge master"
[dev2 9e77002] merge master
lighthouse@VM-8-10-ubuntu:gitcode$ git status
On branch dev2
nothing to commit, working tree clean
# 切回 master
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout master
Switched to branch 'master'
# master 合并 dev2 -- 无需解决冲突
lighthouse@VM-8-10-ubuntu:gitcode$ git merge dev2
Updating adbb267..9e77002
Fast-forward
book | 1 +
1 file changed, 1 insertion(+)
lighthouse@VM-8-10-ubuntu:gitcode$ git status
On branch master
nothing to commit, working tree clean
# 删除 dev2 分支
lighthouse@VM-8-10-ubuntu:gitcode$ git branch -d dev2
Deleted branch dev2 (was 9e77002).
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
I am coding... Done
软件开发中,总有无穷无尽的新的功能要不断添加进来
feature
分支,在上面开发,完成后,合并,最后,删除该 feature
分支。 feature
分支上开发了一半,被产品经理突然叫停,说是要停止新功能的开发。虽然白干了,但是这个 feature
分支还是必须就地销毁,留着无用了。git branch -d
命令删除分支的方法是不行的。演示如下:
# 新增并切换到 dev3 分支
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout -b dev3
Switched to a new branch 'dev3'
lighthouse@VM-8-10-ubuntu:gitcode$ clear
# 开始开发新功能并提交
lighthouse@VM-8-10-ubuntu:gitcode$ vim book
lighthouse@VM-8-10-ubuntu:gitcode$ cat book
Hello Island1314
Hello World
hello version1
hello version2
hello version3
write bbb for new branch
a,b,c,d,e
I am coding... Done
I am writing new features ...
lighthouse@VM-8-10-ubuntu:gitcode$ git add .
lighthouse@VM-8-10-ubuntu:gitcode$ git commit -m "modify book for new features"
[dev3 fb6a737] modify book for new features
1 file changed, 1 insertion(+)
# 此时新功能叫停, 切回 master 准备删除 dev3
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout master
Switched to branch 'master'
对 dev3 进行删除,如下:
# 常规删除 dev3 分支时失败
lighthouse@VM-8-10-ubuntu:gitcode$ git branch -d dev3
error: The branch 'dev3' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dev3'.
# 按照提示进行删除
lighthouse@VM-8-10-ubuntu:gitcode$ git branch -D dev3
Deleted branch dev3 (was fb6a737).
🌊 分支在实际中有什么用呢?
而且 Git 无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件
commit
)当我们在 dev 分支下修改文件之后,master 还是可以看到的(没有 add 的情况下),如下:
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout dev
Switched to branch 'dev'
lighthouse@VM-8-10-ubuntu:gitcode$ vim file
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout master
Switched to branch 'master'
lighthouse@VM-8-10-ubuntu:gitcode$ cat file
i miss you # master 分支
I Miss You # dev 分支
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout dev
Switched to branch 'dev'
lighthouse@VM-8-10-ubuntu:gitcode$ git add file
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout master
A file
Switched to branch 'master'
lighthouse@VM-8-10-ubuntu:gitcode$ cat file
i miss you # master 分支
I Miss You # dev 分支
add
的修改和已 add
但未 commit
的暂存)都存在于工作目录中,不会被 Git 自动隔离到特定分支master
)和当前分支(如 dev
)对同一文件的修改不冲突,Git 允许直接切换,并保留工作目录的改动。而当我们在 切换到 dev
分支进行 commit 之后,然后再切换到 master 分支查看,然后 如下:
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout dev
A file
Switched to branch 'dev'
lighthouse@VM-8-10-ubuntu:gitcode$ git commit file
Aborting commit due to empty commit message.
lighthouse@VM-8-10-ubuntu:gitcode$ git commit -m "改变" file
[dev 1a1993f] 改变
1 file changed, 2 insertions(+)
create mode 100644 file
commit
) 的作用:将暂存区的内容永久记录到当前分支的历史中,此时修改正式归属于 dev
分支。master
)的最新提交重建工作目录。master
分支从未包含 file
文件(即该文件只在 dev
分支提交过,下面等下会细说这个问题),切换到 master
时,Git 会删除工作目录中的 file
文件,因为 master
分支的历史中不存在它总结
dev
分支的历史中,不会丢失。master
分支的工作区被重建为它自己的最新提交状态,因此看不到 dev
分支的改动。这里要说一下,由于我们在 master 分支下没有 commit
过文件,因此当我们在 dev
下首次 commit
,那么 master
分支下的 file 文件就会消失,如下:
lighthouse@VM-8-10-ubuntu:gitcode$ cat file
i miss you # master 分支
I Miss You # dev 分支
lighthouse@VM-8-10-ubuntu:gitcode$ git checkout master
Switched to branch 'master'
lighthouse@VM-8-10-ubuntu:gitcode$ cat file
cat: file: No such file or directory
lighthouse@VM-8-10-ubuntu:gitcode$ ll
total 20
drwxrwxr-x 4 lighthouse lighthouse 4096 Apr 18 19:52 ./
drwxrwxr-x 7 lighthouse lighthouse 4096 Apr 15 21:47 ../
-rw-rw-r-- 1 lighthouse lighthouse 129 Apr 8 23:05 book
drwxrwxr-x 8 lighthouse lighthouse 4096 Apr 18 19:52 .git/
drwxrwxr-x 3 lighthouse lighthouse 4096 Apr 10 22:29 git_learning/
初始状态:
master
分支未提交过 file
文件(或该文件未被跟踪)。dev
分支修改并提交了 file
,此时 file
成为 dev
分支的一部分。切换回 master
:
master
分支没有 file
的记录,Git 会清理工作目录,删除 file
文件以匹配 master
分支的状态因此分支交换的逻辑,可以这样理解,如下:
dev
修改了文件,想临时切到 master
修复问题,Git 允许携带未提交的修改切换(只要不冲突)。dev
分支的历史记录,此时 dev
分支的最新提交包含该文件,而 master
分支的历史记录中没有该文件。master
时,Git 会根据 master
的最新提交重建工作区,因此文件会消失(因为 master
从未记录过它)。git stash
:临时保存未提交的修改,切换分支后再恢复 git add
和 commit
明确添加到分支历史中。这就是为什么在提交后切换到 master
时文件“消失”的原因——Git 严格遵循分支的历史记录管理文件
add
)都存在于工作区中,不直接绑定到任何分支git add
后的内容属于暂存区,与分支无关。
commit
)后,修改会绑定到当前分支的历史记录中,不同分支的提交历史是独立的但是看到这里,也许大家也会有点问题,就是当 commit 之后,那么产生的文件在两个分支下不就内容不一样了吗,此时它两也能算得上全局共享嘛???
解释如下:
假设有一个文件 file.txt
,初始状态如下:
步骤 1:在 master
分支创建文件并提交
git checkout master
echo "Hello from master" > file.txt
git add file.txt
git commit -m "Add file in master"
此时:
master
分支的提交历史包含 file.txt
。file.txt
内容是 Hello from master
。步骤 2:创建 dev
分支并修改文件
git checkout -b dev
echo "Hello from dev" > file.txt
git add file.txt
git commit -m "Update file in dev"
此时:
dev
分支的提交历史包含修改后的 file.txt
(内容是 Hello from dev
)。master
分支的提交历史仍为旧版本(内容是 Hello from master
)。步骤 3:切换回 master
分支查看文件
git checkout master
cat file.txt
Hello from master
master
分支的最新提交是原始版本,而 dev
分支的最新提交是修改后的版本。dev
分支的提交历史中有一个新版本的 file.txt
,而 master
分支的提交历史中仍是旧版本。区域 | 是否全局共享? | 是否受分支切换影响? |
---|---|---|
工作区 | ✅ 是(所有分支共享同一物理目录) | ✅ 是(切换分支时内容会被覆盖) |
暂存区 | ✅ 是 | ✅ 是(切换分支时可能被覆盖) |
版本库(提交) | ❌ 否(每个分支有独立提交历史) | ❌ 否(提交历史永久绑定到分支) |
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有