Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)

参考文章:在Xcode中使用Git进行源码版本控制
Xcode中git的使用方法介绍与"Please tell me who you are"问题的解决方案
我所知道的代码托管平台:
GitHub、码市coding.net、CSDN的code.csdn.net、oschina的码云
一、版本控制的介绍 在iOS开发过程中,很重要的一部分工作就是如何进行源码的版本控制。当代码出现问题时,我们就需要将代码恢复到原先正常的版本。如果是多个人共同开发一个项目,那么代码的控制就会非常复杂。幸运的是,开发者不需要自己控制这些,因为有专门的软件来负责,叫做版本控制系统。
版本控制系统,或者说修改控制系统,实际上是一种检测源文件的改变并将其保存留作以后参考使用的机制(软件)。此外,它还能记录其他有用信息,比如是哪个开发者修改了代码,何时修改的,修改了哪一部分,以及其他历史信息。版本控制系统可以比较不同版本代码的不同,有必要时能恢复整个项目到以前的版本,追踪有害代码从而减少产品的错误。
通过版本控制系统,开发者可以在一个项目的不同分支上工作,当项目的各个部分开发完备时,将它们放到一起形成最终的版本,这个过程被称为合并。事实上,这种做法再团队和软件公司中相当常见:每个人负责项目的一部分,最终所有部分被整合到一起形成最终产品。
对于个人开发者来说,版本控制系统并不是必需的,但是我们仍然强烈推荐开发者使用它,因为它可以使代码方便的在有错误的版本和可以工作的版本之间转换。事实上,很多开发者从来不使用类似的工具,他们会在项目添加新的功能时手动保存原先的项目。这其实是一个很不好的习惯,因为版本控制软件可以更好更高效地完成这项任务。
二、Xcode 创建一个Git源(Creating a Git repository) 每次在Xcode中创建新工程的时候,都会提示开发者是否将项目作为一个本地的git源。在创建工程的最后一步Xcode会有一个复选框,如果选择了它,git源就会被添加到工程目录中。通常这个选项会被忽视,或是被认为是Xcode的另外一个没用的功能,尤其是从未用过git的开发者,或是编程新手。
打开Xcode,创建一个新的工程,在最后一个步骤,先选择一个要保持工程的目录,然后在窗口底部选上Create git repository on (My Mac )。默认情况下,这个选项是被选上的,如果你不想使用git,你可以取消它,

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
创建完项目之后,打开Finder,找到项目存储的目录,在目录中,有一个.git的子目录,时Xcode为存储git源相关数据自动创建的。这就是本项目在本地git源保存的位置。实际上,如果你选上了相应的选项,这个目录就会被创建。相应地,在你创建新应用时,.git子目录也会一同被创建。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
如果你看不到.git目录,说明你的mac上面的隐藏文件是不可见的,你需要让隐藏的文件可见。具体做法就是打开一个终端(Terminal)窗口,输入以下命令:
对于OS X Mavericks 10.9及以后的系统:
defaults write com.apple.finder AppleShowAllFiles TRUE
为了重启Finder应用,输入
killall Finder
或者点击桌面左上角的苹果,选择强制退出,找到 finder,进行强制退出操作。
如果你在创建新项目的时候没有选择 Create Git 选项,就像下面这样:

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
可以按照接下来的步骤进行添加:
打开终端(Terminal)窗口,切换到新项目的目录:
cd 空格,然后把项目文件夹拖进去就可以了,像这样
cd /Users/YOUR-USERNAME/Desktop/NoGitExample
接下来,确认后接着输入:
git init
这会初始化一个空的源,如果在Finder里面查看,你会看到.git子目录已经被创建,很好,接下来输入:
git add .
不要漏掉 add后面的空格和“.”。
这样,当前目录所有的内容就被添加到源里面去了,最后,输入以下命令:
git commit -m 'Initial commit'
接下来会出现一个本地git源所执行的改变列表,等执行完毕后,git源就建好了。接下来把项目关掉(或者把Xcode退出),重新打开工程,点击Source Control菜单,就可以看到所有的选项已经都可以点击了,就像一开始勾选上创建git源一样。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图 三、在本地管理源码版本 1、Commit 提交更改指的是储存一个包含所有更改的新版本。一般来说,当我们做了一些有意义的工作,并且项目处于某一个稳定状态时,就可以提交一次更改。然而具体什么时候提交更改并没有硬性的规定。我的建议是:从上次提交更改之后,如果你怕花费大量时间和精力做的新工作被误删很难恢复,你就需要提交更改了。
默认情况下,Xcode在项目创建之初会提交一次更改,这是为了保存项目初始状态。这项工作会在后台完成,不会打扰你或者要求你进行确认。如果你在项目创建时没有添加git源,但是之后你手动添加了,你可以通过我们先前使用过的命令来进行提交:git commit -m ‘Initial commit’
实际上,你如果去Source Control>History…菜单,你就会看到初次提交更改的记录,以后每次提交更改,都会在这里有所记录。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
history.png
接下来让我们小幅修改一下我们的工程:
在ViewController.m文件中,添加以下代码:

