zoukankan      html  css  js  c++  java
  • git分支间切换注意点和bug分支的处理

    备注:

    本文参考于廖雪峰老师的博客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分支再次确认

    倒退合并master分支到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}
    
    作者: 代码迷途
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意原创文章必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    非原创文章若有需要,建议直接联系原文作者或保留声明情况下转载原文
  • 相关阅读:
    096实战 在windows下新建maven项目
    095实战 ETL的数据来源,处理,保存
    094实战 关于js SDK的程序,java SDK的程序
    093实战 Nginx日志切割,以及脚本上传nginx的切割日志
    092实战 数据收集(各种事件)
    091实战 Nginx配置(日志服务器中关于日志的产生)
    android64位机子兼容32位.so库文件
    给 Android 初学者的 Gradle 知识普及
    Android重力感应开发
    随笔之Android平台上的进程调度探讨
  • 原文地址:https://www.cnblogs.com/codemissing/p/git_bugbranch.html
Copyright © 2011-2022 走看看