git 常用命令
初始化
初始化一个仓库并提交
1
2
3
4
5
6
|
git init
git remote add origin https://gitlink.com/yourusername/repo.git
git pull --rebase origin master
git push -u origin master # 或 git push -u origin main
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
|
合并不相关内容的提交
submodule
下载
下载带有 submodule 的仓库
1
2
3
|
git clone --recursive <主仓库地址>
# 或
git clone --recurse-submodules <主仓库地址>
|
添加
添加一个子模块到仓库:
1
2
3
|
git submodule add https://github.com/user/lib-example.git libs/external
git add .gitmodules libs/external # 添加子模块元数据及目录
git commit -m "feat: 添加子模块 lib-example"
|
添加子模块并指定分支
1
2
3
4
5
|
git submodule add -b dev https://example.com/repo-b.git path/to/submodule
git add .gitmodules path/to/submodule
git commit -m "Add submodule repo-b using 'dev' branch"
git push
|
删除
彻底从 Git 仓库中移除一个子模块(submodule)
1
2
3
4
5
6
7
|
git submodule deinit -f 子模块路径 # 示例:git submodule deinit -f libs/logger
git rm --cached 子模块路径 # 示例:git rm --cached libs/logger
rm -rf 子模块路径 # 示例:rm -rf libs/logger
rm -rf .git/modules/子模块路径 # 示例:rm -rf .git/modules/libs/logger
git add .gitmodules # 提交配置变更
git commit -m "移除子模块:子模块路径" # 示例:git commit -m "移除子模块:libs/logger"
git push origin 主分支名 # 示例:git push origin main
|
验证是否删除干净
1
2
|
cat .git/config | grep submodule
ls -la .git/modules
|
更新
在主仓库中更新子模块引用
1
|
git submodule update --remote
|
提交主仓库的变更
1
2
3
|
git add .gitmodules path/to/submodule
git commit -m "更新子模块引用至最新提交"
git push origin main
|
克隆主仓库时拉取最新子模块
1
|
git clone --recurse-submodules https://github.com/your/main-repo.git
|
或者克隆后执行:
1
|
git submodule update --init --recursive
|
- 参数 –recurse-submodules 会同步子模块的最新提交(基于主仓库记录的ID)
验证子模块状态
子模块内容更新后同步到主仓库
1
2
3
4
5
6
|
cd submodule_name
git pull origin dev # 拉取最新代码
cd ..
git add submodule_name
git commit -m "Update submodule to latest dev"
git push
|
查看有哪些子模块
1
|
git config --file .gitmodules --get-regexp path
|
分支
切换到已存在的分支
若你要切换到本地已有的分支,可使用 git switch 命令(Git 2.23 版本及以后适用),或者传统的 git checkout 命令。
1
2
3
4
5
|
# 方法一:使用switch命令(推荐)
git switch <分支名>
# 方法二:使用checkout命令(传统方式)
git checkout <分支名>
|
创建并切换到新分支
当你需要创建一个新分支并立即切换过去时,可采用以下方式:
1
2
3
4
5
|
# 方法一:使用switch命令(推荐)
git switch -c <新分支名>
# 方法二:使用checkout命令(传统方式)
git checkout -b <新分支名>
|
切换到远程分支(跟踪远程分支)
要是你想切换到远程仓库的某个分支,需先创建一个跟踪该远程分支的本地分支:
1
2
3
4
5
6
7
8
|
# 方法一:自动创建并跟踪远程分支
git switch -c <本地分支名> origin/<远程分支名>
# 简化版:如果本地分支名和远程分支名一样
git switch -t origin/<远程分支名>
# 方法二:使用checkout命令
git checkout -b <本地分支名> origin/<远程分支名>
|
查看本地分支
查看本地 + 远程分支
1
|
git branch -a # 或 --all
|
查看远程分支(仅远程)
1
|
git branch -r # 或 --remotes
|
总结表格
| 命令 |
作用 |
git branch |
查看本地分支 |
git branch -a |
查看本地+远程分支 |
git branch -r |
查看远程分支 |
git branch -v |
查看分支+最后一次提交信息 |
git branch --merged |
查看已合并到当前分支的分支 |
git branch --no-merged |
查看未合并到当前分支的分支 |
git branch -vv |
检查所有本地分支是否追踪远程 |
本地分支与远程分支对齐
1
2
3
4
|
git checkout -b dev origin/dev
git checkout -b arm_linux origin/arm_linux
git checkout -b dsp_bare origin/dsp_bare
git checkout -b dsp_rtt origin/dsp_rtt
|
回退版本
强制回退
1
2
3
4
5
6
7
8
|
# 查看历史
git log --oneline
# 回退到某版本
git reset --hard <commit_id>
# 强制推送(危险操作)
git push origin HEAD --force
|
软回退(不破坏历史),也可以用 revert
1
|
git revert <commit_id> # 撤销一个特定提交,但保留提交历史
|
创建版本 tag
主仓库和子模块都打 tag,并且主仓库在这个 tag 上锁定子模块的 tag 对应的 commit。
1️⃣ 创建版本 tag(主仓库 + 子模块一起)
假设你现在主仓库是 app_linux_arm,有子模块 pnna_driver 和 examples。
步骤
-
进入每个子模块,打 tag:
1
2
3
4
5
6
7
8
9
10
11
|
cd pnna_driver
git checkout main # 或你开发的分支
git pull origin main
git tag v20250829-driver
git push origin v20250829-driver
cd ../examples
git checkout main
git pull origin main
git tag v20250829-examples
git push origin v20250829-examples
|
-
回到主仓库,确保子模块都指向刚才的 tag:
1
2
3
|
cd ..
git add pnna_driver examples
git commit -m "Lock submodules to v20250829-driver and v20250829-examples"
|
-
给主仓库打 tag:
1
2
|
git tag v20250829
git push origin v20250829
|
这样就保证:
app_linux_arm@v20250829 固定指向某个 commit;
- 这个 commit 里,
pnna_driver 和 examples 也固定到对应 tag 的 commit。
→ 完全可复现 ✅。
2️⃣ 下载(clone 带子模块和 tag 的版本)
用户(或者你自己换电脑)需要获取这个固定版本,只需:
1
|
git clone --branch v20250829 --recurse-submodules https://gitlink.org.cn/nudt_dsp/app_linux_arm.git
|
然后子模块会被自动 checkout 到主仓库记录的 commit(也就是你当时打 tag 时的 commit)。
3️⃣ (可选验证)子模块确实在 tag 上
进入子模块验证:
1
2
3
4
5
6
7
|
cd pnna_driver
git describe --tags
# 应该输出 v20250829-driver
cd ../examples
git describe --tags
# 应该输出 v20250829-examples
|
删除 tag
1
2
3
4
5
|
# 删除本地
git tag -d v20250829
# 删除远程
git push origin :refs/tags/v20250829
|
看主仓库当前指向的子模块提交
输出形如:
1
2
|
be7fa48 examples (v20250829-examples)
1a2b3c4 pnna_driver (v20250829-driver)
|
✅ 总结:
- 子模块打 tag → 有独立版本号,方便复用;
- 主仓库打 tag 并提交子模块指针 → 锁定依赖关系;
- clone 时带
--recurse-submodules → 能完整复现当时环境。
其他
删除远程仓库中的文件夹
若 .vscode 已存在于 .gitignore 但未被忽略
可能是缓存未更新,需先清除缓存:
1
2
3
4
|
git rm -r --cached .vscode/
git add .
git commit -m "修复 .gitignore 缓存问题"
git push
|
通过以上步骤,即可精准删除远程仓库的 .vscode 文件夹,同时保留本地配置
让 Git 不再跟踪 Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 验证 Makefile 是否被追踪
git ls-files | grep Makefile
# 1. 移除已有文件的 Git 跟踪
git rm --cached Makefile
# 2. 确保 .gitignore 中有写:
echo "Makefile" >> .gitignore
# 3. 提交更新
git add .gitignore
git commit -m "Ignore Makefile"
git push
|
让本地修改 Makefile,但不被提交:
使用 Git 的 assume-unchanged 标志(适合不希望本地改动被 Git 检测到)
1
|
git update-index --assume-unchanged Makefile
|
此命令的作用是:
告诉 Git:“我本地会改这个文件,但你别提醒我,也别把改动加入 commit。”
💡 检查状态:
1
|
git ls-files -v | grep Makefile
|
前面有小写 h 表示被标记为“assume unchanged”。
🔁 若以后你又需要提交 Makefile 的改动,可以恢复跟踪:
1
|
git update-index --no-assume-unchanged Makefile
|
如果你只是不希望本地对 Makefile 的更改被提交,但远程还保留原始文件,你应该执行:
1
|
git update-index --assume-unchanged Makefile
|
而不是用 git rm –cached,否则会导致远程删除。
hugo
生成一个新的 markdown 文件
1
|
hugo new post/rtconfig_explanation/index.md
|
然后在 index.md 中,修改 draft 参数