@interface ViewController () @property (nonatomic,assign) int sum; @end @implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; int a = 5; int b = 10; self.sum = a + b; NSLog("The result is: %d", self.sum); }

看一下Project navigator面板,你会发现在ViewController.m文件旁边,添加了一个M字母,像下面这样:

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
这意味着那个文件已经被修改,相比上一次提交更改,文件有所改变。一般来说,你每次改变文件,都会出现这个M字母,提醒你有未提交的更改。
下面看看如何提交更改,其实非常简单,只需要打开Source Control>Commit菜单,下面窗口就会出现:

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
让我们一步步看看它告诉我们了什么。在左边(标1的区域),列出了所有被更改的文件,在这个例子中,只有ViewController.m这个文件被改变,因此列表中只有它被显示。如果你仔细观察,你会发现文件左边有一个选择框,默认情况下是被选中的,如果你取消它,这个文件的更改就不会被提交。
在窗口的中间区域,有两个预览窗口,左边那个是文件当前版本,右边是文件上一次提交更改的版本。因为我们目前只是创建时提交过一次更改,因此右边显示的是文件的初始状态。
左边窗口蓝色区域标出的就是更改的内容,这样的表示让我们可以清楚地看出所有的修改。如果你仔细看,会发现在两个窗口之间还有一个带数字的小标签,这个数字一一表示了各项更改。在数字旁边,默认情况下有一个小对勾,表示本更改会被提交,如果你点击右边的小箭头,会弹出一个选项菜单,你可以选择不提交这个更改或是忽略它。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图.jpg
如果你选择了Don’t Commit这个选项,小对勾就会被一个停止标志取代,这项更改就不会被保存到源中。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图.jpg
如果你选择了Discard Change这个选项,会弹出一个确认窗口,提示你所做的更改会被恢复,并且无法取消这个操作。
Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图.jpg
如果你点击了OK按钮,所选区域的改变就会消失,就像他们从未出现过一样。
如果你仔细观察上面这个提交窗口,你会看到你所做的所有修改都会被Xcode看做改变,即使是一个空行。实际上空行相当于回车,在屏幕上是不可见的,因此作为改变也是理所当然的。
正常情况下你不用忽略任何修改,而是允许提交所有更改,因此所有的改变标签旁边必须都是小对勾。
在两个窗口下面是一个空白的区域,中间显示了提交更改的信息。这个地方可以添加一些关于此次更改的简短描述,点击它,加入如下内容:

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
commit.png
点击提交之后,第一次提交就完成了!打开Source control > History,你会发现它会被显示在列表中。
另外,关闭历史窗口,看一下Project Navigator,你会发现ViewController.m旁边的M符号已经消失了。
版本之间的比较(Comparing Versions) 当你提交了同一工程的不同版本之后,在他们之间比较,追踪修改信息就会非常方便。当新添加的代码不能运行时,这时与之间版本进行比较就非常重要了,你可以看出新版本相比上个稳定版有了哪些更改。
要比较同一个文件的两个版本,你可以使用View>Version Editor>Show version editor,或是点击工具栏上的Version Editor按钮:

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图.png
点击之后,编辑器会分为两栏。最初,两栏会显示相同的内容,点击编辑器下面的那个小时钟图标,可以选择之前已经提交的版本进行比较。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
点击之后,两个版本的区别会在编辑器中显示出来。通常,左边显示的是当前版本的文件,右边显示的是之前的版本。蓝色高亮的区域显示了被更改的代码,因此比较代码的变化非常容易。继续选择任何此前的版本,并观察两栏的区别。 你可能会注意到,在两个编辑器中间,还有在提交窗口看到的小标签。点击向下的按钮可以跳出让你忽略更改的选项。如果你点击了忽略更改,Xcode会提示你是否同意。如果你同意忽略,这些被忽略的代码将会永远消失,无法再找回来。所以要注意不要无意中忽略任何代码。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
blame.png 2、分支(Branches) 试想一下,你现在的工程有一个即将发布的版本,或是已经发布的版本,你突然想添加一些新的特性,如何防止这些新添加的代码让整个项目陷入瘫痪呢?答案很简单:你需要使用分支。
如何简单的理解分支呢?你可以把你的项目想象成一棵树,稳定版本就是树的主干。任何添加新功能的版本都必须是树干的一部分。分支,就像是树的枝干,它从树干生长出来,向不同的方向生长。在git中,你可以通过创建分支来为你的代码设置一个新的路径来实现新特性,而不用担心在开发中破坏主干。
实际上,在git中默认都会有一个分支,叫做master。Xcode自动执行的第一次提交中就发生在这个分支中。通常,单独的开发者只在master这个分支开发,这其实不是一个好习惯。无论你是单打独斗还是组团合作,我认为在对项目作出重大改变或添加重大功能时,使用分支是十分重要的,它会为你避免很多麻烦。当然,在团队项目中,为你自己负责部分的代码搞一个分支几乎是必须的。
关于分支,你必须记住以下两点:
提交到App Store或客户的最终产品必须是项目中的master分支项目。
任何在第二分支中实现的代码或者功能最终都必须合并到master分支,这样正式发布的应用程序才是完整的。(以后再讲这一点)
当你开始一个新分支时,你实际上是以当前工作状态作为起点,即使你有任何未提交的更改。从这个时候起,所有的改变都会只体现在分支中。
现在让我们回到Xcode,要创建一个分支,点击Source Control > GitDemo-master > New Brance…这个菜单,然后会弹出如下菜单:

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图.jpg
为这个分支起一个名字,我就把它起名为AnotherBranch好了。现在你怎么给它起名其实都无所谓。点击OK按钮,等一下新的分支就会被创建,而当前的代码也会复制到新分支中去。
打开Source Control菜单,你就可以轻松地找出活动分支是哪一个:它就在项目名字的旁边。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图.jpg
现在,让我们做一次新的分支的提交。在这之前,让我们添加一些新的代码。打开类文件,在私有属性区添加以下方法声明,然后实现它,最后,在viewDidLoad中调用它:
@interface ViewController () -(void)sayHello; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self sayHello]; } - (void)sayHello { NSLog(@"say hello"); }

