Git
本地修改了分支-远程分支已有新提交-如何拉取🌸
暂存后拉取
提交本地更改:
使用
git add和git commit将本地更改提交到本地仓库。确保本地代码没有未提交的更改。拉取远程分支:
# your_branch_name 更改为本地分支名称(如 master/main/develop) git pull origin <your_branch_name>解决冲突:
如果在执行
git pull时发生冲突,Git 会提示你解决冲突。手动 解决冲突 并保存修改。提交合并:
一旦冲突解决完毕,使用
git add命令将解决后的文件添加到暂存区,并使用git commit提交合并的更改。推送到远程分支:
git push origin <your_branch_name>
使用 git stash
如果本地想在不执行commit的情况下拉取远程最新提交,需要使用 git stash 储藏工作区修改,再执行拉取操作,最后恢复修改。
储藏本地修改
git stash push -m "暂存本地修改(不包含未跟踪文件)"git stash push:将工作目录和暂存区的修改保存到“储藏栈”中,工作区会恢复到上次提交的干净状态。-m "描述":可选,添加备注便于识别(推荐使用)。
拉取远程最新提交
# your_branch_name 更改为本地分支名称(如 master/main/develop) git pull origin <your_branch_name>- 此时工作区无本地修改,可安全拉取远程最新代码。
恢复本地修改
git stash pop- 将最近一次储藏的修改恢复到工作区,并自动删除该储藏记录(若有冲突则不会自动删除)。
- 若恢复时发生冲突(文件被远程修改且本地也修改了),需手动解决冲突(冲突文件会包含
<<<<<<<标记)。
重要
当执行
git stash pop时,Git 会尝试将储藏的修改应用到当前工作目录。文件会有以下状态:四种状态
- Auto-merging
- 含义: 表示 Git 成功自动合并 这些文件。远程和
stash中的修改互不干扰,Git 能够自动将这些修改合并。 - 举例:
stash中的一个文件,修改了第10行;git pull下来的版本修改了第20行。这两处修改 Git 就会自动合并。
- 含义: 表示 Git 成功自动合并 这些文件。远程和
- Changes to be committed
- 含义: 这表示在您执行
git stash时,有些修改已经使用git add添加到了暂存区。在pop之后,这些修改 被成功地、自动地 恢复到了暂存区状态,等待您提交。 - 举例: 先修改了
a.txt并git add了它,然后执行了git stash。当pop时,这个对a.txt的修改就会直接出现在暂存区,而不是工作区。
- 含义: 这表示在您执行
- Unmerged paths
- 含义: 这是最关键的一项。表示 发生了合并冲突。有些文件在
stash的版本和git pull后的当前版本中,对 相同的位置 进行了修改,Git 无法自动决定该保留哪个修改,因此需要手动解决这些冲突。 - 文件状态: 这些文件会被标记为
both modified。 - 处理方式: 您需要打开这些文件,解决标记为
<<<<<<<,=======,>>>>>>>的冲突部分,然后使用git add命令将解决后的文件标记为已解决。
- 含义: 这是最关键的一项。表示 发生了合并冲突。有些文件在
- Untracked files
- 含义: 这表示在您执行
git stash时,工作目录中存在一些新增的、未被Git跟踪的文件。默认的git stash不会保存这些未跟踪文件(除非使用git stash -u或-a选项)。这里的提示可能是在告诉您这些文件依然存在,或者是从stash中恢复出来的(如果您用了-u)。
- 含义: 这表示在您执行
当发生冲突时
存在 Unmerged paths(合并冲突),
apply操作 被认为是没有“完全成功”的。Git 出于安全考虑,中断了自动删除的步骤,并给您留下了提示:警告
"The stash entry is kept in case you need it again."
这是由于:
git stash pop在应用存储时遇到了合并冲突不会自动删除stash。这个命令实际上是两个操作的组合:
git stash apply: 尝试将存储的修改应用到当前工作目录。git stash drop: 只有在apply成功完成(没有产生任何冲突)的情况下,才会自动删除对应的存储条目。
在您的情况下,由于存在 “Unmerged paths” (合并冲突),
apply操作被认为是没有“完全成功”的。Git 出于安全考虑,中断了自动删除的步骤,并给您留下了提示:这样做的目的是:
- 给您一个回退的机会: 如果您在解决冲突的过程中搞砸了,或者想放弃这次合并,您可以通过
git stash apply重新应用这个被保留的 stash,或者使用git checkout来撤销对冲突文件的修改,然后换个方式重新尝试。 - 防止数据丢失: 在冲突完全解决之前,Git 无法确定您的最终意图,因此它选择保留原始的存储内容,确保您的工作成果不会因为一次失败的自动合并而丢失。
⚠️ 关键注意事项
未跟踪文件(Untracked Files)
git stash默认不保存未跟踪文件(如新创建未git add的文件)。若需保存,使用:git stash push -u -m "暂存所有修改(含未跟踪文件)"-u参数会包含未跟踪文件。多批次储藏
可多次执行
git stash push保存多组修改,通过git stash list查看记录。恢复时用:git stash pop stash@{0} # 恢复指定储藏(0 为栈索引)若
git stash pop后出现冲突:- 手动编辑冲突文件(搜索
<<<<<<<标记)。 - 解决后执行
git add 冲突文件名标记为已解决。 - 最后
git stash drop删除储藏记录(pop失败时需手动删除)。
- 手动编辑冲突文件(搜索
替代方案(谨慎使用)
git commit -am "临时提交" # 将修改临时提交 git pull --rebase # 变基拉取(将临时提交置于最新提交之上) git reset HEAD~1 # 撤销临时提交,保留修改在工作区- 适用于熟悉
rebase的用户,操作更复杂但可避免储藏栈管理。
- 适用于熟悉
💡 操作流程图解
冲突处理
查看冲突文件状态,查看被标记为冲突(Unmerged paths) 的文件
git status手动解决文件冲突
用编辑器打开冲突文件:
code src/lib/components/layout/Sidebar/UserMenu.svelte在文件中查找冲突标记:
<<<<<<< Updated upstream // 以下是远程版本的代码(来自最新拉取的提交) // 远程修改内容... ======= // 以下是您本地修改的代码(来自 stash) // 本地修改内容... >>>>>>> Stashed changes手动编辑文件:选择保留远程版本/本地版本,或合并两者,并删除所有冲突标记:
<<<<<<<、=======、>>>>>>>。
标记冲突已解决
# 此命令告知 Git 该文件冲突已解决 git add src/lib/components/layout/Sidebar/UserMenu.svelte完成
stash恢复重要
再此之前应该先执行
git status确认冲突文件已经全部解决。git stash drop- 手动删除被保留的
stash条目(因为pop未自动完成,Git 不会自动删除最近一条stash记录。) - 使用
git stash list可查看所有储藏记录。
- 手动删除被保留的
恢复工作区更改
在使用 git stash pop 恢复储藏区更改遇到冲突之后,仓库处于混合状态:
- 已应用:
stash中的部分修改 - 冲突中(如果有):与远程更新冲突的文件
- 已更新:
git pull成功拉取的远程内容
使用 git restore 放弃对已追踪文件的修改(推荐)Git 2.23+ 引入
# 恢复所有文件到最新一次提交的状态
git restore .
# 重新应用最新的一次 `stash`
git stash apply stash@{0}
.表示当前目录
提示
传统命令(Git 1.6.0+)
git checkout -- .
--是一个分隔符,表示"后面是文件路径,而不是分支名".表示当前目录
使用 git reset 撤销恢复(不推荐)
重要
放弃当前冲突恢复(恢复工作区到执行 git stash pop 之前的状态),它彻底清除了工作目录和暂存区中所有未提交的更改。这包括:
- 执行
stash pop之前已经存在于工作目录但尚未提交的本地修改。 stash pop操作试图应用的来自暂存区的修改。stash pop操作产生的所有冲突标记。
git reset --hard HEAD
# 重新应用 `stash`
git stash apply stash@{0}
冲突预防建议:
# 下次 `stash` 时添加详细描述
git stash push -m "修改描述_日期"
# 拉取前检查差异
git diff origin/main...HEAD # 替换 main 为您的分支名
上传本地代码到 GitHub
提示
以下默认远程仓库别名为 origin 。
在 GitHub 上创建仓库。
初始化本地仓库:
- 进入项目文件夹内并在此打开命令行终端。
初始化 Git 仓库:
git init -b <local_branch_name>重要
远程仓库有内容的时候,不要加
-b选项。添加远程仓库链接:
git remote add origin <remote_repository_url>添加和提交代码:
重要
如果远程仓库有初始化好的 README.md 等文件,先拉取仓库最新文件:
# 获取远程分支信息 git fetch origin # (推荐)从远程分支创建本地同名跟踪分支 git checkout -t <remote_name>/<branch_name> # (不推荐)创建并切换到本地分支(自动跟踪远程分支) git checkout -b <local_branch_name> origin/<remote_branch_name> # (不推荐)使用专注切换分支的语法: git switch -c <local_branch_name> origin/<remote_branch_name>继续下方操作。
# 将所有本地文件添加到暂存区 git add . # 将暂存区的更改提交到本地仓库 git commit -m "Initial commit"推送到远程仓库:
git push -u origin <branch_name>提示
-u参数是--set-upstream的简写。- 设置上游分支关联:将本地的分支与远程的
origin/<branch_name>分支建立跟踪关系。 - 简化后续操作:设置关联后,以后执行
git push和git pull时就不需要指定远程仓库和分支名了。
参考:git branch
- 设置上游分支关联:将本地的分支与远程的
查看自己有权限项目
Github:Repositories
远程分支名称解析
在 Git 中,远程分支名称如 origin/main 的命名规则和本地分支 main 的关系,是由 Git 的分支管理机制决定的,核心原因在于 命名空间隔离 和 远程跟踪分支(Remote-Tracking Branch) 的设计。以下是详细解释:
1. 为什么远程分支叫 origin/main?
origin是远程仓库的别名:
当你克隆仓库时,Git 默认将远程仓库命名为origin(可自定义)。origin代表远程仓库的 URL 地址。提示
如果你有多个Remote,则根据这个别名判断分支来自那个Remote。
斜杠
/是命名空间分隔符:origin/main表示“远程仓库origin上的main分支”。斜杠的作用是:- 避免本地分支与远程分支同名冲突(例如本地可同时存在
main和origin/main)。 - 明确标识分支的来源(远程仓库名 + 分支名)。
- 避免本地分支与远程分支同名冲突(例如本地可同时存在
2. 为什么拉取后本地分支叫 main?
- 远程跟踪分支(Remote-Tracking Branch):
origin/main是一个本地存在的引用,它记录远程仓库origin上main分支的最新状态。它不是真正的本地分支,而是 Git 在本地创建的“影子分支”,用于跟踪远程变化。 - 创建本地分支:
当你运行git checkout main(或git switch main)时,Git 会:- 查找本地是否存在
main分支。 - 若不存在,则自动基于
origin/main创建同名的本地分支main,并建立跟踪关系(Tracking Relationship)。
# 示例:拉取远程 main 分支到本地 git checkout main # 等价于:git checkout -b main --track origin/main - 查找本地是否存在
3. 关键概念解析
| 类型 | 名称示例 | 作用 |
|---|---|---|
| 远程仓库别名 | origin | 指向远程仓库 URL 的简称(默认为 origin) |
| 远程跟踪分支 | origin/main | 本地存储的远程分支状态,只读(通过 git fetch 更新) |
| 本地分支 | main | 用户实际操作的开发分支,可提交代码 |
| 跟踪关系(Tracking) | main → origin/main | 本地分支与远程分支的关联,git pull/git push 无需指定远程分支 |
4. 设计目的与优势
- 隔离性:
远程分支(origin/main)和本地分支(main)物理分离,防止误操作覆盖远程分支。 - 清晰的状态管理:
git status会提示本地分支与origin/main的提交差异(例如领先或落后)。git branch -a可同时查看本地分支和远程跟踪分支(以remotes/origin/开头)。
- 简化协作流程:
通过跟踪关系,git pull=git fetch(更新origin/main) +git merge origin/main(合并到本地分支)。
5. 常见操作示例
- 查看远程跟踪分支:
git branch -r # 显示所有远程跟踪分支(如 origin/main) - 手动建立跟踪关系:
git branch -u origin/main # 将当前本地分支跟踪到 origin/main - 删除远程跟踪分支(当远程分支已删除):
git fetch origin --prune # 清理本地失效的远程跟踪分支
总结
origin/main是 Git 在本地创建的远程跟踪分支,用于记录远程仓库状态,命名格式为<远程仓库名>/<分支名>。main是用户操作的本地分支,通过git checkout基于origin/main创建并自动建立跟踪关系。- 斜杠
/是 Git 的命名约定,确保本地与远程分支的命名空间互不冲突。
这种设计既保证了远程分支状态的独立性,又简化了本地开发流程,是 Git 分布式架构的核心特性之一。
——————————
文件状态
在Git中,文件的状态可以分为以下几种:
- 未跟踪(Untracked):文件是新的,Git之前没有跟踪过。
- 已修改(Modified):文件被修改了,但还没有被暂存(unstaged changes)。
- 已暂存(Staged):文件被修改并且已经通过
git add命令添加到了暂存区,等待提交。 - 未修改(Unmodified):文件没有修改,或者修改已经被提交。
在 VS Code 的 Git 窗口中,文件被分为 "Staged Changes" 和 "Changes" 两类,这是 Git 工作流程的核心设计,具体区别如下:
Changes(未暂存的修改)
- 含义:文件已被修改(或新增),但尚未添加到 Git 的暂存区(Staging Area)。
- 状态特点:
- 文件处于工作目录(Working Directory)中。
- 这些修改不会被包含在下一次
git commit中。 - 在 VS Code 中显示为 "Changes" 分组(通常位于顶部)。
- 操作建议:
- 点击文件旁的 "+" 图标 或右键选择 "Stage Changes" 可将其移至暂存区(相当于
git add)。 - 直接编辑文件会导致此分组动态更新。
- 点击文件旁的 "+" 图标 或右键选择 "Stage Changes" 可将其移至暂存区(相当于
Staged Changes(已暂存的修改)
- 含义:文件已通过
git add添加到暂存区,准备被提交。 - 状态特点:
- 文件已进入 Git 的暂存区(Index)。
- 这些修改会被包含在下一次
git commit中。 - 在 VS Code 中显示为 "Staged Changes" 分组(位于 "Changes" 下方)。
- 操作建议:
- 点击文件旁的 "-" 图标 或右键选择 "Unstage Changes" 可移回未暂存状态(相当于
git restore --staged)。 - 点击 √ 提交按钮 会提交此分组的所有文件。
- 点击文件旁的 "-" 图标 或右键选择 "Unstage Changes" 可移回未暂存状态(相当于
- 含义:文件已通过
⚙️ 设计目的:精准控制提交内容
Git 通过分离 工作目录 → 暂存区 → 版本库 的三级流程,实现:
- 选择性提交:仅暂存部分文件(如只提交功能 A 的代码,暂不提交调试日志)。
- 分批提交:将大改动拆解为多个逻辑独立的提交。
- 减少误提交:避免未完成的修改意外进入版本历史。
💡 VS Code 操作对比表
| 状态 | VS Code 显示分组 | 操作 | 等效 Git 命令 |
|---|---|---|---|
| 未暂存的修改 | Changes | 点击 + | git add <file> |
| 已暂存的修改 | Staged Changes | 点击 - | git restore --staged <file> |
提示
示例场景
假设你修改了 a.js 和 b.js:
- 初始状态 → 两文件均显示在 "Changes" 分组。
- 点击
a.js旁的 "+" →a.js移动到 "Staged Changes"。 - 点击提交按钮 → 仅提交
a.js,b.js仍保留在未暂存状态。
Repo
Repo 基于git的工具,它用来管理多个git代码库。把所有的代码用一个git库管理已经越来越力不从心。这个时候的一个很自然的思路就是分而治之,把整个project按模块分成一个个单独的git库,再用一个统一的工具管理,repo因此应运而生。
规范
常用 Commit 标签描述
| 标签 | 描述 | 示例 |
|---|---|---|
feat | 新功能 | feat: 添加用户注册端点 |
fix | 修复 bug | fix: 修复首页数据无法加载的问题 |
docs | 仅文档更改 | docs: 更新 API 接口文档 |
style | 代码风格调整(不影响代码运行) | style: 修正变量命名缩进 |
refactor | 代码重构(既非新功能,也非修 bug) | refactor: 使用策略模式重构支付逻辑 |
perf | 性能优化 | perf: 使用 memo 缓存组件减少重复渲染 |
test | 添加或修改测试用例 | test: 为用户服务添加单元测试 |
build | 影响构建系统或外部依赖的更改 | build: 升级 webpack 到 v5 |
ci | 持续集成配置和脚本的更改 | ci: 在 GitHub Actions 中增加 SonarQube 检查 |
chore | 其他不修改源码或测试文件的杂项变更 | chore: 更新依赖包版本 |
revert | 回滚之前的提交 | revert: 回滚提交 abc123 |
例如:
feat: 添加用户登录功能
- 实现用户名密码登录
- 添加记住密码功能
- 优化登录错误提示
Closes #123
命令✨
| 命令 | 命令示例 | 详细解释 |
|---|---|---|
| git init | git init | 在当前目录初始化一个新的Git仓库 |
| git clone <repository_url> | git clone https://github.com/user/repo.git | 克隆远程仓库到本地 |
| git add <file_path> | git add file.txt | 将文件添加到暂存区 |
| git commit -m "<commit_message>" | git commit -m "Add new feature" | 将暂存区的内容提交到本地仓库 |
| git status | git status | 显示工作树的状态 |
| git push <remote_name> <branch_name> | git push origin master | 将本地仓库的内容推送到远程仓库 |
| git pull <remote_name> <branch_name> | git pull origin master | 从远程仓库拉取内容到本地仓库 |
| git branch | git branch | 显示本地分支列表 |
| git checkout <branch_name> | git checkout main_branch | 切换到指定分支 |
| git merge <branch_name> | git merge feature_branch | 将指定分支合并到当前分支 |
| git remote | git remote | 显示远程仓库的别名列表 |
| git fetch <remote_name> | git fetch origin | 从远程仓库获取最新内容,但不合并到本地仓库 |
| git log | git log | 显示提交历史记录 添加 --oneline 查看简洁版 |
| git reset <commit_hash> | git reset commit_hash | 将HEAD指针指向特定的提交,可选地重置暂存区和工作树 |
| git revert <commit_hash> | git revert commit_hash | 创建一个新的提交,撤销指定提交的更改 |
| git stash | git stash push -m "暂存本地修改" git stash pop | 将当前工作树中的变更保存到堆栈中,以便稍后恢复 |
| git cherry-pick <commit_hash> | git cherry-pick commit_hash | 选择一个特定的提交并将其应用到当前分支 |
| git remote add <remote_name> <repository_url> | git remote add origin https://github.com/user/repo.git | 添加远程仓库别名 |
| git remote remove <remote_name> | git remote remove origin | 移除指定的远程仓库别名 |
| git diff | git diff | 显示暂存区和工作树之间的差异 |
| git diff <commit_old_hash> <commit_new_hash> | git diff 343e12b1 ad494be0 --stat | 查看new相对于old提交之间的差异,加上 --stat 参数则只输出统计信息; |
| git tag <tag_name> | git tag v1.0.0 | 创建一个新的标签 |
| git push --tags | git push --tags | 将本地标签推送到远程仓库 |
| git config --global <config_param> "<config_value>" | git config --global user.name "John Doe" | 配置Git的全局设置 |
| git log --graph | git log --graph | 以图形方式显示提交历史记录 |
| git clean [-n] | git clean -n | 显示将要删除的未跟踪文件列表,使用-f进行实际删除 |
| git rm <file_path> | git rm file.txt | 从Git中删除文件 |
| git show <commit_hash> | git show commit_hash | 显示特定提交的详细信息 |
| git rebase <branch_name> | git rebase main_branch | 将当前分支的更改在指定分支上重新应用 |
命令行参数符号
<>尖括号:- 一般代表命令必填参数,即在执行命令时必须提供的参数。
- 示例:
command <required_parameter>
[]方括号:- 一般代表命令可选参数,即在执行命令时可以选择性地提供的参数,但不是必需的。
- 示例:
command [optional_parameter]
{}花括号:- 有时也用于表示命令必填参数,与尖括号类似。这种用法可能因具体的命令规范而异。
- 示例:
command {required_parameter}
()圆括号:- 圆括号在命令行中通常用于表示一组选项,用户可以从中选择一个。
- 示例:
command (option1 | option2 | option3)
|管道符号:- 管道符号用于将一个命令的输出作为另一个命令的输入。不表示参数本身,但是在命令行操作中很常见。
- 示例:
command1 | command2
...省略号:- 省略号表示参数可以重复出现多次。
- 示例:
command <required_parameter> ...
重要
HEAD 在Git概念中一个特殊的存在,它不直接指向分支,而是指向 当前检出的提交 。详细看 git log tip块中关于 HEAD 的解释。
在命令行中使用,有以下作用:
HEAD: 指代当前提交HEAD^/HEAD~/HEAD~1: 均指上一次提交HEAD^^/HEAD~2: 均值上上一次提交,以此类推。# 例如 git checkout main # HEAD -> main -> 最新提交 git show HEAD~ # 显示 main 分支的上一个提交
查看待commit的文件路径
待commit:已添加到暂存区
git diff --name-only --cached
提示
命令执行之后
- 键入:q 退出命令
- 键入:s 输入文件名称保存到项目根路径
git pull 和 git fetch 区别
提示
先总结:
git pull <remote_name> <branch_name>从远程仓库获取最新代码并 直接合并 到当前分支。git fetch <remote_name> <branch_name>仅从远程仓库获取最新代码但 不进行合并 。
具体区别
git pull:git pull=git fetch+git merge。git pull <remote_name> <branch_name> # 相当于 git fetch <remote_name> <branch_name> git merge <remote_name>/<branch_name>如果有冲突,你需要解决冲突后才能完成合并。
git pull的执行过程会直接更新当前分支的工作目录。
git fetch:git fetch从远程仓库获取最新的提交记录和分支信息,但不会将这些更改直接合并到当前分支。- 它只会将获取的远程分支更新到本地仓库的
.git目录下,而不会修改工作目录中的文件。 git fetch可以帮助你了解远程仓库的最新状态,你可以通过查看远程分支来了解它的提交记录,然后决定是否要进行合并操作。
git merge
将远程分支的更新合并到当前的分支,需要手动执行 git merge 或者其他合并命令(例如 git rebase)来将这些更新应用到你的工作目录和分支。
下面是一种常见的步骤来将远程分支的更新合并到你当前的分支:
git fetch: 从远程仓库获取最新提交记录和分支信息。git merge <remote_name>/<remote_branch_name>: 将远程分支合并到你当前的分支。
或者也可以用 git pull 命令来达到相同的目的,因为 git pull 实际上 = git fetch + git merge :
git pull <remote_name> <remote_branch_name>
无论是使用 git fetch 和手动 git merge,还是直接使用 git pull,都要确保在执行合并操作之前没有未提交的更改,以免可能产生冲突。如果有冲突,你需要先解决冲突后再提交合并的更改。
git stash
当需要 切换到其他分支 或 本地已经做了修改需要拉取远程代码,不希望携带当前工作区内未commit的内容时,stash就派上了用场,它可以储藏当前未commit的数据。
重要
在 Windows 终端或某些 shell 中,stash@{0} 中的花括号 {} 可能被错误解析。实际使用时,可以直接使用数字索引,Git2.11.0+(2016-11-29发布) 会自动识别。只需要键入 index 对应的阿拉伯数字即可。另外提供老版本兼容办法:
- 可以使用
^号进行转义:stash^@{index} - 加双引号:
"stash@{index}"
注:最近一次 stash 记录的 index 值总是 0 。
例如:
>git stash list
stash@{0}: On main: 版本2 # 最近 `stash` 的记录
stash@{1}: On main: 版本1 # 最早 `stash` 的记录
# 查看stash{0}与当前工作区的详细行变更
## `-p` 参数表示以补丁格式显示,包含具体的代码变更
> git stash show -p 0
用法:
储藏工作区内的修改,并给此次
stash命名git stash push -m '暂存提交'重要
如果需要包含以下三种文件,使用
-u选项:- 已暂存文件(已经
git add过的) - 未暂存文件(工作区内修改)
- 未跟踪文件(刚新增还未跟踪的文件)
git stash push -m '暂存提交' -u提示
对比
git stash save的优势?git stash push支持一个非常重要的特性:路径限定符-- <pathspec>。这允许你只暂存工作目录中特定文件或路径的更改,而不是整个工作目录。例如:git stash push -m "暂存src/的修改" -- src/ git stash push -m "暂存file.txt" -- file.txt- 已暂存文件(已经
查看所有的
stashgit stash list查看特定的
stashgit stash show -p stash@{index} # 例如 git stash show -p 0-p:以补丁格式显示,包含具体的代码变更。(不加则仅查看改动了几个文件,一共新增/删除多少行,类似git diff --stat)
恢复最近一次储藏的修改,并将其从
stash列表中移除git stash pop重要
相当于
# 恢复最新的储藏,并在成功恢复之后删除它。 git stash apply && git stash drop如果恢复发生了冲突,Git不会自动删除这个stash,需要手动进行 冲突处理 。
恢复特定的
stashgit stash apply stash@{index}删除特定的
stash,但不会恢复其中的修改git stash drop stash@{index} # 例如 git stash drop 0删除所有暂存的
stashgit stash clear
git diff
比较不同版本、文件或分支之间差异
提示
通用选项
--stat:统计变更摘要(增/删行数)--word-diff:显示单词级差异(非行级)
输出格式说明
---表示修改前的文件。+++表示修改后的文件。-开头的行:被删除的内容。+开头的行:新增的内容。- 上下文行(无符号):未更改的代码,用于定位变更位置。
- 冲突标记:查看这里第2条内容
@@ ... @@变更块头:例如:@@ -55,6 +55,12 @@,则表示这段diff:- 从 文件修改前 的视角看,是从 55 行开始打印,共打印 6 行。
- 从 文件修改后 的视角看,是从 55 行开始打印,共打印了 12 行。
- 前 -> 后 差异为
12 - 6 = 6行,正数,代表新增了 6 行。
比较工作区与暂存区
查看已修改但未暂存(未
git add)的文件内容变化:git diff
比较暂存区与最新提交
查看已暂存但未提交(已
git add)的更改:git diff --staged # 或 git diff --cached
比较两个提交之间的差异
指定两个提交的哈希值或引用
git diff <commit_from> <commit_to>提示
以
commit-from为基准,显示从commit_from到commit_to的代码变化。+:commit_to新增的内容-:表示commit_to删除的内容- 整体展示的是:从
commit_from变为commit_to做了什么修改
比较分支之间的差异
查看两个分支的最新提交差异:
git diff <branch1> <branch2>比较当前分支与另一分支:
git diff <branch_name>
比较特定文件的更改
限定只查看某个文件的差异:
git diff <file_path>跨分支比较指定文件:
git diff <branch1> <branch2> -- <file_path>
git reset
提示
如果在执行完 git commit(提交到本地)还没有执行 git push(推送到云端)时,是可以将更改撤回到工作区的。
HEAD^也可以写作HEAD~,意为最近1次commit。HEAD~2,意为最近2次commit,以此类推。
撤销提交,保留修改(最常用)
场景:你刚刚执行了
git commit,发现代码写错了,或者需要修改一下再提交。命令:
git reset --soft HEAD^效果:
撤销最近一次 commit。
代码的修改仍然保留在暂存区(即保留了
git add的状态)。你可以直接修改文件,然后再次
git commit。
撤销提交,保留修改但不暂存
场景:你想撤销 commit,并且想把修改撤回到工作区(未 add 的状态)。
命令:
git reset --mixed HEAD^ # 或者简写为 git reset HEAD^效果:
- 撤销最近一次 commit。
- 代码的修改保留在工作区,但不在暂存区(需要重新
git add)。 - 你可以直接修改文件,然后再次
git commit。
彻底丢弃提交
警告
慎用!(剑魔不能用😂)
场景:刚才提交的内容完全错了,你想彻底回到上一步,并丢掉刚才写的所有代码。
命令:
git reset --hard HEAD^效果:
- 撤销最近一次 commit。
- 彻底删除所有刚才的修改,代码恢复到上一次 commit 的状态。
- 警告:这些修改无法找回(除非你之前有其他备份)。
git status
首先输出:
On branch master Your branch is up to date with 'origin/master'.这段
git status的输出非常理想,它告诉你当前的代码状态是 完全同步 的。你当前正处在本地的
master分支上工作。你的本地分支master和远程分支origin/master的内容是 一模一样 的。然后是当前工作区工作树状态,主要有以下几种状态:
未跟踪(Untracked)
说明:Git 尚未开始跟踪的新文件
命令行显示:
Untracked files
已修改但未暂存(Modified - unstaged)
说明:已跟踪的文件被修改,但还未添加到暂存区
命令行显示:
Changes not staged for commit
已暂存(Staged)
说明:文件修改已添加到暂存区,准备提交
命令行显示:
Changes to be committed
未修改(Unchanged)
说明:文件自上次提交后未被修改
不会在
git status中显示
git branch
查看所有分支(本地 + 远程):
使用
-a(all) 参数:git branch -a命令输出
* master remotes/orgin/HEAD -> origin/master remotes/origin/fix提示
* master- 含义:这是本地分支。
*(星号):表示这是你当前所在的分支。你现在所有的操作(提交代码等)都会发生在这个分支上。master:分支的名称。
remotes/origin/HEAD -> origin/master- 含义:这是远程仓库的默认分支指针。
- 解释:这表示当你克隆这个远程仓库时,如果不指定具体的分支名,Git 默认会拉取
origin/master这个分支。 - 比喻:它是一个快捷方式,指向了远程仓库的“主分支”。通常不需要手动修改它。
remotes/origin/fix- 含义:这是远程分支。
- 解释:这表示在远程仓库(origin)上有一个名为
fix的分支。 - 状态:这个分支目前只存在于远程服务器上,你的本地还没有一个叫
fix的分支来跟踪它(或者你之前有但还没更新)。
查看本地分支与远程分支关联关系:
git branch -vv
# 输出依次为:`当前所在分支名称`,`上次提交hash`,`远程分支名`,`commit comment`
* master bec7edc [origin/master] 更新xxx文件
创建本地分支:
git branch <本地分支名> <远程分支名>
使用
git checkout <本地分支名>切换分支也可以使用下面的一步操作
git checkout -b <本地分支名> <远程分支名>
删除分支:
git branch -d <branch_name>
-D:强制删除(不会验证 待删除分支 是否已经合并到 当前分支 )
给当前分支 设置上游分支:
提示
设置上游分支之后,在 push 和 pull 的时候就不用每次都指定远程分支的名称了。
git branch --set-upstream-to=origin/<remote_branch_name>
提示
# 或者使用简写 -u(在 push 或 pull 时设置)
git push -u <remote_name> <local_branch_name>
# 或者
git pull -u <remote_name> <remote_branch_name>
git checkout
从远程分支创建本地同名跟踪分支(最常用):
git checkout -t <remote_name>/<branch_name>
# 或者简写
git checkout main
基于当前提交创建一个全新的分支:
git checkout -b feature/new-feature
从某个提交创建分支:
git checkout -b <new_branch_name> <commit_hash>
拉取远程分支的时候重命名:
# 使用 --track 选项(更明确,但需要包含远程别名)
git checkout -b <local_branch_name> --track origin/<remote_branch_name>
# 简写
git checkout -b <local_branch_name> <remote_branch_name>
git log
基础用法:
# 输出示例 7xxxxx3 (HEAD -> main, origin/main, origin/HEAD) 新增xxx方法 6xxxxx7 修复xxx问题第一列:本次提交HASH
第二列(如果有):括号内代表当前有哪些分支处于这一次提交
第三列:commit comment
提示
第二列括号内的内容,可以比喻成每一次提交相当于创建了一个停车场,每一个分支是一辆车,括号内填了谁,就代表这辆车当前停在这。
HEAD 比较特殊,它不直接指向分支,而是指向 当前检出的提交 ,把 HEAD 比喻成你,你现在也在这个停车场内,但是具体下来有两种情况:
- 正常情况下:HEAD 会 间接 指向分支名。例如你
checkout main,相当于你坐上了 main 这辆车,HEAD 通过 main 分支指向最新提交,显示为(HEAD -> main)。 - 分离头指针:当你
checkout一个具体的提交Hash时,就像你没乘坐任何车(没跟随分支)而走进了停车场(检出了代码)。HEAD 直接指向该提交,显示为(HEAD)。这就叫“分离头指针”状态。
- 正常情况下:HEAD 会 间接 指向分支名。例如你
查看最近一次提交的简要更改(类似
git show)git log -1 -p--name-only:只显示变更的文件名-1:数字参数,限制显示的提交数量为 1 条-p或--patch:显示提交引入的具体代码变更(差异对比)提示
代码差异输出格式统一使用
git diff同等样式。
git show
查看commit的详细更改
提示
代码差异输出格式统一使用 git diff 同等样式。
查看指定Hash的详细更改(不指定选项默认:最近一次)
git show [commit_hash]--stat:只显示变更文件统计信息--name-only:只显示变更的文件名--color-words:更友好的显示方式
查看指定文件的最近更改
git show <文件名>查看指定提交中某个文件的差异
git show <commit_bash> -- <file_path> # 显示提交完成时的文件完整内容 git show <commit_bash>:<file_path>图形化方式查看
gitk HEAD
git tag
标签是一个指向某个特定提交的 静态指针 。所以是可以不和代码一起提交的。
创建标签
# 创建轻量标签(lightweight tag) git tag v1.0.0 # 创建带注释的标签(annotated tag)- 推荐 git tag -a v1.0.1 -m "版本v1.0.1发布说明" # 为特定提交创建标签 git tag -a v1.0.2 <commit_hash> -m "标签说明"提示
没指定
commit_hash选项时的默认行为是给当前的HEAD所指向的提交创建标签。查看标签
# 查看所有标签 git tag # 查看标签详情 git show v1.0.1 # 按模式搜索标签 git tag -l "v1.0*"
推送标签到远程仓库
推送单个标签
# 推送指定标签 git push origin v1.0.1 # 或者使用完整格式 git push origin refs/tags/v1.0.1推送所有标签
git push origin --tags同时推送代码和标签
# 先推送代码分支 git push origin main # 再推送标签 git push origin --tags # 或者一步完成(如果分支和标签都需要推送) git push origin main --tags提示
如果需要给当前还在工作区的代码打tag,需要先commit之后再执行
git tag。最后执行上方相关push命令。
其他常用操作
# 删除本地标签
git tag -d v1.0.0
# 删除远程标签()
git push origin --delete v1.0.0
# 拉取远程标签
git fetch --tags
代理
配置代理
# Set HTTP proxy
git config --global http.proxy "http://127.0.0.1:7890"
# Set HTTPS proxy
git config --global https.proxy "http://127.0.0.1:7890"
# 验证
git config --get http.proxy
git config --get https.proxy
取消代理
# Unset HTTP proxy
git config --global --unset http.proxy
IDEA的 Update Project
场景一:默认/使用 Merge 方式更新
相当于 git pull ,这是最传统、最安全的方式。
执行的 Git 指令序列大致如下:
git fetch origin- 这是最关键的一步。它从远程仓库(通常是
origin)获取所有最新的分支、标签信息,但不会自动合并到你的当前工作分支。它只是让你本地知道远程仓库现在是什么样子。
- 这是最关键的一步。它从远程仓库(通常是
git merge origin/your-current-branch-name(例如git merge origin/main)- 在
fetch获取到远程的最新信息后,IDEA 会将远程分支(origin/main)合并 到你当前检出的本地分支(main)。
- 在
简单来说,Merge 方式 = git fetch + git merge
结果: 如果远程有新的提交,你的本地分支会生成一个额外的 合并提交,将两条开发线汇合。
场景二:使用 Rebase 方式更新
这是一种更线性和整洁的更新方式,也是目前很多团队推荐的做法。
执行的 Git 指令序列大致如下:
git fetch origin- 同样,第一步永远是先获取远程的最新信息。
git rebase origin/your-current-branch-name(例如git rebase origin/main)- 在
fetch之后,IDEA 不是执行合并,而是执行 变基。它会将你本地尚未推送到远程的提交“暂时取下”,然后基于远程最新的提交重新应用你的提交。
- 在
简单来说,Rebase 方式 = git fetch + git rebase
结果: 你的本地提交会“移动”到项目最新提交的顶端,形成一条直线式的历史,没有合并提交。
如何查看和配置更新类型?
在 IDEA 中,路径是:
File -> Settings -> Version Control -> Git
在右侧找到 Update Method 进行选择。
- Merge: 默认选项。
- Rebase: 更干净的提交历史。
- Branch Default: 使用为该分支配置的默认策略。
特殊情况下的行为
- 如果当前分支有未提交的更改:
IDEA 非常智能,它不会直接执行merge或rebase,因为这会与未提交的更改冲突。它会先尝试 Stash(储藏) 你的更改。- 相当于执行:
git stash push -m "IDEA Stash before Update" - 然后执行
git fetch+git merge/rebase - 最后再尝试 Unstash(应用储藏):
git stash pop - 如果应用储藏时发生冲突,IDEA 会提示你解决冲突。
- 相当于执行:
- 如果当前分支在远程没有对应的上游分支:
IDEA 的 Update Project 按钮可能会变灰或无法正常工作,因为它不知道要和哪个远程分支进行同步。
总结对比
| 特性 | Merge 方式 | Rebase 方式 |
|---|---|---|
| 等效命令 | git fetch + git merge | git fetch + git rebase |
| 提交历史 | 保留合并提交,呈网状 | 线性整洁,像一条直线 |
| 安全性 | 较高,不重写历史 | 较低,重写了本地提交历史 |
| 适用场景 | 公共分支(如 main/master),团队新手友好 | 个人功能分支,追求清晰历史 |
多 Remote
(一个本地项目,关联两个远程仓库)
1. 准备本地仓库
可以用现有仓库,也可以新建一个:
git init
如果已经连接了 GitHub 或其他远程,执行:
git remote -v
会看到类似输出:
origin git@github.com:username/repo.git (fetch)
origin git@github.com:username/repo.git (push)
2. 添加第二个远程仓库
假设第二个远程是 GitLab,远程名可以自定义,常见如 origin2 或 gitlab,这里用清晰的 gitlab :
git remote add gitlab git@gitlab.com:username/repo.git
再次查看:
git remote -v
输出会是:
origin git@github.com:username/repo.git (fetch)
origin git@github.com:username/repo.git (push)
gitlab git@gitlab.com:username/repo.git (fetch)
gitlab git@gitlab.com:username/repo.git (push)
这样你就同时关联了两个远程。
3. 同时推送到两个远程仓库
有两种方式:
方式一:手动分别推送
git push origin main
git push gitlab main
灵活且安全,但要多执行一次命令。
方式二:配置多推送地址,实现一次命令推送两个远程
编辑 .git/config,在 [remote "origin"] 下添加多条 pushurl:
[remote "origin"]
url = git@github.com:username/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
pushurl = git@github.com:username/repo.git
pushurl = git@gitlab.com:username/repo.git
此后执行:
git push origin main
就会同步推送到 GitHub 和 GitLab 两个仓库。
警告
如果用于 CI/CD,请确保两个仓库的流水线不会因同一提交重复触发,这点很重要。
额外操作:重命名或删除远程
重命名远程:
git remote rename origin github1
删除远程:
git remote remove gitlab1
提示
为什么要用两个远程?
- 备份:GitHub 崩了,GitLab 还在;
- 迁移:试用新平台,旧平台继续线上运行;
- 镜像:想多地方展示代码,简单又直观;
- CI/CD 分离:GitHub 管理代码,GitLab 管理部署。
Submodule
核心概念
定义:Git Submodule 允许一个 Git 仓库引用另一个 Git 仓库作为子目录。子模块本质上是一个指向特定提交哈希的指针,而非文件本身。
特点:
- 子模块拥有独立的版本历史、分支和标签
- 父仓库仅记录子模块的提交 ID(Commit Hash)
- 主仓库不负责子模块的代码维护,但需要手动同步更新版本
提示
父仓库“看”不到子模块的分支,它只记录一个特定的 Commit ID(哈希值)。
- 通过命令
git submodule status查看
所以无论你在子模块里切到了哪个分支,父仓库只认准那个哈希值对应的代码状态。
警告
如果子模块没有显式指定分支的话,默认子模块处于 分离头指针 状态。
Git 将子模块信息存储在两个关键位置
.gitmodules(仓库内)- 受版本控制,随仓库同步。使用
submodule相关命令的时候会自动更新。 - 记录子模块路径与 URL 的映射关系
- 受版本控制,随仓库同步。使用
.git/config(本地)- 本地配置,不随仓库同步
- 记录具体的克隆 URL 和设置
主仓库记录子模块哈希值的地方有两个
.gitmodules文件(配置信息:URL、路径、跟踪分支等)[submodule "path/to/submodule"] path = path/to/submodule url = https://github.com/user/repo.git branch = main.git/modules目录(实际哈希存储).git/modules/<子模块路径>/HEAD .git/modules/<子模块路径>/refs/heads/ # 分支引用 .git/modules/<子模块路径>/refs/remotes/ # 远程引用
提示
使用 git submodule sync 可将 .gitmodules 中的 URL 更新同步到本地 .git/config(仅影响已经注册过的子模块)。
- 指定
--recursive选项后,将 递归 更新注册过的子模块。
添加
# 基本用法
git submodule add <repository_url> <path>
# 指定分支添加
git submodule add -b <branch_name> <repository_url> <path>
后续步骤:
- 执行后会产生
.gitmodules文件和子模块目录 - 必须提交这两个更改到主仓库:
git add .gitmodules <path>
git commit -m "添加子模块"
克隆
方式一:一键克隆(推荐)
git clone --recurse-submodules <repository_url>
方式二:分步操作
# 1. 克隆主仓库
git clone <repository_url>
cd <project_name>
# 2. 初始化并递归更新子模块
git submodule update --init --recursive
或者
# 1. 克隆主仓库
git clone <repository_url>
cd <project_name>
# 初始化并递归更新子模块
git submodule init
git submodule update --recursive
## 上方两步可以省略为一步操作
git submodule update --init --recursive
更新
重要
- 这里的更新指的是 更新子模块到远程最新状态 ,而不是提交代码到子模块的意思。
- 有很多解释说,执行完下面的更新命令需要执行
git add <submodule_path>,如果你并不是主项目的维护者,完全不必做这一步操作。这一步的作用只是为了更新主项目中记录的子模块HASH,但此时子模块中的代码已经是最新的了。
更新所有子模块:
提示
默认只更新第一层子模块,需要递归一般都需要加上 --recursive 选项。
更新子模块到主项目记录的状态(需要先手动更新主项目)
git submodule update--checkout:该选项即是该命令的默认行为,可以省略。
更新子模块到子模块远程的最新状态
git submodule update --remote--remote:本地如果有修改,远程会直接覆盖。--merge:本地有修改,远程尝试合并,如果有冲突会提示。
提示
使用
git submodule update命令来让子模块回到主项目记录的版本。更新子模块到主项目记录的状态(更新主项目的同时更新子模块)
git pull --recurse-submodules重要
先更新 主项目,成功 之后再递归更新子模块到 主项目记录的提交 。如果需要使用最新的子模块,需要使用上一项命令。
对于这条命令有一个 Git 配置可以实现:
# 1. 仅在当前仓库生效 git config submodule.recurse true # 2. 在全局所有仓库生效 git config --global submodule.recurse true这样普通的
git pull也会自动更新子模块到主项目记录的提交。
更新特定子模块:
指定子模块路径(推荐)
git submodule update --remote <submodule_path> git add <submodule_path>手动拉取子模块更新(不推荐)
cd <submodule_path> git pull origin main cd .. git add <submodule_path> git commit -m "更新子模块版本"
状态
# 查看子模块状态(当前 commit ID)
git submodule status
# 查看子模块提交摘要
git submodule summary
# 查看配置文件
cat .gitmodules
提示
git submodule status 命令输出解释:
+53b2dbba libs/core (heads/main)
| 部分 | 示例值 | 含义 |
|---|---|---|
| 前缀符号 | + | - 号表示未初始化( git submodule init 未执行)。+ 号表示子模块内有新提交但未更新到父仓库。空格:表示正常,子模块代码与父仓库记录完全一致。 |
| Commit Hash | 53b2dbba | 子模块当前实际指向的提交 ID。 |
| 路径 | libs/core | 子模块在父项目中的目录路径。 |
| 引用信息 | (heads/main) | (可选) 显示子模块当前所在的远程分支名称。说明你是基于远程的 main 分支更新的。 |
删除
# 1. 反初始化
git submodule deinit -f <path>
# 2. 移除文件与缓存
rm -rf .git/modules/<path>
git rm -f <path>
# 3. 提交更改
git commit -m "删除子模块"
批量操作
# 对所有子模块执行相同命令
git submodule foreach <command>
# 示例:拉取所有子模块代码
git submodule foreach git pull
跟踪分支
重要
影响 git submodule update --remote 命令实际从哪个分支拉取的代码配置为:
- 项目根路径下
.gitmodules->[submodule]->branch。
以下命令中的 submodule_path 的值,例如 libs/utils 中的斜杠为 正斜杠 不要错。
查看子模块当前跟踪的分支:
# 查看配置中子模块的跟踪分支(默认应该是空) git config -f .gitmodules submodule.<submodule_path>.branch # 查看本地代码跟踪分支 cd <submodule_path> # `*` 号后面即是当前跟踪分支 git branch -a修改子模块跟踪分支:
一步完成配置和切换(推荐:仅在拉取操作时拉取指定分支,而不切换子模块的本地分支)
git submodule set-branch -b <branch_name> -- <submodule_path> git submodule update --remote提示
保留子模块默认行为:仍然是
detached HEAD(分离头指针)。修改
.gitmodules配置中子模块的默认跟踪分支(不推荐:会切换子模块的本地分支)# 先拉取远程分支 git checkout -b <branch_name> origin/<branch_name> # 更改配置 git config -f .gitmodules submodule.<submodule_path>.branch <branch_name> # 提交更改 git add .gitmodules && git commit -m "xxx"在子模块内切换分支(不推荐:会切换子模块的本地分支)
cd <submodule_path> git checkout <branch_name> # 如果上一步失败,先创建本地分支跟踪远程分支: git checkout -b <branch_name> origin/<branch_name> # 然后提交子模块更改 git add .gitmodules && git commit -m "xxx"
常见问题
Q: 如何识别文件夹是子模块?
A: 使用 ls -la 查看,子模块文件夹显示为 commitHash path 格式(如 @b9b8c6f libs/mylibrary)。
Q: 子模块更新出现冲突怎么办?
A:
# 强制重置子模块
git submodule update --init --force
# 或进入子模块目录手动解决
cd <submodule_path>
git status # 查看冲突
# ...解决冲突...
Sparse Checkout
稀疏检出(Sparse Checkout)允许只检出仓库中的特定子目录或文件,而不必下载整个仓库的内容(仅影响工作目录,.git 等历史记录仍完整保留)。
例如 NativeTemplateDemo · OpenHarmony-codelabs 项目是仓库中的一个文件夹,但它同时又是一个单独的仓库,我们只需要其中这一个的仓库,但没必要Clone下来整个仓库。这时就用到了稀疏检出功能。
首次克隆
(推荐):
git clone --filter=blob:none --sparse https://gitcode.com/openharmony/codelabs.git
cd codelabs
git sparse-checkout set NativeAPI/NativeTemplateDemo
# 后续更新
git pull --filter=blob:none
提示
| 命令 | 作用 |
|---|---|
git sparse-checkout add <dir> | 新增目录 |
git sparse-checkout set <dir> | 覆盖设置 |
git sparse-checkout remove <dir> | 删除单个目录 |
git sparse-checkout list | 查看当前目录列表 |
git sparse-checkout disable | 禁用稀疏检出(检出所有文件) |
或者使用以下步骤(不推荐)
# 1. 初始化本地仓库
git init
# 2. 启用稀疏检出模式
git config core.sparsecheckout true
# 3. 指定要检出的路径(结尾正斜杠表示匹配目录;后续需要更多目录使用 `>>` 追加)
echo "NativeAPI/NativeTemplateDemo/" > .git/info/sparse-checkout
# 4. 添加远程仓库地址
git remote add origin https://gitcode.com/openharmony/codelabs.git
# 5. 拉取代码(只拉取指定路径的内容)
git pull origin master
现有仓库
启用 Sparse Checkout,在仓库根目录执行:
git config core.sparseCheckout true指定要检出的目录/文件
在
.git/info/sparse-checkout文件中列出需要保留的路径(每行一个路径):# 示例:仅保留 src 和 docs 目录 echo "src/" >> .git/info/sparse-checkout echo "docs/" >> .git/info/sparse-checkout重要
- 路径是目录的,结尾应该加上
/,这样不会包含意外文件。例如src-file.txt。 - 支持通配符(如
*.js)。但不会递归匹配,需要多层就要显式列出各层的目录配置。
- 路径是目录的,结尾应该加上
应用稀疏检出配置
git checkout HEAD提示
手动更改了
.git/info/sparse-checkout配置文件也需要使用此命令重新检出。或强制刷新工作区:
git read-tree -mu HEAD
恢复完整检出
# 关闭稀疏检出
git config core.sparsecheckout false
# 删除稀疏检出配置
rm .git/info/sparse-checkout
# (推荐)恢复全量文件
git read-tree -mu HEAD
# (不推荐)者 重新拉取完整仓库
git reset --hard
提示
Windows删除使用 del 命令。
Github Actions
修改
例如多平台统一直播,逍遥橙子大佬的项目:xiaoyaocz/dart_simple_live: 简简单单的看直播 。默认在推送 tag 的时候,才执行。这样 fork 项目之后,默认不会执行Actions,则需要修改一下 workflows 。
禁用 dev 分支的工作流:
on:
# 禁用所有触发事件
push:
disabled: true
pull_request:
disabled: true
启用 release 分支的手动触发:
on:
# 添加手动触发
workflow_dispatch:
需要在 GitHub 仓库中配置的 Secrets:
密钥文件
KEYSTORE_BASE64 # 将 keystore.jks 文件进行 base64 编码后的字符串密钥密码信息
STORE_PASSWORD # keystore 的密码 KEY_PASSWORD # 密钥的密码 KEY_ALIAS # 密钥别名GitHub Token
TOKEN # GitHub 个人访问令牌,用于发布 Release执行工作流
如何生成和配置?
生成 keystore:
keytool -genkey -v -keystore keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your_alias_name>提示
certutil命令如果没有显式指定密钥密码(通过-keypass参数),工具只会提示用户输入 密钥库密码 ,不会单独提示输入 密钥密码 ,默认使用与 密钥库相同 的密码来保护密钥。如果想要单独设置密钥密码,需要在命令后拼接上
-keypass 你的密钥密码。将 keystore 转换为 base64:
# Linux/Mac base64 -i keystore.jks | tr -d '\n' # Windows certutil -encode keystore.jks temp.txt && type temp.txt | findstr /v /c:"-" | findstr /v /c:"certificate" > base64.txt在 GitHub 中配置:
- 进入仓库 →
Settings→Secrets and variables→Actions - 点击
New repository secret - 分别添加上述所有
secrets
- 进入仓库 →
提示
请妥善保管原始的 keystore.jks 文件和密码,这些是应用签名的关键,丢失后将无法更新应用。
