美文网首页
git学习及分支管理策略

git学习及分支管理策略

作者: 好奇的小刺猬 | 来源:发表于2016-05-07 15:49 被阅读831次

    git分支使用的坏习惯

    最近使用git提交代码发现大家的方式都不一样,自己在使用中也遇到了一些问题,导致代码危险。具体描述一下就是:
    1.刚开始创建本地b_28分支与远程b_28对应。在此基础上,我自己改一个bug就基于这个又拉取了本地分支b_bug,一直在这个本地分支上修改,这个b_bug也一直没有关联任何远程代码。
    2.后来远程b_featureA分支(原来是和b_28一样的)做了些版本小修改。
    3.我不明就里的,本地又checkout了一个b_featureA,还把这些修改merge到了自己的b_bug。
    4.管理员让我提交自己bug的修复。我将b_bug merge到本地b_28,然后先拉了origin b_28的更新,还好本地没冲突,然后push到了远端origin b_28。
    5.远端分支的话,管理员b_featureA开发完了,要merge到b_28,并以后要在b_28基础上开发

    其实这就有问题了,本来是用大家最新提交后的origin b_featureA去merge到origin b_28,但是由于我之前push到上面的代码包含了不必要的对origin b_featureA拉取,导致这个提交不安全。(事实上由于我在第3步之后又将b_bug中一个文件K恢复到了b_28版本,导致这个更新丢失了。这次远端merge的时候,K竟然还是未改的,b_featureA对它的改动并没有merge成功,但也没有提示,还好最后检查了。其实要是我没有恢复过这个K也就没事了)
    因此,我犯了一个不必要的错误,要保证本地分支的parent只有一个,不要随便merge别的分支。
    然后对于分支的使用原则,问了些人,大家习惯不一样,这几找了几个列子,想分清楚集中使用方法。


    大家怎么用

    主要关注功能分支:
    我觉得可能不同的项目或者不同习惯的人需要不同的分支策略,这些没有必要非要按照某种规则去遵守。
    一、阮一峰:Git分支管理策略 重点推荐,简单全面
    1.创建一个功能分支:

    git checkout -b feature-x develop

    2.开发完成后,将功能分支合并到develop分支:

    git checkout develop
    git merge --no-ff feature-x

    3.删除feature分支:

    git branch -d feature-x

    二、这个跟上面的是一样的方法,还有全面的命令,总结的很好:git使用规范
    三、 这个稍微有点不一样:Git 问题, 一个 master, 多个新功能分支, 怎样有序地合并和提交?
    git支持很多种工作流程,我们采用的一般是这样,远程创建一个主分支,本地每人创建功能分支,日常工作流程如下:
    1.去自己的工作分支

    $ git checkout work

    2.工作
    3.提交工作分支的修改

    $ git commit -a

    4.回到主分支

    $ git checkout master

    5.获取远程最新的修改,此时不会产生冲突

    $ git pull

    6.回到工作分支

    $ git checkout work

    7.用rebase合并主干的修改,如果有冲突在此时解决

    $ git rebase master // 将改变当前工作分支的提交历史,rebase使得master上的更改在work上重演一遍

    8.回到主分支

    $ git checkout master

    9.合并工作分支的修改,此时不会产生冲突。

    $ git merge work

    10.提交到远程主干

    $ git push

    这样做的好处是,远程主干上的历史永远是线性的。每个人在本地分支解决冲突,不会在主干上产生冲突。
    注意衍合rebase的使用:分支的衍合
    简单介绍rebase的:git rebase简介(基本篇)
    Attention:一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。
    如果你遵循这条金科玉律,就不会出差错。否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你

    四、一个小团队的使用:请推荐一个适合4-6人小团队的git代码管理模式?
    整体项目分为master和develop两个分支,master主要用来发布网站使用.develop主要是用来分开使用.
    1.平时每个人开发的时候,从develop中clone一下并创建一个开发者自己的分支,如zhang.(再有新加入者的时候,类似同样的方法分支另起一个名字li.).** Q:相当于每个开发者有一个自己的远程分支?按照人来确立分支而不是按照功能分支 **
    2.当开发工作完成后,提交本地仓库并git push到自己的分支.
    3.最后先将develop合并到自己的分支(开发期间可能被开发者进行过修改),以确保合并成功.
    4.合并无误后,再将当前合并后的zhang分支合并到develop分支中.(注:这里的合并操作先是在本地分支合并.然后再合并到远程分支.有点多操作一步).
    5.到最后一天工作结束后再将develop合并到master分支,通过master上线运行.
    另外对于线上环境有紧急bug要修改的时候.再从master里创建一个分支.独立维护.结束后,再分别同步master和develop两个分支.

    ** 五、我打算用这个方式了,感觉跟第三个很类似:3.2 Git 分支 - 分支的新建与合并**
    让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流。 你将经历如下步骤:
    1.开发某个网站。
    2.为实现某个新的需求,创建一个分支。
    3.在这个分支上开展工作。
    正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。 你将按照如下方式来处理:
    1.切换到你的线上分支(production branch)。
    2.为这个紧急任务新建一个分支,并在其中修复它。
    3.在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支。
    4.切换回你最初工作的分支上,继续工作。

    我认为的使用方式,还没有验证过不知道是不是好用:
    比如有两个相互独立的任务featureA和featureB,简单点,他们都是从origin/dev拉过来开发。
    第一种:

    1. 分别建立本地分支

    $ git branch b_featureA origin/dev //新建本地分支featureA --关联远程分支dev
    $ git branch b_featureB origin/dev //新建本地分支featureB --关联远程分支dev

    1. featureA和featureB在各自的分支上工作

    2. 最后修改完,先pull远端的代码,可能会有冲突,此时

    $ git stash // 先暂存本地修改
    $ git pull // 再拉取
    $ git stash pop stash@{0} // 还原暂存区的内容,并解决冲突

    1. 解决冲突后

    $ git push origin dev

    1. 如果本地分支featureA和本地分支featureB没用了,可以删除

    这种方法没有一个比较稳定的本地分支。

    第二种:
    1.新建本地local_dev --关联远程dev

    $ git branch local_dev origin/dev

    2.基于本地的开发分支local_dev 创建两个功能分支,它们不关联任何远程分支

    $ git branch b_featureA
    $ git branch b_featureB

    3.分别在featureA和featureB在各自的分支上工作

    4.featureA开发完毕,切回到local_dev,它pull最新代码,此时不会有冲突。然后两种情况:
    方法一:将最新的更改merge到local_dev,有可能冲突,也有rebase的,不熟悉先不用了。
    没有冲突工作区也干净后,push到远端。删除本地featureA。
    如果有暂时不想提的,可以stash起来,先不删除,然后进行后续开发。

    方法二:再复杂一点,切回到featureA,将local_dev的更新merge过来,冲突在此处解决。
    都提交后,切回到local_dev,将featureA的更新merge过来,此时不会再有冲突。
    local_dev推送到远端。

    方法三:我没想到,一个同事说的,切回到featureA,将origin/dev的更新merge过来,就是直接将远端分支的更改merge过来,有冲突就在此处解决。然后都开发完毕后,切回到local_dev,将featureA的更新merge过来,然后将local_dev推送到远端。比方法二少一步merge,然后好像也没什么大的缺点。
    不过还没用过直接将远程分支merge到本地这种未对应远程分支的分支上。而且,经常看到这样的忠告:

    不要用git pull,用git fetch和git merge代替它。

    5.featureB同上

    我之前是用的最复杂的第二种的方法二。好处是冲突都是在本地最末端的分支上,和其他功能都不会相互影响,就是操作太麻烦了。
    打算采用上面的三,期待有更好的方法。


    一些常用命令

    基本命令

    $ git remote add origin git@github.com:michaelliao/learngit.git // 将本地的git目录和远程建好的git目录关联
    $ git add . // 添加所有文件到git版本控制,注意不是git stash
    $ git commit -m "commit log" // 提交修改,必须要加注释
    $ git checkout -b story remotes/origin/story // 在本地创建story分支并track,可以pull和push
    //恢复版本
    $ git checkout -- readme.txt // 把readme.txt文件在工作区的修改全部撤销,还未添加到暂存区
    $ git reset HEAD readme.txt // 已经add,还没有commit,先用这句unstage,在用上一句
    // 如果已经commit
    $ git log // 查看提交记录,确定恢复到哪个版本
    $ git log -p // 查看详细提交记录
    $ git reset --hard HEAD^ // 恢复到上一个版本,因为HEAD指的是当期版本,HEAD是上一个,HEAD^是上上个,其余的可以用版本编号的前几位来恢复
    $ git reset --hard 3628164 // 前几位来恢复,只要这个号码能唯一确定一个版本就可以
    $ git push -u origin b_28 // 将本地修改的b_28推送到远端b_28,加上了-u参数,Git不但会把本地的分支内容推送的远程新的分支,还会把本地的分支和远程的分支关联起来,在以后的推送或者拉取时就可以简化命令。第一次推送分支的所有内容,以后就可以用git push origin b_28了
    $ git branch -d feature // 删除feature分支
    $ git branch -a // 加上-a参数可以查看远程分支,远程分支会用红色表示出来
    $ git branch -vv // git branch -vv(两个v),就能够看到本地分支跟踪的远程分支。
    $ git merge --no-ff develop // 默认情况下,Git执行"快进式合并"(fast-farward merge)加上这个参数就是非快进式合并
    $ git push origin :branch_you_want_to_delete // 删除远程的某个分支,注意冒号前面有个空格,慎用

    跟踪远程分支
    从远程分支 checkout 出来的本地分支,称为 跟踪分支 (tracking branch)。跟踪分支是一种和某个远程分支有直接联系的本地分支。在跟踪分支里输入 git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。同样,在这些分支里运行 git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。
    在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是 git push
    和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如 origin
    上除了 master 之外的其它分支。刚才我们已经看到了这样的一个例子:git checkout -b [分支名] [远程名]/[分支名]。如果你有 1.6.2 以上版本的 Git,还可以用 --track
    选项简化:
    $ git checkout --track origin/serverfixBranch //serverfix set up to track remote branch serverfix from origin.Switched to a new branch 'serverfix'

    要为本地分支设定不同于远程分支的名字,只需在第一个版本的命令里换个名字:
    $ git checkout -b sf origin/serverfixBranch //sf set up to track remote branch serverfix from origin.Switched to a new branch 'sf'

    git本地新建一个分支后,如果没有做远程分支关联, git 会在git pull, git push操作中提示你显示的添加关联。你只要没有显示指定,git pull的时候就提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建。如果新建分支的时候没有指定,随后再指定本地dev分支与远程origin/dev分支的链接,可以用下面的命令

    $ git branch --set-upstream dev origin/dev

    工作区域暂存

    $git stash
    $ git stash list
    $ git stash apply
    $ git stash drop stash@{0}
    $ git stash pop //来重新应用储藏,同时立刻将其从堆栈中移走。


    学习参考资料:看了这些就够了

    1.Git常用操作和技巧
    2.git - 简明指南
    3.Pro Git简体中文版
    4.廖雪峰 简明git教程
    5.Git Commands and Best Practices Cheat Sheet

    相关文章

      网友评论

          本文标题:git学习及分支管理策略

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