Git配置

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
  • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
  • 当前项目的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前项目有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

配置用户信息

1
2
$ git config --global user.name "you_name"
$ git config --global user.email you_email

如果用了 –global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。

如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 –global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。

编辑git配置文件 git config

1
$ git config -e    			 # 针对当前仓库

image-20230609212037277

1
$ git config -e --global	  # 针对系统上所有仓库

image-20230609212104306

查看配置信息 git config --list

1
$ git config --list

image-20230609212207535

查询指定某个信息(查看用户名称)

1
$ git config user.name

Git对仓库进行克隆(下载)git clone

克隆仓库的命令格式为:

1
$ git clone <repo>

如果我们需要克隆到指定的目录,可以使用以下命令格式:

1
$ git clone <repo> <directory>

参数说明:

  • **repo:**Git 仓库。
  • **directory:**本地目录。

Git创建仓库(初始化) git init

当前目录下创建

1
$ git init

在当前目录下z创建hongpeng_code文件夹并在其中创建 .git

1
$ git init zhongpeng_code

Git将文件添加到暂存区 git add

多文件添加

1
$ git add [file1] [file2]

添加目录

1
$ git add [dir]

添加当前目录下的所有文件

1
$ git add .

Git查看上次提交之后是否对文件进行再次修改 git status

1
$ git status

使用 -s 参数来获得简短的输出结果

1
$ git status -s

AM 状态的意思是这个文件在我们将它添加到缓存之后又有改动。

Git比较文件的不同(暂存取与工作区的差异) git diff

git diff 有两个主要的应用场景。

  • 尚未缓存的改动:git diff
  • 查看已缓存的改动: git diff –cached
  • 查看已缓存的与未缓存的所有改动:git diff HEAD
  • 显示摘要而非整个 diff:git diff –stat

显示暂存区和工作区的差异:

1
$ git diff [file]

显示暂存区和上一次提交(commit)的差异:

1
2
3
$ git diff --cached [file]

$ git diff --staged [file]

显示两次提交之间的差异:

1
$ git diff [first-branch]...[second-branch]

Git将暂存区内容添加到本地仓库 git commit

-m添加注释

1
$ git commit -m "我的注释"

提交暂存区的指定文件到仓库 git commit [file1] [file2] ... -m [message]

1
$ git commit [file1] [file2] ... -m [message]

在不add的情况下将文件添加到仓库 git commit -a

-a 参数设置修改文件后不需要执行 git add 命令,直接来提交

1
$ git commit -a

Git上次添加到本地仓库 进行修改commit信息 git commit --amend

1
2
3
4
5
6
7
8
# 修改最近提交的 commit 信息
$ git commit --amend --message="modify message by test" --author="YuKiFuHaNe <915228208@qq.com>"

# 仅修改 message 信息
$ git commit --amend --message="modify message by test"

# 仅修改 author 信息
$ git commit --amend --author="YuKiFuHaNe <915228208@qq.com>"

修改历史提交 commit 的信息

操作步骤:

  • git rebase -i 列出 commit 列表

  • 找到需要修改的 commit 记录,把 pick 修改为 edite:wq 保存退出

  • 修改 commit 的具体信息git commit --amend,保存并继续下一条git rebase --continue,直到全部完成

  • 中间也可跳过或退出git rebase (--skip | --abort)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 列出 rebase 的 commit 列表,不包含 <commit id>
    $ git rebase -i <commit id>
    # 最近 3 条
    $ git rebase -i HEAD~3
    # 本地仓库没 push 到远程仓库的 commit 信息
    $ git rebase -i

    # vi 下,找到需要修改的 commit 记录,```pick``` 修改为 ```edit``` 或 ```e```,```:wq``` 保存退出
    # 重复执行如下命令直到完成
    $ git commit --amend --message="modify message by test" --author="YuKiFuHaNe <915228208@qq.com>"
    $ git rebase --continue

    # 中间也可跳过或退出 rebase 模式
    $ git rebase --skip
    $ git rebase --abort

Git回退版本 git reset

1
$ git reset [--soft | --mixed | --hard] [HEAD]

–soft 参数用于回退到某个版本:

–mixed 为默认,可以不用带该参数,用于重置暂存区的文件与上一次的提交(commit)保持一致,工作区文件内容保持不变。

–hard 参数撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交:

**注意:**谨慎使用 –-hard 参数,它会删除回退点之前的所有信息。

指定回退版本

1
2
$ git reset HEAD^            # 回退所有内容到上一个版本   
$ git reset --soft HEAD~3 # 回退上上上一个版本

指定文件回退

1
$ git reset HEAD^ my.py      # 回退my.py文件的版本到上一个版本

撤销工作区中所有未提交的修改内容,将暂存区与工作区都回到上一次版本,并删除之前的所有信息提交

1
git reset --hard HEAD

HEAD 说明:

  • HEAD 表示当前版本

  • HEAD^ 上一个版本

  • HEAD^^ 上上一个版本

  • HEAD^^^ 上上上一个版本

  • 以此类推…

可以使用 ~数字表示

  • HEAD~0 表示当前版本
  • HEAD~1 上一个版本
  • HEAD^2 上上一个版本
  • HEAD^3 上上上一个版本
  • 以此类推…

Git删除文件 git rm

将文件从本地和暂存区删除 git rm <file> 谨慎使用

1
$ git rm <file>

如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f

1
$ git rm -f <file>

只删除暂存区的文件 git rm --cached <file>

1
$ git rm --cached <file>

Git移动、重命名文件、目录或软连接 git mv

1
$ git mv <file> <newfile>

如果新文件名已经存在,但还是要重命名它,可以使用 -f 参数:

1
$ git mv -f <file> <newfile>

Git查看提交历史 git log

全部提交记录 git log

1
$ git log

--oneline查看记录的简洁版本 git log --oneline

1
$ git log --oneline

--graph查看历史中什么时候出现了分支、合并 git log --graph

1
$ git log --graph

--author查看指定用户的提交日志 git log --author

查看zhongpeng用户已简洁版本后5行

1
$ git log --author=zhongpeng --oneline -5

