您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
理解 XCode 中的 Git 版本控制(二)
 
作者 kangear的博客,火龙果软件    发布于 2014-07-31
   次浏览      
 

版本对比

在你提交了多个版本之后,对比各个版本、跟踪代码的变化是非常容易的。当新添的代码不能如预期工作时,版本对比显得尤为重要,因为你需要找到从上个稳定版本以来的所有变化。

要比较两个不同版本的文件,或者点击菜单里的 View > Version Editor > Show Version Editor,或者点击工具栏上的 Version Editor 按钮,如下图所示:

一旦上面这一步完成,编辑器就会分裂成两部分。最开始,左、右栏都显示当前版本的文件。要把任意一栏切换为某个之前提交的版本,来到这一栏底部的工具栏,点击最后一个按钮,上面有时钟标志:

一瞬间,选择的版本对应的差异就显示在屏幕上了。一般来说,左栏用来显示当前版本的文件,而右栏用来访问旧的版本。之前提到过的蓝色区域表示了更改的代码,能轻松跟踪代码的增加。因此,再往下进行,选择任意一个之前的提交,观察两栏显示出的差异。

你应该注意到,在两个编辑器的方框之间,有我们在提交窗口中第一次看到的圆形标签。点击它们中任意一个向下箭头,将显示放弃改变的选项。如果你点击它,Xcode会要求你确认,如果你同意了,已经选择的代码将永远的被放弃,没有任何的机会恢复。因此,要小心,不要放弃任何一片代码,甚至是在偶然的情况下。

除了上面介绍的方法,你还有一个方法你可以恢复到以前的版本。如果你仔细观察两个方框下的工具条,在它的中间有一个带时钟和箭头的按钮。

如果你点击了它,两个方框之间列将改变并且标签将被以前提交的一系列时间戳替换。请注意不是他们所有都代表了真实的提交,这取决与提交的总量,圆角矩形的真实数字匹配以前版本的实际数量。例如,在我们的应用程序中在底部仅仅有两个形状匹配了真实的提交。

在这一栏底部,有两个箭头。左边的箭头属于左栏,指向右边;右边的属于右栏,指向左边。把这两个箭头拖到任何一个历史版本,你可以立即看到这个版本出现在对应的一栏中。如果你想对比当前版本和任何一个历史版本,只需让一个箭头指向 local 一行,然后拖动另外一个箭头。时间戳的顺序,从顶到底是从最新到最旧。这意味着写着 base 的一行,代表上一次提交的版本;而再往上看,就是那些更老的版本。下图总结了我刚才所描述的:

现在你知道如何对比版本,并跟踪代码在各个版本的变化了。现在随便玩一玩这个特性吧,之后我们再往下讲。

是谁的责任?

在比较文件的版本之前,Xcode允许追查谁提交了代码,还有谁修改了那部分的代码。如果一个项目是多人开发的话,这是一个非常有用的功能。只需简单地打开视图View > 文本编辑Version Editor > 展示责任视图Show Blame View 菜单,或者保持鼠标按钮在工具栏的文本编辑Version Editor按钮上,然后选择责任Blame选项。一个如下图所示的新窗口就会展示在你面前:

正如你所看到的,被选文件的代码是根据所提交的人的不同而被水平线分割了好几部分。根据提交的信息,每一部分的代码的作者,以及其他相关信息会展现在窗口的右侧中的一个特殊的窗格里。

