Skip to content

Latest commit

 

History

History
596 lines (398 loc) · 13.6 KB

File metadata and controls

596 lines (398 loc) · 13.6 KB

Git 教程

Git 是一个免费开源的分布式版本控制系统,旨在快速高效地处理从小型项目到大型项目的所有事务。

Git 常用命令

初始化及配置

  • 初始化 git 本地仓库
git init
  • 显示仓库的配置
git config -l
  • 配置颜色
git config --global color.ui true
  • 配置编辑器为 vim
git config --global core.editor vim
  • 给远程仓库地址添加别名
git remote add origin git@github.com:Rasic2/gvasp.git

其中 origin 代表给远程仓库添加的别名, git@github* 代表远程仓库的地址。

提交相关

  • 显示工作目录和暂存区的状态
git status
  • 将文件添加到暂存区
git add .
  • 将暂存区的内容添加到本地仓库
git commit -m "comment"

其中 comment 表示对本次版本更新的标注。

  • 修改 commit 的最后一条注释
git commit --amend
git commit --amend --author "qwer <qwer@qq.com>" --no-edit
  • 将本地仓库的内容同步到远程
git push origin master

其中 origin 代表远程仓库的别名, master 代表一个分支。

  • 将远程仓库的内容同步到本地
git pull origin master
  • 将工作区的内容缓存
git stash
  • 显示缓存区记录
git stash list
  • 将缓存区的第一条记录恢复到工作区
git stash pop

分支相关

  • 基于分支新建分支
git checkout -b new_branch  # 基于当下分支
git checkout -b new_branch old_branch  # 基于已有分支
  • 删除本地分支
git branch -d branch_name
  • 删除远程分支
git push origin --delete branch_name
  • 同步远程分支
git fetch --prune  # 当远程仓库上已经删除了某个分支,但本地的 `git branch -r` 仍然显示该分支
  • 重命名分支
git branch -m new_branch_name
  • 合并分支
git merge branch_name
git rebase branch_name  # 变基
  • 撤销操作
git revert -n OLDER_COMMIT^...NEWER_COMMIT  # 撤销从 OLDER_COMMIT 到 NEWER_COMMIT 的所有 COMMIT,并且保存为一次 COMMIT

tag 相关

  • 查看已有的 tag
git tag
  • 为当前 commit 增加 tag(如 v0.0.3)
git tag v0.0.3
  • 后期为某个版本号增加 tag(如 v0.1.1)
git tag -a v0.1.1 COMMIT_ID -m "message"
  • 删除已有的 tag(如 v0.0.1)
git tag -d v0.0.1  # 删除本地 tag
git push origin :refs/tags/v0.0.1  # 删除远程 tag
  • 将本地 tag 提交到远程仓库
git push origin --tags
  • 从远程仓库获取 tag
git fetch origin --tags