Git查看操作(删除移除等)日志 git reflog

1
$ git reflog

image-20240225224851079

该日志仅保留在本地

1
2
3
4
5
6
7
git reflog [show] [<log-options>] [<ref>]
git reflog expire [--expire=<time>] [--expire-unreachable=<time>]
[--rewrite] [--updateref] [--stale-fix]
[--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>…]
git reflog delete [--rewrite] [--updateref]
[--dry-run | -n] [--verbose] <ref>@{<specifier>}…
git reflog exists <ref>

查看指定范围的日志 --since ~ --until--before ~ --after

Git 项目中三周前且在四月十八日之后的所有提交

1
$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges

merges 选项以隐藏合并提交

Git以列表形式查看修改、提交历史 git blame <file>

查看指定文件的修改记录

1
$ git blame <file>

Git远程仓库操作 git remote

显示所有远程仓库 git remote -v

1
$ git remote -v

显示某个远程仓库信息 git remote show

1
$ git remote show 仓库地址

添加远程版本库 git remote add

1
$ git remote add <shortname> <url>

shortname:本地的版本库

1
2
3
# 提交到 Github
$ git remote add origin git@github.com*****/*****-test.git
$ git push -u origin master

删除远程仓库 git remote rm

1
$ git remote rm <name>

修改远程仓库名称 git remote rename

1
$ git remote rename <old_name> <new_name>

Git远程获取代码库 git fetch

1
$ git fetch [alias]				# 将远程代码库同步到本地
1
$ git merge [alias]/[branch] 	 # 从远端仓库提取数据并尝试合并到当前分支  
1
2
3
4
5
6
7
8
9
10
# 方法一
$ git fetch origin master #从远程的origin仓库的master分支下载代码到本地的origin maste
$ git log -p master.. origin/master #比较本地的仓库和远程参考的区别
$ git merge origin/master #把远程下载下来的代码合并到本地仓库,远程的和本地的合并

# 方法二
$ git fetch origin master:temp #从远程的origin仓库的master分支下载到本地并新建一个分支temp
$ git diff temp #比较master分支和temp分支的不同
$ git merge temp #合并temp分支到master分支
$ git branch -d temp #删除temp

alias:别名

下载远程代码并合并 git pull

git fetchgit merge FETCH_HEAD 的简写

1
2
3
4
5
6
7
8
$ git pull
$ git pull origin
将远程主机 origin 的 master 分支拉取过来,与本地的 brantest 分支合并。

$ git pull origin master:brantest
如果远程分支是与当前分支合并,则冒号后面的部分可以省略。

$ git pull origin master

上传远程代码并合并 git push

1
2
$ git push <远程主机名> <本地分支名>:<远程分支名>如果本地分支名与远程分支名相同,则可以省略冒号:
$ git push <远程主机名> <本地分支名>

上传远程代码并合并 git push

git push 命令用于从将本地的分支版本上传到远程并合并。

命令格式如下:

1
$ git push <远程主机名> <本地分支名>:<远程分支名>

如果本地分支名与远程分支名相同,则可以省略冒号:

1
$ git push <远程主机名> <本地分支名>

以下命令将本地的 master 分支推送到 origin 主机的 master 分支。

1
$ git push origin master

相等于:

1
$ git push origin master:master

如果本地版本与远程版本有差异,但又要强制推送可以使用 –force 参数:

1
$ git push --force origin master

删除主机的分支可以使用 –delete 参数,以下命令表示删除 origin 主机的 master 分支:

1
$ git push origin --delete master

子模块(submodule) git submodule add <url> <repo_name>

初始化子模块 git submodule update

1
2
git submodule update --init --recursive
# 初始化子模块才能将数据同步,递归的初始化并下载子模块仓库的内容

更新子模块 git submodule update

1
git submodule update

更新子模块为远程项目的最新版本 git submodule update --remote

1
git submodule update --remote

下载主仓库的所有项目内容 git clone --recursive

1
2
git clone --recursive <project url>
# 第一次使用 git clone 下载主仓库的所有项目内容的话
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
## 删除子模块

# 删除子模块文件夹
$ git rm --cached <repo_name>

# 删除 .gitmodules 文件中相关子模块的信息类似于
[submodule "repo_name"]
path = repo_name
url = https://github.com/author/GWToolkit.git

# 删除 .git/config 中相关子模块信息 ,如果对子模块有自己的更改或提交就会有这个
[submodule "repo_name"]
url = https://github.com/author/repo_name.git
active = true

# 删除 .git 文件夹中的相关子模块文件
$ rm -rf .git/modules/GWToolkit

子树(subtree) git subtree 将一个项目的子目录作为独立的Git仓库处理

添加子树 git subtree add

1
2
$ git subtree add --prefix=<subtree-directory> <remote-url> <branch> --squash
# <subtree-directory>是子树在当前仓库中的目录,<remote-url>是远程仓库的URL,<branch>是要添加的远程分支, --squash选项用于将子树的历史压缩成一个提交

拉取子树的更新 git subtree pull

1
2
$ git subtree pull --prefix=<subtree-directory> <remote-url> <branch> --squash
# 从远程仓库的指定分支拉取更新,并将它们合并到子树目录中

推送子树的更改 git subtree push

1
2
$ git subtree push --prefix=<subtree-directory> <remote-url> <branch> --squash
# 这将把子树目录中的更改推送到远程仓库的指定分支

分割子树 git subtree split

1
2
$ git subtree split --prefix=<subtree-directory> --branch=<new-branch>
# 这将创建一个新的分支,其中只包含子树目录的历史记录

典型使用场景

git subtree splitgit subtree命令的一个子命令,用于将一个子树(子目录)从当前仓库中分离出来,创建一个新的分支,其中只包含子树的历史记录。这在将子树转移到一个独立的仓库或将其与其他仓库合并时非常有用。

以下是git subtree split的详细用法:

1
subtree split --prefix=<subtree-directory> --branch=<new-branch> [--annotate=<annotation>] [--rejoin] [--onto=<commit>]
  • <subtree-directory>:要分离的子树目录。
  • <new-branch>:新创建的分支名称,其中包含子树的历史记录。
  • --annotate=<annotation>(可选):为分离的提交添加注释。这有助于在将来识别子树的来源。
  • --rejoin(可选):在分离子树后,将其重新连接到主仓库。这样,您可以继续在主仓库中跟踪子树的更改。
  • --onto=<commit>(可选):将子树的历史记录重新定位到指定的提交。这在将子树合并到另一个仓库时非常有用。

典型的使用场景:

  1. 将子树转移到独立仓库:

    如果您有一个包含多个项目的仓库,但现在希望将其中一个项目转移到一个独立的仓库,可以使用git subtree split命令。首先,使用git subtree split创建一个新分支,其中只包含子树的历史记录。然后,将新分支推送到新仓库。

  2. 将子树与其他仓库合并:

    如果您有两个仓库,希望将其中一个仓库的子目录合并到另一个仓库中,可以使用git subtree split命令。首先,在源仓库中使用git subtree split创建一个新分支,其中只包含子树的历史记录。然后,在目标仓库中使用

    git fetch获取新分支,并使用git merge将其合并到目标仓库。

  3. 从独立仓库中提取子项目:

    如果您有一个独立的仓库,其中包含多个子项目,您可以使用git subtree split将这些子项目分离出来,以便在其他仓库中使用。这样,您可以更轻松地在多个仓库之间共享和重用代码。

    假设我们有一个名为``main-repo的Git仓库,其中包含一个名为subproject的子目录。我们希望将subproject`

    分离出来,并将其转移到一个名为subproject-repo的新仓库。以下是如何使用git subtree split完成此操作的示例:

    • 首先,在main-repo中使用git subtree split创建一个新分支,其中只包含subproject的历史记录:
    1
    2
    $ cd main-repo
    $ git subtree split --prefix=subproject --branch=subproject-branch

    这将创建一个名为subproject-branch的新分支,其中包含subproject目录的历史记录。

    • 将新分支推送到新仓库:

    首先,创建一个名为subproject-repo的新仓库。然后,在main-repo中将subproject-branch

    推送到新仓库:

    git push <subproject-repo-url> subproject-branch:main

    其中,<subproject-repo-url>是新仓库的URL。这将把subproject-branch推送到新仓库的main分支。

    • 现在,subproject-repo已经包含了subproject的历史记录。您可以将其克隆到本地,并开始在新仓库中独立地开发和维护subproject
    1
    2
    $ git clone <subproject-repo-url>
    $ cd subproject-repo

    这个示例展示了如何使用git subtree split将一个子目录从现有仓库中分离出来,并将其转移到一个新的独立仓库。

    3、分离后协同主项目开发

    ·git subtree split·将子目录分离到新仓库后,您仍然可以在主项目中继续开发子项目。为了在主项目和新仓库之间保持同步,您可以使用git subtree pullgit subtree push命令。

    以下是如何在主项目和新仓库之间保持同步的示例:

    1. 在主项目中开发子项目:

      在主项目的subproject目录中进行开发和提交更改。

    2. 将更改推送到新仓库:

      当您准备将更改推送到新仓库时,使用git subtree push命令:

    git subtree push --prefix=subproject <subproject-repo-url> main

    这将把subproject目录中的更改推送到新仓库的main分支。

    • 从新仓库拉取更新:

    如果在新仓库中进行了开发,您可以使用git subtree pull命令将更新拉取到主项目中:

    git subtree pull --prefix=subproject <subproject-repo-url> main

    这将从新仓库的main分支拉取更新,并将它们合并到主项目的subproject目录中。

    通过这种方式,您可以在主项目和新仓库之间保持子项目的同步,从而实现协同开发。请注意,为了避免冲突和合并问题,建议在主项目和新仓库之间保持良好的沟通,并确保团队成员了解他们应该在哪个仓库中进行开发。

    • 要避免在主项目中修改subtree子项目后提交中携带了主项目的修改日志:

      可以使用git add命令仅将子项目的更改添加到暂存区,然后进行提交。这样,提交将仅包含子项目的更改,而不会包含主项目的其他更改。

      以下是如何仅提交子项目更改的示例:

      1. 在主项目中修改子项目(例如subproject)。使用git add命令仅将子项目的更改添加到暂存区:

      git add subproject/这将仅将subproject目录中的更改添加到暂存区,而不会添加主项目的其他更改。

      1. 提交子项目的更改:

        git commit -m "Update subproject"这将创建一个新的提交,其中仅包含子项目的更改。通过这种方式,您可以确保提交中仅包含子项目的更改,而不会携带主项目的修改日志。当然,在推送子项目的更改到新仓库时,仍然需要使用git subtree push命令。

Git 仓库浏览器 gitk

gitk documents

image-20250616105539518

GIthub

本地 Git 仓库和 GitHub 仓库之间的传输是通过SSH加密的,所以我们需要配置验证信息:

1
$ ssh-keygen -t rsa -C "youEail"

image-20230611114052472

image-20230611114432344

  • -t:指定密钥类型,可以使用RSA、DSA、ECDSA、ED25519等。
  • -b:指定密钥长度,可以使用1024、2048、3072、4096等,默认为2048。
  • -C:添加注释,用于标识该密钥的用途或所属人等。
  • -f:指定保存密钥文件的路径和文件名,默认为/.ssh/id_rsa或/.ssh/id_dsa等。
  • -N:设置密钥密码,用于保护密钥的安全性。
  • -P:修改已有密钥的密码,使用该选项需要先指定已有密钥文件的路径和文件名。
  • -q:静默模式,不输出任何信息,常用于批量生成密钥。
  • -i:将已有的密钥文件转换为OpenSSH格式。
  • -e:将OpenSSH格式的密钥文件转换为其他格式,如PKCS#8格式等。

LFS大文件

GitHub 阻止大小超过 100 MiB 的文件,要跟踪超出此限制的文件,必须使用 Git Large File Storage (Git LFS),下面是Github大文件

产品 文件大小上限
GitHub Free 2 GB
GitHub Pro 2 GB
GitHub Team 4 GB
GitHub Enterprise Cloud 5 GB

Git Large File Storage 的帐户都会获得 1 GiB 的免费存储空间和一个月的免费带宽 1 GiB

什么时候需要 Git LFS

如果你在命令行用 git push 添加或更新 $>$ 50MB 的文件,你会收到一个 warning,不过你仍然可以正常 push。但如果 $>$ 100MB 的时候就无法 push 了。如果你是在浏览器要上传文件的话,这个限制更为严重,不能超过 25MB,这是 GitHub 对仓库的限制。Git LFS 就是用于解决这个问题1

什么时候不需要用 Git LFS

下面几个场景不需要用

  1. 文件大小没有超过限制当然就没有必要用了
  2. 如果是要分发二进制文件(比如 \*.exe)等,此时直接用 GitHub 提供的 release 功能就好了

安装Git Large File Storage

导航到git-lfs.com并单击下载

1
2
3
## 验证安装是否成功
$ git lfs install
> Git LFS initialized.

配置 Git 大文件存储

1
2
3
4
5
6
7
8
9
10
11
12
## 关联.psd文件
$ git lfs track "*.psd"
> Tracking "*.psd"
## 将关联的扩展名匹配的文件添加到存储库
$ git add path/to/file.psd
## 提交文件并将其推送到 GitHub
$ git commit -m "add file.psd"
$ git push
> Sending file.psd
> 44.74 MB / 81.04 MB 55.21 % 14s
> 64.74 MB / 81.04 MB 79.21 % 3s

删除单个文件

  1. 使用 filter-repo 命令从仓库的 Git 历史记录中删除文件。 有关使用它们的详细信息,请参阅“从存储库中删除敏感数据”。

  2. 导航到 .gitattributes 文件。

    注意

    .gitattributes 文件通常保存在本地存储库中。 在某些情况下,你可能已创建包含所有 Git LFS 关联的全局 .gitattributes 文件。

  3. 找到并删除 .gitattributes 文件内关联的 Git LFS 跟踪规则。

  4. 保存并退出 .gitattributes 文件。

删除 Git LFS 仓库内的所有文件

  1. (可选)要卸载仓库中的 Git LFS,请运行:

    1
    $ git lfs uninstall

    对于 1.1.0 以下的 Git LFS 版本,运行:

    1
    $ git lfs uninit

追踪的大文件之前不小心加到 Git 仓库里了

此时只是简单使用 git lfs track ... 追踪大文件是不够的,因为这个大文件已经存在 Git 仓库的历史记录里,这会导致 Git 仓库无法变小。正确的方法是使用 git lfs migrate,将 Git 历史的大文件变成 Git LFS 追踪的对象比如可以用 --include=,Git LFS 会自动根据我们指定的模式进行选择。下面的 --include="*.txt 的意思就是选中 Git 仓库历史的 txt 文件,可以用 man git-lfs-migrate 查看更多信息

1
2
3
4
$ git lfs migrate import --include="*.psd"

# 让远程仓库也改过来
$ git push --force

不再跟踪某些文件

1
2
$ git lfs untrack "*.psd"
$ git rm --cached "*.psd"

删除敏感数据

使用 git-filter-repo 从本地存储库的历史记录中清除文件

  1. 安装该git-filter-repo工具的最新版本。您需要一个带有 标志的版本--sensitive-data-removal,即至少 2.47 版本。您可以git-filter-repo手动安装,也可以使用包管理器安装。例如,要使用 HomeBrew 安装该工具,请使用以下brew install命令。

    1
    $ brew install git-filter-repo

    有关更多信息,请参阅存储库中的INSTALL.mdnewren/git-filter-repo

  2. 将仓库克隆到本地计算机。请参阅克隆仓库

    1
    $ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
  3. 导航到存储库的工作目录。

    1
    $ cd YOUR-REPOSITORY
  4. 运行git-filter-repo命令来清理敏感数据。

    如果要从所有分支/标签/引用中删除特定文件,请运行以下命令,并将其替换PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA要删除的文件的 git 路径,而不仅仅是其文件名(例如src/module/phone-numbers.txt):

    1
    $ git-filter-repo --sensitive-data-removal --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA

    重要的

    如果包含敏感数据的文件曾经存在于任何其他路径(因为它已被移动或重命名),则必须--path为该文件添加额外的参数,或者再次运行此命令并命名备用路径。

    如果您想要替换../passwords.txt存储库历史记录中任何位置找到的任何非二进制文件中列出的所有文本,请运行以下命令:

    1
    $ git-filter-repo --sensitive-data-removal --replace-text ../passwords.txt
  5. 仔细检查您是否已从存储库历史记录中删除了所有您想要删除的内容。

  6. 了解此次历史记录重写将对多少拉取请求产生不利影响。您将需要以下信息。

    1
    $ grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refs

    您可以删除-c以查看哪些拉取请求受到影响:

    1
    2
    3
    4
    5
    $ grep '^refs/pull/.*/head$' .git/filter-repo/changed-refs
    refs/pull/589/head
    refs/pull/602/head
    refs/pull/604/head
    refs/pull/605/head

    此输出包含第二和第三个斜杠之间的拉取请求编号。如果受影响的拉取请求数量超出预期,您可以丢弃此克隆,而不会产生任何不良影响,然后重新执行重写或放弃敏感数据删除。一旦您进入下一步,重写将不可逆。

  7. 对仓库状态满意后,请强制推送本地更改,以覆盖 GitHub.com 上的仓库。虽然--force暗示了这一点--mirror,但我们在下方添加了它,以提醒您强制更新所有分支、标签和引用,并丢弃在您清理仓库期间其他人可能对这些引用所做的任何更改。

    1
    $ git push --force --mirror origin

    此命令将无法推送任何以 开头的引用refs/pull/,因为 GitHub 将这些引用标记为只读。这些推送失败的情况将在下一节中处理。如果任何其他引用推送失败,则可能是您为该分支启用了分支保护,需要暂时关闭它并重新推送。重复此操作,直到更新失败的引用全部以 开头refs/pull/

