整理了一下Git使用方法

39 阅读10分钟

前言

Git是我们进行编程使用的版本控制工具。同时他也是截止目前世界上最先进的分布式版本控制系统。从毕业以来进入到实践工作当中,我发现在实际开发中的项目协作上,或者说在项目版本管理工具Git的使用上,存在着很多可以去优化的地方。为此,自己曾经花了一段时间去学习研究Git的使用,以及如何使用Git更好的来管理多人协作项目。当然,经过了一个阶段的系统学习,想写一些关于这段时间学习的感受,也方便以后回过头来重新复习一遍。


本文章主要讨论几个问题:

  1. 什么是Git? Git是用来做什么的?
  2. 什么是版本控制,他的作用是什么?
  3. 集中式版本控制系统与分布式版本控制系统的工作方式,区别?
  4. Git的工作方式以及项目Git文件负责的职能

1.什么是Git?它是用来做什么的?

Git是截至目前(2020年)世界上最先进的分布式版本控制工具。

并且它是用来对项目进行版本控制的。

2.什么是版本控制,他的作用是什么?

我们先举个例子:1、如果你在用电脑写一份文档时,想删除掉一段文字,但是很不巧,这段文字可能在未来的某个时刻会被用到,这个时候一般你需要先将这个文档另存为“文档A”,然后再这个基础上再去修改保存“文档B”。 现在文档B在某个层面上需要进行某个结构的调整,但是你也不清楚这样子的调整能不能通过领导的审查的时候,便会在这个基础上保存一个新的“文档C”,在我们做软件需求上都认同这样一句话“软件需求是在不断变更的”。那一段时间下来,你会发现多了“文档DEFGHIJK...”,既浪费了电脑内存又不方便管理。

2、还有另一种情况,收集一个表格,同时需要多人协同填写,那统计者便会收到多个表格,并且在进行汇总合并,费时又费力...

那么,是否存在一种方法,既可以存储多个版本信息,又可以多人在线协同的呢?

3. 集中式与分布式版本控制系统的工作方式,区别?

集中式版本控制系统 -- cvs,svn

简单来说,他的版本库存放于中央服务器上,而我们在工作时,首先从中央服务器上获取到项目的最新版本,然后在开始进行我们的修改,完成工作后,再把自己的工作内容推送到中央服务器上。

但是这样的方式缺点也很明显:首先是必须联网,并且文件是按照原始数据进行储存,如果是局域网就还好,带宽大、网速快,但是如果是外网访问的云,如果需要传输大文件或者文档,这个传输时间也是蛮扎心的了,另外A终端创建新分支在B终端上也会拥有一样的分支。

分布式版本控制系统 -- git

git中,每个开发者都有一个属于自己的本地仓库,在工作时,首先在自己的本地仓库进行修改与提交,最后将这些修改的元数据,即修改部分信息,而不是像svn的原始数据推送到远程服务器上。git的每个提交保存的是差异记录,所有提交合在一起得到完整记录,有点像是数学并集问题。

在git的使用当中,远程服务器的职能更偏向于用来交换大家的修改与数据存储,即使没有网络,也可以使用本地仓库进行版本管理,只是不方便多方交换各自的数据而已。另外git创建的分支不会影响其他人的使用。

4. Git目录解析?

目录名字作用
config储存项目配置信息(remote url,name, e_mail, account)
objects文件夹储存git对象
HEAD文件记录当前头指针
index文件储存暂存区的信息
refs储存分支信息,包含当前分支,远程分支名,以及tags标签
hooks钩子,常用与提供部分脚本,做一些自动化操作;比如日志的规划化检查

5. (延申)Git为什么要进行提交日志规范?

从上文得知,Git是目前最流行的版本控制工具,并且书写良好的Commit Message可以大大增强分支管理的阅读性,提高代码的维护效率。但是在实际开发当中由于缺少了对Commit Message的规范以及约束,出现了提交日志随意,质量参差不齐,甚至是无效的提交日志的情况,导致了阅读性降低,甚至是无法从提交日志上直观阅读代码信息。

所以基于这样的层次上,引入项目Git提交日志规范是非常有必要的。

5.1: 用什么规范?

ihao/git-commit-helper: ihao/git-commit-helper(链接)


格式要求如下:

(): ;;

5.1.1: 日志Type类型?

日志允许如下这些日志分类,方便输出 release note 或 changelog

  feat:新的功能特性

  fix:BUG修复
  
  docs:文档更新
  
  style:与代码逻辑无关的样式修改(空格、格式、句尾结束符等)
  
  refactor:代码重构,但与修复bug或者新功能无关

  perf:性能优化

  test:测试用例

  chore:工程化更新(编译脚本、辅助工具等)
5.1.2: 自动执行禅道事务(可选,需要配置hooks)

git hooks脚本可提供自动执行禅道内事务,比如关闭bug,完成需求,记录工作日志等,这些都可以在这种完成。

示例:

  • #1001 完成一个需求任务
  • #1001-1-12 在一个需求任务内记录工作日志
  • @2001完成一个BUG
  • @2001-1 在一个BUG内记录工作日志

