Git 高级语法
1 gitignore
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore
的文件,列出要忽略的文件的模式。
要养成一开始就为你的新仓库设置好 .gitignore
文件的习惯,以免将来误提交这类无用的文件。
文件 .gitignore
的格式规范如下:
-
所有空行或者以
#
开头的行都会被 Git 忽略。相等于注释。 -
匹配模式可以以
/
开头防止递归。 -
匹配模式可以以
/
结尾指定目录。 -
要忽略指定模式以外的文件或目录,可以在模式前加上叹号
!
取反。 -
可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
- 所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。
- 问号
?
只匹配一个任意字符 - 星号
*
匹配零个或多个任意字符 [abc]
匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);- 如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
- 使用两个星号
**
表示匹配任意中间目录,比如a/**/z
可以匹配a/z
、a/b/z
或a/b/c/z
等。
yml
# .gitignore
*~ # 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。
*.a # 忽略所有的 .a 文件
*.[oa] # 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。
!lib.a # 跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
/TODO # 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
build/ # 忽略任何目录下名为 build 的文件夹
doc/*.txt # 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/**/*.pdf # 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。
如果之前已经提交过某个需要忽略文件夹,需要执行以下命令行
yml
$ git rm -r --cached 文件名
1.1 例子
yml
# uniapp 项目下的 .gitignore
unpackage
.vite
.hbuilderx
node_modules
2 提交
2.1 提交规范
Git 提交规范工具-Cz 工具集 Cz 工具集使用介绍 - 规范 Git 提交说明 前端工程化-husky+commitizen+ 自定义 cz-customizable 适配器 git 提交代码规范化
-
Commitizen
是一个规范提交的插件 -
当你在使用
git commit
提交时,Commitizen
能够快速地帮你完成提交信息的补充。 -
不仅如此,
Commitizen
可以帮助你的团队规范统一的 commit message。
1. 安装
js
npm install -g commitizen
npm install cz-customizable --save-dev
commitizen init cz-customizable --save --save-exact // 初始化
npm i -D cz-customizable
2. 配置 .cj-config.js
文件
js
module.exports = {
// type 类型(定义之后,可通过上下键选择)
types: [
{ value: "feat", name: "feat: 新增功能" },
{ value: "fix", name: "fix: 修复 bug" },
{ value: "docs", name: "docs: 文档变更" },
{
value: "style",
name: "style: 代码格式(不影响功能,例如空格、分号等格式修正)",
},
{
value: "refactor",
name: "refactor: 代码重构(不包括 bug 修复、功能新增)",
},
{ value: "perf", name: "perf: 性能优化" },
{ value: "test", name: "test: 添加、修改测试用例" },
{
value: "build",
name: "build: 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)",
},
{ value: "ci", name: "ci: 修改 CI 配置、脚本" },
{
value: "chore",
name: "chore: 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)",
},
{ value: "revert", name: "revert: 回滚 commit" },
],
// scope 类型(定义之后,可通过上下键选择)
scopes: [
["page", "页面相关"],
["components", "组件相关"],
["hooks", "hook 相关"],
["utils", "utils 相关"],
["element-ui", "对 element-ui 的调整"],
["styles", "样式相关"],
["deps", "项目依赖"],
["auth", "对 auth 修改"],
["other", "其他修改"],
// 如果选择 custom,后面会让你再输入一个自定义的 scope。也可以不设置此项,把后面的 allowCustomScopes 设置为 true
["custom", "以上都不是?我要自定义"],
].map(([value, description]) => {
return {
value,
name: `${value.padEnd(30)} (${description})`,
};
}),
// 是否允许自定义填写 scope,在 scope 选择的时候,会有 empty 和 custom 可以选择。
// allowCustomScopes: true,
// allowTicketNumber: false,
// isTicketNumberRequired: false,
// ticketNumberPrefix: 'TICKET-',
// ticketNumberRegExp: '\\d{1,5}',
// 针对每一个 type 去定义对应的 scopes,例如 fix
/*
scopeOverrides: {
fix: [
{ name: 'merge' },
{ name: 'style' },
{ name: 'e2eTest' },
{ name: 'unitTest' }
]
},
*/
// 交互提示信息
messages: {
type: "确保本次提交遵循 规范!\n选择你要提交的类型:",
scope: "\n选择一个 scope(可选):",
// 选择 scope: custom 时会出下面的提示
customScope: "请输入自定义的 scope:",
subject: "填写简短精炼的变更描述:\n",
body: '填写更加详细的变更描述(可选)。使用 "|" 换行:\n',
breaking: "列举非兼容性重大的变更(可选):\n",
footer: "列举出所有变更的 ISSUES CLOSED(可选)。 例如: #31, #34:\n",
confirmCommit: "确认提交?",
},
// 设置只有 type 选择了 feat 或 fix,才询问 breaking message
allowBreakingChanges: ["feat", "fix"],
// 跳过要询问的步骤
// skipQuestions: ['body', 'footer'],
// subject 限制长度
subjectLimit: 100,
breaklineChar: "|", // 支持 body 和 footer
// footerPrefix : 'ISSUES CLOSED:'
// askForBreakingChangeFirst : true,
};
3. 使用
js
git add .
git cz
2.2 修改提交人
yml
# 设置全局
$ git config --global user.name "Author Name"
$ git config --global user.email "Author Email"
# 或者设置本地项目库配置
$ git config user.name "Author Name"
$ git config user.email "Author Email"
yml
# OLD_EMAIL 为历史邮箱,无需name,用邮箱搜索内容
# CORRECT_NAME,CORRECT_EMAIL 为希望修改后提交人和提交邮箱
# 执行完成用git log查看就变了
$ git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
3 统计代码行数
js
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t";
git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -;
done
加上时间范围:
js
git log --format='%aN' | sort -u | while read name; do echo -en "$name\t";
git log --author="$name" --after="2023-04-01" --before="2023-04-30" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -;
done
4 github 贡献
github 没有贡献?
4.1 会被记录的 Contribution 情形
- Issues and pull requests
-
同时满足以下两个条件将会被计入 Contribution
-
这个操作是在一年之内。(Calendar 只显示一年之内的 Contribution)
-
这个操作是针对一个独立的仓库。(在 Fork 的仓库中进行的操作不会被记录)
- Commits
-
同时满足以下四个条件将会被计入 Contribution
-
Commits 是在一年之内。(Calendar 只显示一年之内的 Contribution)
-
进行 Commits 的用户被关联到了你的 Github 帐号中(使用 SSH 方式能够不输入帐号密码进行 push,如果此时你 Commit 的帐号不在 Github 帐号列表中,就不会被计入 Contribution)
-
是在一个独立的版本库中进行 Commit。(在 Fork 的仓库中进行 Commit 则不会被记录)
-
是在这个版本库的默认分支(通常是 Master)进行的 Commit。(如果你在 Dev 分支下进行开发,你的 Commit 不会被计入 Contribution,但是并不会丢失它们,一旦当你 Merge 到 Master 分支后,所有的 Commit 都会被重新计入。多人协作也是同理,只有被并入 Master 分支的 Commit 才会被计入,如果你的 Commit 在合并时被组长丢弃,在 Github 看来,你就白干了......)
- 附加条件:如果你 Commit 的仓库不是你创建的,那么至少要满足以下四条之一,才会被计入 Contribution
- 你是这个仓库的协作者,或者是这个版本库的拥有组织中的一员。
- 你 fork 过这个仓库。
- 你对这个仓库发起过 pull request 或者 issue。
- 你对这个仓库标记了 Star。
- (私有仓库的 Commit 也会被计入 Contribution,没有这个私有仓库权限的用户将看不到这个 Commit 的跳转链接)
4.2 Contributions 未被 Github 计入的几个常见原因
- 进行 Commits 的用户没有被关联到你的 Github 帐号中。
- 不是在这个版本库的默认分支进行的 Commit。
- 这个仓库是一个 Fork 仓库,而不是独立仓库。