从 GitHub 彻底删除数据

使用git-filter-repo删除敏感数据并将更改推送到 GitHub 后,您必须采取更多步骤才能从 GitHub 中完全删除数据。

  1. 通过GitHub 支持门户联系我们,并提供以下信息:

    • 所涉及的所有者和存储库名称(例如 YOUR-USERNAME/YOUR-REPOSITORY)。
    • 上一步中发现的受影响拉取请求数量。支持团队会使用此信息来确认您是否了解受影响的程度。
    • 报告的第一个更改的提交git-filter-repo(在其输出中查找NOTE: First Changed Commit(s)。)
    • 如果NOTE: There were LFS Objects Orphaned by this rewrite出现在 git-filter-repo 输出中(紧接着第一次更改提交之后),则说明您有 LFS Objects Orphaned,并将命名文件也上传到票证。

    如果您已成功清理除 PR 之外的所有引用,并且没有任何分支引用敏感数据,则支持人员将:

    • 取消引用或删除 GitHub 上任何受影响的 PR。
    • 在服务器上运行垃圾收集以从存储中删除敏感数据。
    • 删除缓存的视图。
    • 如果涉及 LFS 对象,请删除和/或清除孤立的 LFS 对象。

    重要的

    GitHub 支持不会删除非敏感数据,并且仅在我们确定无法通过轮换受影响的凭据来降低风险的情况下才会协助删除敏感数据。

  2. 协作者必须对基于您旧的(已污染的)仓库历史记录创建的任何分支进行变基(rebase ),而不是合并。一次合并提交可能会重新引入您刚刚费尽心思清除的部分或全部已污染的历史记录。他们可能还需要采取其他措施;请参阅手册中的“确保其他副本已清理:同事的克隆”git-filter-repo

