前言
记得刚开始做项目开发的时候都是一个人完成一个项目,单打独斗的开发,也不知道什么是团队开发,没有这个概念,随着工作后来知道公司里项目都是团队开发,这个时候这么多人怎么开发一个项目呢,难道用u盘拷贝嘛,后来知道有这个一个项目版本管理工具
前期SVN
比较流行后面,开始使用Git
这样团队·在做项目开发基于git 版本管理就会很轻松
快速上手
初始化本地仓库
项目中使用git
需要把项目初始化为git仓库这里要自行安装git 通过git --version
查看git版本是否安装成功
初始化项目git仓库 找到项目根路径 通过命令
git init
初始化本地仓库把项目代码添加到仓库 通过
git add .
来添加点代表所有文件。添加本地仓库成功后,java文件会变成绿色提交文件到本地仓库通过
git commit -m "First commit"
m后面表示提交的注释信息
关联远程仓库
这里我们以GitHub作为项目远程仓库例子到远程仓库的页面上,复制仓库地址
这里可以使用https
或者ssh
两种远程连接方式,htts比较方便直接连接使用,ssh需要配置对呀key和toke,但是比http更加的安全,这里我为了方便就使用https,一般在公司项目都会使用ssh的
- 关联远程仓库地址到本地仓库
git remote add origin {远程仓库地址}
# Sets the new remote
- push到远程仓库
把本地项目代码push同步到远程仓库通过git push -u origin master
命令来实现,master代表远程主分支。
忽略文件
在项目中有一些代码,是不需要提交的每次更新,比如,class
字节文件,也就是targer
文件,还有开发工具的生成的一些文件,jar
文件,属性文件,等等,这个时候我们就可以通过编写.gitignore
把不需要的提交的文件目录添加到.gitignore文件中就可以啦
- 忽略规则
通过在项目下定义.gitignore文件,在该文件中定义相应的忽略规则,来管理当前文件夹下的文件的Git提交行为
在.gitingore 文件中,遵循相应的语法,在每一行指定一个忽略规则。如:
*.log
*.temp
/vendor
- 语法规则
gitignore
注释用'#', *
表示匹配0个或多个任意字符,所以上面的模式就是要忽略所有的xml文件,log文件和apk文件。
.gitignore
配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为版本管理带来很大的便利
# 表示此为注释,将被Git忽略
*.a 表示忽略所有 .a 结尾的文件
!lib.a 表示但lib.a除外
/TODO 表示仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ 表示忽略 build/目录下的所有文件,过滤整个build文件夹;
doc/*.txt 表示会忽略doc/notes.txt但不包括 doc/server/arch.txt
bin/: 表示忽略当前路径下的bin文件夹,该文件夹下的所有内容都会被忽略,不忽略 bin 文件
/bin: 表示忽略根目录下的bin文件
/*.c: 表示忽略cat.c,不忽略 build/cat.c
debug/*.obj: 表示忽略debug/io.obj,不忽略 debug/common/io.obj和tools/debug/io.obj
**/foo: 表示忽略/foo,a/foo,a/b/foo等
a/**/b: 表示忽略a/b, a/x/b,a/x/y/b等
!/bin/run.sh 表示不忽略bin目录下的run.sh文件
*.log: 表示忽略所有 .log 文件
config.php: 表示忽略当前路径的 config.php 文件
/mtk/ 表示过滤整个文件夹
*.zip 表示过滤所有.zip文件
/mtk/do.c 表示过滤某个具体文件
被过滤掉的文件就不会出现在git仓库中(gitlab或github)了,当然本地库中还有,只是push的时候不会上传。
需要注意的是,gitignore还可以指定要将哪些文件添加到版本管理中,如下:
!*.zip
!/mtk/one.txt
唯一的区别就是规则开头多了一个感叹号,Git会将满足这类规则的文件添加到版本管理中。为什么要有两种规则呢?
想象一个场景:假如我们只需要管理/mtk/目录中的one.txt文件,这个目录中的其他文件都不需要管理,那么.gitignore规则应写为::
/mtk/*
!/mtk/one.txt
假设我们只有过滤规则,而没有添加规则,那么我们就需要把/mtk/目录下除了one.txt以外的所有文件都写出来!
注意上面的/mtk/*不能写为/mtk/,否则父目录被前面的规则排除掉了,one.txt文件虽然加了!过滤规则,也不会生效!
----------------------------------------------------------------------------------
还有一些规则如下:
fd1/*
说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;
/fd1/*
说明:忽略根目录下的 /fd1/ 目录的全部内容;
/*
!.gitignore
!/fw/
/fw/*
!/fw/bin/
!/fw/sf/
说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;注意要先对bin/的父目录使用!规则,使其不被排除。
注意 这里一般会出现问题
.gitignore
文件明明配置了但是没有生效
有两种可能:
.gitignore 文件配置有问题,比如我碰到过一次这个问题:我在 windows 系统下的 idea 中使用了 「Add to gitignore」 这个插件去添加需要被 ignore 的文件夹时候,它会在我的 .gitignore 文件中写入:.idea\ ,实际上应该是:/.idea/
在你添加新的 ignore 规则前,你曾经已经提交过这个规则对应的文件,这时候你需要先把本地缓存删除(改变成未 track 状态)使用指令:
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
git 常用命令
远程仓库相关命令
检出仓库:
git clone git://github.com/jquery/jquery.git
查看远程仓库:
git remote -v
添加远程仓库:
git remote add [name] [url]
删除远程仓库:
git remote rm [name]
修改远程仓库:
git remote set-url --push [name] [newUrl]
拉取远程仓库:
git pull [remoteName] [localBranchName]
推送远程仓库:
git push [remoteName] [localBranchName]
如果想把本地的某个分支test提交到远程仓库,并作为远程仓库的master分支,或者作为另外一个名叫test的分支,如下:
$git push origin test:master // 提交本地test分支作为远程的master分支
$git push origin test:test // 提交本地test分支作为远程的test分支
分支(branch)操作相关命令
查看本地分支:
git branch
查看远程分支:
git branch -r
创建本地分支:
git branch [name]
----注意新分支创建后不会自动切换为当前分支切换分支:
git checkout [name]
创建新分支并立即切换到新分支:
git checkout -b [name]
删除分支:
git branch -d [name]
---- -d选项只能删除已经参与了合并的分支,对于未有合并的分支是无法删除的。如果想强制删除一个分支,可以使用-D选项合并分支:
git merge [name]
----将名称为[name]的分支与当前分支合并创建远程分支(本地分支push到远程):
git push origin [name]
删除远程分支:
git push origin :heads/[name]
或$ git push origin :[name]
版本(tag)操作相关命令
查看版本:
git tag
创建版本:
git tag [name]
删除版本:
git tag -d [name]
查看远程版本:
git tag -r
创建远程版本(本地版本push到远程):
git push origin [name]
删除远程版本:
git push origin :refs/tags/[name]
合并远程仓库的tag到本地:
git pull origin --tags
上传本地tag到远程仓库:
git push origin --tags
创建带注释的tag:
git tag -a [name] -m 'yourMessage'
git分支
这里git基本使用 参考 廖雪峰老师 git基本使用教程
主分支
实际开发中,一个仓库(通常只放一个项目)主要存在两条主分支:master
与develop
分支。这个两个分支的生命周期是整个项目周期。就是说,自创建出来就不会删除,会随着项目的不断开发不断的往里面添加代码。master
分支是创建git仓库时自动生成的,随即我们就会从master分支创建develop
分支,如下图所示。
- master:这个分支最为稳定,这个分支代表项目处于可发布的状态。
例如王二狗向master分支合并了代码,那就意味着王二狗完成了此项目的一个待发布的版本,项目经理可以认为,此项目已经准备好发布新版本
了。所以master分支不是随随便便就可以签入代码的地方,只有计划发布的版本功能在develop分支上全部完成,而且测试没有问题了才会合并到master上。
- develop:作为开发的分支,平行于master分支。
例如王二狗要开发一个注册功能,那么他就会从develop分支上创建一个feature分支 fb-register(后面讲),在fb-register分支上将注册功能完成后,将代码合并到develop分支上。这个fb-register就完成了它的使命,可以删除了。项目经理看王二狗效率很高啊,于是:“二狗你顺带把登录功能也做了吧”。二狗心中暗暗骂道:日了个狗的,但是任务还的正常做,二狗就会重复上面的步骤:从develop分支上新创建一个名为fb-login的分支,喝杯咖啡继续开发,1个小时后登录功能写好了,二狗又会将这个分支的代码合并回develop分支后将其删除
支持分支
这些分支都是为了程序员协同开发,以及应对项目的各种需求而存在的。这些分支都是为了解决某一个具体的问题而设立
,当这个问题解决后,代码会合并回主分支develop或者master后删除
,一般我们会人为分出三种分支
Feature branches
:这种分支和我们程序员日常开发最为密切,称作功能分支 必须从develop分支创建,完成后合并回develop分支
Hotfix branches
:这个分支主要为修复线上特别紧急的bug准备的Release branches
:这个分支用来分布新版本。
参考