Git 分支与整合策略

持续部署的前提是模块化设计、自动化测试和持续集成。使用好 Git 的分支(branch)与整合(integrate)功能,有利于高效率的持续集成。Pro Git 关于 分支 的建议是不错的,值得采用。

整合

Rebasing(变基) 是一个很不错的功能,和 Merging(合并)一对兄弟,是用来整合来自不同分支的修改的两种方法。

Rebasing

对于多人协同开发来说,本地修改 commit(提交) 后,在 push(推送) 代码前,Rebasing 一下是一个很好的做法,log 看起来比较整齐,有助于阅读和理解(由于 merge 带来了蜘蛛网般的 log,想看清代码走向非常费劲;log 中常见的 "Merge branch 'v0.7d-rebuild' of http://git.example.com/wbs.wph into v0.7d-rebuild" ,本是不必要的 merge,也自然消失了)。
请不要对已经 push 出去的东西 再次 rebase 了。

怎么理解 Rebase 呢?
假定把当前分支作为新特性分支,在开发过程中,主分支(Rebase 分支)又发生变化了,我们就要基于 Rebase 分支最新末端重新应用一下当前分支的每个 commit。
同理,rebase 概念适用于有跟踪关系的远程和本地分支的整合。

在 config 中设置 rebase 选项,使得 git pull 使用 rebase 整合所做修改
git config --global pull.rebase true
git config --global branch.autoSetupRebase always
  • pull.rebase:git pull 时使用 rebase 而非 merge 来整合修改;
  • branch.autoSetupRebase:对所有的 tracking branches 都设置 rebase;
  • git config 时加上 --global 选项,对所有 repo 起作用;
  • 单次操作可以这么着:git pull --rebase [<remote name> <branch name>];
  • pull with rebase @ gitready.com
采用 merge 示意图

git pull 命令采用 merge 策略,即:pull(拉取)= fetch(抓取)+ merge;

采用 rebase 示意图

git pull 命令采用 rebase 策略,即:pull(拉取)= fetch(抓取)+ rebase;

由基于 C2,变为基于 C4;变基后,C3 和 C5 变为 C3' 和 C5'
变基时出现冲突,怎么办?
  • 镇定,冲突总能解决;
  • 耐心,避免引入更多缺陷;
  • 首先修改文件,解决冲突;
  • 然后 add,commit 修改后的文件;
  • 最后运行 git rebase --continue(请不要轻易使用 skip or abort);

    When you have resolved this problem, run "git rebase --continue".
    If you prefer to skip this patch, run "git rebase --skip" instead.
    To check out the original branch and stop rebasing, run "git rebase --abort".

冲突产生的原因
冲突的解决之道
  • 尽早集成(smaller changesets),有助于避免冲突,即使出现冲突也容易解决;
  • 每次 pull(fetch+rebase),就是一次(代码)集成;

    请经常 pull;不一定非要到 push 前才去 pull;
    经常 pull,经常集成(integrating often),使得 push 不再那么匆忙(有因怕冲突而匆忙 push 的情形);当且仅当需要 push 的时候才去 push;

  • 每次 push,都是一次发布;
  • 对于解决冲突的 commits,一定要 review code
    git log --min-parents=2 -p --cc
删除分支的理由和时机
  • 当你的两个分支指向同一个 commit 时,就可以删除其中一个;无冗余,保持整洁了;
  • 当你的一个分支 A 已经完全合并到另一个分支 B 上,A 分支使命已经完成、不再使用时,就可以删除这个分支 A;
    请使用 git branch --merged 和 git branch --no-merged 来检查是否已合并到当前分支;
  • 你觉得碍眼,就想任性一下要删除时;
    删除没有合并的分支时,git 会提醒你,当然也可以强行删除;
了解 remote 的分支情况
  • git ls-remote [<remote>]
  • git remote show [<remote>]
A commit and its tree
选自 Branches in a Nutshell,理解 git 存储机制
分支管理策略(Branching Workflows
A “silo” view of progressive-stability branching
  • master 分支
  • dev(develop) 分支是我们的主要分支,在当下,上线发布使用 dev 分支;
  • 从 dev 开分支 hotfix;
  • 迭代分支(feature、topic)从 dev 分支开出,我们使用 0.8, 0.8c 这样的方式命名;
  • 迭代分支应经常 merge dev(git merge dev);(迭代完成后)dev 合并迭代;删除迭代分支;
  • 保持适度分支,避免复杂过程;
    这个分支就太复杂了,不会考虑采用

    作者 nvie这篇文章 里阐述的更多;
merge 示意图

Git 会使用两个分支的末端所指的快照(C4 和 C5)以及这两个分支的共同祖先 Common Ancestor(C2),做一个简单的三方合并。


一次典型合并中所用到的三个快照
A merge commit(C6), it has more than one parent.
高级主题
  • Deleting Remote Branches
    git push origin --delete <branchname>
  • distributed git
  • 重命名分支名字(修改分支名字)
    git branch -m [<oldname>] <newname> 修改本地 oldname => newname
    git push -u origin <newname> 推送到远程;
    git push origin :<oldname> 删除远程的 oldname;
  • git branch
    -vv
    -v, --verbose
    When in list mode, show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well (see also git remote show <remote>).
  • git log --decorate --oneline --all --graph
    查看所有分支(图形形式);
  • git branch -d <branchname>
    如果你的 repo 是 clone 来的,并且和上游保持同步联系,那么删除本地分支名,就是为了清爽,你随时可以 checkout 出来。有时会报警告:

    warning: deleting branch 'v0.7d-example' that has been merged to 'refs/remotes/origin/v0.7d-example', but not yet merged to HEAD.

  • git branch -d -r <branchname>
    delete remote-tracking branches. 这只是删除本地记录的那个远程分支名;要真正删除远程分支,请使用 git push :<branchname>
  • git fetch --prune
    -p,--prune,After fetching, remove any remote-tracking references that no longer exist on the remote. git fetch
    如果有人清理了远程 repo 分支,你 git pull 后 并不会同步清理 本地记录的那些远程分支名;请使用该命令清理那些在远程并不存在的refs;
    git remote prune origin --dry-run,检查清理 origin 无效分支,git remote update --prune origin 也可以;
  • Learn Version Control with Git
  • 讨论 Martin Fowler 对持续集成和特性分支看法的文章,内容丰富,值得看;
  • Branching and Merging Primer,August 2006, Chris Birmele @ Microsoft
  • 可能无法删除远程分支
    通常是因为该分支是当前活跃分支。在远程 bare repo 下,执行:git symbolic-ref HEAD refs/heads/<anotherbranchname>,也就是改换 HEAD 指向另一个分支,然后就可以删除你想删除的分支了;或者直接修改 HEAD 文件;
  • 只有部分分支推送成功的问题
    有时候,你修改本地一个分支(v0.8分支),直接 push,发现这个分支成功推送,而另一个分支(dev分支)出了问题,如下:
$ git push
Counting objects: 2, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 257 bytes | 0 bytes/s, done.
Total 2 (delta 1), reused 0 (delta 0)
To http://git.example.com/wbs.wph.git
   0187b7f..9c68fb9  v0.8 -> v0.8
 ! [rejected]        dev -> dev (non-fast-forward)
error: failed to push some refs to 'http://git.xxtao.com/wbs.wph.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
- 请每次都要仔细查看返回的信息,git 做的非常好的一点就是会认认真真地告诉你下一步应该怎么做,你照着做就好了。
- 照着做尽管并不是 100% 都成功,无论如何值得认真尝试;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容