git分支间切换注意点和bug分支的处理

简介: 从分支点开始,不同分支修改工作区的内容(不添加到暂存区和提交),切换分支,工作区的内容是一样的。 本文参考于廖雪峰老师的博客Git教程。依照其博客进行学习和记录,感谢其无私分享,也欢迎各位查看原文。

备注:

本文参考于廖雪峰老师的博客Git教程。依照其博客进行学习和记录,感谢其无私分享,也欢迎各位查看原文。

知识点

  • 当前一个分支上修改文件或目录后,在没有提交前,任何一个分支的状态(git status)都会同步为一样
  • 合并或切换分支工作,一定是在当前分支提交后,或者使用git stash将当前暂存区状态保存下来之后进行,即当前分支git status显示为干净的仓库再切换
  • 同时修改了同一个工作区相同文件,由于Git管理版本是通过移动HEAD指针,工作区的修改对于移动到不同分支的指针是一样的。此时masterdev分支git add添加到暂存区,git status在不同分支状态是一样的,如果master分支先commit,中间所做的修改,会全部算作master的修改(由于dev没有提交,仅仅add添加了暂存区,中间的修改在切换分支提交后会在dev分支丢失,但所有修改都存在于master的提交中)。故:实际开发中一定要提交或者暂存当前暂存区的状态后,再切换分支进行其他修改,否则在本分支所做修改的状态会丢失。
  • git stash对于git没有管理的文件状态不会保存(新创建或修改没有添加过的文件)。
  • git stash list查看stash的列表
  • git stash pop恢复stash到当前分支,并删除stash
  • git stash apply,git stash drop恢复stash和删除stash
  • git stash apply stash@{0}恢复指定的stash到当前分支。

记一次分支合并问题状况

从分支点开始,不同分支修改工作区的内容(不添加到暂存区和提交),切换分支,工作区的内容是一样的。

这一点也证明了,Git修改的是HEAD指正,而不是文件

如下:

  • -git status查看dev分支上Git的状态,干净工作区
  • 切换到mster,查看Git状态,干净工作区
$ git status
位于分支 dev
无文件要提交,干净的工作区
$ git checkout master
切换到分支 'master'
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
$ git status
位于分支 master
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
  • master分支下,修改readme文件,查看状态,和切换到dev分支下,常看状态。忽略远程分支的提示。
$ git status
位于分支 master
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)
    修改:     readme.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
$ git checkout dev
M    readme.txt
切换到分支 'dev'
$ git status
位于分支 dev
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)
    修改:     readme.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")

必须在提交或者暂存当前暂存区的状态后,再切换或合并分支

工作区的修改对于不同分支是一样的:

同时修改了同一个工作区相同文件,由于Git管理版本是通过移动 HEAD指针,工作区的修改对于移动到不同分支的指针是一样的。此时 masterdev分支 git add添加到暂存区, git status在不同分支状态是一样的,如果 master分支先 commit,中间所做的修改,会全部算作 master的修改(由于 dev没有提交,仅仅 add添加了暂存区,中间的修改在切换分支提交后会在 dev分支丢失,但所有修改都存在于 master的提交中)。故: 实际开发中一定要提交或者暂存当前暂存区的状态后,再切换分支进行其他修改,否则在本分支所做修改的状态会丢失。

同理,合并分支也一样,必须在提交或者暂存当前暂存区状态后,再进行分支的合并。

如下为修改工作区或添加到暂存区后对git分支切换和提交的整体测试:

  • 如下, master分支上修改readme,查看状态,
$ git status
位于分支 master
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)
    修改:     readme.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
  • 切换到dev查看状态,
$ git checkout dev
M    readme.txt
切换到分支 'dev'
$ git status
位于分支 dev
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)
    修改:     readme.txt
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
  • dev分支上修改readme文件,切换到master分支,查看内容
