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 仓库,而不是独立仓库。
相关推荐
会讲英语的码农36 分钟前
Git项目管理
gitee·github
油泼辣子多加2 小时前
2024年11月21日Github流行趋势
github
A洛2 小时前
Vercel 设置自动部署 GitHub 项目
github·webhooks·自动部署·vercel
油泼辣子多加3 小时前
2024年11月22日Github流行趋势
github
和你一起去月球6 小时前
TypeScript - 函数(下)
javascript·git·typescript
我不是程序猿儿7 小时前
【GIT】TortoiseGit的变基(Rebase)操作
git
yyycqupt13 小时前
git使用(一)
git
Kkooe17 小时前
GitLab|数据迁移
运维·服务器·git
Beekeeper&&P...18 小时前
git bash是什么,git是什么,git中的暂存区是什么,git中的本地仓库是什么,git中工作目录指的是什么
开发语言·git·bash