因为使用Github,OSChina管理自己项目的时候,使用git终端命令不是特熟悉,所以特地特地把公司之前买的Git 版本控制管理(第二版)给看了一遍,再结合自己实际操作,对Git的使用和理解还是提升的不少;所以就写一篇博文来记录自己的学习Git之旅,有误之处欢迎大家指正。
- Git的简单介绍
- Git和SVN的对比
- Git使用的快速入门
- Github、OSchina的使用
对于前两部分的内容,大家可以初略看下,有个印象知道一些名词概念就好,重点还是得多练习、多操作,也就是第三部分内容需要实际操作;
Git的简单介绍
1. Git是什么?
Git是一款免费、开源的分布式版本控制系统;
是由Linux之父Linus开发,开发缘由自己可以上网查看下或者下载我在百度云盘分享的Git权威指南,Linus确实很牛逼,不得不佩服人家,花了一个月的时间就开发成功了!
与Git对应的集中式版本控制有CVS、SVN(集中式版本库控制的集大成者)。
2. Git读音:
有必要先说一下Git的读音,音标:[gɪt],字母G的发音与Gives、Gift的发音一样,所以发音听起来像是“歌易特”;我之前的读法和听到很多人的读法一直都是错误的:“计易特”;
3. Git 工作原理
有必要介绍下几个名词:
工作区(Working Directory):仓库文件夹里除.git目录以外的目录;
版本库(Repository):位于工作区根目录下.git目录中,用于存储记录版本信息,.git是一个隐藏文件夹,在终端中输入这条命令defaults write com.apple.finder AppleShowAllFiles -bool true
就可以显示隐藏文件(隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool false
);
- 暂缓区(stage)
- 分支(master):git自动创建的第一个分支
- HEAD指针:用于指向当前分支
4. Git的工作流程
Git和SVN的对比
1. 集中式版本控制和分布式版本控制的对比
从下面两个图可以看出这二者之间的区别:
- 分布式下开发者可以本地提交代码,集中式必须联网才能提交;
-
分布式下开发者的电脑就是一个完整的版本库,拥有本地的代码仓库。
2. Git和SVN的对比
1、 速度:Git比SVN快;
2、结构:Git是分布式管理,SVN是集中式管理;
3、其他:Git支持本地版本控制工作,SVN必须联网才能;Git拥有更强大的分支管理;Git只会在根目录拥有一个.git,旧版本的svn会在的每个目录放一个.svn等等。
Git使用的快速入门
-
使用
git init
创建初始版本库;
打开GitDemo文件夹可以看到新增了个.git隐藏文件夹,所有的版本数据库数据都将存放在.git的隐藏子目录中;
-
使用
git clone [remoteURL]
从远程服务器克隆一份代码到本机;
在公司中,经常是团队开发,先从服务器把项目给clone到自己电脑
-
使用
git add [xxx]
将文件添加到暂缓区
我们都知道Mac 电脑的Xcode已经完美的集成了Git,如下图,当我在GitDemo中新建一个项目是勾选框将为灰色;
如图:此时项目的文件有个状态为A、M和“?”(刚开始可能全是“?”当重新打开后就变为下图的状态了)
此时用在终端中输入命令git status
查看你的文件在工作目录与缓存的状态
上图显示的红色字体表示:新添加的文件或者修改的文件在工作区没有添加到暂缓区如果此时用git add .
命令将会把工作区的所有文件添加到暂缓区中; -
使用
git commit
把暂缓区的所有内容提交到当前分支(master分支)
使用终端输入git status
查看,都变为绿色了,这就表示工作区的代码已经添加到暂缓区中,可以提交到本地代码仓库了
终端输入命令git commit -m"初始化版本仓库"
,Xcode项目的各个文件右边的A和M都消失了,说明纳入版本控制成功 添加.gitignore文件(.git 同一级目录下)
我之前分享的使用oschina托管自己项目第三大点有说过在GitHub下载gitignore文件,因为我的项目是Objective-C语言编写的所以我要添加的是Objective-C.gitignore,在终端中如下命令:
cp /Users/xcq/Downloads/gitignore-master/Objective-C.gitignore .gitignore
git add .gitignore
git commit -m"添加gitignore文件"
可以看到当前目录多了一个.gitignore
添加.gitignore文件步骤很重要、很重要、很重要,重要的事情说三遍;添加.gitignore文件的步骤操作最好在git init步骤之后,也就是创建初始版本库之后就在工做根目录(也就是与.git同一层及目录)下添加.gitignore文件,然后再用Xcode新建一个项目,这样做才会真正的把所有不需要纳入版本控制的文件忽略;我之前的操作正好相反,是先新建了一个CQActionView的项目,然后才添加的.gitignore文件,这样做的后果是UserInterfaceState.xcuserstate并没有忽略,每一次command + 编译都会产生
用Xcode自带Git的Commit也能看到,项目没有做任何修改,但是一编译就会有一些用户缓存数据
还有种情况是我们已经写好的项目需要用Git管理,然后才添加的.gitignore文件,这也会出现上述问题,
解决方案如下:(其中:CQActionView/CQActionView.xcodeproj/project.xcworkspace/xcuserdata/xcq.xcuserdatad/UserInterfaceState.xcuserstate 是上面第二张图红色的那个路径,直接copy过来就行;
git rm --cached [xxx]
会将文件从缓存区删除,但是工作目录中还存有该文件 )
git rm --cached CQActionView/CQActionView.xcodeproj/project.xcworkspace/xcuserdata/xcq.xcuserdatad/UserInterfaceState.xcuserstate
git commit -m"Removed file that shouldn't be tracked"
-
使用
git branch [xxx]
创建分支,git branch
查看在本地的分支,git branch -va
可以查看本地+远程分支列表
如图,我们新建了一个“branch1”分支。如果你在master分支做了变更并且更新提交, 然后切换到了“ branch1”分支,Git 将还原你的工作目录到你创建分支时候的样子; -
工作实例:如下图,公司的远程仓库有有两个分支:master和feature_react_native。
老大要求我在feature_react_native分支上进行功能开发,但是我clone到本地的代码对应的是远程的master分支,此时我就需要修改这种映射关系。如下图,通过git branch -vv
查看本地分支和远程分支的跟踪关联关系:为本地的master和react_native分支都是对应远程的origin/master分支,这是导致的结果是,你完成修改代码然后push到的是远程的master分支,这是不符合要求的,
通过git branch --set-upstream react_native origin/feature_react_native
让本地分支react_native与远程分支origin/feature_react_native关联,这样你以后提交的代码就不会提交到远程master分支了
-
使用
git checkout [xxx]
切换分支,Git 会用该分支的最后提交的快照替换你的工作目录的内容, 所以多个分支不需要多个目录
如图,我在master分支,修改了ViewController.m文件并且提交,当我们切换到“branch1”分支的时候,ViewController.m又重新回到修改前的模样 -
使用
git checkout -b [branchname]
创建新的分支,并立即切换到它,也就是6和7步可以合并到这一步;git checkout -b develop master
基于主分支创建develop分支;
与此同时你打开Xcode的Sourse Control也可以看到有三个分支:
-
git branch -d [branchname]
删除本地分支,git push origin --delete [branchname]
删除远程分支
使用
git merge [branchname]
来合并分支
我在“ branch1”分支中编写了一段代码,完成了一段功能,并且想合并到master分支中,此时我需要先切换到master分支中,然后执行git merge branch1
新建的本地仓库与远程仓库进行关联,在本地仓库.git文件目录下执行
git remote add origin [remoteURL]
,origin
是远程仓库的名字。然后本地仓库的内容推送到远程仓库git push -u origin master
;如果失败则执行git pull origin master [--allow-unrelated-histories]
,如果提示失败信息:fatal: refusing to merge unrelated histories
,则上面中括号的参数需要添加。
以下是一些其他Git命令,我就没做例子,大家可以操作练习
给git起个别名
git config alias.[别名] “status”查看历史版本
git log
50163165822d3141742f4d4aece0e5c222ef156e
git reflog // 查看分支引用记录
git 版本号是有SHA1机密算法生成的一个40位的哈希值版本回退
# 回到当前版本,放弃所有没有提交的修改
git reset --hard HEAD
# 回到上一个版本
git reset --hard HEAD^
# 回到之前第10个修订版本
git reset --hard HEAD~10
# 回到指定版本号的版本
$ git reset --hard [版本号前七位]
- 添加标签(又叫添加里程碑)
git tag -a v1.0 -m 'version 1.0'
,其中v1.0代表tagname,version 1.0代表标签的说明信息;
git push origin v1.3:v1.3
,将标签推送到远程仓库,v1.3:v1.3代表将本地v1.3推送到远程仓库的v1.3;
git tag
查看本地的标签;
git tag -d 1.0
删除本地的标签,1.0代表标签的版本;
git push origin :v1.2
删除远程的标签,这种情况发生在推送到远程的标签版本有错误,为了防止其他人获取到错误的标签,应该尽快的删除标签。
掌握以上的git内容,就能胜任平时90%开发的任务。最后,关于Git 分支的练习,我这有个好的练习网址:Learn Git Branching ,也是一个同事分享给我的,他的Git命令使用的溜溜的;很不错的一个练习Git分支操作的网址,大家点击进去之后可能什么内容都没有,不要急,稍等片刻就会出来。
Github、OSchina的使用
从Github上clone代码,push,pull的操作大家可以下载GitHub Desktop 图形化界面进行操作,
OSchina就可以使用Xcode集成的Git,大家可以添加远程仓库地址,在Preferences(common + ,)--》Account -->左下角有个加号--》Add Repository;然后就可以提交到远程中了。
终于写完了,不容易啊,太困了,最后的内容写的有点粗糙啊,见谅。。。😂😂😂