Git 高级语法

Git 高级语法

1 gitignore

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件的模式。

要养成一开始就为你的新仓库设置好 .gitignore 文件的习惯,以免将来误提交这类无用的文件。

文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。相等于注释。

  • 匹配模式可以/开头防止递归。

  • 匹配模式可以/结尾指定目录。

  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号!取反。

  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。

    • 所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。
    • 问号?只匹配一个任意字符
    • 星号*匹配零个或多个任意字符
    • [abc] 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);
    • 如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
    • 使用两个星号**表示匹配任意中间目录,比如 a/**/z 可以匹配 a/za/b/za/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 目录,以及自动生成的文档等等。

Git 忽略文件.gitignore 详解

如果之前已经提交过某个需要忽略文件夹,需要执行以下命令行

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 修改提交人

git 命令修改代码提交人

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 情形

  1. Issues and pull requests
  • 同时满足以下两个条件将会被计入 Contribution

  • 这个操作是在一年之内。(Calendar 只显示一年之内的 Contribution)

  • 这个操作是针对一个独立的仓库。(在 Fork 的仓库中进行的操作不会被记录)

  1. 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 看来,你就白干了......)

  1. 附加条件:如果你 Commit 的仓库不是你创建的,那么至少要满足以下四条之一,才会被计入 Contribution
  • 你是这个仓库的协作者,或者是这个版本库的拥有组织中的一员。
  • 你 fork 过这个仓库。
  • 你对这个仓库发起过 pull request 或者 issue。
  • 你对这个仓库标记了 Star。
  • (私有仓库的 Commit 也会被计入 Contribution,没有这个私有仓库权限的用户将看不到这个 Commit 的跳转链接)

4.2 Contributions 未被 Github 计入的几个常见原因

  • 进行 Commits 的用户没有被关联到你的 Github 帐号中。
  • 不是在这个版本库的默认分支进行的 Commit。
  • 这个仓库是一个 Fork 仓库,而不是独立仓库。
相关推荐
程序媛Dev3 小时前
50.4k Star!我用这个神器,在五分钟内搭建了一个私有 Git 服务器!
运维·服务器·git
老马啸西风4 小时前
v0.29.1 敏感词性能优化之内部类+迭代器内部类
性能优化·开源·nlp·github·敏感词
杨杨杨大侠5 小时前
第5章:实现Spring Boot集成
java·github·eventbus
杨杨杨大侠5 小时前
第6章:高级特性与性能优化
java·github·eventbus
澈轩6 小时前
Git 用得好,下班走得早
git
HelloGitHub6 小时前
这款开源调研系统越来越“懂事”了
前端·开源·github
ruanCat6 小时前
配置 github workflow 工作流文件,实现仓库自动更新 github page 站点
github
绝无仅有7 小时前
面试总结之Nginx 经验常见问题汇总第二篇
后端·面试·github
绝无仅有7 小时前
面试实战总结之Nginx配置经验第一篇
后端·面试·github
掘金安东尼7 小时前
Chrome 17 岁了——我们的浏览器简史
前端·javascript·github