<scope> 内可以填写多个指令,指令之间以 , 号分隔

一个最简单提交日志示范:

docs: 接口文档更新

fix(@9528):修复无法提交信息的bug

feat(#9528,#9527-1-2,@9000): 完成留言回复功能,并解决留言无法回复问题

备注:该语句解释为:提交一个新功能,同时关闭9528号禅道任务和9000号禅道BUG,并在9527号禅道任务中记录工作日志,消耗1小时,剩余2小时,日志内容即提交日志内容。

5.1.3:如何配置git hooks?

📎git-commit-helper-master.zip

1.项目安装: 下载 git-commit-helper-master.zip,并解压,将文件commit-msg 直接复制到项目.git/hooks文件夹下即可。

2.全局安装(仅对配置后的新建项目有效):将 commit-msg 放置到git环境目录下 Git/.git-template/hooks 目录内,若不存在/.git-template/则自行创建,并cmd命令行输入 git config --global init.templatedir '~Git/.git-template' 即可。

3.在commit-msg 中修改禅道相关信息:

ZT_HOST="实际禅道访问地址"

ZT_USER="禅道帐号"

ZT_PASS="禅道密码"

6.Git的基本使用方

6.1. git 安装时全局参数配置

//查看当前配置的author用户名
git config --global user.name 
//查看当前配置的author邮箱
git config --global user.email 
//修改当前author信息
git config --global user.name "your name" user.email "your email"

6.2. 创建一个本地仓库

git init

6.3. 显示当前工作目录

git status

6.4. 添加文件到暂存区、提交

//添加一个类暂存区
git add class1.java
//添加多个类文件暂存区
git add class2.java class3.java ...
//将所有修改(modify)以及新文件(add)添加到暂存区
git add .
//将所有修改(modify)以及删除(delete)添加到暂存区
git add -u
//将所有修改(modify)以及删除(delete)、新增(add)添加到暂存区
git add -a 
git add -m "提交说明"
//绑定到远程仓库
git remote add origin <git ip-address>
//提交
git push

6.5. Git log 查看版本信息

//默认输出
git log --online
//在log的基础上输出增删改的数据统计
git log --stat
//输出commit的具体修改内容
git log -p 
//限定提交作者
git log --author
//限定日期
git log --before -after
//限制输出数量
git log -n

6.6. Git Stash脏目录、临时储存区

当你的Git存在正在修改的索引以及文件,但此时你需要一个干净的工作目录,这种情况下不可能把未完成的代码提交,或者创建新分支。
举例子来说,你当前在开发新功能,此时反馈有个紧急bug要修复,那此时Git stash是个不错的选择。
处理策略:先将当前代码stash,然后修复完bug之后,再将未完成的代码unstash,继续开发。

//显示stash列表
git stash list
//显示做了哪些代码的改动 
git stash show 
//显示stash第一个的详情代码改动
git stash show -p
//执行储存时,添加备注
git stash save "message"
//stash栈中pop一次,并在栈中删除当前栈顶的内容
git stash pop
//stash栈中恢复一次,不在栈中删除当前栈顶的内容
git stash apply
//删除某次stash中的改动
git stash drop <stash name>
//清空stash
git stash clear

6.7. 修改commit message

//修改最新的commit message
git commit --amend  
//可应用于修改多次commit
git rebase -i

6.8. 分支操作

//显示当前所在分支
git branch 
//创建一个名为dev2的分支
git branch dev2
//显示本地以及远程的所有分支
git branch -a
//检出到dev分支
git checkout dev
//检出到dev分支,如果不存在dev,则以HEAD所在的地方创建dev分支
git checkout -b dev
//修改分支名dev为develop
git branch -m dev develop
//删除本地分支dev
git branch -d dev
//删除远程分支dev
git push origin -d dev

//插入一个checkout的其他命令:检出文件:意思是某个文件上的修改的恢复
git checkout xx.java

6.9. git reset操作

远程库回滚:
如果拥有强制提交权限,可使用--hard命令,不过会丢失远程库代码~(极不建议)
建议使用revert

--soft 完全保留 工作区和暂存区
--mixed 完全保留工作区,彻底清除暂存区
--hard 彻底清除工作区和暂存区
--keep 保留工作区和HEAD之间的差异

Revert 反做,使用一次commit来回滚之前的内容:
举例子来说:比如分支1当前有A(id 001) -> B(002) -> C(003), 版本B存在Bug,需要进行回退处理,又不想影响版本C的功能:
git revert 002,会生成新的commit D(004)

6.10. git reflog

查看分支操作记录,包括reset记录和删除记录
继续举例子: 当前提交树:A->B->C,我回滚Reset到了B,当前提交树没有了版本C的提交。
第二天起床我后悔了,该怎么办呢?

使用Git reflog会输出你的流程大概为A(001)->B(002)->C(003)->D(004 Reset to B),
这个时候重新调用git reset --hard C。那么当前提交树又变成A -> B -> C.