避免将来发生意外提交

防止贡献者意外提交有助于防止敏感信息泄露。更多信息,请参阅防止组织数据泄露的最佳实践

您可以采取一些措施来避免提交或推送不应共享的内容:

  • 如果敏感数据可能存在于不应由 git 跟踪的文件中,请将该文件名添加到.gitignore(并确保提交并推送该更改,.gitignore以便保护其他开发人员)。
  • 避免在代码中硬编码机密。使用环境变量或机密管理服务(例如 Azure Key Vault、AWS Secrets Manager 或 HashiCorp Vault)在运行时管理和注入机密。
  • 创建一个预提交钩子,在提交或推送到任何地方之前检查敏感数据,或者在预提交钩子中使用一些知名工具,例如 git-secrets 或 gitleaks。(请务必要求每位协作者设置您选择的预提交钩子。)
  • 使用GitHub Desktopgitk等可视化程序提交更改。可视化程序通常可以更轻松地查看每次提交时添加、删除和修改的文件。
  • 避免在命令行上使用catch-all 命令git add .和- 而是使用和单独暂存文件。git commit -a``git add filename``git rm filename
  • 用于git add --interactive单独审查和暂存每个文件中的更改。
  • 用于git diff --cached检查已暂存待提交的更改。git commit只要您未使用此-a标志,就会生成精确的差异。
  • 为您的代码库启用推送保护,以检测并阻止包含硬编码机密的推送提交到您的代码库。更多信息,请参阅关于推送保护

