背景
集中式和分布式
- 集中式版别控制体系:一切的版别都保存在一个中心服务器中,修正文件时需求先从中心服务器中获取,修正完毕后再上传回服务器。这样的版别办理方法存在很多问题,比方服务器宕机导致版别文件丢掉、对服务器的访问依赖于网速、协同作业不便等。
- 分布式版别控制体系:每台本地计算机都能够保存一个完好的版别库,不同计算机之间的版别同享通过推送完结。关于分布式办理体系,中心服务器的功用不再是存储版别,而是办理交流,充任不同计算机之间同享版别的中介。
作业原理
-
本地库房和长途库房
git通过本地的git库房来保存和办理版别,因此绝大多数git操作都是无需联网的。假如需求中心服务器供给的中介和保管功用,则能够和长途库房树立衔接,比方github、gitee等。
-
保存快照而不是diff
传统的版别控制体系是通过保存文件的diff来进行版别控制的,可是git选择直接记录项目版别文件的快照,使得每一个版别都具有完好性,而且版别的更迭看起来像是一个快照流。
起步和装备
装备用户信息
- 在多人协作的项目里,不要忘记首先要给本地计算机的git装备用户信息,便利团队进行代码检查
-
--global
意思是大局装备,也能够只装备某个本地库房的(默许--local
) -
# 能够检查config文件的一切变量键值对 git config --list | -l # 装备大局用户名 git config --global user.name <user-name> # 装备大局用户邮箱 git config --global user.email <user-email>
装备指令的alias
- 声明某个command的alias,装备成功后只要输入别号就等同于输入指令
git config --global alias.<alias> <command>
- 示例:
# 给status指令装备一个st别号
git config --global alias.st status
git st # 等同于git status
- 装备alias能提高运用git的效率,可是降低了可读性,在一开端对某些git指令不熟悉的时候不主张装备。
克隆长途库房
- 通过cd或许直接在某个目录下
shift + 右键
,切换git bash的作业目录。
假如需求把本地项目交给git做版别办理,就在项目文件夹下通过git init
指令创立本地库房,可是一般操作都是先在长途创立库房再clone到本地。
- 克隆长途库房:
# 将url为<url>的长途库房克隆到本地
git clone <url>
# clone库房时会默许在指定目录下生成一个和项目同名的项目文件夹,能够指定项目文件夹的名字
git clone <url> <name>
- url的传输协议能够是Https或许SSH:
- Https协议:任何人都能够clone该库房,可是在对长途库房推送时需求权限认证,则需求验证用户名和暗码
- SSH协议:在clone库房之前就现已通过SSH Key和远端树立衔接,确保clone时用户就现已有必定的库房权限,因此能够免密推送
作业流程
创立新分支
# 1. 创立一个本地新分支但不切换
git branch <branch-name>
# 也能够创立一个跟踪长途分支的本地分支
git branch <branch-name> --track <remote>/<branch-name>
# 2. 创立一个本地新分支并切换
git branch <branch-name>
git switch <branch-name>
# *或许直接检出新分支
git checkout -b <branch-name>
# 3*. 创立一个追寻长途分支的本地新分支并检出
git checkout -b <branch-name> --track <remote>/<branch-name>
示例:
# 拉取项目时默许拉取的是master分支,假如想在本地新建一个追寻到远端develop分支的分支,能够直接用checkout指令
git co -b dev --track origin/develop
开发作业流
1. 拉取主分支最新代码
# 每天打开电脑第一步,pull一下远端master分支的代码,及时获取更新
# master分支
git pull
- 注意pull和fetch的差异,pull会把更新和本地分支兼并,而fetch不会
2. 处理自己的作业分支
有时候master分支更新了一些比较重要的feature时,作业分支需求和主分支同步更新,有两种方法:
- 方法一:兼并到master分支
git merge master
兼并到master分支可能会发生抵触,假如发生抵触,要到IDE手动处理完抵触的文件后,提交一个merge commit才干完结兼并。
- 方法二:变基到master分支
git rebase master
# 或许
git pull --rebase origin master
变基的意思是把作业分支的基点变成master分支的最新commit,再依次提交原本作业分支上的commit,使得作业分支的commit前史更清晰明了。可是要注意长途作业分支的commit前史是不会变基的,需求本地分支强行push到长途。
-
merge和rebase的差异:
-
rebase抹去了分支的“兼并”这一操作,使得分支的commit前史是愈加线性的。这也是rebase和merge的最大差异,merge保留了“兼并”这一过程。
-
rebase更适合feat分支运用,则用于新增项目功用特性的分支。由于一旦master和作业分支发生抵触,rebase会直接生成一个detached head,即当时head指向的作业环境是和之前的分支分离的,此时假如需求再兼并的话会很麻烦,不如直接运用merge便利。
-
3. 作业中的git运用
-
普通流程
# 1. 增加文件到暂存区 # 增加一切修正后的文件 git add . # 增加部分文件,以空格隔开 git add <file> # 2. 将暂存区的更改提交到本地git库房 # commit必须要带上commit message git commit -m "some messages" # 假如需求兼并add和commit操作,能够用-am git commit -am <file> -m "some messages"
commit message规范
读物:优化你的Git commit message
- feat(feature):新增功用
- fix(fix bugs):修正代码
- style:款式,不触及代码
- perf(performance):性能优化
- test:单元测试
- refactor:重构
- docs:文档
-
回退
# 1. commit的回退 # 用于撤销某个commit,而且会留下一条新的commit git revert <commit> # 2. 版别的回退 # soft形式:被修正文件回到暂存区(即文件被add可是未commit的状况),改动最小 git reset --soft <version> # mixed形式:默许形式,被修正文件回到未提交状况 git reset --mixed <version> # hard形式:丢弃一切修正,强行回退 git reset --mixed <version>
-
暂存文件
当需求切换分支进行作业,可是不想提交当时修正的内容时,能够暂存已完结的修正。
# 要注意stash是一个栈 git stash --save "save messages" git stash pop # 运用栈顶的stash并弹出栈(从stash中删去) git stash apply # 运用某个stash,不会删去
-
兼并多个commit记录
有时候多个commit合起来才是一个完好的任务,为了确保远端commit前史的流畅性,能够通过rebase指令来兼并多个commit。
# 1. 选取某个前史commit为基点,该基点之后提交的commit都将被兼并成一个新的commit # -i后边紧跟的便是基点commit,比方当选取HEAD~2为基点时,则兼并HEAD和HEAD~1两个commit git rebase -i HEAD~2 # 2. 跳出vim界面后,输入-i进入INSERT形式,把除第一个以外的pick改为s,意为兼并 # 3. 按下ESC键退出INSERT形式,输入:wq保存并退出,git将开端执行rebase操作 # 4. 操作完毕后,会再次跳出一个要求输入commit message的vim界面,把旧的message删去,输入一条新的commit message后保存退出 # 假如仅仅兼并本地的commit的话,那么到这一步现已完毕了 # 假如长途的分支也需求兼并,牢记千万不要直接merge,不然长途的commit前史依然是没有改动的!!! # 5. 为了改动长途分支的commit前史,还需求强制push,完结commit兼并操作 git push -f
假如是想在Source Tree上完结兼并commit的话,只需求选择软兼并,回退到某个基点commit上,再进行commit即可,相同要注意强制push的问题。
-
兼并指定commit的修正
有时候需求把某个分支上的某个指定commit兼并进自己的分支,而无需和整条分支兼并,就能够运用cherry-pick指令。
git cherry-pick <commit> # cherry-pick不局限于自己的分支,能够兼并其他分支上的commit,兼并成功后,当时分支会直接多一个commit记录
4. 团队协作
# git blame指令能够看到某行代码的作者,在团队协作中有很大作用
# -L指的是定位某一行
git blame -L <start>,<end>
可是在实践作业中,能够运用插件愈加直观地看到某一行代码的作者,比方VS Code的Gitlens插件。
5. 比对前史版别
git diff
能够看到不同版别之间的改动,便利咱们定位和再次修正,可是缺少愈加友爱的可视化,因此作业中一般都是运用插件或许直接用git的可视化软件检查。
6. 兼并到master
在实践作业中,master作为最重要的主干分支,并不能够随意merge其他作业分支。
咱们在自己的作业分支完结开发后,假如现已通过自测,则需求提一个merge request,通过Code Review和测试后,才干正式上线。
提mr能够自己手动提;在IDE中commit时,gitlab会主动根据commit message生成一个mr衔接,点进去也能够提交mr。