背景

集中式和分布

  1. 集中式版别控制体系:一切的版别都保存在一个中心服务器中,修正文件时需求先从中心服务器中获取,修正完毕后再上传回服务器。这样的版别办理方法存在很多问题,比方服务器宕机导致版别文件丢掉、对服务器的访问依赖于网速、协同作业不便等。
  2. 分布式版别控制体系:每台本地计算机都能够保存一个完好的版别库,不同计算机之间的版别同享通过推送完结。关于分布式办理体系,中心服务器的功用不再是存储版别,而是办理交流,充任不同计算机之间同享版别的中介。

作业原理

  1. 本地库房和长途库房

    git通过本地的git库房来保存和办理版别,因此绝大多数git操作都是无需联网的。假如需求中心服务器供给的中介和保管功用,则能够和长途库房树立衔接,比方github、gitee等。

  2. 保存快照而不是diff

    传统的版别控制体系是通过保存文件的diff来进行版别控制的,可是git选择直接记录项目版别文件的快照,使得每一个版别都具有完好性,而且版别的更迭看起来像是一个快照流。

    工作向git使用指南

起步和装备

装备用户信息

  1. 在多人协作的项目里,不要忘记首先要给本地计算机的git装备用户信息,便利团队进行代码检查
  2. --global意思是大局装备,也能够只装备某个本地库房的(默许--local
  3. # 能够检查config文件的一切变量键值对
    git config --list | -l
    ​
    # 装备大局用户名
    git config --global user.name <user-name>
    ​
    # 装备大局用户邮箱
    git config --global user.email <user-email>
    

装备指令的alias

  1. 声明某个command的alias,装备成功后只要输入别号就等同于输入指令
git config --global alias.<alias> <command>
  1. 示例
# 给status指令装备一个st别号
git config --global alias.st status
​
git st # 等同于git status
  1. 装备alias能提高运用git的效率,可是降低了可读性,在一开端对某些git指令不熟悉的时候不主张装备。

克隆长途库房

  1. 通过cd或许直接在某个目录下shift + 右键切换git bash的作业目录

假如需求把本地项目交给git做版别办理,就在项目文件夹下通过git init指令创立本地库房,可是一般操作都是先在长途创立库房再clone到本地。

  1. 克隆长途库房
# 将url为<url>的长途库房克隆到本地
git clone <url>
​
# clone库房时会默许在指定目录下生成一个和项目同名的项目文件夹,能够指定项目文件夹的名字
git clone <url> <name>
  1. 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才干完结兼并。

工作向git使用指南

  • 方法二:变基到master分支
git rebase master
# 或许
git pull --rebase origin master

变基的意思是把作业分支的基点变成master分支的最新commit,再依次提交原本作业分支上的commit,使得作业分支的commit前史更清晰明了。可是要注意长途作业分支的commit前史是不会变基的,需求本地分支强行push到长途

工作向git使用指南

  • merge和rebase的差异:

    • rebase抹去了分支的“兼并”这一操作,使得分支的commit前史是愈加线性的。这也是rebase和merge的最大差异,merge保留了“兼并”这一过程。

    • rebase更适合feat分支运用,则用于新增项目功用特性的分支。由于一旦master和作业分支发生抵触,rebase会直接生成一个detached head,即当时head指向的作业环境是和之前的分支分离的,此时假如需求再兼并的话会很麻烦,不如直接运用merge便利。

      工作向git使用指南

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。