likes
comments
collection
share

工作向git使用指南

作者站长头像
站长
· 阅读数 1

背景

集中式和分布

  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。