相对位置

除了使用 commit id 作为绝对路径外,Git 还支持三种相对路径:-, ^ 和 ~

  • - 用来表示刚刚的 commit id

  • ~ 表示 commit id 前的某个 commit

例如 :

git checkout 6feba~2 表示 6feba 前两个 commit

常用命令

  • 查看两个版本的差异:

    git diff ba9f93 f6a6ae
  • 查看指定文件的版本历史:

    git log conf.py
  • 下载指定文件夹的数据 :

    1. 复制链接,并将 tree/master 替换为 trunk
    2. svn co https://github.com/Mooophy/Cpp-Primer/trunk/ch03

合并项目

需要将一个项目添加到另一个项目的子路径下,同时保存项目的 commit 历史

# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init

# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
git commit --allow-empty -m "Initial dummy commit"

# Add a remote for and fetch the old repo
# (the '--fetch' (or '-f') option will make git immediately fetch commits to the local repo after adding the remote)
git remote add --fetch old_a <OldA repo URL>

# Merge the files from old_a/master into new/master
git merge old_a/master --allow-unrelated-histories

# Move the old_a repo files and folders into a subdirectory so they don't collide with the other repo coming later
mkdir old_a
dir -exclude old_a | %{git mv $_.Name old_a}

# Commit the move
git commit -m "Move old_a files into subdir"

# Do the same thing for old_b
git remote add -f old_b <OldB repo URL>
git merge old_b/master --allow-unrelated-histories
mkdir old_b
dir –exclude old_a,old_b | %{git mv $_.Name old_b}
git commit -m "Move old_b files into subdir"

将更改提交到新的分支上

git stash
git checkout -b dev
git stash pop
git add.
git commit -a "修改内容"
git push origin dev:dev

合并部分文件

将分支 B 中的部分文件或文件夹合并到分支 A 上 :