从存储库中删除敏感数据涉及四个高级步骤:

  • 使用 git-filter-repo 在本地重写存储库
  • 使用本地重写的历史记录更新 GitHub 上的存储库
  • 与同事协调清理其他存在的克隆
  • 防止重复并避免未来敏感数据泄露

开启警惕模式(可选)

打开一种称为**警惕模式**的东西,在该模式下我们可以显示所有 git 提交的验证状态。
image-20250617094517538

image-20250617094401563

配置用户签名信息 (Github关于提交签名验证

GitHub添加签名

image-20250614214505458

SSH签名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
### Navigate to cloned repo root for individual repos ###
### Configure name ###
$ git config user.name "Your_User_Name"

### Configure email (same as what was specified in SSH key gen) ###
$ git config user.email "your_email@example.com"

### set your SSH signing key in Git, paste the text below, substituting /PATH/TO/.SSH/KEY.PUB ###
$ git config user.signingkey "/PATH/TO/.SSH/KEY.PUB"

### Enable/Enforce commit signing ###
$ git config commit.gpgsign true

### Configure commit signing format ###
$ git config gpg.format ssh

全局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
### Global signing on all repos ###
### Configure name ###
$ git config --global user.name "Your_User_Name"

### Configure email (same as what was specified in SSH key gen) ###
$ git config --global user.email "your_email@example.com"

### Configure Git to use SSH to sign commits and tags
git config --global gpg.format ssh

### set your SSH signing key in Git, paste the text below, substituting /PATH/TO/.SSH/Sign_KEY.PUB ###
$ git config --global user.signingkey "/PATH/TO/.SSH/Sign_KEY.PUB"

### Enable/Enforce commit signing else you need committing changes in your local branch, add the -S flag to the git commit command `git commit -S -m "YOUR_COMMIT_MESSAGE"`###
$ git config --global commit.gpgsign true

image-20250614200106424

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git log --show-signature -1
error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification
commit ******************************* (HEAD -> main)
No signature
Author: YuKiFuHaNe <915228208@qq.com>
Date: Sat Jun 14 20:16:49 2025 +0800

Update Git.md

- Add SSH GPG sign
- format all bash code blocks

Signed-off-by: YuKiFuHaNe <915228208@qq.com>

image-20250614214939756

显示没有签名不影响,这个是本地认证的,当然你也可以配置好本地就不会出现了通过配置#34387

1
2
3
$ cat /PATH/TO/.SSH/Sign_KEY.PUB > /PATH/TO/.SSH/allowed_signers
# 然后编辑allowed_signers格式是<邮箱> <密钥类型> <公钥>
$ git config --global gpg.ssh.allowedSignersFile " /PATH/TO/.SSH/allowed_signers"

image-20250614220005152

1
2
3
4
5
6
7
8
9
10
11
12
$ git log --show-signature -1
commit ********************************* (HEAD -> main)
Good "git" signature for 915228208@qq.com with ED25519 key SHA256:******************************************************
Author: YuKiFuHaNe <915228208@qq.com>
Date: Sat Jun 14 20:16:49 2025 +0800

Update Git.md

- Add SSH GPG sign
- format all bash code blocks

Signed-off-by: YuKiFuHaNe <915228208@qq.com>

image-20250614215015372

GPG签名

生成新的 GPG 密钥

1
$ gpg --full-generate-key
1
2
# 如果使用的不是 2.1.17 或更高版本  `gpg --full-generate-key` 命令无效,使用下面这个
$ gpg --default-new-key-algo rsa4096 --gen-key

当系统要求输入您的电子邮件地址时,请确保输入您 GitHub 帐户中已验证的电子邮件地址。为了保护您的电子邮件地址的私密性,请使用 GitHub 提供的no-reply电子邮件地址。有关更多信息,请参阅验证您的电子邮件地址设置提交电子邮件地址

使用此gpg --list-secret-keys --keyid-format=long命令列出您拥有公钥和私钥的 GPG 密钥的长格式。签署提交或标签时需要私钥。本例中,GPG 密钥 ID 为1DBE5B4FC75D6BF2

1
$ gpg --list-secret-keys --keyid-format=long

image-20250614193110182

粘贴以下文本,替换您想要使用的 GPG 密钥 ID。在此示例中,GPG 密钥 ID 为1DBE5B4FC75D6BF2,然后将GPG密钥添加到Github

1
2
$ gpg --armor --export 1DBE5B4FC75D6BF2
# Prints the GPG key ID, in ASCII armor format

image-20250614193245126

告诉Git你的GPG密钥

如果你之前配置 Git 使用不同的密钥格式来使用 --gpg-sign 进行签名,请取消此配置,以便使用 openpgp 的默认格式。

1
$ git config --global --unset gpg.format

使用 gpg --list-secret-keys --keyid-format=long 命令来列出你拥有公钥和私钥的 GPG 密钥的完整形式。私钥是用于签名提交或标签所必需的。GPG密钥ID为1DBE5B4FC75D6BF2然后将ID添加到git中

1
$ gpg --list-secret-keys --keyid-format=long

image-20250614193110182

1
$ git config --global user.signingkey 1DBE5B4FC75D6BF2

或者,使用一个子密钥。GPG 子密钥 ID 是 C7BA975838CE5DB9

1
$ git config --global user.signingkey C7BA975838CE5DB9 

可选地,要配置 Git 默认对所有提交和标签进行签名,可以输入以下命令

1
2
$ git config --global commit.gpgsign true
$ git config --global tag.gpgSign true

签名标签

为标签签名,在 git tag 命令中添加 -s

1
2
$ git tag -s MYTAG
# Creates a signed tag

通过运行 git tag -v [tag-name] 验证您的已签名标签

1
2
$ git tag -v MYTAG
# Verifies the signed tag

签名提交 gpgsign 与 signoff

image-20250615000506469

设置别名git config --global alias.cm 'commit --signoff

image-20250916143640607

Screenshots_2025-06-15_00-07-18

特性 --signoff (-s) -S(GPG/SSH 签名)
类型 纯文本声明 加密签名(密码学验证)
可见性 提交消息中的文本行 隐藏的二进制签名(git log --show-signature 查看)
目的 法律/流程合规(如 DCO) 身份认证(防伪造)
验证方式 人工检查或脚本匹配 Signed-off-by Git 自动验证密钥有效性
典型用户 开源贡献者 需要高安全性的项目

git commit --amend --no-edit --signoff (-s)

  • 作用:在提交消息末尾 添加一行 Signed-off-by 文本(法律声明)。

  • 用途:主要用于开源项目(如 Linux 内核),表明贡献者遵守开发者证书(DCO)。

  • 示例输出

    1
    2
    3
    Fix login bug

    Signed-off-by: Your Name <your@email.com> # 新增的签名行

2. git commit --amend --no-edit -S

  • 作用用 GPG 或 SSH 密钥对提交进行加密签名(生成数字签名)。
  • 用途:验证提交的真实性(防篡改),GitHub/GitLab 会显示 “Verified” 徽章。
  • 要求:需提前配置 GPG 或 SSH 签名密钥)。

