美文网首页
2019-04-22 Git本地分支(Branch)的用途和用法

2019-04-22 Git本地分支(Branch)的用途和用法

作者: 鸭鸭学语言 | 来源:发表于2019-04-29 02:53 被阅读0次

    一. 分支 (branch) 

    用于:

                1. 由于debug或增加功能,从原有程序项目分出新项目。最终可以合并回原项目

                    分支常命名为:

                        bug/<bug_id>/<bug_说明>

                        feat/<新功能_说明>

                2. 原项目(master)为release-to-user 分支,另分出一个项目,做develope。最终合并(提交)回原项目

                        分支常命名为:develop

                        这种用途,合并时由于master分支始终无人修改,会采用fast-forward合并模式 (master上将没有新commit节点产生)。所以,为了产生新commit节点,须: git merge --no-ff  develop

    工作原理:

                创建新分支时,从当前分支的指定的commit节点,作以下动作:

                    1. 复制track list 

                    2. 记录这个commit节点为新分支的HEAD (用于下次切换)

                切换分支时,包扩了以下动作

                    1. 找到要切换分支的指定的commit节点 (默认是该分支的HEAD)

                    2. 比较这个commit节点的数据内容 和当前分支的在文档库里的对应版本,找出不同的文件

                    3. 取回在这些不同的文件到working directory

                    4. 覆盖 staging area数据

                    5. 替换 track list

                    6. 根据5删除working directory中不在track list上的文件

            可见:   各分支,共享 repository+staging area+working directory+.gitignore;但各分支有自己的track list,且在分支生成后,各不相干。

    管理命令:

        A. git branch  <新分支名字>   [<起源分支>] [<起源的commit节点标识符或标签>]          创建新分支,但不切换

                起源分支:默认是当前分支

                起源commit节点:默认是起源分支的HEAD

        B. git branch                                        察看文档库中所有分支

            * gitk --all 能在GUI里显示出所有分支的演进图。如果不加-all参数,只显示当前分支的

            * git log --graph --oneline --all --decorate  效果同上

        C. git branch -d <待删分支名字>        删除分支。不能删除当前分支。只能删除已合并完的分支

                支持参数:

                    1. -D    强制删除那个分支,放弃它的修改,不等合并

        D. git checkout  <分支名字>               切换分支。只有当前分支的修改已提交版本库,才有效

                支持参数:

                    1. -b : 创建并切换到新分支

                    2. -f : 不判断当前分支修改是否已提交版本库,强制checkout的6个动作 (导致当前分支的修改丢失)

            * 执行checkout之前,一定要做git status, 确保 :没提交的提交;当前分支的修改,不要误带入要切入的分支

            * 正常的2种checkout的使用情况: 

                        git checkout <分支>  -->分支切换操作

                        git checout  <commit节点>  <文件名> -->取回当前分支某文件的历史版本  

                不正常的使用情况: 

                        git checkout  <commit节点>  -->  这时 HEAD指向此commit节点形成detach head状态;当git add和git commit后,长出无名分支。

                        修复:

                            方法A:  删除此无名分支。 步骤:1. 命名当前分支 (git branch -m xxx),在这之前不要切换出去  2. 切换出去并删除此分支 (git checkout master; git branch -D xxx)

                            方法B: 合并无名分支到master上。步骤:1. 命名当前分支 (git branch -m xxx),在这之前不要切换出去  2. 切换出去,合并此分支 (git checkout master; git merge xxx)

        E. git branch -m <新分支名字>            给当前分支改名字

        F. git merge <分支名字B>                   合并另一分支到当前分支,没冲突的情况下,动作包含了git add -A .和 git commit的动作 。

                被合并分支B不会被删除,也不会有任何变化。当前分支A,会有新的HEAD, 他的父节点,HEAD^1是A自身的HEAD^, HEAD^2是B的HEAD。

               因此,合并完成后,如果要撤销这个合并:不需要对分支B做任何操作;对分支A,消磁退到它的父节点:

                    git reset --hard HEAD^

                合并没完成(由于冲突),撤销这个合并:

                    git merge --abort

                * 相对分支生长点(叫base节点)的版本,没有修改发生的分支,无法作为被合并的分支角色。

                * 两种合并机制:

                    1.  fast-forward      即当前分支没有过修改。合并时,HEAD快进到被合并分支的HEAD。只有一个HEAD^

                         选项支持: --no-ff        放弃ff模式,为当前分支另生成HEAD,等效于3-way。

                    2.  3-way                即两个分支都发生过修改。合并室,生成新HEAD。3-way有两个HEAD^                    

        G.  git rebase  <源分支>                         把当前分支的base节点,推进到源分支的新HEAD节点。没冲突的情况下,动作包含了git add -A .和 git commit的动作 。

               情景:

                    当前分支开发了太久,master分支都更新了。如果用git merge,会形成网状演进图,不清晰。所以使用rebase。

                    不是和此分支是团队共享的分支。

               支持选项:

                    1.  git rebase --skip         跳过某冲突文件

                    2.  git rebase --abort       放弃未完成的演进

                    3.  git rebase --continue    fix冲突(同二)以后,手工git add ., 然后提交 

    二、冲突

    原因: 

        3-way merge时,两个分支间存在修改同一个文件的情况

    情景:

        merge -- 两分支合并

        rebase -- 源分支的新HEAD节点版本的更新运用到当前分支中,即当前分支base节点向前推进到源分支的新的HEAD

        cherry-pick -- 指定commit节点 合并到working directory

        revert -- 指定commit节点的前一节点版本 合并到working directory, 即让working directory的修改基于的base,向历史回退。是cherry-pick的原理一样,看上去和git reset --hard 一样,但reset不会创建新的commit节点,revert更不会删任何commit节点。

    解决办法1  手工fix:

        以上情景 探测到冲突时,会在冲突文件中加入<<<<<<<标识冲突开始,>>>>>>标识冲突结束。因此: 

            step 1. vi 这个冲突文件,fix共同修改的部分,删掉标识符。

            step 2. git diff             对比确认

            step 3. git add .          手工更新staging area

            step 4. git commit -m “操作说明”    手工提交

    解决办法2 mergetool:    

        前提条件:git配置mergetool --

            git config --global  merge.tool kdiff3

            git config --global merge.tool.kdiff3.path  “<安装路径>“ 

        然后,git merge因为冲突失败后:

            step 1. git mergetool            --> kdiff3会自动作好上面方法1的step1,2

            step 2. 人review kdiff的劳动成果,保存退出。mergetool会自动作上面方法1的step3.

            step 3. git commit -m “操作说明”    手工提交

    三、让合并来服务本地文件

        这些动作,都会产生新的commit节点

        操作命令:

            A.  git cherry-pick <commit节点的标识符或标签>        合并commit节点版本到本地的文件。没冲突的情况下,动作包含了git add -A .和 git commit的动作 。

                支持选项::

                    1.  git cherry-pick --abort            合并没完成(由于冲突),撤销这个合并

                    2. git cherry-pick --continue        合并冲突fix以后,手工做这个动作,等效于merge的冲突解决后的git commit。

                冲突解决:

                    同merge,只是最后的手工git commit,被git cherry-pick --continue  替换。

            B. git revert <commit节点的标识符或标签>                    合并commit节点版本的前一个版本到本地的文件,动作包含了git add -A .和 git commit的动作 。

                支持选项:

                    1.  git revert  --abort                    合并没完成(由于冲突),撤销这个合并

                冲突解决:

                    同merge

    四、如何反悔

    对于merge、rebase (也可以是revert、cherry-pick)后,后悔想恢复版本库到操作之前。git reset --hard <commit节点标识符或标签>支持。

    但关键是找到操作之前的那个commit节点标识符。这里,需要reflog

        操作命令:

            git reflog <HEAD或分支名称>                列出该分支的所有的commi节点和对它对应的操作, 靠上的是新的

            git reset --hard <commit节点标识符或标签>

    相关文章

      网友评论

          本文标题:2019-04-22 Git本地分支(Branch)的用途和用法

          本文链接:https://www.haomeiwen.com/subject/soxpgqtx.html