Git 小技巧

设置换行符转换

在 windows 下开发时,迁出的代码是 CRLF 会导致编译的 sh 脚本不能正确执行:

git config --global core.autocrlf false

一个项目 push 到多个远程 Git 仓库

有时候一个项目需要 push 到多个远程仓库,比如 github 和 coding,下面介绍几种方法。

方法 1: 添加两个远程仓库分别推送

$ git remote add github git@github.com:xxx/xxx.git # 添加 github 远程仓库
$ git remote add coding git@e.coding.net:xxx/xxx.git # 添加 coding 远程仓库
$ git remote -v # 查看远程仓库
coding git@e.coding.net:xxx/xxx.git (fetch)
coding git@e.coding.net:xxx/xxx.git (push)
github git@github.com:xxx/xxx.git (fetch)
github git@github.com:xxx/xxx.git (push)
$ git push github main # 推送到 github
$ git push coding main # 推送到 coding

方法 2: 使用 Git remote set-url 修改远程仓库地址

$ git remote add origin git@github.com:xxx/xxx.git # 添加 origin 远程仓库
$ git remote -v # 查看远程仓库
origin git@github.com:xxx/xxx.git (fetch)
origin git@github.com:xxx/xxx.git (push)
$ git remote set-url --add origin git@e.coding.net:xxx/xxx.git # origin 远程仓库添加 coding 的 push 地址
$ git remote -v # 查看远程仓库
origin git@github.com:xxx/xxx.git (fetch)
origin git@github.com:xxx/xxx.git (push)
origin git@e.coding.net:xxx/xxx.git (push)
$ git push origin main # 推送到 origin 远程仓库

方法 3: 修改本地仓库的配置文件

$ vim .git/config # 修改本地仓库的配置文件
[remote "origin"]
    url = "git@github.com:xxx/xxx.git"
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = "git@e.coding.net:xxx/xxx.git"

设置默认拉取/推送的远程仓库分支

$ git remote add origin git@github.com:xxx/xxx.git # 添加 origin 远程仓库
$ git branch --set-upstream-to=origin/main main # 设置默认拉取的远程仓库分支
$ git config --global push.default origin # 设置默认推送的远程仓库分支
$ git pull # 拉取代码
$ git push # 推送代码

使用 git filter-branch 去除敏感信息

# 当前仓库中有一个文件 password.txt,需要将其删除
$ git filter-branch --tree-filter 'rm -f password.txt' HEAD --all # --tree-filter 表示对每个 commit 都执行一次命令, HEAD 表示当前分支,--all 表示对所有分支的所有 commit 执行命令(可选)

# 当前仓库中有多个目录,只需要保留其中一个目录,其他目录都删除
$ git filter-branch --subdirectory-filter <目录名> HEAD --all # --subdirectory-filter 表示将指定目录作为新的根目录

# 当前仓库中有多个目录,需要删除其中一个目录,其他目录都保留
$ git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <目录名>' HEAD --all

# 修改 commit 信息
$ git filter-branch --commit-filter '
  if [ "$GIT_AUTHOR_NAME" = "xxx" ];
  then
    GIT_AUTHOR_NAME="xxx";
    GIT_AUTHOR_EMAIL="xxx";
    GIT_COMMITTER_NAME="xxx";
    GIT_COMMITTER_EMAIL="xxx";
    git commit-tree "$@";
  else
    git commit-tree "$@";
  fi' HEAD --all
## 或者
$ git filter-branch -f --env-filter 'GIT_AUTHOR_NAME="xxx"; GIT_AUTHOR_EMAIL="xxx"; GIT_COMMITTER_NAME="xxx"; GIT_COMMITTER_EMAIL="xxx";' HEAD --all