也可以通过模板配置问题进行配置

1
$ git config --global commit.template ~/.commit-message

模板示例文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# ------------------------ COMMIT MESSAGE TEMPLATE ------------------------

# Lines starting with '#' are comments and will be ignored.

# LINES SHOULD BE NO LONGER THAN THIS:

########################################################################

# <type>[optional scope]: <subject>

#

# [Optional body]

#

# [Optional footer(s)]

#

# -------------------------------------------------------------------------

# **Guidelines:**

# <type>: Short identifier of the change type (e.g., feat, fix, docs, style, refactor, test, chore).

# - **feat**: A new feature

# - **fix**: A bug fix

# - **docs**: Documentation changes

# - **style**: Code style updates (formatting, missing semicolons, etc.)

# - **refactor**: Code changes that neither fix a bug nor add a feature

# - **perf**: Performance improvements

# - **test**: Adding or updating tests

# - **chore**: Changes to the build process or auxiliary tools

# [optional scope]: A noun describing the section of the code affected (e.g., parser, API, backend).

# <subject>: A brief summary of the changes in present tense (not capitalized and no period at the end).

# - Use the imperative mood ("fix", not "fixed" or "fixes")

# - Keep it under 50 characters

# [Optional body]: More detailed explanatory text, if necessary.

# - Wrap text at 72 characters

# - Explain the what, why, and how

# - Use bullet points if helpful

# [Optional footer(s)]: Additional metadata.

# - Include references to issues, e.g., "Closes #123"

# - Mention breaking changes, e.g., "BREAKING CHANGE: description"

# - Include co-authors or reviewers

# Signed-off-by [You]

签名重新提交

方法 1:git commit --amend(适用于未推送的提交)

如果你的提交 尚未推送git push),可以修改最后一次提交并重新签名:

1
2
3
4
$ git commit --amend --no-edit -S
# 或者
$ git commit --amend --no-edit -s -S
## git commit --amend --no-edit --signoff

然后强制推送(如果已推送过)

1
$ git push --force-with-lease

方法 2:git rebase -i(适用于已推送的提交)

如果提交 已经推送,你可以用 rebase 修改历史记录:

  1. 交互式变基

    1
    $ git rebase -i HEAD~3  # 修改最近 3 个提交(可调整)
  2. 在编辑器里,把要修改的提交前的 pick 改成 edit(或 e),保存退出。

  3. 对每个 edit 的提交执行

    1
    2
    $ git commit --amend --no-edit -s -S  # 补签名
    $ git rebase --continue
  4. 强制推送

    (覆盖远程历史):

    1
    $ git push --force-with-lease

方法 3:git filter-branch(批量补签名)

如果要 批量修改多个提交,可以使用 filter-branch

1
2
3
$ git filter-branch --commit-filter '
git commit-tree -S "$@";
' HEAD

然后强制推送:

1
$ git push --force-with-lease

验证签名

检查是否成功补签:

1
$ git log --show-signature -1

添加远程仓库

1
$ git remote add [shortname] [url]

提取远程仓库

Git 有两个命令用来提取远程仓库的更新。

1、从远程仓库下载新分支与数据:

1
$ git fetch

该命令执行完后需要执行 git merge 远程分支到你所在的分支。

2、从远端仓库提取数据并尝试合并到当前分支:

1
$ git merge

推送到远程仓库

推送你的新分支与数据到某个远端仓库命令:

1
$ git push [alias] [branch]

以上命令将你的 [branch] 分支推送成为 [alias] 远程仓库上的 [branch] 分支

删除远程仓库

删除远程仓库你可以使用命令:

1
$ git remote rm [别名]

GIt高级用法

还原工作区(文件内容)

git checkout – <file_name> 丢弃工作区的修改,并用最近一次的commit内容还原到当前工作区(对文件中内容的操作,无法对添加文件、删除文件起作用)

git checkout HEAD^ – <file_name> 将指定commit提交的内容(HEAD^表示上一个版本)还原到当前工作区

git checkout <branch_name> – <file_name> 将指定分支的指定提交内容还原到当前分支工作区

git checkout . 清除工作区没add的文件修改

git checkout --orphan <branch_name> 创建一个空分支

代码回退

restore(恢复) 针对的是暂存区的恢复(重点理解)

1
2
3
4
5
## 将不在暂存区的文件"撤销"更改(回滚到修改前)
$ git restore [file]

## 将提交到暂存区的文件恢复到工作区
$ git restore --staged [file]

reset(重置) 针对的本地仓库的恢复 ``

1
2
3
4
5
6
7
$ git reset --hard [commit Id] # reset --hard 会在重置 HEAD 和branch的同时,重置stage区和工作目录里的内容。
$ 你的stage区和工作目录里的内容会被完全重置为和HEAD的新位置相同的内容。换句话说,就是期间的所有修改会被全部擦掉。
git reset --soft [commit Id] # reset --soft 会在重置 HEAD 和 branch 时,保留工作目录和暂存区中的内容,并把重置 HEAD 所带来的新的差异放进暂存区。
$ git reset --mixed(默认) [commit Id] # //git reset --hard HEAD 表示当前commit,作用也是工作区(删除)、暂存区(删除)、本地仓库(回滚)这种,和指向其它commit没什么区别
# 一般用这个命令,将写了半天的代码恢复到没写之前~.~,有没有发现和IDEA中的Rollback很像
# 没错Rollback的原理就是:git reset --hard HEAD
$ git reset --hard HEAD
1
$ git reset --hard origin  # 删除所有本地未push的commit. 包括未commit的代码

HEAD^ 的意思是上一个版本,也可以写成HEAD~1

如果你进行了2次commit,想都撤回,可以使用HEAD~2

  • –mixed
    意思是:不删除工作空间改动代码,撤销commit,并且撤销git add . 操作
    这个为默认参数,git reset --mixed HEAD^git reset HEAD^ 效果是一样的。
  • –soft
    不删除工作空间改动代码,撤销commit,不撤销git add。
  • –hard
    删除工作空间改动代码,撤销commit,撤销git add。

revert(恢复) 针对的是本地仓库的恢复

1、revert的原理是,在当前提交后面,新增一次提交,抵消掉上一次提交导致的所有变化。它不会改变过去的历史,所以是首选方式,没有任何丢失代码的风险

2、revert可以抵消上一个提交,那么如果想要抵消多个需要执行 git revert 倒数第一个commit id 倒数第二个commit

3、这个就常用于当你提交了一次commit之后发现提交的可能有问题就可以用到revert

4、还有一种情景是已经有很多人提交过代码,但是想改之前的某一次commit记录又不想影响后面的也可以使用revert,他会把你后面提交的记录都放到工作区只是合并的时候需要注意一点

git revert [commitId]

1
对commitId执行反向操作,恢复到commitId的上一个commitId的代码

git revert HEAD

1
2
3
4
5
6
7
8
9
10
11
#提交记录
A1 ---> A2 ---> A3 ---> A4 ---> A5 ---> A6(最新版本)
#对应的HEAD值,一般HEAD指向最新的一条A6
5 ---> 4 ---> 3 ---> 2 ---> 1 ---> 0(最新版本)
#HEAD相当于HEAD~0 表示对最近的一次提交(A6)实施反向操作,也就是将代码变成A5的版本
#相当于 git revert HEAD~0 相当于 git revert A6
$ git revert HEAD
#git revert HEAD~1 表示git revert A5,也就是将代码变成A4的版本
$ git revert HEAD~1
#如果要回到A3,那么就要生成A4,A5,A6相反的提交,这里可以用范围( ] 前开后闭
$ git revert HEAD~3..HEAD

保存暂存区切换分支

1
$ git stash      
1
$ git stash pop  
1
2
3
4
5
6
7
8
9
10
$ git stash              暂存状态
$ git stash list 查看暂存列表
$ git stash clear 清空暂存列表
$ git stash drop stash@{0} 删除第一个暂存

