分支(Branches)
试想一下,你现在的工程有一个即将发布的版本,或是已经发布的版本,你突然想添加一些新的特性,如何防止这些新添加的代码让整个项目陷入瘫痪呢?答案很简单:你需要使用分支。
如何简单的理解分支呢?你可以把你的项目想象成一棵树,稳定版本就是树的主干。任何添加新功能的版本都必须是树干的一部分。分支,就像是树的枝干,它从树干生长出来,向不同的方向生长。在git中,你可以通过创建分支来为你的代码设置一个新的路径来实现新特性,而不用担心在开发中破坏主干。
实际上,在git中默认都会有一个分支,叫做master。Xcode自动执行的第一次提交中就发生在这个分支中。通常,单独的开发者只在master这个分支开发,这其实不是一个好习惯。无论你是单打独斗还是组团合作,我认为在对项目作出重大改变或添加重大功能时,使用分支是十分重要的,它会为你避免很多麻烦。当然,在团队项目中,为你自己负责部分的代码搞一个分支几乎是必须的。
关于分支,你必须记住以下两点:
1. 提交到App Store或客户的最终产品必须是项目中的master分支项目。
2. 任何在第二分支中实现的代码或者功能最终都必须合并到master分支,这样正式发布的应用程序才是完整的。(以后再讲这一点)
当你开始一个新分支时,你实际上是以当前工作状态作为起点,即使你有任何未提交的更改。从这个时候起,所有的改变都会只体现在分支中。
现在让我们回到Xcode,要创建一个分支,点击Source Control > GitDemo-master > New Brance…这个菜单,然后会弹出如下菜单:
为这个分支起一个名字,我就把它起名为AnotherBranch好了。现在你怎么给它起名其实都无所谓。点击OK按钮,等一下新的分支就会被创建,而当前的代码也会复制到新分支中去。
打开Source Control菜单,你就可以轻松地找出活动分支是哪一个:它就在项目名字的旁边。
现在,让我们做一次新的分支的提交。在这之前,让我们添加一些新的代码。打开类文件,在私有属性区添加以下方法声明:
- @interface ViewController ()
- ...
- -(void)sayHello;
- @end
然后实现它:
- -(void)sayHello{
- NSLog("Hello");
- }
最后,在viewDidLoad中调用它:
- - (void)didReceiveMemoryWarning
- {
- ...
- [self sayHello];
- }
现在,点击Source Control > Commit菜单,版本比较窗口将会出现,你会看到只有一个被修改过的文件--ViewController.m文件,新添加的部分会被高亮显示。
输入下一个提交信息:First commit to a new branch,然后点击commit 1 file按钮。现在AnotherBrance分支的改变就会被提交了。
打开Version Editor(menu View > Version Editor > Show Version Editor),找到右边编辑面板下面的工具栏,你会看到被选中的分支是AnotherBranch,点击它,你会看到这个分支和master分支同时出现,从master分支中选择任意版本,Xcode都会高亮显示两者之间的区别。通过这样,你可以方便地跟踪所有分支间代码的改变。
最后,切换到另一个分支,或是master分支,你可以点击Source Control > GitDemo –AnotherBranch > Switch to Branch…菜单。
从这个窗口你可以选择想要跳转的分支,在这里让我们跳回master分支:
选择它并点击Switch按钮,master分支就会成为当然活动分支。你会发现在AnotherBranch中做出的改变并没有出现在master分支。很好,我们在管理工程推进的同时,却没有修改稳定版本。
合并分支(Merging Branches)
在分支中进行开发是一种好习惯,然而,如果代码改变要体现在发行版中,那么分支就必须被合并到master分支中。这一节我们将会告诉你怎样合并它们。在Xcode里,将两个分支合并成一个非常简单。
让我们做一个小实验来看看合并是怎样工作的。首先,确保master分支是现在的活动分支。如果不是,赶紧改过来:Source Control > GitDemo – AnotherBranch > Switch To Branch… menu,并从展示窗口选择master分支。
下一步,创建一个新的分支:Source Control > GitDemo – master > New Branch… menu,命名为LastBranch
先让Xcode飞一会,然后,到ViewController.m文件中,再创建一个私有方法,首先声明它:
- @interface ViewController ()
- ...
- -(void)sayByeBye;
- @end
然后实现它:
- -(void)sayByeBye{
- NSLog("Bye - Bye");
- }
最后,在ViewDidLoad方法中调用它:
- - (void)viewDidLoad
- {
- ...
- [self sayByeBye];
- }
在合并之前,先提交这些更改。使用Source Control > Commit菜单来执行提交。
终于还是来到这一步,关于把两个不同的分支合并成一个,你有两种选择“
1. 从分支合并:与你选择的分支相关的任何改变都会被合并到现在活动分支中。
2. 合并到分支:当前活动分支的任何改变都会被合并到你选择的分支中。
这两种方式你都可以在Source Control > GitDemo 菜单中找到。注意当你的活动分支是master分支时,第二个选项是不可选的。
假设一个开发者在Anotherbranch分支实现一个sayHello方法,另外一个开发者在LastBranch中创建实现了sayByeBye方法,现在你需要将两个人的工作合并到下一个稳定版本中,想一想你需要怎么做?很简单,按以下方法将改变从两个分支中合并进来:
首先,确保当前活跃分支是master分支。
然后,打开Source Control > GitDemo – master > Merge From Branch…菜单,选择AnotherBranch然后点击Merge按钮。
接下来会出现一个比较窗口,在里面你会看到合并之后代码的更改,看一眼,感觉差不多了就再点击Merge按钮。
Xcode会询问你是否保存项目的快照,点击Enable按钮。让Xcode飞一会,然后就好啦。AnotherBranch里面添加的内容已经合并到master分支中。
使用同样的方法来合并LastBranch。你会发现如果你不提交更改,Xcode不会让你再次合并。于是,我们只好先提交一下。在比较窗口你会发现一个红色的区域显示合并之后的更改,而不是之前的蓝色。这意味着分支中的代码将会替换原先活动分支中的代码。
你可以轻松地避免这种现象的发生。在编辑面板的下面有几个小按钮,你可以试试他们都有什么作用,我选了第一个,它的意思是master分支的代码会被放在上面,另一个分支的代码会跟在它后面。
处理接下来所有需要更改的代码,不要有遗漏。完事后就点击Merge按钮。
恭喜你!你已经成功的学会从多个分支合并了代码,类似的情形你也应该会了。