Skip to content

Instantly share code, notes, and snippets.

@sivagao
Created November 10, 2012 00:57
Show Gist options
  • Select an option

  • Save sivagao/4049323 to your computer and use it in GitHub Desktop.

Select an option

Save sivagao/4049323 to your computer and use it in GitHub Desktop.
gitmagic: braches.txt
== 分支巫术 ==
即时分支合并时Git最给力的杀手锏
*方案* :Git有一个更好的工具对付这种情况,比克隆快多了而且节省空间: *git branch* 。
使用这个魔咒,目录里的文件突然从一个版本变到另一个。除了只是在历史记录里上跳下窜外,这个转换还可以做更多。你的文件可以从上一个发布版变到实验版本到当前开发版本到你朋友的版本等等。
=== 老板键 ===
我们已经创建了一个Git仓库,该仓库记录一个包含特定信息的文件。现在我们键入:
$ git checkout -b boss # 创建并切换到新分支中
$ echo "My boss is smarter than me" > myfile.txt
$ git commit -a -m "Another commit"
看起来我们刚刚只是覆盖了原来的文件并提交了它。但这是个错觉。键入:
$ git checkout master # 切到文件的原先版本。 嘿真快!这个文件就恢复了。
你可以在两个版本之间相切多少次就切多少次,而且每个版本都可以独立提交。
=== 肮脏的工作 ===
比如你正在开发某个特性,并且由于某种原因,你需要回退三个版本,临时加进几行打印语句来,来看看一些东西是如何工作的。那么:
$ git commit -a
$ git checkout HEAD~3
现在你可以到处加丑陋的临时代码。你甚至可以提交这些改动。当你做完的时候,
$ git checkout master
如果你后来想保存临时变更怎么办?简单:
$ git checkout HEAD~3 -b dirty
$ git checkout -b dirty
只要在切换到主分支之前提交就可以了。在checkout一个旧状态之后,Git自动把你放到一个新的,未命名的分支,这个分支可以使用 *git checkout -b* 来命名和保存。
=== 快速修订 ===
你正在做某件事的当间,被告知先停所有的事情,去修理一个新近发现的臭虫,这个臭虫在提交 `1b6d...`:
$ git commit -a
$ git checkout 1b6d -b fixes
那么一旦你修正了这个臭虫:
$ git commit -a -m "Bug fixed"
$ git checkout master
并可以继续你原来的任务。你甚至可以“合并”到最新修订:
$ git merge fixes
=== 合并 ===
*pull*命令就是fetch出官方项目的git中取出提交commit并且合并到你的当前分支。如果你的本地有变更,git将会自动合并,并报告任何冲突。
通常,一个提交只有一个“父提交”,也叫前一次提交。合并分支到一起产生一个至少有两个父的提交。 `HEAD~10` 真正指哪个提交?
因为在合并时候当前分支成了第一个父;多数情况下我们只关注我们在当前分支都改了什么,而不是从其他分支合并来的变更。
你可以用插入符号来特别指定父。比如,显示来自第二个父的日志:
$ git log HEAD^2
$ git checkout 1b6d^^2~10 -b ancient #开始一个新分支 ``ancient'' ,表示第一个父的第二个父的倒数第十次提交的状态。
=== 不间断工作流 ===
多亏了无痛分支合并,我们可以不必遵循这些规则,在第一部分正式准备好前开始第二部分的工作。假设你已经将第一部分提交并发去审批,比如说你现在在主分支。那么分岔:
$ git checkout -b part2
接下来,做第二部分,随时可以提交变更。只要是人就可能犯错误,经常你将回到第一部分在修修补补。如果你非常幸运,或者超级棒,你可能不必做这几行:
$ git checkout master # 回到第一部分修复问题
$ git commit -a # 提交变更
$ git checkout part2 # 回到第二部分
$ git merge master # 合并这些改动
最终,第一部分获得批准:
$ git checkout master # 回到第一部分
$ submit files # 对世界发布
$ git merge part2 # 合并第二部分
$ git branch -d part2 # 删除分支“part2”
现在你再次处在主分支,第二部分的代码也在工作目录。
很容易扩展这个技巧,应用到任意数目的部分。它也很容易追溯分支:假如你很晚才意识到你本应在7次提交前就创建分支。那么键入:
$ git branch -m master part2 # 重命名“master”分支为“part2”。
$ git branch master HEAD~7 # 以七次前提交建一个新的“master”。
分支 `master` 只有第一部分内容,其他内容在分支 `part2` 。 我们现在后一个分支;我们创建了 `master` 分支还没有切换过去,因为我们想继续工作在 `part2` 。这是不寻常的。直到现在,我们已经在创建之后切换到分支,如:
$ git checkout HEAD~7 -b master # 创建分支,并切换过去。
=== 重组杂乱 ===
或许你喜欢在同一个分支下完成工作的方方面面。你想为自己保留工作进度并希望其他人只能看到你仔细整理过后的提交。开启一对分支:
$ git branch sanitized # 为干净提交创建分支
$ git checkout -b medley # 创建并切换分支以进去工作
接下来,做任何事情:修臭虫,加特性,加临时代码,诸如此类,经常按这种方式提交。然后:
$ git checkout sanitized
$ git cherry-pick medley^^
应用分支 ``medley'' 的祖父提交到分支 ``sanitized'' 。通过合适的挑选(像选樱桃那样)你可以构建一个只包含成熟代码的分支,而且相关的提交也组织在一起。
=== 管理分支 ===
列出所有分支:
$ git branch
默认你从叫 ``master'' 分支开始。一些人主张别碰“master”分支,而是创建你自己版本的新分支。
选项 *-d* 和 *-m* 允许你来删除和移动(重命名)分支。参见 *git help branch* 。
分支``master'' 是一个有用的惯例。其他人可能假定你的仓库有一个叫这个名字的分支,并且该分支包含你项目的官方版本。
=== 临时分支 ===
$ git stash
=== 按照你希望的方式工作 ===
你可能犹疑于分支是否值得一试。毕竟,克隆也几乎一样快,并且你可以用 *cd* 来在彼此之间切换,而不是用Git深奥的命令。
正如浏览器的多个标签页和多个窗口一样,你喜欢的工作方式。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment