git高级功能

git
git submodule

删除历史提交里的文件

pip install git-filter-repo
git filter-repo --path public/favicon.ico --invert-paths --force
git push origin --force

前言

在多仓库项目中,可以把不同环境或模块拆成子仓库,再通过 Git Submodule 组合到主仓库中。这样既能隔离权限,也能让部署服务器只拉取自己需要的仓库内容。

出于安全或权限隔离考虑,可以为每个子仓库配置独立账号,分别授予主仓库和子仓库对应的访问权限。部署服务器上使用这些账号拉取代码,避免把过大的全局权限放进同一个凭证里。

Tip

.gitmodules 文件中,建议将子模块 URL 改成相对路径。这样主仓库地址变更时,子模块不需要逐个调整。

GitLab 实现方式

以下步骤不包括账号权限配置。

第 1 步

新增GitLab Runner

第 2 步

在主仓库中添加.gitlab-ci.yml配置文件

第 3 步

在主仓库中配置流水线触发器(WebHook)

第 4 步

在各个子仓库中分别添加钩子

.gitlab-ci.yml
stages:
  - update

update_submodules:
  stage: update
  only:
    - triggers
  tags:
    - docker
    - ci
  image: docker:git
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  before_script:
    - git config --global user.name "gitlab bot"
    - git config --global user.email "[email protected]"
    - git remote set-url origin https://gitlab-ci-token:${GIT_PUSH_TOKEN}@gitlab.test.com/test.git
  script:
    - |
      git submodule update --remote --merge
      git add .
      if git diff-index --quiet HEAD; then
        echo "Nothing changed"
      else
        git commit -m "Auto update submodules"
        git push origin HEAD:master
      fi

本地克隆

首次克隆

首次拉取主仓库后,需要初始化子模块,再按环境更新对应目录。

git clone https://dc-cn-sy:[email protected]/xxx.git
git submodule init
git submodule update --remote deploy/${ENV}

后续更新

主仓库更新后,再同步子模块到远程分支最新提交。

git pull && git submodule update --remote deploy/${ENV}

添加子模块

新增子模块时,把不同环境放到约定目录,便于 CI/CD 按 ${ENV} 变量选择部署内容。

git submodule add https://dc-cn-sy:[email protected]/xxx.git deploy/${ENV}