现在,点击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都会高亮显示两者之间的区别。通过这样,你可以方便地跟踪所有分支间代码的改变。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
最后,切换到另一个分支,或是master分支,你可以点击Source Control > GitDemo –AnotherBranch > Switch to Branch…菜单。
从这个窗口你可以选择想要跳转的分支,在这里让我们跳回master分支,选择它并点击Switch按钮,master分支就会成为当然活动分支。你会发现在AnotherBranch中做出的改变并没有出现在master分支。很好,我们在管理工程推进的同时,却没有修改稳定版本。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图a
Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图b.jpg 合并分支(Merge Branch...) 在分支中进行开发是一种好习惯,然而,如果代码改变要体现在发行版中,那么分支就必须被合并到master分支中。这一节我们将会告诉你怎样合并它们。在Xcode里,将两个分支合并成一个非常简单。
让我们做一个小实验来看看合并是怎样工作的。首先,确保master分支是现在的活动分支。如果不是,赶紧改过来:Source Control > GitDemo – AnotherBranch > Switch To Branch… menu,并从展示窗口选择master分支。
下一步,再重新创建另一个新的分支:Source Control > GitDemo – master > New Branch… menu,命名为LastBranch。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
让我们添加一些新的代码。打开类文件,在私有属性区添加以下方法声明,然后实现它,最后,在viewDidLoad中调用它:
@interface ViewController () -(void)sayHello; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self sayHello]; } - (void)sayHello { NSLog(@"say hello"); }