$ git checkout master
M    readme.txt
切换到分支 'master'
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
$ cat readme.txt
`this is a test that I learning and use git version control system
this is a beginning
wofaidognyixie dognxi
create two new branch
Creating a new branch is quick and simple.
add a new branch
master modify
dev modify
  • master分支上将修改添加到暂存区,查看状态
$ git add readme.txt
$ git status
位于分支 master
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)
    修改:     readme.txt
  • 切换到dev分支,修改readme文件后,切换回master分支,查看状态。会出现工作区的修改提示
$ git checkout dev
M    readme.txt
切换到分支 'dev'
$ git checkout master
M    readme.txt
切换到分支 'master'
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
$ git status
位于分支 master
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)
    修改:     readme.txt
尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)
    修改:     readme.txt
  • 切换回dev分支,git add添加在存储区后,查看状态,状态为暂存(未提交)
$ git checkout dev
M    readme.txt
切换到分支 'dev'
$ git add readme.txt
$ git status
位于分支 dev
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)
    修改:     readme.txt
  • 切换回master分支,git status查看状态也为暂存(未提交)
$ git checkout master
M    readme.txt
切换到分支 'master'
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
liu@liu-virtual-machine:~/gitTest$ git status
位于分支 master
您的分支领先 'origin/master' 共 8 个提交。
  (使用 "git push" 来发布您的本地提交)
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)
    修改:     readme.txt
  • master分支提交,查看状态,显示无文件要提交,工作区干净
$ git commit -m"commit master"
[master 1ba95a4] commit master
 1 file changed, 2 insertions(+)
$ git status
位于分支 master
您的分支领先 'origin/master' 共 9 个提交。
  (使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
  • 切换到dev分支,工作区状态为干净,暂存区无提交,如下。
$ git checkout dev
切换到分支 'dev'
$ git status
位于分支 dev
无文件要提交,干净的工作区
  • 此时,分别在masterdev分支先查看readme文件内容

dev分支,显示为所有改动之前的内容

master分支下的readme文件内容为最新(包含在dev分支下修改和添加到暂存区的内容)

超前提交的分支无法合并落后版本的分支(即无法倒退到未提交过的分支状态)

目前所知,依靠分支之间的合并(merge)无法实现版本倒退(也许有办法,未进行深入研究),只能通过git reset --hard commit_id实现版本回退。

master上新建分支dev,然后修改master上内容,并添加提交,此时master的版本比dev版本要高,如果此时想把dev(分支的低版本)合并到master上会发生什么呢?

  • master如果更新后(更新后的上游分支),试图将未进行更新的dev分支合并到当前分支,会提示必须给出一个提交信息解释此合并,否则会终止合并提交

倒退合并master分支到dev分支提示

输入合理解释后,会再一次确认存储缓冲区的更改

倒退合并master分支到dev分支再次确认

套退合并马萨特然分支到dev分支确认后提示写入格式

倒退合并master分支到dev分支确认提示写入格式询问是否新建一个文件存储合并信息

如下为操作完成后的终端状态

$ git merge dev
Merge made by the 'recursive' strategy.
 testOndev.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 testOndev.txt

但是查看文件内容,并没有回到原先状态。

倒退合并失败,其实这种情况应该使用版本回退

  • 即使使用--no-ff参数,使用普通模式合并,如下:
$ git merge --no-ff -m"merge backup" dev
Already up-to-date.

文件内容依然保持和master一致,没有合并到dev分支状态。

解决:使用版本回退git reset --hard commit_id,可以完成实际的修改。

$ git reset --hard a7d3eb7
HEAD 现在位于 a7d3eb7 fixed conflict

内容修改。

bug分支

有了上面切换分支和合并失败的经历,就不难理解下面的操作了。

软件开发中,bug总是在你想到和想不到的正常情况和意外情况下出现。修复bug,在Git中完全可以通过建立一个临时分支来修复,修复后合并分支即可。

但是当你正在开发时,对于突然接到一个修复bug的任务,由于当前开发(dev分支)没有完成,dev上的工作可能还没有提交。

此时如果想创建一个临时分支issue10修复master分支的bug

查看Git状态如下:

$ git status
位于分支 dev
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

    新文件:   newFile

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

    修改:     readme.txt

由于没有开发完,可能暂时无法提交

暂存当前暂存区的状态

  • Git提供了一个stash功能,可以把当前暂存区工作状态“储藏”起来,等以后恢复现场后继续工作。
$ git stash
Saved working directory and index state WIP on dev: 0df6e43 Merge branch 'dev'
HEAD 现在位于 0df6e43 Merge branch 'dev'
  • 查看状态,显示无文件要提交,工作区也是干净的。
$ git status
位于分支 dev
无文件要提交,干净的工作区

注:git stash对于git没有管理的文件状态不会保存(新创建没有添加过的文件)。

  • 确定从哪个分支上修复bug,现在在master分支上修复,切换并新建分支issue10
$ git checkout master
切换到分支 'master'
您的分支领先 'origin/master' 共 13 个提交。
  (使用 "git push" 来发布您的本地提交)
$ git checkout -b issue10
切换到一个新分支 'issue10'
$ cat readme.txt

`this is a test that I learning and use git version control system
this is a beginning
wofaidognyixie dognxi
create two new branch
Creating a new branch is quick and simple.
add a new branch
master modify
dev modify again commit on master

如上为readme内容,将master modify改为modify on master,提交

$ git add readme.txt
$ git commit -m"fixed a bug"
[issue10 afc33ef] fixed a bug
 1 file changed, 1 insertion(+), 1 deletion(-)

切换到master分支并合并。最后删除issue10分支

$ git checkout master
切换到分支 'master'
您的分支领先 'origin/master' 共 13 个提交。
  (使用 "git push" 来发布您的本地提交)
$ git merge --no-ff -m"merged fixed bug" issue10
Merge made by the 'recursive' strategy.
 readme.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git branch -d issue10
已删除分支 issue10(曾为 afc33ef)。

bug修改完成后,现在回到dev分支接着开发,此时dev的状态是干净的。

