git教程¶
密码¶
- GitLab使用手册配置Git永久记住密码,免去重复输入的烦恼 - 心向阳 - 博客园 (cnblogs.com)
- github配置了公钥依旧提示git@github.com‘s password: Permission denied, please try again.的解决办法
- Git报错:git@github.com: Permission denied (publickey)
Github.token¶
- git client 配置以及连接GitHub、Bitbucket_purplego的博客-CSDN博客
- 【VSCode 笔记】Git: Host key verification failed
- [ github ] github clone private repo克隆私有项目详细-简书(jianshu.com)
- git client 配置以及连接GitHub、Bitbucket
- github项目如何快速git clone https
Git 仓库配置用户和邮箱¶
特定仓库¶
要为一个特定的 Git 仓库配置用户和邮箱,可以使用以下命令:
- 进入你要配置的 Git 仓库目录:
- 配置用户名称:
- 配置用户邮箱:
可以通过查看 .git/config 文件来确认配置是否已被成功写入:
在文件中,你应该能看到类似以下的配置:
全局配置用户和邮箱¶
这表示 user.name 和 user.email 已经被成功配置到该仓库的本地配置文件中。
这些配置只会影响当前仓库,不会影响全局配置。如果你需要配置全局的用户和邮箱,可以使用 --global 选项:
git config --global user.name "Your Global Name"
git config --global user.email "your.global.email@example.com"
全局配置的信息会存储在用户主目录下的 Git 配置文件中,具体路径是:
~/.gitconfig或~/.config/git/config文件:这个文件包含了你为所有 Git 仓库配置的全局设置。
当你使用 git config --global user.name "Your Name" 或 git config --global user.email "your.email@example.com" 时,这些配置信息会被写入到 ~/.gitconfig 文件中。
你可以通过以下命令查看全局配置文件内容:
这个文件中的配置对系统中所有的 Git 仓库都有效。
命令¶
reset¶
在本地修改文件、或者删除文件后,如果想恢复这些文件内容为git仓库保存的版本,可以使用下面几个命令:
git checkout [--] <filepath>:可以恢复还没有执行git add的文件,但不能恢复已经执行过git add的文件git reset [--] <filepath>:把文件从git的staged区域移除,即取消git add,再使用git checkout进行恢复git reset --hard:恢复整个git仓库的文件内容为当前分支的最新版本
commit¶
根据提示,把第二个“pick”改成“squash”,这样就可以把第二个commit合并到到第一个里。
git 修改最新commit的作者¶
使用 git commit --amend --author 修改提交的作者信息:
git 修改指定commit的作者¶
要修改指定提交(commit)的作者信息,你可以使用以下步骤:
-
找到你要修改的提交的哈希值: 你可以通过
git log来查看提交历史,并找到需要修改的提交哈希值。 -
使用交互式变基来修改提交:
执行以下命令以启动交互式变基,从而修改指定的提交:
其中 <commit-hash> 是你要修改的提交的哈希值。^ 表示从前一个提交开始。
- 标记为编辑(edit):
在进入交互式变基编辑界面后,将要修改的提交前面的 pick 改为 edit,然后保存并退出。
- 修改作者信息:
运行以下命令修改提交的作者信息:
这会修改该提交的作者为你指定的新作者。
- 继续变基:
修改完作者信息后,继续执行变基过程:
- 强制推送到远程仓库(如果提交已推送到远程仓库):
由于你修改了历史提交,你需要强制推送到远程仓库:
注意:强制推送会覆盖远程仓库的历史,可能影响其他协作者,因此应谨慎使用。
git-filter-repo¶
安装 git-filter-repo:
批量在subject后面追加一行:
START_COMMIT="a96ff9987bcc"; git filter-repo --commit-callback 'msg_lines = commit.message.split(b"\n", 1); subject = msg_lines[0]; body = msg_lines[1] if len(msg_lines) > 1 else b""; new_body = b"\nCTKfeat: #74477\n\n" + body.strip() + b"\n" if body.strip() else b"\nCTKfeat: #74477\n"; commit.message = subject + b"\n" + new_body' --force --refs "$START_COMMIT^..HEAD"
说明:¶
START_COMMIT="a96ff9987bcc": 定义起始提交。git filter-repo: 使用git filter-repo执行提交信息修改。--refs "$START_COMMIT^..HEAD": 处理从a96ff9987bcc到HEAD之间的所有提交(包括a96ff9987bcc)。--commit-callback: 修改提交信息,确保CTKfeat: #74477前后都有空行。
查看文件每次提交的diff¶
git diff查看改动内容¶
- 查看已暂存文件的改动:使用
git diff --cached <file>。 - 查看工作目录中未暂存文件的改动:使用
git diff <file>。
将 <file> 替换为具体的文件路径。
查找某句代码在哪个提交中出现¶
git log -S 'cpumask_test_cpu(cpu, sched_domain_span(sd))' --oneline kernel/sched/fair.c | cat
8aeaffef8c6e sched/fair: Take the scheduling domain into account in select_idle_smt()
3e6efe87cd5c sched/fair: Remove redundant check in select_idle_smt()
3e8c6c9aac42 sched/fair: Remove task_util from effective utilization in feec()
c722f35b513f sched/fair: Bring back select_idle_smt(), but differently
6cd56ef1df39 sched/fair: Remove select_idle_smt()
df3cb4ea1fb6 sched/fair: Fix wrong cpu selecting from isolated domain
kernel/sched/fair.c参数可以去掉。
进一步使用git show 查看上述所有commit的具体内容:
git log -S 'cpumask_test_cpu(cpu, sched_domain_span(sd))' --oneline kernel/sched/fair.c | awk {'print $1'} | xargs git show > sched_domain_span.log
kernel/sched/fair.c参数可以去掉。
查找所有使用 @example.com 域名的提交作者¶
awk '!seen[$0]++':awk命令的这个用法可以用来去除重复行。seen[$0]++是一个关联数组,用于跟踪已经看到的行,如果行第一次出现,它会被打印;如果是重复的行,则不会被打印。
这个命令可以帮助确保每个作者的邮箱地址只显示一次。
查找所有使用 @example.com 域名的提交¶
在 git log 中显示简短的提交信息(--oneline 格式),同时包含作者的姓名、邮箱以及提交的 commit id:
%h:简短的commit id。%s:提交信息的简短描述(相当于--oneline格式的描述)。%an:作者的名字。%ae:作者的邮箱。
通过这种方式,你将获得包含简短 commit id、提交信息、作者姓名和邮箱的输出,并且只显示 @example.com 域名的提交记录。
git log --grep¶
搜索 Git 历史记录中涉及 __d_lookup 的提交:
完全精准匹配(避免部分匹配如 __d_lookup_rcu),可使用单词边界正则表达式:
要同时匹配提交信息中包含 __d_lookup 和 lookup_fast 的 Git 提交记录,可以使用 --grep 结合正则表达式,或者通过管道 (|) 进行多条件筛选:
方法 1:使用 --grep 正则表达式(单次匹配)
方法 2:使用 git log 管道 + grep(更灵活)
方法 3:使用 -P(Perl 正则,更精准)
查看某个补丁在内核哪些版本中有¶
在Linux kernel stable tree mirror中查找某个提交:
git remote -v
origin https://github.com/gregkh/linux.git (fetch)
origin https://github.com/gregkh/linux.git (push)
git log --oneline | grep "arm64: implement ftrace with regs"
3b23e4991fb6 arm64: implement ftrace with regs
在Linux kernel source tree中查找这个提交:
https://github.com/torvalds/linux/commit/3b23e4991fb6
将3b23e4991fb6替换成要查找的commit:


head¶
statsh¶
rebase merge¶
- Linux :关于git:您尚未完成合并(MERGE_HEAD存在)
- 使用交互式 git rebase 工具压缩 Git 提交
- refusing to merge unrelated histories的解决方案(本地/远程)综合
pull¶
pull request¶
push¶
- Gitlab强制推送提示"You are not allowed to force push code to a protected branch on this project." · Issue #11 · LeachZhou/blog (github.com)
- Github远程推送一直Everything up-to-date - sinatJ - 博客园 (cnblogs.com)
- submodule 子项目提交代码后无法push到远程仓库_三叔的负能量的博客-CSDN博客
- git-警告:忽略损坏的ref refs / remotes / origin / HEAD
worktree¶
总结这两个 git worktree 命令的区别:¶
1. git worktree add ../linux-0.11 Linux-0.11/master¶
- 作用:在
../linux-0.11目录下创建一个新的工作树(worktree),并检出 已存在的分支Linux-0.11/master。 - 特点:
- 不会创建新分支,只是检出已有分支。
- 适用于 直接使用现有分支 进行开发或测试。
2. git worktree add -b linux-stable/linux-6.6.y ../linux-6.6.y linux-stable/linux-6.6.y¶
- 作用:在
../linux-6.6.y目录下创建一个新的工作树,并 基于linux-stable/linux-6.6.y分支创建一个同名的新分支linux-stable/linux-6.6.y。 - 特点:
-b表示 创建新分支(即使分支名相同,也会新建一个分支)。- 适用于 需要基于某个分支创建新分支 进行开发(比如
linux-stable/linux-6.6.y-dev)。 - 如果
linux-stable/linux-6.6.y已经存在,Git 会报错(除非加上-B强制覆盖)。
关键区别¶
| 命令 | 是否创建新分支 | 适用场景 |
|---|---|---|
git worktree add ../linux-0.11 Linux-0.11/master |
❌ 不创建 | 直接使用已有分支 |
git worktree add -b linux-stable/linux-6.6.y ../linux-6.6.y linux-stable/linux-6.6.y |
✅ 创建 | 基于某个分支创建新分支 |
推荐用法¶
- 如果只是想在另一个目录使用已有分支(如
Linux-0.11/master),直接用git worktree add不加-b。 - 如果想基于某个分支创建新分支(如
linux-stable/linux-6.6.y-dev),用git worktree add -b。
这样能避免意外创建重复分支,同时保持工作树清晰。
worktree remove¶
移除某个工作树(worktree):
tag¶
要查看某个提交是否被标签包含,可以使用以下命令:
示例¶
检查提交 3b23e4991fb6 是否被任何标签包含:
git tag --contains 3b23e4991fb6 | head -n10
v5.10
v5.10-rc1
v5.10-rc2
v5.10-rc3
v5.10-rc4
v5.10-rc5
v5.10-rc6
v5.10-rc7
v5.10.1
v5.10.10
branch¶
-
查看远程仓库的分支:
-
查看所有远程仓库的分支:
-
查看已知的远程仓库及其分支:
-
重命名远程仓库:
-
将远程仓库重命名:
例如,将
origin重命名为upstream:执行完这个命令后,你的远程仓库名称就会从
origin改为upstream。 -
克隆特定远程分支:
-
获取特定远程分支而不影响其他分支:
-
将该远程分支检出为本地分支:
-
查看当前分支对应的远程分支:
-
查看所有本地分支及其对应的远程分支:
-
查看当前分支对应的远程分支:
-
查看包含指定提交的本地分支:
-
要查看包含特定提交(如
3b23e4991fb6)的所有分支,可以使用以下 Git 命令:git branch --contains <commit>:这个命令将列出所有包含指定提交的本地分支。 -
如果你想查看所有远程和本地分支中包含该提交的分支,可以使用以下命令:
运行以上命令后,输出可能类似于:
在输出中,带有
*的分支表示当前所在的分支,其他分支则表示包含指定提交的所有分支。如果输出为空,则表示没有分支包含该提交。
show-ref¶
查看本地引用的对应命令:
# 查看所有本地引用(分支、标签等)
git show-ref
# 只查看本地分支
git show-ref --heads
# 只查看本地标签
git show-ref --tags
# 查看特定格式(类似ls-remote输出)
git show-ref --heads --tags | awk '{print $1 " " $2}'
ls-remote¶
| 想查看内容 | 正确命令 | 等价于查看哪类引用 |
|---|---|---|
| 远程所有 refs | git ls-remote origin |
refs/*(所有引用) |
| 远程所有分支 | git ls-remote --heads origin |
refs/heads/*(即 branches) |
| 远程所有标签 | git ls-remote --tags origin |
refs/tags/*(即 tags) |
git ls-remote origin¶
该命令从远程仓库 openeuler 获取所有引用(分支或标签),并筛选显示名字包含 OLK-5.10 或 4.19.90-2505.5.0 的分支和标签信息。
输出示例:
a6f78a2e772d1f32d57476a1ab4d5b98733eefbb refs/heads/OLK-5.10
d451decadbd4fa2c1eb6d9367411f06841cb794d refs/remotes/origin/OLK-5.10
fe768b6e8d1772a8938f62f0fdfdb3b9d9272c08 refs/tags/4.19.90-2505.5.0
5ae76523ccf96ec8b8d73d541e305bf15b6b697e refs/tags/4.19.90-2505.5.0^{}
遍历当前仓库的所有远程库,查找并打印包含指定分支(如 OLK-5.10)或 tag(如 4.19.90-2505.5.0)的远程引用信息,并显示该 branch 或 tag 存在哪些远程库中:
#!/bin/bash
branch_tag="OLK-5.10"
for r in $(git remote); do
matches=$(git ls-remote "$r" 2>/dev/null | grep "$branch_tag")
if [ -n "$matches" ]; then
echo "Remote: $r"
echo "$matches"
echo
fi
done
一行式:
branch_tag="OLK-5.10"; for r in $(git remote); do matches=$(git ls-remote "$r" 2>/dev/null | grep "$branch_tag"); if [ -n "$matches" ]; then echo "Remote: $r"; echo "$matches"; echo; fi; done
输出示例:
Remote: openeuler
a6f78a2e772d1f32d57476a1ab4d5b98733eefbb refs/heads/OLK-5.10
d451decadbd4fa2c1eb6d9367411f06841cb794d refs/remotes/origin/OLK-5.10
git ls-remote --heads origin¶
该命令从远程仓库 openeuler 获取所有分支,并筛选显示名字包含 OLK-5.10的分支。
输出示例:
遍历当前仓库的所有远程库,查找并打印包含指定分支(如 OLK-5.10)的远程引用信息,并显示该分支存在哪些远程库中:
#!/bin/bash
branch="OLK-5.10"
for r in $(git remote); do
matches=$(git ls-remote --heads "$r" 2>/dev/null | grep "$branch")
if [ -n "$matches" ]; then
echo "Remote: $r"
echo "$matches"
echo
fi
done
一行式:
branch="OLK-5.10"; for r in $(git remote); do matches=$(git ls-remote --heads "$r" 2>/dev/null | grep "$branch"); if [ -n "$matches" ]; then echo "Remote: $r"; echo "$matches"; echo; fi; done
输出示例:
git ls-remote --tags origin¶
查看远程 linux-stable 仓库中是否包含 tag v4.4.161:
输出示例:
e121ec12de616a864a10cc45cb80bb22b2a80bd4 refs/tags/v4.4.161
b001adea66f0e0a7803adfbf9128a2d7969daa4e refs/tags/v4.4.161^{}
遍历当前仓库的所有远程库,查找并打印包含指定 tag(如 v4.4.161)的远程引用信息,并显示该 tag 存在哪些远程库中:
#!/bin/bash
tag="v4.4.161"
for r in $(git remote); do
matches=$(git ls-remote --tags "$r" 2>/dev/null | grep "$tag")
if [ -n "$matches" ]; then
echo "Remote: $r"
echo "$matches"
echo
fi
done
一行式:
tag="v4.4.161"; for r in $(git remote); do matches=$(git ls-remote --tags "$r" 2>/dev/null | grep "$tag"); if [ -n "$matches" ]; then echo "Remote: $r"; echo "$matches"; echo; fi; done
输出示例:
Remote: WSL2-Linux-Kernel
e121ec12de616a864a10cc45cb80bb22b2a80bd4 refs/tags/v4.4.161
b001adea66f0e0a7803adfbf9128a2d7969daa4e refs/tags/v4.4.161^{}
Remote: gregkh
e121ec12de616a864a10cc45cb80bb22b2a80bd4 refs/tags/v4.4.161
b001adea66f0e0a7803adfbf9128a2d7969daa4e refs/tags/v4.4.161^{}
Remote: linux-stable
e121ec12de616a864a10cc45cb80bb22b2a80bd4 refs/tags/v4.4.161
b001adea66f0e0a7803adfbf9128a2d7969daa4e refs/tags/v4.4.161^{}
name-rev¶
使用 git name-rev 命令可以帮助开发者更方便地识别提交在版本历史中的位置,提供一个更人性化的提交引用方式。
用法示例¶
- 查找提交的符号名称
输出示例:
解释:
- 该命令查找提交 1b06a0 的符号名称。
- 输出显示 1b06a0 距离标签 release-0074 有 744 次提交。
submodule¶
- git中子模块/子仓库的使用
- Git submodule 知识总结
- 7.11 Git工具-子模块
- git submodule 使用小结 - 简书 (jianshu.com)
- git submodule 的使用 - 简书 (jianshu.com)
- Git Submodule管理项目子模块 - nicksheng - 博客园 (cnblogs.com)
- git submodule update 游离分支 临时分支问题记录 解决办法
- git添加submodule以及更名
- Git修改.Submodule文件url生效
- submodule切换分支_Git submodule-切换submodule的分支
-
git submodule 分支是否与主项目的分支一起切换?
设置永久记住密码
- 将git仓库从submodule转换为subtree
- Git - - subtree与submodule - Anliven -博客园(cnblogs.com)
- Git SubTree使用
.gitignore¶
查看哪些文件被忽略:
.gitignore_global¶
可以使用如下命令将这些常见的 ctags / cscope / global 索引文件添加到 ~/.gitignore_global 中:
✅ 完整流程(适合首次设置)¶
# 创建全局忽略文件(如果还没有)
touch ~/.gitignore_global
# 添加常见索引文件
cat >> ~/.gitignore_global <<EOF
GPATH
GRTAGS
GTAGS
cscope.in.out
cscope.out
cscope.po.out
EOF
# 设置 Git 使用该文件作为全局忽略规则
git config --global core.excludesFile ~/.gitignore_global
✅ 验证是否生效¶
然后在你的任意 Git 仓库里运行:
确认 cscope.out、GTAGS 等文件不再显示为“未跟踪文件”。
.gitkeep¶
- git提交空文件夹_fengchao2016的博客-CSDN博客_git空文件夹不能提交
- 如何向git仓库提交空文件夹?.gitignore和.gitkeep配合 - everfight - 博客园 (cnblogs.com)
gerrit¶
Github Action¶
- 通过 GitHub Actions 将 GitHub 仓库自动备份到 Gitee、GitLab
- bash - Github Action - Error: Process completed with exit code 1 - Stack Overflow
- Github actions git log only output one line
patch¶
将某个作者的所有提交打成序列号递增的patch¶
#!/bin/bash
# 定义补丁目录变量
PATCH_DIR="../patchs"
# 生成补丁文件到指定目录
git log --oneline --reverse --author="^realwujing" | awk '{print $1}' | xargs -I {} git format-patch -1 {} -o "$PATCH_DIR"
# 切换到补丁目录
cd "$PATCH_DIR" || { echo "Directory $PATCH_DIR does not exist"; exit 1; }
# 计数器初始化
i=1
# 遍历所有 .patch 文件,按照当前目录中的排序方式处理
for patch in $(ls -lt | tac | awk '{print $NF}' | grep '\.patch$'); do
# 使用 sed 删除原有的序号部分
base_name=$(echo "$patch" | sed 's/^[0-9]\{4\}-//')
# 使用 printf 格式化为四位数字,不足前面补零
new_name=$(printf "%04d-%s" $i "$base_name")
# 显示原始文件名和新的文件名
echo "Renaming $patch to $new_name"
# 重命名文件
mv "$patch" "$new_name"
# 增加计数器
i=$((i + 1))
done
-
定义补丁目录变量:
PATCH_DIR="../patchs"将目标目录存储在一个变量中。 -
生成补丁文件到指定目录:
git format-patch命令将补丁文件生成到"$PATCH_DIR"目录。 -
切换到补丁目录:
cd "$PATCH_DIR"进入指定目录。如果目录不存在,则输出错误信息并退出。 -
遍历并重命名文件:
- 使用
sed删除原有的序号部分,得到文件的基本名称。 - 使用
printf格式化新的文件名,包括递增的序号。 - 增加对比输出:使用
echo显示每个文件的原始名称和新的名称。 -
使用
mv重命名文件。 -
计数器递增:每处理一个文件,计数器
i递增。
这个脚本在重命名过程中会输出每个文件的原始名称和新的名称,便于跟踪文件的变化。
使用git am,可以将上述一系列补丁应用到某个分支上,如果存在冲突,则会报错并生成reject文件,需要手动处理冲突:
cherry-pick¶
-x 在提交信息的末尾追加一行(cherry picked from commit ...),方便以后查到这个提交是如何产生的:
git cherry-pick -x
-s,--signoff:
git cherry-pick -s
可以同时使用 -x 和 -s这两个选项来同时记录来源和签名:
新提交的日志:
commit xyz789
Author: Bob <bob@example.com>
Date: Wed Mar 19 13:00:00 2025 +0800
Fix login bug
(cherry picked from commit abc123)
Signed-off-by: Alice <alice@example.com>
send-email¶
.gitconfig中的配置如下:
[user]
email = realwujing@qq.com
name = wujing
[url "git@github.com:"]
insteadOf = https://github.com/
[commit]
template = ~/.gitcommit_template
[sendemail]
smtpServer = smtp.qq.com
smtpServerPort = 587
smtpEncryption = tls
smtpUser = realwujing@qq.com
smtpPass = kpdkskfgpbaxsrnwbifi
测试连接和认证:
/var/folders/hh/0wpdzj8s79scygrdntrwy32h0000gn/T/xctMCK9Q3r/v-to-realwujing-qq.com-0001-git-send-email-and-Signed-off.patch
The following files are 8bit, but do not declare a Content-Transfer-Encoding.
/var/folders/hh/0wpdzj8s79scygrdntrwy32h0000gn/T/xctMCK9Q3r/v-to-realwujing-qq.com-0001-git-send-email-and-Signed-off.patch
Which 8bit encoding should I declare [UTF-8]?
To whom should the emails be sent (if anyone)? realwujing@qq.com
Message-ID to be used as In-Reply-To for the first email (if any)?
(mbox) Adding cc: wujing <realwujing@qq.com> from line 'From: wujing <realwujing@qq.com>'
(body) Adding cc: wujing <realwujing@qq.com> from line 'Signed-off-by: wujing <realwujing@qq.com>'
From: wujing <realwujing@qq.com>
To: realwujing@qq.com
Subject: [PATCH v--to=realwujing@qq.com] git: send-email and Signed-off-by
Date: Sat, 6 Jul 2024 19:19:17 +0800
Message-ID: <20240706111927.56825-1-realwujing@qq.com>
X-Mailer: git-send-email 2.45.2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Cc list above has been expanded by additional
addresses found in the patch commit message. By default
send-email prompts before sending whenever this occurs.
This behavior is controlled by the sendemail.confirm
configuration setting.
For additional information, run 'git send-email --help'.
To retain the current behavior, but squelch this message,
run 'git config --global sendemail.confirm auto'.
Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): y
OK. Log says:
Server: smtp.qq.com
MAIL FROM:<realwujing@qq.com>
RCPT TO:<realwujing@qq.com>
From: wujing <realwujing@qq.com>
To: realwujing@qq.com
Subject: [PATCH v--to=realwujing@qq.com] git: send-email and Signed-off-by
Date: Sat, 6 Jul 2024 19:19:17 +0800
Message-ID: <20240706111927.56825-1-realwujing@qq.com>
X-Mailer: git-send-email 2.45.2
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Result: 250