如果你还没有完成上一步,打开责任视图,注意看 Xcode 是怎么用不同提交和不同作者来区别呈现代码块的。这样的界面可以非常快速地定位到某一块代码是什么时间提交,谁提交的,还可以获得一些额外信息。这些额外信息只要把鼠标移到责任栏上就可以看到。当鼠标放在一个提交片段上时,你可以看到最右出现了一个画着 i 标识的小按钮。如果你点击它,就会选中这段代码,并弹出一个窗口,上面显示着全部的提交信息。通过这个窗口,你可以切换到对比窗口(标为 #1)以及本次提交修改的文件(标为 #2)。

除了上一节我们看到的对比视图和刚刚介绍的责任视图之外,还有一个日志视图,可以通过 View > Version Editor > Show Log View 访问到;或者在工具栏上长按 Version Editor 按钮,然后选择 Log 选项。我不再详细说了,留给你自己试试吧。毕竟,理解日志是什么、怎么用并不难。

分支

想象你的项目有一个可用的版本,准备发布,或者已经发布了;现在你想开发一个新特性,但又不想意外毁坏了目前稳定可用的程序。在这种情况下,要避免可能的灾难性后果,保证你的项目不会被弄毁,你应该怎么做呢?答案很简单:用分支。

要清楚理解什么是分支,可以把你的项目想象成一棵树,其中树干永远是项目主要的、稳定的、可用的版本。而任何新添加的特性,都必须先成为树干的一部分,然后才能进入发布阶段。在版本控制系统中的“分支”,就像树的树枝一样,从树干长出来,沿着一个不同的方向生长。在 git (最终在 Xcode)中,你可以创建分支来为代码开辟一条新路(如实现一个新特性),而不用担心在开发时会损坏当前可用的版本。

实际上,git 总会默认创建一个分支,名为 master。Xcode 进行的初始提交,就是在这个分支中进行的。一般来说,单打独斗的开发者会只用这一个分支工作,尽管这是个坏习惯。无论你是单独工作还是在团队里,我认为都应该在你要做重大改动或添加时使用分支,这样可以避免陷入麻烦。当然,在团队合作的项目里,个人开发的部分几乎是必须要在一个单独的分支里完成的。

记住以下两点很重要:

1. 提交到 App Store 或客户手中的最终产品,一定是 master 分支的版本。

2. 任何处于次级分支的代码或实现的特性,都必须先合并到 master 分支,之后才能被包括进应用的正式发布(稍后还将谈到)。

当你开了一个新分支开始工作时,事实上这个新分支就是从当前的地方开始的,即使还有没提交的更改也不例外。从此以后,再做出的代码更改就是只在新分支上了。

现在回到Xcode。去创建新的分支,到资源控制Source Control > GitDemo – master > 新分支New Branch…菜单,你会看到如下图所示的窗口:

给该分支取个名。我给它取名为(正如你在下图所看到的)AnotherBranch,在这里你取什么名它都不会有所不同。然后点击OK按钮,等待一段时间直到新分支被创建好,且当前的代码被复制到该分支上。

你可以很容易地找到你当前活跃的分支是哪个。简单地打开资源控制Source Control菜单,旁边的项目名称的选项那里就可以看到你当前的分支。

现在,让我们提交代码到新的分支。在做这个之前,让我们增加一些新的的代码,因此进入私有类区域,增加如下的方法声明:

@interface ViewController ()

...

-(void)sayHello;

@end

然后,实现它:

-(void)sayHello{
    NSLog("Hello");
}

最后,在 viewDidLoad方法中调用它:

- (void)didReceiveMemoryWarning
{
    ...    

    [self sayHello];
}

现在,切换到 Source Control > Commit菜单,将显示版本比较窗口。你将看到仅仅一个已修改的文件 ViewController.m将要提交,并且新增加的代码高亮显示。

提交代码并且增加如下的提交信息:第一次提交到分支,然后点击Commit 1 File按钮。改变将发生在AnotherBranch分支

打开版本编辑器(菜单视图 View > 版本编辑器Version Editor > 显示版本编辑器Show Version Editor),然后再到右边编辑窗口下面的工具栏中。你会看到被选择的分支是AnotherBranche。点击它,这时候该分支和主分支都会出现。从主分支上,选择你想要的任何一个版本,Xcode就会把AnotherBranch分支上的当前版本和主分支上被选择的版本之间的变化高亮出来。采用这种方式,以及我们之前的教程所谈到的比较版本部分的内容,你都可以很轻松地追踪到你工程中所有分支之间代码的变化。

最后,切换到另一个分支,或者主分支,进入资源控制Source Control > GitDemo – AnotherBranch > 切换到另一个分支Switch to Branch… 菜单:

从出现的窗口中,选择你想切换到的分支,在我们这个例子中选的是主分支:

选择它并点击切换Switch按钮。主分支就会再次变成当前活跃的分支,你会发现那些只有在AnotherBranch分支中所做的变化都不会在这里出现。这很棒,因为我们能够成功地推动我们的工程,而不需要修改稳定的版本。

合并分支

在主分支以外的分支上工作,这在执行状态中是很好的习惯。然而,如果任何代码的添加或者修改都意味着要在应用程序下一个版本中出现的话,这就必须放到主分支上,所以在这一部分,我们将会看如何完成这项任务。正如标题所总结的一样,我们谈论的这部分功能就叫合并,以及Xcode提供的一种快速合并两个分支版本的方法。

让我们做一个小实验来看看如何合并工作。首先要确定你现在处在主分支上。如果不是,请到资源控制器Source Control > GitDemo – AnotherBranch > 切换到另一个分支Switch To Branch…菜单中,并在弹出窗口里选择主分支。

接着,用资源控制器Source Control > GitDemo – master > 新建分支New Branch… 菜单创建一个新的分支,取名为LastBranch。

给Xcode一点时间去准备。现在,在ViewController.m文件中创建一个或多个假的私有方法,并声明它:

@interface ViewController ()

...


-(void)sayByeBye;

@end

然后实现它:

-(void)sayByeBye{
    NSLog("Bye - Bye");
}

最后,在viewDidLoad方法中调用它:

- (void)viewDidLoad
{
    ...    

    [self sayByeBye];
}

在合并之前,该分支上做的修改必须先提交到本地仓库。因此,在资源控制器Source Control > 提交Commit...去执行提交。

言归正传。合并两个不同的分支到一个分支上,你有两种选择:

1.从分支上合并Merge From Branch: 你可以选择在分支上做过的任何修改来合并到当前工作的分支上。

2.合并到分支上Merge Into Branch: 你可以选择在当前工作的分支上做过的任何修改合并到分支上。

这两种选择你都可以在资源控制Source Control > GitDemo菜单里找到。注意,当你当前活跃的分支是主分支的话,第二个选择是不可用的。

现在假设有一个开发者在我们之前创建的AnotherBranch分支上开发并在上面实现了sayHello的方法,而另一个开发者在LastBranch上开发并实现了sayByeBye的方法,而你的任务就是把这两个新增的都添加到应用程序中下一个稳定版本。你打算怎么做?简单来说,当具备主分支活跃,你得先从其他两个分支进行如下合并:

首先,确保你工作的是主分支,如果不是要先切换到主分支上。

然后,打开资源控制器Source Control > GitDemo - master > 从分支合并Merge From Branch...,然后从窗口打开并选择AnotherBranch分支并点击合并Merge按钮。

一个版本比较的窗口将会出现,在那里就会有机会再合并代码前重新审查所有代码修改过的地方。如果你需要,我们可以快速浏览一下,当你准备好了,就可以再次点击合并Merge按钮。

当Xcode询问你有关该项目快照的事,点击启用按钮继续。稍等片刻,瞧!AnotherBranche分支已经合并到主分支上了。

按照同样的方法,从LastBranch分支中合并过来。你就会发现如果你没有提交本次版本修改过的文件,Xcode不会让你再次合并。所以,唯一的方法只有,先提交。提交完了再尝试从LastBranche分支上合并。在版本比较的窗口中你会发现一些红色的区域,表示这些修改的地方会在合并之后代替蓝色那部分。这意味着要合并过来的分支上的代码将会代替当前正在工作的主分支上的相同行数的代码,如下图所示:

如果你使用编辑窗口下的工具栏按钮,你可以很容易避免这种情况,并保持现有的和新增的代码。在选择的区域内,点击圆形上面带箭头的按钮,可以使用所有按钮来查看他们的效果。在下面的截图中,我选了第一个按钮,意味着存在在主分支上的代码将会置于从其他分支合并过来的代码的前面:

仔细检查所有修改过的地方,确认任何分支里的代码都没有被排除在外。一旦你完成了,你要确认所有代码都在的,然后就点击合并Merge按钮。

恭喜!你已经成功从多个分支中合并代码到一个分支上了,现在你知道如何用Xcode处理类似的事情了。

放弃修改

这个选项是对放弃那些在工程中不想被修改的文件非常有用的,因为只需要点击一下鼠标就可以撤销所有自上次提交到目前所做的操作。当实现的方式不是预期的方向,而你想从上次提交的版本重新开始工作,这时候就非常有用。注意,放弃所有改变的操作是不可恢复的选项,因此,如果你不小心做了这个操作,你将没有任何机会恢复到你刚刚所做的工作。所以,要谨慎。

在此前,当我们讨论版本对比的时候,我们第一次看到了如何通过在编辑器窗口之间使用每个标记区域的小菜单按钮来放弃指定代码段的修改。这里,我们将看到如何在整个项目中执行放弃操作,并瞬间恢复到上次提交的版本。

测试这部分的目的,打开ViewController.h文件,添加一个公共方法声明:

@interface ViewController : UIViewController
 
-(void)aVeryCoolMethod;
 
@end

现在,在ViewController.m 文件添加一小段这个方法的实现:

-(void)aVeryCoolMethod{
    NSLog("I'm feeling that you'll discard me... Really?");
}

如果你注意到了项目导航栏,M标志旁已经添加了我们创建的两个文件。这正是我们想要的看到的,如果取消了变化,所有修改的文件将会受影响并恢复到先前的状态。

这里有个很重要的细节需要提一下:你可以放弃所有文件之前所做的修改,也可以放弃部分指定文件修改。这个决定在于你,如果你想选择性放弃,那么请首先确保选的文件是你想放弃修改的。为了让后面可以看得清楚点,如果你只选择ViewController.m文件然后打开资源控制(Source Control)菜单,你会发现在ViewController.m会有个标题为“放弃修改(Discard Changes)”的选项。同样的,如果你只选择ViewController.h文件并打开相同的菜单,你也会在ViewController.h中发现放弃修改(Discard Changes)的选项。不过,如果你想同时放弃这两个文件的修改(并假设这里面会有超过两处的修改),只需在项目浏览器(Project Navigator)选择他们并再次打开资源控制器(Source Control)菜单。相应的指令变成放弃这两个文件的修改……如下图所示:

在这个例子中,我们不打算使用这个选项,用放弃所有改变(Discard All Changes)来代替。通过点击它,屏幕上就会出现确认的提示窗口,这是Xcode防止你误操作的方式。

点击放弃所有改变(Discard All Changes...)提示框的按钮,公共方法就会恢复到原来的样子。正如你所见,放弃所有改变仅仅是点击几下就会远离你现在的状态,所以我再次提醒你,当你想放弃之前操作的时候要非常小心,尤其是你通常都使用资源控制器(Source Control)菜单。

总结

在本次教程中,我努力深入细致地把如何使用Xcode管理版本和资源控制讲述给大家。在幕后,真正工作的其实是git,一个非常流行和非常有用的版本控制系统。你或许发现文中并没有提及到GitHub或者任何有关Xcode功能的地方,但是我这么做的目的,是想完全关注在通过Xcode进行的git管理上,除此之外,如果你知道如何处理版本控制,你也可以直接使用GitHub。进一步说,正如我在教程开始时候经常提到的,如果你是团队中的一员,那么用版本控制系统来工作是强制性的。如果你是个人工作而且你之前没用这个的话,那么也强烈地建议、鼓励你现在开始使用Xcode的版本控制。这是一种保证你不会对现成的工作造成任何的损害,也不会增加工作量的方式,除此之外,当添加新的功能来拓展你的应用程序时也变得非常容易。最后,我希望前面所展示的例子是有帮助的,以及使用Xcode来管理版本是能够有效地节省工作时间的。

和往常一样,你可以随时留下评论来分享你的看法。

   
次浏览       
相关文章

每日构建解决方案
如何制定有效的配置管理流程
配置管理主要活动及实现方法
构建管理入门
相关文档

配置管理流程
配置管理白皮书
CM09_C配置管理标准
使用SVN进行版本控制
相关课程

配置管理实践
配置管理方法、工具与应用
多层次集成配置管理
产品发布管理
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]


软件配置管理的问题、目的
软件配置管理规范
CQWeb 7.1性能测试与调优指南
为什么需要使用ClearCase
ClearCase与RTC的集成
利用ClearQuest 进行测试管理
更多...   


产品发布管理
配置管理方法、实践、工具
多层次集成配置管理
使用CC与CQ进行项目实践
CVS与配置管理
Subversion管理员


配置管理实践(从组织级到项目级)
通号院 配置管理规范与应用
配置管理日构建及持续集成
丹佛斯 ClearCase与配置管理
中国移动 软件配置管理
中国银行 软件配置管理
天津华翼蓝天科技 配置管理与Pvcs