$ git checkout dev
切换到分支 'dev'
$ git status
位于分支 dev
无文件要提交,干净的工作区
  • 使用git stash list查看暂存的状态
$ git stash list
stash@{0}: WIP on dev: 0df6e43 Merge branch 'dev'

恢复暂存起来的状态

  • git stash apply恢复,但恢复后,stash内容并不删除,需要用git stash drop来删除
  • 使用git stash pop,恢复的同时会把stash内容也删除。
$ git stash pop
位于分支 dev
要提交的变更:
  (使用 "git reset HEAD <文件>..." 以取消暂存)

    新文件:   newFile

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git checkout -- <文件>..." 丢弃工作区的改动)

    修改:     readme.txt

丢弃了 refs/stash@{0} (90a1bdda8ec2c4d1a2833b45ffa2a0be3f2af670)

可以多次stash,恢复的时候,先用git stash list查看,然后用git stash apply指定恢复到哪个状态

$ git stash apply stash@{0}
相关文章
|
1月前
|
开发工具 git
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
这篇文章是关于Git常用命令的总结,包括初始化配置、基本提交、分支操作、合并、压缩历史、推送和拉取远程仓库等操作的详细说明。
104 1
git学习四:常用命令总结,包括创建基本命令,分支操作,合并命令,压缩命令,回溯历史命令,拉取命令
|
1月前
|
开发工具 git 开发者
关于git 解决分支冲突问题(具体操作,包含截图,教你一步一步解决冲突问题)
本文通过具体操作和截图,详细讲解了如何在Git中解决分支冲突问题,包括如何识别冲突、手动解决冲突代码、提交合并后的代码,以及推送到远程分支。
318 3
关于git 解决分支冲突问题(具体操作,包含截图,教你一步一步解决冲突问题)
|
2月前
|
缓存 开发工具 git
Git创建分支以及合并分支
在Git中,创建分支使用`git branch [branch_name]`,切换分支使用`git checkout [branch_name]`。修改文件后,通过`git add [file]`添加到暂存区,然后`git commit`提交到本地仓库。如果是新建分支的第一次推送,使用`git push origin [branch_name]`推送到远程仓库,之后可以简化为`git push`。合并分支时,使用`git merge [branch_name]`将指定分支的更改合并到当前分支。
58 2
Git创建分支以及合并分支
|
1月前
|
开发工具 git
Git分支使用总结
Git分支使用总结
35 1
|
30天前
|
Unix Shell 网络安全
git学习六:(bug总结)git@github.com: Permission denied (publickey).等
本文是关于解决在使用Git和GitHub时遇到的“git@github.com: Permission denied (publickey)”错误的指南。文章提供了详细的步骤,包括确认SSH Agent运行状态、检查密钥配置、确保密钥匹配、验证仓库URL、检查权限和代理设置,以及配置SSH文件。这些步骤帮助用户诊断并解决SSH认证问题。
77 0
|
2月前
|
存储 Linux 开发工具
Git基础命令,分支,标签的使用【快速入门Git】
本文详细介绍了Git版本控制系统的基础概念和常用命令,包括工作区、暂存区和版本库的区别,文件状态的变化,以及如何进行文件的添加、提交、查看状态、重命名、删除、查看提交历史、远程仓库操作和分支管理,还涉及了Git标签的创建和删除,旨在帮助读者快速入门Git。
Git基础命令,分支,标签的使用【快速入门Git】
|
2月前
|
测试技术 开发工具 git
掌握 Git 分支策略:提升你的版本控制技能
在现代软件开发中,版本控制至关重要,Git 作为最流行的分布式版本控制系统,其分支管理策略对于高效协作和代码维护尤为重要。本文介绍了几种常用的 Git 分支策略,包括主线开发模型、功能分支模型、Gitflow 工作流和 Forking 工作流,并探讨了如何根据项目需求选择合适的分支模型。通过保持 `master` 分支稳定、及时合并清理分支、使用命名规范、利用 Pull Request 进行代码审查及自动化测试等最佳实践,可以显著提升团队协作效率和软件质量。掌握这些策略将帮助开发者更好地管理代码库,加快开发流程。
|
3月前
|
存储 小程序 安全
【技巧】git stash用的好,切换分支随便搞
本文详细介绍了 Git 中的 `git stash` 命令,帮助你在切换分支时临时保存未提交的更改。通过实际操作示例,展示了如何使用 `git stash` 的各种命令,如 `save`、`list`、`apply` 等。无论你是初学者还是有一定经验的开发者,都能从中受益。
63 0
【技巧】git stash用的好,切换分支随便搞
|
12天前
|
缓存 Java Shell
[Git]入门及其常用命令
本文介绍了 Git 的基本概念和常用命令,包括配置、分支管理、日志查看、版本回退等。特别讲解了如何部分拉取代码、暂存代码、删除日志等特殊需求的操作。通过实例和图解,帮助读者更好地理解和使用 Git。文章强调了 Git 的细节和注意事项,适合初学者和有一定基础的开发者参考。
32 1
[Git]入门及其常用命令