Git简介
Git是目前世界上最先进的分布式版本控制系统
集中式VS分布式
集中式:
- 需要一个中央服务器
- 必须联网
- 如果中央服务器损坏,源代码存在丢失风险
- 案例:CVS,SVN
分布式:
- 也需要一个中央服务器,但只是为了交换分支的修改,
- 每个开发者都拥有完整的版本库,工作时不需要联网
- 安全性高
- 案例:Git
创建版本库
版本库又名仓库,可以理解为一个目录,目录里的所有文件都可以被Git管理起来,每个文件的修改,删除、Git都能跟踪到,以便任何时候都可以追踪历史,或者在将来的某个时刻可以还原
第一步,选择一个合适的地方,创建一个空目录
mkdir learngit
cd learngit
pwd
/Users/michael/learngit
pwd命令用于显示当前目录。
第二步,通过git init命令把这个目录变成Git可以管理的仓库:
git init
Initialized empty Git repository in /Users/michael/learngit/.git/
瞬间Git就把仓库建好了,.git目录是用来跟踪管理版本库的,不要轻易手动修改这个目录里面的文件,避免破坏Git仓库!
如果没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就能看见了
明确一点:所有的版本控制系统,其实只能跟踪文本文件的改动,而图片、视频等二进制文件版本控制系统并不知道改了啥。
添加文件
把一个文件放到Git仓库只需要两步:
第一步,用命令git add告诉Git,把文件添加到仓库
git add readme.txt
执行上面的命令,没有任何显示,这就对了,Unix的哲学是”没有消息就是好消息“,说明添加成功
第二步,用命令git commit告诉Git,把文件提交到仓库:
git commit -m 'wrote a readmen file'
[master (root-commit) @aadf4e]wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
git commit命令执行成功后会告诉你,1 file changed:1个文件被改动(我们新添加的readme.txt文件);2 insertions:插入了两行内容(readme.txt有两行内容)。
小结:
- 初始化一个Git仓库,使用
git init - 添加文件到Git仓库,分两步:
- 使用命令
git add <file>,注意,可反复多次使用,添加多个文件 - 使用命令
git commit -m <message>,完成
- 使用命令
修改文件
git status命令可以让我们时刻掌握仓库当前的状态
git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
Git告诉我们readme.txt被修改了,如果想知道具体修改的内容,可以使用git diff命令查看
提交修改和提交新文件是一样的两步,第一步git add,在执行第二步git commit之前,我们再运行git status看看当前仓库的状态,确保无误再提交
git status
On branch master
nothing to commit, working tree clean
Git告诉我们当前没有需要提交的修改,而且,工作目录是干净的(working tree clearn)的。
小结:
- 要随时掌握工作去的状态,使用
git status命令 - 如果
git status告诉你有文件被修改过,用git diff可以查看修改的内容。
git log命令用来查看历史记录
git log命令显示从最近到最远的提交日志
$ git log
commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master)
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:06:15 2018 +0800
append GPL
commit e475afc93c209a690c39c13a46716e8fa000c366
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 21:03:36 2018 +0800
add distributed
commit eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Fri May 18 20:59:18 2018 +0800
wrote a readme file
git log --pretty=oneline可以把上述日志缩减
$ git log --pretty=oneline
1094adb7b9b3807259d8cb349e7df1d4d6477073 (HEAD -> master) append GPL
e475afc93c209a690c39c13a46716e8fa000c366 add distributed
eaadf4e385e865d25c48e7ca9c8395c3f7dfaef0 wrote a readme file
看到的一大串类似1094adb...的是commit id(版本号),是一个SHA1计算出来的非常大的数字,用十六进制表示
版本回退
如何把readme.txt回退到上一个版本呢?
Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交,上一个版本就是HEAD^,上上个版本就是HEAD^^,当然网上100个版本写成HEAD~100
现在可以使用git reset --hard HEAD^来把当前版本回退到上一个版本
此时git log查看历史记录是,发现最新那个版本append GPL已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回到21世纪怎么办?
在上面的命令行窗口还没关掉的情况下,可以看到那个append GPL的commit id是1094adb...,于是可以指定回到未来的某个版本:
执行命令:git reset --hard 1094a
版本号没必要写全,前几位就行,Git会自动去找
Git的版本回退非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把修改了HEAD的指向,然后顺便把工作区的文件更新了
如果你关闭了电脑,没记录下最新版本的commit id,怎么回到最新版本呢?
可以使用git reflog命令,用来记录你的每一次命令:
小结:
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id- 穿梭前,用
git log可以查看提交历史,以便确定要回退到哪个版本。 - 要重返未来,用
git reflog查看命令历史,以便确定要回到未来的哪个版本。
工作区和暂存区
工作区(Working Directory):就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区
版本库(Repository):工作区有一个隐藏的目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD
我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支;
因为我们创建Git版本库的时候,Git自动为我们创建了唯一一个master分支,所以,git commit就是往master分支上提交更改。
可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
每次修改,如果不用git add到暂存区,那就不会加入到commit中。
撤销修改
git checkout -- <file>可以丢弃工作区的修改
命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
readme.txt自修改后还没有被放到暂存区,现在,撤销修改就是回到和版本库一模一样的状态;readme.txt已经添加到暂存区后,又做了修改,现在,撤销修改就回到添加到暂存区后的状态。
如果是已经把修改添加到暂存区,还没有提交,可以用git reset HEAD <file>把暂存区的修改撤销掉(unstage),重新放回工作区。
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新版本。
假设已经添加到暂存区,还提交到了版本库,那么就使用git reset --hard commit_id进行版本回退。
小结:
- 场景一,当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令
git checkout -- <file> - 场景二,当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令
git reset HEAD <file>,就回到了场景一,第二步按照场景一操作 - 场景三,已经提交了不合适的修改到版本库,想要撤销本次提交,参考版本回退,前提是没有推送到远程仓库。
删除文件
通常情况下,你直接在文件管理器中把文件删了,或者二用rm命令删了,这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status命令回立即告诉你哪些文件被删除了:
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
现在你又两个选择:
一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
提示:先手动删除文件,然后使用git rm <file>和git add <file>效果是一样的
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
git checkout -- text.txt
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以"一键还原"
注意:从来没有被添加到版本库就被删除的文件是无法恢复的!
小结:
命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你回丢失最近一次提交后你修改的内容。
远程仓库
-
要关联一个远程库,使用命令
git remote add origin git@server-name:path/repo-name.git -
关联一个远程库时必选给远程库指定一个名字,
origin是默认习惯命名; -
关联后,使用命令
git push -u origin master第一次推送master分支的所有内容;此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程仓库的存在,也就是没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送以下就完成了同步,真是太方便了!
从远程库克隆
- 要克隆一个仓库,首先必须知道仓库的地址,然后使用
git clone命令克隆 - Git支持多种协议,包括
https,但ssh协议速度最快,使用https除了速度慢以外,还有个最大的麻烦就是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh协议而只能使用https
分支管理
# 从远程仓库拉取代码合并到本地,可简写为 git pull 等同于 git fetch && git merge
git pull <远程主机名> <远程分支名>:<本地分支名>
# 获取远程仓库特定分支的更新
git fetch <远程主机名> <分支名>
# 创建dev分支,然后切换到dev分支:
git checkout -b dev
# 相当于以下两条命令:
# 创建分支
git branch dev
# 切换分支
git checkout dev
# 最新版本使用git switch 命令切换分支,为了与版本回退区分
#创建并切换到新的dev分支,可以使用git switch -c dev
# 直接切换到已有的master分支,可以使用
git switch master
# 命令会列出本地所有分支,当前分支前会有一个*号
git branch
# 合并分支,此命令用于合并指定分支到当前分支,切换到master分支,把dev分支合并到master分支上,并且分支指向master
git merge dev
# 删除本地分支
git branch -d dev
# 查看本地和远程分支 -a, *号代表你当前工作目录所在的分支
git branch -a
# 删除远程版本
git branch -r -d origin/branch-name
git push origin :branch-name
# 重命名本地分支-在当前分支
git branch -m new_branch_name
# 重命名本地分支-不在当前分支
git branch -m old_branch_name new_branch_name
# 重命名远端分支(假设是在当前分支,并且远端分支与本地分支名是一致的)
git branch -m new_branch_name
git push --delete origin old_branch_name
git push origin new_branch_name
git branch --set-upstream-to origin/new_branch_name
小结:
查看分支:git branch
创建分支:git branch <name>
切换分支:git checkout <name>或者git switch <name>
创建+切换分支:git checkout -b <name>或者git switch -c <name>
合并某分支到当前分支:git merge <name>
删除分支:git branch -d <name>
解决冲突
小结:
- 当Git无法自动合并分支时,就必须首先解决冲突,解决冲突后,再提交,合并完成。
- 解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
- 用
git log --graph命令可以看到分支合并图
分支策略
小结:
合并分支时,加上--no-ff参数可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
$ git merge --no-ff -m "merge with no-ff" dev
Bug分支
小结
- 修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除
- 当手头的工作没有完成时,先把工作现场
git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场;可以多次stash,使用git stash -m "message..."可以给暂存做一个信息的记录,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令git stash apply stash@{0},git stash clear可以删除所有缓存的stash - 在master分支上修复的bug,想要合并到当前dev分支,可以用
git cherry-pick <commit_hash>命令,把bug分支提交的修改“复制”到当前分支,避免重复劳动。过程中,如果出现冲突,解决冲突后,进行git add .,接着执行git cherry-pick --continue
Feature分支
小结:
- 开发一个新feature,最好新建一个分支;
- 如果丢弃一个没有合并过的分支,可以通过
git branch -D <branch_name>强行删除。
多人协作
小结:
- 查看远程库信息,使用
git remote -v - 本地新建的分支如果不推送到远程,对其他人就是不可见的
- 在本地创建和远程分支对应的分支,使用
git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致; - 从本地推送分支,使用
git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交; - 如果
git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch -set-upstream-to <branch-name> origin/<branch-name>建立本地分支和远程分支的关联 - 从远程抓取分支,使用
git pull,如果有冲突,要先处理冲突 - 推送本地分支到远程仓库:
git push --set-upstream origin <branch-name> - 将远程Git仓库里的指定分支拉取到本地:
git pull <origin-name> <origin-branch-name>:<branch-name>,git pull操作就可以从远程库中获取某个分支的更新,再与本地指定的分支进行自动merge(即使本地不存在这个分支)
Rebase
作用一:rebase 翻译为编辑,它的作用和merge很相似,用于把一个分支的修改合并到当前分支上
如下图所示,下图介绍了经过rebase后提交历史的变化情况。
现在我们来用一个例子来解释一下上面的过程:
假设我们现在有2条分支,一个为master,一个为feature/1,他们都基于初始的一个提交 add readme 进行检出分支,之后,master分支增加了3.js,和 4.js 的文件,分别进行了2次提交,feature/1 也增加了 1.js 和 2.js的文件,分别对应以下2条提交记录。
此时,对应分支的提交记录如下:
master 分支如下图:
feature/1分支如下图:
结合起来看是这样的:
此时,切换到feature/1 分支下,执行 git rebase master, 成功之后,通过 git log查看记录。
如下图所示:可以看到先是逐个应用了 master 分支的更改,然后以master分支最后的提交作为基点,再逐个应用feature/1的每个更改。
所以,我们的提交记录就会非常清晰,没有分叉,上面演示的是比较顺利的情况,但是大部分情况下,rebase 的过程中会产生冲突的,此时,就需要手动解决冲突,然后依次git add ., git rebase --continue的方式来处理冲突,完成rebase的过程,如果不想要某次rebase的结果,那么需要使用git rebase --skip来跳过这次rebase操作。
作用二: 合并开发分支上的多个commit
在开发中,常会遇到在一个分支上产生了很多的无效提交,这种情况下使用rebase将多次提交压缩成依次提交,得到一个干净的提交历史,例如某个分支的提交历史情况如下:
进入交互模式的方式是执行:
git rebase -i [startpoint] [endpoint]
其中-i的意思是--interactive,即弹出交互式的界面让用户编辑完成合并操作,[startpoint] [endpoint]则指定了一个编辑区间,如果不指定[endpoint],则该区间的终点默认是当前分支HEAD所指向的commit(注:该区间指定的是一个前开后闭的区间)。 对于上述提交历史的例子,我们把最后一个提交对象(ac18084)之前的提交压缩成一次提交,我们需要执行的命令是:
git rebase -i ac18084
此时会进入一个vim的交互页面,编辑器列出的信息像下列这样:
上面未被注释的部分列出的是我们本次rebase操作包含的所有提交,下面注释部分是git为我们提供的命令说明。每一个commit id 前面的pick表示指令类型,git 为我们提供了以下几个命令:
pick:保留该commit(缩写:p)
reword:保留该commit,但我需要修改该commit的注释(缩写:r)
edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
squash:将该commit和前一个commit合并(缩写:s)
fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
exec:执行shell命令(缩写:x)
drop:我要丢弃该commit(缩写:d)
想要合并这一堆更改,我们要使用Squash策略进行合并,即把当前的commit和它的上一个commit内容进行合并,大概可以表示为下面这样,在交互模式的rebase下,至少保留一个pick,否则命令会执行失败。
pick ... ...
s ... ...
s ... ...
s ... ...
按i进行编辑,修改文件后按下 :然后wq保存退出,此时又会弹出一个编辑页面,这个页面是用来编辑提交的信息,修改为 feat: 更正, 最后保存一下,接着使用 git log查看提交的commit信息,rebase后的提交记录如下图所示,是不是清爽了很多?rebase操作可以让我们的提交历史变得更加清晰。
小结
- git rebase 让你的提交记录更加清晰可读
- rebase操作可以把本地未push的分叉提交历史整理成直线
- rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比
- 特别注意:只能在自己使用的feature分支上进行rebase操作,不允许在集成分支上进行rebase,因为这种操作会修改集成分支的历史记录。
git merge 和 git rebase 的区别
- 不同于
git rebase的是,git merge在不是fast-forward(快速合并)的情况下,会产生一条额外的合并记录,类似merge branch 'xxx' into 'xxx'的一条提交信息。
- 另外,在解决冲突的时候,用merge只需要解决一次冲突即可,简单粗暴,而用rebase的时候,需要依次解决每次的冲突,才可以提交。
标签管理
发布一个版本时,我们通常先在版本库中打一个标签(tag),这儿确定了打标签时刻的版本,将来无论什么时候,取某个标签的版本,就是把那个变迁的时刻的历史版本取出来。所以,标签也是版本库的一个快照。
Git的标签虽然是版本库的快照,但其实它就是指向某个commit的指针(跟分支很像,但是分支可以移动,标签不能移动)
创建标签
小结
- 命令
git tag <tagname>用于新建一个标签,默认为HEAD,也可以指定一个commit id - 命令
git tag -a <tagname> -m "balabalbala..."可以指定标签信息 - 命令
git tag可以查看所有标签
操作标签
小结
- 命令
git push origin <tagname>可以推送一个本地标签 - 命令
git push origin --tags可以推送全部未推送过的本地标签 - 命令
git tag -d <tagname>可以删除一个本地标签 - 命令
git push origin :refs/tags/<tagname>可以删除一个远程标签
github的使用
访问一个开源项目主页,点"Fork"就在自己的账号下克隆了该仓库,然后,从自己的账号下clone,一定要从自己的账号下clone仓库,不然是没有权限推送修改的
自定义Git
Git会适当的显示不同的颜色:git config --global color.ui true
忽略特殊文件
当你想添加一个文件到Git,发现添加不了,原因是这个文件被.gitignore忽略了,可以使用-f强制添加到Git
git add -f App.class
或者使用git check-ignore -v <file-name>命令检查:
git check-ignore -v App.class
.gitignore:3:*.class App.class
# 排除所有.开头的隐藏文件:
.*
# 排除所有.class文件:
*.class
# 不排除.gitignore和App.class:
!.gitignore!App.class
把指定文件排除在.gitignore规则外的写法就是!+文件名,所以,只需要把例外文件添加进去即可。
配置别名
# co 表示checkout ci表示commit br表示branch
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
# unstage 表示 reset HEAD 撤销修改
git config --global alias.unstage 'reset HEAD'
# last 表示显示最后一次提交信息c
git config --global alias.last 'log -1'
# 配置lg
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
git lg的效果
配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用,每个仓库的Git配置文件都放在.git/config文件中:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@github.com:michaelliao/learngit.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[alias]
last = log -1
别名就在[alias]后面,要删除直接把对应的行删除掉即可
当前用户的Git配置文件放在用户主目录下的一个隐藏文件.gitconfig中
git分支命名规范
| 分支 | 命名 | 说明 |
|---|---|---|
| 主分支 | master | 主分支,所有提供给用户的正式版本,都在这个主分支上发布 |
| 开发分支 | dev | 开发分支永远是功能最新最全的分支 |
| 功能分支 | feature-* | 新功能分支,某个功能点正在开发阶段 |
| 发布分支 | release-* | 发布定期要上线的功能 |
| 修复分支 | bug-* | 修复线上代码的bug |
日常开发流程
主分支 Master 首先,代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。
Git主分支的名字,默认叫做 Master 。它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。
开发分支 Dev
主分支只用来发布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做 Dev
这个分支可以用来生成代码的最新隔夜版本(nightly)。如果想正式对外发布,就在 Master 分支上,对 Dev 分支进行”合并”(merge)。
Git创建 Dev 分支的命令:
git checkout -b dev master
将 Dev 分支发布到 Master 分支的命令:
切换到 Master 分支
git checkout master
对 Dev 分支进行合并
git merge –no–ff dev
这里稍微解释一下,上一条命令的–no–ff参数是什么意思。默认情况下,Git执行”快进式合并”(fast-farward merge),会直接将 Master 分支指向 Dev 分支。 使用–no–ff参数后,会执行正常合并,在 Master 分支上生成一个新节点。为了保证版本演进的清晰,我们希望采用这种做法。
功能分支 Feature
功能分支的名字,可以采用feature- * 的形式命名。
创建一个功能分支:
git checkout -b feature-x dev
开发完成后,将功能分支合并到dev 分支:
git checkout dev
git merge –no-ff feature-x
删除feature分支:
git branch -d feature-x
预发布分支 Release
第二种是预发布分支,它是指发布正式版本之前(即合并到 Master 分支之前),我们可能需要有一个预发布的版本进行测试。
预发布分支是从 Dev 分支上面分出来的,预发布结束以后,必须合并进 Dev 和 Master 分支。它的命名,可以采用release- * 的形式。
创建一个预发布分支:
git checkout -b release-1.2 dev
确认没有问题后,合并到master分支:
git checkout master
git merge –no-ff release-1.2
对合并生成的新节点,做一个标签:
git tag -a 1.2
再合并到dev 分支:
git checkout dev
git merge –no-ff release-1.2
最后,删除预发布分支:
git branch -d release-1.2
修补分支 Bug
最后一种是修补bug分支。软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。
修补bug分支是从 Master 分支上面分出来的。修补结束以后,再合并进 Master 和 Dev 分支。它的命名,可以采用fixbug- * 的形式。
创建一个修补bug分支:
git checkout -b fixbug-0.1 master
修补结束后,合并到master分支:
git checkout master
git merge –no-ff fixbug-0.1
git tag -a 0.1.1
再合并到dev 分支:
git checkout dev
git merge –no-ff fixbug-0.1
最后,删除”修补bug分支”:
git branch -d fixbug-0.1
git tag usage
#添加
git tag -a V0.1.110811 -m"基本部署完成,有BUG待做"
#删除
git tag -d V0.1.110811
#推送到远程
git push origin V0.1.110811
git push –tags
git提交记录规范
每个 git commit 记录都需要按照固定格式,具体格式为:
第一行:
作者: 功能模块名称(或 功能模块ID)
第二行:
提交描述,中英文皆可(+ : 增加代码 * : 修改代码 - : 删除代码)
commit message格式
<type>(<scope>): <subject>
type(必须)
用于说明git commit的类别,只允许使用下面的标识。
feat:新功能(feature)。
fix/to:修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。
- fix:产生diff并自动修复此问题。适合于一次提交直接修复问题
- to:只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fix
docs:文档(documentation)。
style:格式(不影响代码运行的变动)。
refactor:重构(即不是新增功能,也不是修改bug的代码变动)。
perf:优化相关,比如提升性能、体验。
test:增加测试。
chore:构建过程或辅助工具的变动。
revert:回滚到上一个版本。
merge:代码合并。
sync:同步主线或分支的Bug。
scope(可选)
subject(必须)
subject是commit目的的简短描述,不超过50个字符。
建议使用中文(感觉中国人用中文描述问题能更清楚一些)。
- 结尾不加句号或其他标点符号。
- 根据以上规范git commit message将是如下的格式:
fix(DAO):用户查询缺少username属性
feat(Controller):用户查询接口开发
常用命令备忘
Control + C结束不了进程就用 Q 退出