GIT在iOS开发中的使用
前言
在iOS
开发中,很多公司对项目的版本控制管理都使用了git
,当然也有部分公司使用的是svn
。当年我最初接触的是svn
,觉得使用起来挺方便的,但是每次切分支都需要下载一份新的代码起来,这实在太麻烦了,而且公司的网络下载一个项目的所有资源起来也有数百M
,这还用工作么?
当年,第一次听说github
的时候,就听说是使用git
来管理的,可是那时的我感觉好复杂,不知道如何入手。如今,对git
的使用可以说是很熟练了,不管是使用命令操作还是直接使用GUI
界面工具操作。
就让我带着还不会使用git
的同志,跨过那些我曾经走过的坑…
创建新仓库
如果我们在本机上想要创建一个新的git
仓库,可以直接使用下面的命令:
1
2
3
|
git init
|
还有一种命令可以创建仓库:
1
2
3
|
git init --bare
|
我相信大家一定会疑问,这两者有什么区别呢?从字面上看,bare
就是赤裸裸的意思,也就是说生成用于记录版本库历史记录的.git
目录下面的文件而不会包含实际项目源文件的拷贝。进入版本目录,会发现只有.git
目录下的文件。这个版本库里面的文件都是.git
目录下面的文件,把原本在.git
目录里面的文件放在版本库的根目录下面;换句话说,不使用--bare
选项时,会生成.git
目录以及其下的版本历史记录文件,这些版本历史记录文件就存放在.git
目录下;而使用--bare
选项时,不再生成.git目录,而是只生成.git目录下面的版本历史记录文件,这些版本历史记录文件也不再存放在.git
目录下面,而是直接存放在版本库的根目录下面。
这么多说明是不是头晕了?我们来来测试一下:
1
2
3
4
5
6
7
8
9
|
cd Desktop/
mkdir testgit1
cd testgit1
git init
ls
cd .git
ls
|
这里在桌面创建一个目录叫testgit1
,进入到testgit1
目录下,然后执行git init
来初始化一个仓库。然后,就会生成一个.git
目录,然后查看当前目录是否有文件?第一个ls
命令是不是什么也没有?是的,默认.git
目录是隐藏的。我们进入到.git
目录下,查看:
1
2
3
4
|
HEAD config hooks objects
branches description info refs
|
下面简单说明一下这几个东东分别干嘛用:
HEAD
是个头指针,在处理版本切换时,就是这个指针前移、后移等,因此只会生成快照而已,不会重新下载完整的一份代码,所以切换只需要几秒钟就可以在不同的分支上开发了。是不是很方便?config
是配置文件,想要看看内部有什么东西,可以直接vi config
查看。hooks
叫钩子,主要是用于控制commit
、push
等操作动作,若需要深入了解,可百度,这个东西也是有很深的学问的。objects
是存储所有的git
对象,关于这个也可以百度阅读相关文章,内容也很多。branches
自然是分支的意思,用于管理分支,里面会有所有的分支。description
自然是描述信息info
这个目录就不清楚具体是干嘛用了refs
这个目录有heads
和tags
,前者不清楚其用意,后者就是标签,比如我们支持cocoapods
的开源库中升级就需要设置tag
,对应版本。
用git init
初始化的版本库,用户可在该目录下执行所有git
操作,但别的用户在将push
上来的时候容易出现冲突。因此,实际中会将远程服务器端创建一个仓库时,才会使用--bare
,而我们个别用户在创建仓库时,不使用--bare
。
克隆版本
如果是本地的git
仓库,就直接使用下面的命令,其中/path/to/repository
是绝对路径:
1
2
3
|
git clone /path/to/repository
|
如果是在远程服务器这边的仓库,可以用这样的命令。其中username
公司给你开的git
用户,host
是你们公司放置项目代码的服务器,/path/to/repository
是远程git
仓库的访问路径:
1
2
3
|
git clone username@host:/path/to/repository
|
工作流
首先,我们需要理解git
版本控制的工作流:
本地仓库由工作目录
,它持有实际文件;第二个是缓存区
,它像个缓存区域,临时保存你的改动;最后是HEAD
,指向你最近一次提交后的结果。
看看官方的图解:
其流程:当前working dir
通过add
命令添加到stage
缓存区中,再通过commit
命令提交,HEAD
就指向了这次提交的结果。
add命令添加
使用下面的命令添加到缓存区,其中第一行代码是只提交一个文件到缓存区,而第二行代码是添加所有有改动的文件到缓存区:
1
2
3
4
|
git add <filename>
git add *
|
commit命令提交本地
然后我们就可以通过commit
提交,其中-m
选项是comment
的意思,也就是注释,后面跟着一行注释说明:
1
2
3
|
git commit -m "代码提交信息"
|
执行完commit
后,现在,所做的改动已经提交到了HEAD
,但是还没到提交到远端仓库。
push命令推到远端
你的改动现在已经在本地仓库的HEAD
中了,执行如下命令以将这些改动提交到远端仓库:
1
2
3
|
git push origin master
|
可以把master
换成你想要推送的任何分支。 如果当前我们不是在主干上开发,我们提交的代码是要提交到当前正在开发的分支上。假设当前正在开发的分支名称叫:Double11Activity表示双11活动分支。那么我们所做的改动应该推送到Double11Activity
分支上。
1
2
3
|
git push origin Double11Activity
|
remote add添加远端仓库
如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:
1
2
3
|
git remote add origin <server>
|
其中server
就是我们远程git
服务器的访问路径。比如:
1
2
3
|
git remote add origingit@182.92.160.41:/data/git/demo.git
|
查看仓库是否已经添加到远端git
仓库,可使用下面的命令:
1
2
3
|
git remote -v
|
如果出现类似这样:
1
2
3
4
|
origin git@server:/Data/git/ios/demo.git (fetch)
origin git@server:/Data/git/ios/demo.git (push)
|
假设系统是CentOS
系统,其中,git
是用户,server
是服务器地址,/Data/git/ios/demo.git
是具体的项目仓库目录访问地址。
有了这些,我们就能够将本地改动推送到所添加的服务器上去了。
pull命令拉代码
想想多人同时开发时,除了你自己会发动代码之外,其他同事也会改动代码并提交到远端仓库,因此我们每次在提交之前,都应该先pull
一下,将其他同事最新的代码拉下来。如果有冲突,则需要先解决冲突,然后合并,且在xcode
编译运行通过,再将代码推送到远端仓库。
拉最新代码的命令就很容易了:
1
2
3
|
git pull
|
如果出现冲突,一定要解决,否则工程就打不开。如果解决不好,且在本机没有在xcode
上跑通,那么一旦提交到远端,其他同事一拉代码,就会导致无法打开,或者编译不通过,会影响他人的工作。
分支branch
分支是用来将敏捷开发的根本。在你创建仓库的时候,master
是“默认的”,通常用做主干
。在其它分支上进行开发,完成后再将它们合并到主干上。
创建一个叫做feature_x
的分支,并切换过去:
1
2
3
|
git checkout -b feature_x
|
如果只是创建一个分支而不自动切换到该分支上,可以这样:
1
2
3
|
git checkout feature_x
|
想要切换到master
上,这样:
1
2
3
|
git checkout master
|
删除分支:
1
2
3
|
git branch -d <分支名>
|
通常在开发中,每一期的需求在开发之前,都需要建立一个新的分支,并在这个分支上开发。创建之后,我们还需要推送到远端,不然其他同事无法一起参与开发。
1
2
3
4
|
git branch -b <branchname>
git push origin <branchname>
|
合并分支:
1
2
3
|
git merge <branch>
|
合并方法:如果要将分支A
合并到分支B
,那么应该这样:先切换到B
分支,然后执行命令:
1
2
3
|
git merge A
|
也就是说,A
要合并B
,就要先切换到A
分支,再执行合并命令。如果是B
要合并A
,就需要先切换到B
分支,然后再合并A
分支。
对于多人同时开发,尤其多团队敏捷开发的大团队,代码合并是非常麻烦的事。今天下午将其他团队刚上线的版本合并到主干,再将主干合并到当前我们团队与其他团队抽人共同开发的分支上,解决冲突就花了4个小时。
好在没有没有动storybard/xib
这些地方,合并也就几个小时就可以了。如果上一期开发做了很多的界面改动,而这个界面原来是由sb/xib
开发的话,合并过来就困难了,那些是很难读懂的一串串的东西,不知如何调。因此,对于大团队开发,真的不建议使用xib/sb
来开发。
合并之前,可以先查看当前分支与待合并过来的分支的有什么不同:
1
2
3
|
git diff <source_branch> <target_branch>
|
注意事项
通常上线的分支都是master
,也就是主干,因此在实际开发中,必须保证主干永远是最干净的,只能将主干代码合并到其他分支,然后测试通过并上线后,再合并到主干上
推荐git界面软件:SourceTree
这个软件对于那些不懂命令,也不想用命令的开发者来说,这个软件就是一大福利。
我们可以直接将本地的仓库直接添加进来,也可以克隆远端仓库到本地。点击新仓库就可以添加了,其中有四个选项,我们会选择第一个:从URL克隆,也就是git
访问地址。
这里面有很多个操作,每个就是对应于一个命令,如果不想使用命令操作,可以直接使用这个。
在实际开发中,解决冲突时,我还是要使用这个软件来解决的,因此冲突文件有时候会达到上百个类文件冲突,要花一天时间来解决冲突。
GIT在iOS开发中的使用的更多相关文章
- fir.im Weekly - iOS开发中的Git流程
本期 fir.im Weekly 收集了微博上的热转资源,包含 Android.iOS 开发工具.源码等好用的轮子,还有一些 APP 设计的 Tips,希望对你有用. 精仿知乎日报 iOS 端 @我偏 ...
- iOS开发中遇到的一些问题及解决方案【转载】
iOS开发中遇到的一些问题及解决方案[转载] 2015-12-29 [385][scrollView不接受点击事件,是因为事件传递失败] // // MyScrollView.m // Creat ...
- CocoaPoda在iOS开发中的使用
CocoaPoda在iOS开发中的使用 CocoaPods 简介 CocoaPods是iOS开发中不可避免的依赖管理第三方的工具,能简化一些第三方库文件需要添加编译参数及依赖库的繁复工作 CocoaP ...
- 总结iOS开发中的断点续传那些事儿
前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...
- iOS开发中静态库之".framework静态库"的制作及使用篇
iOS开发中静态库之".framework静态库"的制作及使用篇 .framework静态库支持OC和swift .a静态库如何制作可参照上一篇: iOS开发中静态库之" ...
- iOS开发中静态库制作 之.a静态库制作及使用篇
iOS开发中静态库之".a静态库"的制作及使用篇 一.库的简介 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的类型? 根据源代码的公开情况,库可以分为2种类 ...
- ios开发中的小技巧
在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...
- IOS 开发中 Whose view is not in the window hierarchy 错误的解决办法
在 IOS 开发当中经常碰到 whose view is not in the window hierarchy 的错误,该错误简单的说,是由于 "ViewController" ...
- [转]iOS开发中的火星坐标系及各种坐标系转换算法
iOS开发中的火星坐标系及各种坐标系转换算法 源:https://my.oschina.net/u/2607703/blog/619183 其原理是这样的:保密局开发了一个系统,能将实际的坐标转 ...
随机推荐
- 30天C#基础巩固----Lambda表达式
这几天有点不在状态,每一次自己很想认真的学习,写点东西的时候都会被各种小事情耽误,执行力太差.所以自己反思了下最近的学习情况,对于基础的知识,可以从书中和视频中学习到,自己还是需要注意下关于 ...
- 浅谈Dictionary用法
一.基础篇 1.Dictionary泛型类提供了从一组键到一组值的映射,即键和值的集合类. 2.Dictionary通过键来检索值的速度是非常快的,这是因为 Dictionary 类是作为一个哈希表来 ...
- 模拟 --- hdu 12878 : Fun With Fractions
Fun With Fractions Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit ...
- Visual Studio Code编写HTML
第一步双击打开Visual Studio Code,我们发现什么也没有,但是有一个默认打开的编辑页面.我们先点击File->OpenFoldor 为什么先这么做呢,有两个原因,第一个原因假如你有 ...
- [Asp.net 5] DependencyInjection项目代码分析2-Autofac
Microsoft.Framework.DependencyInjection.Autofac源码分析 该工程只有一个代码静态类AutofacRegistration,但是该类有3个扩展方法,以及3个 ...
- object references an unsaved transient instance - save the transient instance before flushing错误
异常1:not-null property references a null or transient value解决方法:将“一对多”关系中的“一”方,not-null设置为false(参考资料: ...
- JWS ,JAX-WS ,JAX-RS,REST,Restlet,SOAP 相关概念
与 WebServices 相关的 J2EE 技术称为 JWS(Java WebServices),其中含有 JAX-WS.JAX-RS.JAXB.JAXR.SAAJ.StAX 等技术 支持 SOAP ...
- JAVA中的输入方法
输入整数(int)类型 导入包 import java.io.*; 输入语句 BufferedReader myIn=new BufferedReader(new inputStreamReader( ...
- Codeforces Round #369 (Div. 2)---C - Coloring Trees (很妙的DP题)
题目链接 http://codeforces.com/contest/711/problem/C Description ZS the Coder and Chris the Baboon has a ...
- 转载java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.spinner/com.example.spinner.MainActivity}: java.lang.NullPointerException
今天学习Android开发突然遇到了这个问题,查阅了很多资料,并且对集中原因进行了分析. 错误信息字符串:java.lang.RuntimeException: Unable to start act ...