冲突相关

  • 对于冲突的文件,使用合并进来的分支(如 main)覆盖当前分支(如test

    1. 确保你正处于合并冲突的状态中,并且当前分支是 test。

    2. 对于每一个冲突文件,使用 --theirs 选项来检出 main 的版本。 :::{note}

      • 在合并操作中,--theirs 代表要合并进来的分支(即 main)的版本。
      • --ours 代表当前所在的分支(即 test)的版本。

      :::

    git checkout --theirs -- path/to/conflicted_file1.js
    git checkout --theirs -- path/to/conflicted_file2.css
    git checkout --theirs -- path/to/conflicted_file3.html
    1. 提交版本
    git add .
    git commit

历史相关

  • 比较差异
git diff zyguo..main # 比较两个分支的差异
git diff abc123 def456 -- app.py # 比较某文件在两次提交中的差异
  • 显示历史日志
git log
git log --stat    # 查看所有提交记录的修改文件信息
git log -p file   # 查看某个文件的修改历史
git log COMMIT1..COMMIT2 -- file # 查看某个文件从 COMMIT1 到COMMIT2 所有的修改情况(概略信息)
git log COMMIT1..COMMIT2 -p file # 查看某个文件从 COMMIT1 到COMMIT2 所有的修改情况(详细信息)
git log -n 4 --pretty=format:"%s" # 查看最近4条提交记录并只显示提交信息
  • 合并分支(变基)
git rebase branch  # 区别于 git merge,该命令会删除原有 commit,新建 commit
  • 梳理提交历史
git rebase -i HEAD~num  # 进入交互模式

- pick

重新安排 pick 命令的顺序会更改提交的顺序。如果选择不包括提交,则应删除整行。

- reword

使用后会提供更改提交信息的机会,提交所做的任何更改均不受影响。

- edit

添加或修改提交,可以将大型提交拆分为较小的提交,或者删除在提交中所做的错误更改。

- squash

该命令可以将两个或多个提交合并为一个提交。提交被压缩到其上方的提交中,有机会重新编写描述这两个更改的新提交消息。

- fixup

与 squash 类似,但提交仅合并到其上方的提交中,并且较早提交的消息用于描述所有更改。

- exec

可以对提交运行任意的 Shell 命令。

:::{note} 重新推送到远程仓库时,需要加上 --force-with-lease,不建议直接用 --force,详情可看这里。 :::

  • 将一个 commit 拆分成多个

依次执行如下步骤:

git checkout -b new_branch_name commit_id  # 想拆分 commit 的版本号
git reset HEAD^  # 撤销上一个 commit 到工作区
git add some_files && git commit -m ""  # 新建多个 commit
git checkout branch  # 切换到想更改历史的分支
git rebase new_branch_name  # 变基到拆分 commit 的分支即可自动将某个 commit 拆分成多个
  • 版本回退
git reset --hard commit_id  # 移动HEAD指针,并清空工作区和暂存区(git add)
git reset --soft commit_id  # 移动HEAD指针,并把版本差异放进暂存区
git reset --mixed commit_id # 移动HEAD指针,并把版本差异放进工作区
git reset  # 默认 mixed 模式

规范 Git 提交说明

使用 git cz 命令可以自动生成规范的 Git 提交,要使用该命令,需要以下几个步骤:

  1. 安装 nodejsnpm(Ubuntu 系统)
sudo apt-get update
sudo apt-get install nodejs npm
  1. 安装适配器
npm install -g cz-conventional-changelog
  1. 在项目目录下初始化 cz-conventional-changelog 适配器
commitizen init cz-conventional-changelog --save --save-exact
  1. 在 Git 提交时使用 git cz 命令
git add .
git cz

Git hook 相关

强制检查提交

  1. 首先,进入你的 Git 仓库并创建或编辑 .git/hooks/commit-msg 文件:
#!/bin/bash

# 提交消息文件
COMMIT_MSG_FILE=$1

# 允许的前缀列表
PREFIXES="feat|fix|docs|style|refactor|build|chore|perf|test|ci|revert"

# 读取提交消息的第一行
COMMIT_MSG=$(head -n 1 "$COMMIT_MSG_FILE")

# 检查提交消息是否以允许的前缀开头
if ! echo "$COMMIT_MSG" | grep -qE "^($PREFIXES)"; then
    echo "错误:提交消息必须以以下前缀之一开头:$PREFIXES" >&2
    exit 1
fi
  1. 将这个钩子脚本设置为可执行:
chmod +x .git/hooks/commit-msg

Commit 前操作

  1. 创建 .git/hooks/pre-commit 文件:
#!/bin/bash

# 获取当前分支名称
current_branch=$(git rev-parse --abbrev-ref HEAD)

# 获取远程分支的最新更新
git fetch origin $current_branch

# 比较本地和远程分支
local_commit=$(git rev-parse $current_branch)
remote_commit=$(git rev-parse origin/$current_branch)

if [ "$local_commit" != "$remote_commit" ]; then
   echo "Your local branch is not up to date with origin/$current_branch."
   echo "Please pull the latest changes before committing."
   exit 1
fi

# 如果一致,则允许提交
exit 0
  1. 将这个钩子脚本设置为可执行:
chmod +x .git/hooks/pre-commit

本地保护 main 或 master 分支

  1. 创建 .git/hooks/pre-push
#!/bin/bash

protected_branches=("main" "master")
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

if [[ " ${protected_branches[@]} " =~ " ${current_branch} " ]]; then
  echo "ERROR: You are not allowed to push directly to the $current_branch branch. Use a feature branch and create a Pull Request."
  exit 1
fi

exit 0
  1. 将这个钩子脚本设置为可执行:
chmod +x .git/hooks/pre-push

使用 Git 模版来初始化 hook 钩子

  1. 创建一个模板目录:

    mkdir -p ~/.git-templates/hooks
  2. 添加 commit-msg 钩子:

    vim ~/.git-templates/hooks/commit-msg
  3. 在钩子文件中添加代码:

    #!/bin/bash
    
    # 提交消息文件
    COMMIT_MSG_FILE=$1
    
    # 允许的前缀列表
    PREFIXES="feat|fix|docs|style|refactor|chore|perf|test|ci|revert"
    
    # 读取提交消息的第一行
    COMMIT_MSG=$(head -n 1 "$COMMIT_MSG_FILE")
    
    # 检查提交消息是否以允许的前缀开头
    if ! echo "$COMMIT_MSG" | grep -qE "^($PREFIXES)"; then
        echo "错误:提交消息必须以以下前缀之一开头:$PREFIXES" >&2
        exit 1
    fi
  4. 确保钩子文件是可执行的:

    chmod +x ~/.git-templates/hooks/commit-msg
  5. 配置 Git 使用模板目录:

    git config --global init.templateDir '~/.git-templates'
  6. 初始化新的 Git 仓库:

    git init my-new-repo

自动生成 CHANGELOG

conventional-changelog

使用 conventional-changelog 命令可以自动生成 CHANGELOG,要使用该命令,需要以下几个步骤:

  1. 安装或者更新 nodejsnpm(Ubuntu 系统默认 apt 安装的版本较低,需要使用 n 升级到较高的版本)
sudo apt-get update
sudo apt-get install nodejs npm
sudo npm install -g n
sudo n stable  # 安装 nodejs stable
sudo n latest  # 或安装 nodejs latest
sudo n ls      # 查看已下载的安装版本
sudo n 18.21.1 # 切换版本
  1. 安装 conventional-changelog-cli
npm install -g conventional-changelog-cli
  1. 更新 CHANGELOG.md
touch CHANGELOG.md  # 首次需手动创建
npx conventional-changelog -p angular -i CHANGELOG.md -s -r 0

github_changelog_generator

  1. 安装 Rubygithub_changelog_generator
brew install ruby
gem install github_changelog_generator
  1. 生成 CHANGELOG.md
github_changelog_generator -u github_project_namespace -p github_project

Git 删除大文件历史

当使用 Git 进行版本管理时,可能会不慎将一些库文件、配置文件或特大文件加入版本管理而使得 .git 文件夹占用空间过大。因此特别有必要对一些 git 历史进行重写,删除不想被 git 追踪的文件,官方推荐使用的工具是 git-filter-repo(可使用 pip 或 conda 进行安装),下面将对该工具的一些具体用法进行说明。

  • 对 git 历史进行分析
git filter-repo --analyze

首次运行该命令会生成 .git/filter-repo 目录,可查看该目录获取文件的大小和历史名字,如 .git/filter-repo/analysis/path-all-sizes.txt

=== All paths by reverse accumulated size ===
Format: unpacked size, packed size, date deleted, path name
       35149      12121 <present>  LICENSE
         291        209 <present>  README.md

::: {note} 后续分析时覆盖该目录需加入参数 --force。 :::

  • 删除文件
git filter-repo --path foo.zip --invert-paths

该命令表示将 foo.zip 从 git 历史中移除。

使用 opencommit 自动生成 commit

  1. 使用 npm 安装 opencommit:
nvm use 18
npm install -g opencommit
  1. 配置 OPENAI
oco config set OCO_API_URL=https://xxxx.openai.azure.com
oco config set OCO_AI_PROVIDER='azure' OCO_MODEL='gpt-4o'
oco config set OCO_API_KEY=xxx
  1. 【可选配置】
oco config set OCO_GITPUSH=false # 关闭自动 push
oco config set OCO_ONE_LINE_COMMIT=true # 单行 commit
 oco config set OCO_OMIT_SCOPE=true # 省略 scope
  1. 使用 oco 命令生成 commit
git add .
oco

更多参考资源

1. 常用 Git 命令总结

2. Git 教程

3. Git reset 命令的使用

4. 细读 Git | 让你弄懂 origin、HEAD、FETCH_HEAD 相关内容

5. GitHub fork 与 pull request

6. git rebase,看这一篇就够了

7. 【git 整理提交】git rebase -i 命令详解

8. Git Reset 三种模式

9. Cz 工具集使用介绍 - 规范 Git 提交说明

10. git commit 、CHANGELOG 和版本发布的标准自动化

11. Ubuntu 安装最新版本 NodeJs 和 Npm 的方法