$ git stash save "说明" 暂存未提交工作区
$ git stash pop 恢复
$ git stash apply
$ git stash apply 将缓存堆栈中的stash多次应用到工作目录中,但并不删除stash拷贝
$ git stash apply stash@{0} 指定使用哪一个stash

模板设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 🌈 Git Commit Message Template
# Language: [EN]/[ZH]/[JA] (Delete unused)
# -------------------------------------------------------------------
# [EN] Follow Conventional Commits & Angular Style Guide:
# <type>(<scope>): <subject> # Header line (required)
# <BLANK LINE> # Separate header from body
# <body> # Detailed description (optional)
# <BLANK LINE> # Separate body from footer
# <footer> # Issue links/breaking changes (optional)
#
# [ZH] 请遵循约定式提交规范 (https://www.conventionalcommits.org/zh-hans/):
# <类型>(<作用域>): <主题> # 标题行(必填)
# <空行> # 分隔标题和正文
# <正文> # 详细描述(可选)
# <空行> # 分隔正文和页脚
# <页脚> # 关联Issue/重大变更说明(可选)

# ==================== HEADER (必填/Required) ====================
# [EN] Allowed types: feat|fix|docs|style|refactor|perf|test|chore|revert|ci|build
# [ZH] 允许的类型: feat(功能)|fix(修复)|docs(文档)|style(格式)|refactor(重构)|perf(性能)|test(测试)|chore(杂项)|revert(回滚)|ci(集成)|build(构建)
<type>(<scope>): <subject>

# ==================== BODY (可选/Optional) ====================
# [EN] Describe motivation, changes, and any technical details
# [ZH] 描述动机、变更细节和技术实现(每行72字符换行)
<body>

# ==================== FOOTER (可选/Optional) ====================
# [EN] Reference issues (e.g. Closes #123) and breaking changes
# [ZH] 关联Issue(如 Closes #123)和重大变更说明
<footer>

# -------------------------------------------------------------------
# [EN] Validation Rules (Do NOT modify below this line)
# [ZH] 校验规则(请勿修改以下内容)
# --------------------------
# Header-Max-Length: 50
# Body-Max-Line-Length: 72
# Allowed-Types: feat,fix,docs,style,refactor,perf,test,chore,revert,ci,build
# -------------------------------------------------------------------

安装依赖

1
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky commitizen cz-customizable

package.json 配置

1
2
3
4
5
6
7
8
9
10
11
{
"config": {
"commitizen": {
"path": "./node_modules/cz-customizable"
}
},
"scripts": {
"commit": "git-cz",
"prepare": "husky install"
}
}

commitlint.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// 类型必须包含所有.cz-config.js中定义的类型(含自定义类型)
'type-enum': [
2,
'always',
[
'feat', 'fix', 'docs', 'style', 'refactor',
'perf', 'test', 'build', 'ci', 'chore',
'revert', 'WIP', 'ui', 'release'
]
],

// Scope 校验规则(与.cz-config.js的scopes同步)
'scope-enum': [
2,
'always',
[
'components', 'hooks', 'utils', 'element-plus',
'styles', 'deps', 'auth', 'other'
]
],

// 长度限制(折中方案:取72和100的中间值)
'header-max-length': [2, 'always', 80],

// 大小写规则(宽松处理,适配中文团队)
'subject-case': [0], // 完全禁用大小写校验

// 正文和脚注格式(保持Conventional Commits要求)
'body-leading-blank': [1, 'always'],
'footer-leading-blank': [1, 'always'],

// 可选:允许空scope(适配.cz-config.js的allowEmptyScopes)
'scope-empty': [1, 'never'] // 1=warning级别,非强制
}
};

.cz-config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
module.exports = {
// 类型定义(与commitlint的type-enum完全一致,含图标和中文)
types: [
['feat', '新增功能', '✨'],
['fix', '修复Bug', '🐛'],
['docs', '文档变更', '📝'],
['style', '代码样式', '💄'],
['refactor', '代码重构', '♻️'],
['perf', '性能优化', '⚡️'],
['test', '测试相关', '✅'],
['build', '构建工具', '👷'],
['ci', 'CI配置', '🔧'],
['chore', '杂项任务', '🎫'],
['revert', '回退代码', '⏪'],
['WIP', '开发中', '🚧'],
['ui', '界面调整', '🎨'],
['release', '版本发布', '🚀']
].map(([value, desc, icon]) => ({
value,
name: `${icon} ${(value + ':').padEnd(8)}${desc}`
})),

// 影响范围(与commitlint的scope-enum完全一致)
scopes: [
['components', '组件相关'],
['hooks', 'Hook函数'],
['utils', '工具方法'],
['element-plus', 'ElementPlus组件'],
['styles', '样式文件'],
['deps', '依赖更新'],
['auth', '权限相关'],
['other', '其他修改']
].map(([value, desc]) => ({
value,
name: `${value.padEnd(15)}(${desc})`
})),

// 交互提示(中文化优化)
messages: {
type: '选择提交类型: (上下键选择,回车确认)',
scope: '选择影响范围: (可选,上下键选择)',
customScope: '请输入自定义范围: (可选)',
subject: '简短描述变更: (必填,建议中文)',
body: '详细说明 (可选,使用"|"换行):',
footer: '关联ISSUE (如 #123): (可选)',
confirmCommit: '确认提交? (y/n)'
},

// 配置规则(与commitlint对齐)
allowCustomScopes: true, // 允许自定义scope
allowBreakingChanges: ['feat', 'fix'], // 允许BREAKING CHANGE
allowEmptyScopes: true, // 允许空scope(对应commitlint的scope-empty规则)
subjectLimit: 80, // 与commitlint的header-max-length同步
skipQuestions: ['body', 'footer'] // 默认跳过非必填项
};
  • Scope 校验太严格 (修改 commitlint.config.js)

1
2
3
4
rules: {
'scope-enum': [0], // 完全禁用scope校验
'scope-empty': [0] // 允许空scope
}

启用Git Hook

1
npx --no-install commitlint --edit "\$1"'