git checkout A
git checkout B public/** view/index.html

部分 commit

合并指定分支的某个 commit 到另一分支 :

git cherry-pick commit_id

本地强制覆盖远程和远程强制覆盖本地

git push --force
git pull --rebase

撤销 commit

如果想撤销某次 commit,可以使用 :

git reset --soft commit_id
git reset --hard commit_id

两者的区别是 soft 只是撤销了 commit_id,更改的代码会保留到暂存区

撤销代码更改

使用下面代码可以撤销当前工作区的更改 :

git restore .

如果需要删除新增文件 :

git clean -f

子模块的使用

可以在克隆仓库时初始化子模块 :

git clone --recursive

如果克隆时忘记克隆子模块,就在仓库文件夹下执行 :

git submodule update --init --recursive

删除子模块

git rm submodule_dir

使用 git rm 会自动更新 .gitsubmodule

更新子模块

git submodule update --remote --merge

更改子模块 URL

直接修改 .gitsubmodule 之后提交即可。

在子模块中修改代码并提交

有时候我们需要在子模块中更改代码,然后提交到上游,只需要在子模块路径下 :

git checkout master
# do some changes
git add .
git commit
git push

然后在主仓库中正常提交即可

在提交过程中一定要先提交子模块,然后提交主模块。防止子模块忘记提交导致主模块引用了不存在的提交

撤销暂存

在添加文件后,使用以下命令撤销暂存 :

git reset HEAD files

修改 commit 信息和添加新文件到上个 commit

命令分别为 :

git commit --amend
git add files
git commit --amend

git pull

有时候 git pull 会失败。这时候只需要执行 :

git merge

并解决冲突即可

另外,git pull 相当于 git fetch + 快速合并

此问题的根本原因是上游代码发生了更改,然后下游在没有拉取代码的前提下又产生了新的 commit

撤销指定行

有些时候我们可能需要撤销指定行,使用 :

git checkout -p

代码提交

在使用 CVS 提交代码时,应当遵循相关的规范以方便后期的查看,这种方式被称为 约定式提交

消息格式

[1]

每个提交消息都包含一个标题、一个正文和一个页脚。标题包括了类型、范围和主题:

<type>(<scope>): <subject> <BLANK LINE> <body> <BLANK LINE> <footer>

标题是必须的,但是范围是可选的。

提交消息的任何一行都不应当超过一百个字符。

撤销

如果提交还原了之前的提交,它应该以 revert:开头,后跟还原提交的标题。在正文中,它应该说:This reverts commit <hash>.,其中 hash 是被还原的提交的 SHA。

类型

必须是以下之一:

  • feat: 新功能

  • fix: bug 修复

  • docs: 仅文档更改

  • style: 不影响代码含义的更改(空格、格式、缺少分号等)

  • refactor: 既不修复错误也不添加功能的代码更改

  • perf: 提高性能的代码更改

  • test: 添加缺失的或纠正现有的测试

  • chore: 对构建过程或辅助工具和库(例如文档生成)的更改

范围

范围可以是指定提交更改位置的任何内容。例如$location, $browser,$compile,$rootScope,ngHref,ngClick,ngView,等…​

您可以 * 在更改影响多个范围时使用。

主题

该主题包含对更改的简洁描述:

  • 使用祈使句。现在时:“change”而不是“changed”也不是“changes”

  • 不要大写第一个字母

  • 末尾没有点 (.)

正文

就像在主语中一样,使用祈使句,现在时:“change”不是“changed”也不是“changes”。正文应包括改变的动机,并将其与以前的行为进行对比。

页脚

页脚应包含有关重大更改的任何信息,也是 引用此提交关闭的 GitHub 问题 的地方。

Breaking Changes 应该以 BREAKING CHANGE: 带有空格或两个换行符的单词开头。提交消息的其余部分然后用于此。

可以在 本文档 中找到详细说明。

使用 commitizen 规范提交

安装:

sudo pip3 install -U Commitizen

提交:

cz commit

集成到 Pre-commit

集成到 pre-commit 允许你在提交时使用 cz check 检查提交的信息是否正确。

创建 .pre-commit-config.yaml 文件并添加以下内容

---
repos:
- repo: https://github.com/commitizen-tools/commitizen
   rev: master
   hooks:
      - id: commitizen
      stages: [commit-msg]

运行命令:

pip install pre-commit
pre-commit install --hook-type commit-msg

WSL 中的 GPG 签名

  1. 安装 Gpg4Win

  2. 修改 ~/.gnupg/gpg-agent.conf 并追加以下内容:

    pinentry-program "/mnt/c/Program Files (x86)/Gpg4win/bin/pinentry.exe"
  3. 重启 GPG 代理

    gpg-connect-agent reloadagent /bye

另外,.gnupg 目录的权限默认为 700,而文件的权限则为 600

GPG 签名问题

出现错误 :

gpg: 签名时失败: 对设备不适当的 ioctl 操作
gpg: [stdin]: clear-sign failed: 对设备不适当的 ioctl 操作

解决方式 :

echo "pinentry-program /usr/bin/pinentry-curses" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

项目提交规范

如果一个项目被放到了开源项目,抑或是你想要提交 PR,有以下几点需要注意:

  • submodule 不要使用 ssh 链接。这样会导致没有私钥的机器无法 clone 项目

  • 提交时注意消息规范。比如有些组织要求对 commit 进行签名 :

    Author: cathaysia <DragonBillow@outlook.com>
    Date:   Thu Mar 17 13:45:34 2022 +0800
    
       feat(v2): add Update method for v2.Manager
    
       Signed-off-by: LongtaoZhang <DragonBillow@outlook.com>
  • 提交时切记先提交 submodule,再提交主仓库。否则主仓库会引用不存在的链接,导致其他人 clone 失败

另外可能还需要注意一些行话: LGTM : code review 行话 - 简书

git tag

打标签

git tag

显示标签及其 commit 内容

git tag -n

按打标签时间排序

git tag --sor=taggerdate

git bisect

git bitsect 使用二分查找来找到到底是那一次 commit 引入了 bug,关键步骤如下:

# 现在仓库指向 HEAD
git bisect start HEAD HEAD~10
# 仓库指针指向 HEAD~5
git bisect good # 说明 HEAD - HEAD~5 是正常的
# 仓库指针指向 HEAD~8
git bisect bad # 说明 bug 在 HEAD~6 - HEAD~7
# 仓库指针指向 HEAD~6
git bisect bad # 说明 bug 在 HEAD~6
# git 给出提示:
# HEAD~6 is the first bad commit
git bitset reset # 退出查错

protocol error: bad line length character: Welc

出现此问题的原因是 .ssh/config 中 ForwardX11 设置为 yes。

单独为指定主机设置即可:

Host 127.0.0.1
  HostName 127.0.0.1
  Port 10000
  User root
  ForwardX11 yes
  ForwardX11Trusted yes

将提交内容追加到指定 commit 上

  1. 将 HEAD 移动到需要更改的 commit 上:

    git rebase -i 0bdf89

    在 commit 中将 pick 更改为 edit。

  2. 更改文件

  3. 使用 git commit --amend 将改动追加上去

  4. 使用 git rebase --continue 移动 HEAD 到最新 commit 上。

  5. 解决冲突

如果是已经改动过。只需要先暂存再弹出即可。

更改 atuhor 和 committer

  1. 首先在 git 中设置为正确的用户名。

  2. 使用 git reset -i 切换到需要修改的 commmit。

  3. 执行 git commit --amend --no-edit --reset-author

如果需要全部更改,可以简单地运行 git rebase -r --root --exec "git commit --amend --no-edit --reset-author"
Last moify: 2025-01-17 02:01:39
Build time:2025-07-18 09:41:42
Powered By asphinx