在合并之前,先提交这些更改。使用Source Control > Commit菜单来执行提交。
终于还是来到这一步,关于把两个不同的分支合并成一个,你有两种选择:
从分支合并:与你选择的分支相关的任何改变都会被合并到现在活动分支中。(Merge from Branch...)
合并到分支:当前活动分支的任何改变都会被合并到你选择的分支中。(Merge into Branch...)
这两种方式你都可以在Source Control > GitDemo 菜单中找到。注意当你的活动分支是master分支时,第二个选项是不可选的。
假设一个开发者在Anotherbranch分支实现一个sayHello方法,另外一个开发者在LastBranch中创建实现了sayByeBye方法,现在你需要将两个人的工作合并到下一个稳定版本中,想一想你需要怎么做?很简单,按以下方法将改变从两个分支中合并进来:
首先,确保当前活跃分支是master分支。
然后,打开Source Control > GitDemo – master > Merge From Branch…菜单,选择AnotherBranch然后点击Merge按钮。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
接下来会出现一个比较窗口,在里面你会看到合并之后代码的更改,看一眼,感觉差不多了就再点击Merge按钮。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
Xcode会询问你是否保存项目的快照,点击Enable按钮。让Xcode飞一会,然后就好啦。AnotherBranch里面添加的内容已经合并到master分支中。 使用同样的方法来合并LastBranch。你会发现如果你不提交更改,Xcode不会让你再次合并。于是,我们只好先提交一下。在比较窗口你会发现一个红色的区域显示合并之后的更改,而不是之前的蓝色。这意味着分支中的代码将会替换原先活动分支中的代码。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
你可以轻松地避免这种现象的发生。在编辑面板的下面有几个小按钮,你可以试试他们都有什么作用,我选了第一个,它的意思是master分支的代码会被放在上面,另一个分支的代码会跟在它后面。

Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)
文章图片
示例图
处理接下来所有需要更改的代码,不要有遗漏。完事后就点击Merge按钮。 恭喜你!你已经成功的学会从多个分支合并了代码,类似的情形你也应该会了。
忽略更改(Discarding Changes) 放弃不想要的代码更改功能非常有用,只需轻轻一点,自从上一次提交之后的更改都会被放弃。当你在开发过程中发现出了大乱子,你想从上一个稳定状态重新开始时,这个功能就派上用场啦。注意放弃更改这个功能没有回头路,点完之后你就没有办法再撤销这个操作,所以,要小心使用啊!
【Xcode8-Source|Xcode8-Source Control进行版本控制(本地和远程)】之前,当我们在讨论版本比较时,我们学会了如何忽略某一部分更改的方法,下面,我们要学一下如何一下忽略自从上一次提交之后的所有更改。
让我们添加一些新的代码。打开类文件,在私有属性区添加以下方法声明,然后实现它,最后,在viewDidLoad中调用它:
@interface ViewController () -(void)sayHello; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self sayHello]; } - (void)sayHello { NSLog(@"say hello"); }``` 如果你注意到Project Navigator,我们刚刚更改的文件旁边有了一个M标识,很好,我们想看看如果忽略这些更改,这些文件是否会回到更改之前的状态。这里有一个重要的细节:你可以选择忽略所有文件的更改,也可以选择忽略单个文件的更改,这完全取决于你。如果你想忽略一个文件的更改,首先选定这个文件。在这个例子里,如果你只选择ViewController.m文件然后打开Source Control菜单,你会在ViewController.m中发现Didcard Changes这个选项。类似的,如果你只选择ViewController.h也是一个道理。然而,如果你想忽视这两个文件的更改(这里假定有两个以上的更改),就在Project Navigator中选中它们,然后再打开Source Control菜单。相应的位置就会显示Discard Changes in 2 Files,像下面这样: ![示例图](http://upload-images.jianshu.io/upload_images/2250061-7452139bb1372ca4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 然而,这次我们不会使用这个按钮,我们要用Discard All Changes。点击它之后,一个确定提示框就会出现,这是这部分Xcode防止你误删代码的唯一措施。 ![示例图](http://upload-images.jianshu.io/upload_images/2250061-24ff2b6097622bc2.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 点击Discard All Changes, 那你刚才写的那个公共方法就永远属于过去了。看到了吧,只需几步就可以让你从当前工作状态恢复到之前的提交,所以我再一次提醒你要在使用Source Control 中小心点,别误点了这个按钮。 #### 四、利用远程仓库进行源码版本控制 ![示例图](http://upload-images.jianshu.io/upload_images/2250061-6156835e9e5f0632.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 【1】在Configure配置中,可以查看我们的远程仓库,分支情况等。也可以可视化进行配置添加。 ![示例图](http://upload-images.jianshu.io/upload_images/2250061-523a75ec8cc99923.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 【2】第二个选项Check Out,也就是检出代码,相当于从远程仓库clone代码。 ![示例图](http://upload-images.jianshu.io/upload_images/2250061-aba6ab8a3655be7f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 【3】Push就是向远程仓库提交代码,你可以选择你要提交的分支: ![示例图](http://upload-images.jianshu.io/upload_images/2250061-bbb3817a4c3202d9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 【5】下面的Pull就是从远程仓库拉取代码,pull的时候也可以选取分支。个人建议在Push之前首先进行Pull,如果有冲突可以在本地进行解决,不要让自己的代码“污染”远程仓库。。。 ![示例图](http://upload-images.jianshu.io/upload_images/2250061-2417371fea20e554.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) #####总结 上面讲了那么多在Xcode中进行版本控制的方法。其实在幕后,真正起作用的还是git----地球上应用最多的版本控制系统。如果你是一个团队在工作,使用版本控制工具是必须的!如果你是单打独斗,使用版本控制工具也是很有必要的,它可以为你花大量时间和精力所做的工作提供保障,并且在你添加新功能时可简单地进行扩展。这个工具就像有些人说的那样,一旦用了,就再也回不去了!最后,希望这个教程会对你有用。如果有啥想说的,就在下面留言吧。或者二话不说直接打赏我也不介意的。

    推荐阅读