尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Git 实用操作指南

Git 实用操作指南 Git 实用操作全指南从基础到进阶学习 Git 最权威的资料是其官方文档推荐优先查阅Git 官方文档中文版。本文整理了日常开发中高频使用的 Git 命令按核心场景分类方便我快速查阅和使用。一、Git 核心概念工作区、暂存区与仓库Git 工作流程围绕三个核心区域展开理解它们的关系是熟练使用 Git 的基础。工作区本地电脑中实际编辑文件的目录即日常写代码的地方。暂存区索引临时存放修改的区域用于确认哪些修改需要提交到仓库。本地仓库存储所有提交历史的数据库记录了项目的完整版本变化。远程仓库托管在服务器上的仓库如 GitHub、GitLab用于团队协作和代码备份。核心流程工作区 →git add→ 暂存区 →git commit→ 本地仓库 →git push→ 远程仓库二、基础操作仓库初始化与文件管理这部分包含从创建 / 克隆仓库到跟踪、提交文件的基础命令是日常开发的高频操作。1. 仓库创建与克隆git init在当前目录初始化一个新的 Git 仓库。git clone URL从指定 URL 克隆远程仓库到本地。git clone --depth 1 URL 目录名只克隆最近 1 次提交历史减少下载体积并指定本地目录。git clone -b 分支名 URL克隆远程仓库的指定分支。2. 文件跟踪与删除git add / rmgit add 文件名将工作区的文件添加到暂存区开始跟踪该文件。git add [dir]添加指定目录到暂存区包括子目录。git add -u将正在跟踪的被修改过的工作区文件添加到暂存区。git add .将当前目录所有文件添加到暂存区。git rm 文件名删除被 Git 跟踪的文件同时删除工作区文件。git rm --cache 文件名从暂存区移除文件不再跟踪但保留工作区文件。3. 文件移动与重命名git mvgit mv 原文件名 新文件名重命名一个已被 Git 跟踪的文件。git mv 原目录/文件名 新目录/文件名将文件移动到新目录并重命名。注意此命令能保留文件的提交历史。你用git status查看会发现renamed: playbooks/networking/wifi_ap.md - playbooks/wifi/wifi_access_point.md这样的log。如果直接使用操作系统的mv或rename命令移动文件Git 会将其视为“删除原文件”和“添加新文件”两个独立操作会丢失修改的关联性。使用git mv可以避免这个问题。3. 提交修改先检查配置gitconfig--globaluser.name# 查询全局user.namegitconfig--globaluser.email# 查询全局user.emailgitconfig--global--list# 查询全局配置gitconfig--globaluser.namexxx# 配置全局user.namegitconfig--globaluser.emailxxx# 配置全局user.emailgit commit -m 提交说明将暂存区的修改提交到本地仓库并添加说明。git commit -s -m 提交说明添加签名。git commit -s 后回车添加签名Git 会打开默认编辑器如vim或nano(git config --global core.editor vim命令可将git默认编辑器调整为vim)git commit -am 提交说明直接将已跟踪文件的修改未暂存添加到暂存区并提交。(省去了git add ,太着急了吧)4. 查看历史提交git loggit status查看文件状态未暂存文件红色暂存文件绿色提交后无显示。git log查看提交历史按时间倒序排列。git log -n 2查看最近两次的提交历史按时间倒序排列。git log da35b6 -n 2查看da35b6在内最近两次的提交历史按时间倒序排列。git log -p -2查看最近 2 次提交的具体修改内容对比差异。git log --prettyoneline将每条提交记录压缩为一行显示简洁高效。git log --prettyformat:%h 【%an】 %ar 《%s》自定义提交记录格式包含简化哈希% h、作者% an、距今时间% ar、提交说明% s。git log --graph以图形化形式展示提交历史清晰查看分支合并关系。git log -- 文件名查看对指定文件的所有提交git log -S function看哪些提交改了function这个字符串git log -p -S function在上一个基础上看修改function这个字符串的具体内容git log -p -S function– driver/your_driver.c 在上一个基础上缩小查找范围git log -L :函数名:文件名通过-L选项指定函数范围直接定位修改过该函数的所有提交git log branch1..branch2 --oneline查看branch2在branch1基础上还有哪些提交三、差异对比(diff)工作区、暂存区与仓库的差异通过git diff命令查看不同区域的文件差异是定位修改内容的关键操作。命令对比范围用途git diff工作区 vs 暂存区(git add)查看未暂存的修改git diff HEAD 文件名工作区 vs 本地仓库当前 HEAD查看工作区与最新提交的差异git diff --cached 文件名暂存区(git add) vs 本地仓库当前 HEAD查看已暂存但未提交的修改git diff refs/remotes/origin/master工作区 vs 远程 master 分支查看本地与远程分支的差异git diff 旧提交ID1 新提交ID2 --stat两次提交之间查看两次提交的文件修改统计如修改行数git diff 旧提交ID1 新提交ID2 文件名两次提交的指定文件查看具体文件在两次提交间的差异四、远程仓库操作连接与同步团队协作中需频繁与远程仓库交互包括连接、推送、拉取等操作。1. 远程仓库管理git remote -v查看已配置的远程仓库 URL-v表示显示详细信息。git remote add 远程名 URL添加远程仓库通常远程名设为origin。git remote rm 远程名删除指定的远程仓库配置。git remote rename 旧名 新名修改远程仓库的名称。2. 推送与拉取git push 远程仓库 本地分支名:远程分支名将特定本地分支推送到远程仓库若远程分支不存在则自动创建。git push 远程仓库 远程分支名简化写法将本地master分支推送到origin远程的master分支。git push -u 远程仓库 远程分支名推送分支并建立 “跟踪关系”后续推送直接用git push。git push 远程仓库 --delete 分支名删除 指定的 远程仓库 中的 指定分支git fetch 远程仓库拉取远程仓库的所有分支更新到本地不合并到当前分支若不指定分支则拉取所有分支。git fetch --prune拉取远程更新的同时删除本地存在但远程已删除的分支保持同步。3. 远程分支查看删除等git branch -r只查看本地缓存的远程分支如origin/master。git branch -a查看所有分支本地分支白色当前分支绿色远程分支红色。git branch -vv查看本地分支与远程分支的关联关系以及最近一次提交信息。git remote show 远程名展示本地分支与远程分支的详细关联情况包括更新状态。五、分支操作创建、切换与合并分支是 Git 核心功能用于并行开发、修复 bug 等场景避免影响主分支。1. 分支创建与切换git branch 分支名创建新分支如git branch Lyrix。git checkout 分支名或git switch 分支名切换到指定分支两者功能一致。git checkout -b 新分支名创建新分支并立即切换到该分支。git checkout -b 本地分支名 远程名/远程分支名基于远程分支创建本地分支并建立跟踪关系。git checkout .放弃工作区所有未暂存的修改恢复到最近一次提交状态。2. 分支合并git merge 待合并分支名将指定分支的内容合并到当前分支如在master分支执行git merge Lyrix将Lyrix合并到master。合并冲突处理合并时若出现冲突先用git status查看冲突文件用编辑器修改冲突内容保留需要的代码删除冲突标记,再执行git add和git commit完成合并。3. 分支删除git branch -d 分支名删除已合并到其他分支的本地分支若分支未合并会提示报错。git branch -D 分支名强制删除未合并的本地分支谨慎使用避免丢失代码。git push 远程名 -d 远程分支名删除远程仓库的指定分支如git push origin -d Lyrix。4. 摘樱桃 cherry-pickgit cherry-pick 提交ID1 提交ID2 提交ID3将其他分支的某个特定提交 “复制” 到当前分支适用于只需要单个提交、不需要整分支合并的场景俗称 “摘樱桃”。可以一次摘很多用空格分隔但注意他们是。5. 分支重命名git branch -m new_branch_name重命名当前所在分支。六、进阶操作储藏、补丁与版本回退子模块这部分包含应对临时需求、代码复用、版本修正的进阶命令解决开发中的特殊场景。1. 工作区储藏Stash当需要临时切换分支但当前工作区修改未完成、不便提交时用stash保存工作区状态。git stash将工作区和暂存区的修改保存到 “储藏栈”工作区恢复干净状态。git stash save 储藏说明保存储藏时添加说明方便后续识别。git stash pop应用储藏栈中最近的一次储藏并删除该储藏记录只能用一次。git stash apply应用指定的储藏如git stash apply stash{1}且不删除储藏记录可多次应用。git stash list查看所有储藏记录。git stash drop 储藏ID删除指定的储藏记录如git stash drop stash{0}。git stash show查看储藏内容中哪些文件有修改。git stash show -p查看储藏内容的具体修改差异。2. 补丁操作Patch通过补丁文件分享代码修改适用于未通过远程仓库协作的场景如邮件发送修改。1生成补丁(git diff或git format-patch)git diff 文件名 补丁名.patch生成单个文件的修改补丁如git diff Test.java test.patch。git diff 补丁名.patch生成所有修改文件的补丁。git format-patch 提交ID1..提交ID2 --stdout 补丁名.patch生成两个提交间所有修改的补丁不包含提交ID1。git format-patch -1 提交ID --stdout 补丁名.patch生成单个提交的补丁。git format-patch HEAD~3 --stdout 补丁名.patch生成最近 3 次提交的补丁。2应用补丁git apply 补丁名.patch应用git diff生成的补丁需手动执行git add和git commit。git am 补丁名.patch应用git format-patch生成的补丁自动包含提交信息无需手动提交。git apply --check 补丁名.patch检查补丁是否可正常应用无输出则表示无冲突。git apply -R 补丁名.patch撤销已应用的补丁。3. 版本回退与修改1版本回退reset修改 HEAD 指针位置回退到历史版本适用于需要彻底删除后续提交的场景谨慎使用避免丢失代码。git reflog查看所有历史版本的操作记录获取需要回退的提交 ID。(如果之前rebase啥的把有用从commit给误删了需要用这条命令查看之前 HEAD 指针的记录)git reset --hard 提交ID强制回退到指定版本工作区、暂存区均同步修改会覆盖本地未提交的代码需提前备份。git reset --soft 提交ID回退到指定版本暂存区和工作区的修改保留未提交状态。git reset --mixed 提交ID回退到指定版本暂存区修改清空工作区修改保留默认模式。远程版本回退若已推送到远程仓库需执行git push -f 远程名 分支名强制覆盖远程分支团队协作中需提前沟通避免影响他人。2反做revert撤销某个历史提交的修改但保留该提交之后的所有版本适用于需要 “取消旧修改” 但不删除后续提交的场景比reset更安全推荐优先使用。git revert -n 提交ID反做指定提交的修改-n表示不自动提交。修改冲突文件若有执行git add和git commit -m 撤销XXX提交再用git push推送到远程。3修改提交历史rebase用于 ①合并多个提交、②提交顺序调整、③提交说明修改、④适用于提交历史混乱时整理记录仅整理本地未推送的提交已推送的提交禁止使用。git rebase -i HEAD~2交互式修改最近 2 次提交HEAD~2表示最近 2 次可替换为具体提交 ID。git rebase -i commit_id修改指定的commit_id只有的提交git rebase -i --root从最初的 commit 之前开始修改。执行命令后会弹出编辑界面按提示修改提交如将pick改为squash合并提交删除行则删除提交具体步骤参考我的博客【git rebase操作】.4. git 子模块git submodule在大型项目、开源项目或者包含第三方依赖库的代码仓库中经常用到。简单来说Git 允许你把另一个独立的 Git 仓库当作当前仓库的一个“子文件夹”来引用。比如你的项目依赖了一个第三方的开源库你不想把它的代码直接复制粘贴到你的项目里这样不好同步更新于是你选择把它作为一个“子模块”挂载进来。当你拉取包含git子模块的项目时你只需要执行# 初始化并递归更新当前仓库中所有的 Git 子模块Submodulegitsubmodule update--init--recursive如果你作为大型项目开发这个如何第三方开源仓库的指定 commit 作为子模块挂载到你的工程呢第一步添加子模块# 语法git submodule add 第三方仓库地址 你希望存放的子模块目录名gitsubmoduleaddhttps://github.com/username/repo.git path/to/submodule执行完这条命令后Git 会自动把这个仓库克隆到你指定的目录下并且会在你的项目根目录生成一个.gitmodules文件用来记录子模块的仓库地址和路径。进入子模块切换到指定的 Commit刚添加完时子模块默认会停留在第三方仓库的默认分支比如main的最新提交上。我们需要把它切换到你想要的那个“指定 commit”。# 1. 进入子模块的目录cdpath/to/submodule# 2. 检出checkout你指定的 commit ID或者 tag 标签gitcheckout abc123456789# 3. 退出子模块目录回到主仓库根目录cd../..第三步在主仓库中提交“版本锁定”记录最关键的一步把这个“子模块指向了 abc1234 版本”的信息记录到主仓库的提交历史中。# 1. 将子模块目录的变更添加到暂存区注意这里 add 的是子模块的文件夹路径不要带尾部斜杠gitaddpath/to/submodule# 2. 提交到主仓库并写上清晰的日志gitcommit-m添加第三方库 xxx 作为子模块并锁定到指定版本 abc1234第四步推送到远程仓库最后把你的主仓库包含.gitmodules文件和子模块的 commit 指针推送到远程gitpush origin main七、标签操作(tag)版本标记与发布通过标签Tag标记重要版本如发布版本v1.0方便后续快速定位和回滚。git tag 标签名在当前提交创建标签如git tag v1.0。git tag查看所有本地标签。git tag -d 标签名删除本地标签。git push 远程名 标签名将指定标签推送到远程仓库如git push origin v1.0。git push 远程名 --tags将所有本地标签推送到远程仓库。git checkout 标签名切换到指定标签对应的版本少用处于 “分离头指针” 状态修改需创建新分支。[!WARNING]git checkout 标签名使用注意如果当前暂存区有来自不同仓库的同名tag, 则该命令可能会不如你意。这样操作获取远程仓库 tag 对应的 commit IDgitls-remote repoA tags/tag_name基于 commit ID 切换到目标版本gitcheckout a1b2c3d4e5f6abcdef1234567890abcd12345678八、常见问题与补充说明如何查看当前所在分支执行git status、git log或git branch --list当前分支会用*标记或显示为绿色。合并分支时必须切换到目标分支吗是的。例如要将Lyrix合并到master必须先切换到master分支再执行git merge Lyrix。本地分支与远程分支如何同步执行git fetch 远程名拉取远程最新更新执行git merge 远程名/远程分支名将远程更新合并到本地分支如git merge origin/master。Fast Forward Merge 与 3-Way Merge 的区别Fast Forward Merge目标分支如master没有新提交直接将目标分支指针指向待合并分支如Lyrix无合并记录。3-Way Merge目标分支有新提交需基于两者的共同祖先创建新的合并提交保留合并记录。日常开发分支管理思路你的思路本质上是通过分支隔离 “有效成果” 和 “临时调试”这是合理的但可以进一步优化分支策略让流程更清晰、协作更顺畅即使是个人开发。以下是具体建议一、你的方案的合理性与可优化点合理性用两个分支隔离 “干净的有效补丁” 和 “杂乱的调试过程”避免有效代码被临时调试代码污染方便后续整理和合并。可优化点若仅用两个分支长期开发可能导致 “有效分支” 堆积过多补丁难以追溯每个功能的来源“调试分支” 过于杂乱回头看时可能分不清哪些调试是针对哪个问题的。二、更推荐的分支管理策略适合个人开发核心思路按 “功能 / 任务” 拆分短期分支用一个 “主开发分支” 整合有效成果用 “临时调试分支” 做尝试形成 “短期尝试→验证有效→合并到主开发分支” 的闭环。具体分支结构建议分支类型命名示例用途生命周期主开发分支dev或develop存放经过验证的、可整合的有效代码类似你的 “有效 patch 分支”长期存在持续更新功能 / 任务分支feature/xxx针对单个功能或任务如 “修复 XXbug”“实现 XX 功能”创建的短期分支功能完成并合并后删除调试 / 实验分支debug/xxx-issue记录针对某个问题的调试过程带临时日志、调试代码问题解决后可删除或归档稳定版本分支release/v1.0可选从dev分支拉出用于发布或测试的稳定版本长期保留仅修复 bug三、日常开发流程按步骤说明从主分支创建功能分支每次开始一个明确的任务如 “开发 A 功能”“修复 B bug”从dev分支创建一个功能分支gitcheckout devgitpull# 确保主分支最新gitcheckout-bfeature/implement-A# 功能分支这个分支只专注于该任务提交记录尽量清晰如 “完成 A 功能的核心逻辑”“修复 A 功能的边界条件”。用调试分支做 “脏实验”若开发中需要做大量尝试性调试如 “测试某个猜想”“临时加日志排查问题”从当前功能分支创建调试分支gitcheckout feature/implement-Agitcheckout-bdebug/test-A-logic# 调试分支这里可以随意提交临时代码甚至带printk、注释掉部分逻辑不用担心污染功能分支。验证有效后合并到功能分支调试出有效结论后如 “这个思路可行”“这段代码能修复问题”将调试分支中的有效代码整理后合并到功能分支# 切换到功能分支gitcheckout feature/implement-A# 合并调试分支的有效代码可选 rebase 让提交更整洁gitmerge--squashdebug/test-A-logic# 把调试分支的提交压缩成一个gitcommit-m完成A功能的XX逻辑解决了XX问题# 若提交描述信息拼写错误、不准确时重新编辑描述。修改最近一次提交的描述未推送时使用gitcommit--amend# 如果修改历史提交信息需要git rebase 修改pick为reword只改提交描述如果已经推送到远端想想强推则git push --force-with# 调试分支完成使命可删除gitbranch-ddebug/test-A-logic功能完成后合并到主开发分支当功能分支的代码经过充分验证如自测通过、无调试残留合并到dev分支gitcheckout devgitmerge feature/implement-Agitpush origin dev# 功能分支可删除或保留以备后续修改gitbranch-dfeature/implement-A四、关键技巧让分支管理更高效提交记录 “原子化”每个提交只做一件事如 “修复 XX 函数的参数错误”“添加 XX 功能的配置项”避免一个提交包含多个不相关修改。这样后续回滚或查找问题时更方便。善用git stash临时保存工作区若调试到一半需要切换分支如突然要改另一个 bug可用git stash保存当前未提交的修改切换分支处理完后再git stash pop恢复避免频繁创建临时分支。定期 “清理” 无用分支功能分支和调试分支完成后及时删除避免本地分支列表过于臃肿可用git branch -vv查看已合并的分支放心删除。必要时 “归档” 调试过程若某些调试过程有参考价值如 “解决了一个罕见 bug 的思路”可以不删除调试分支而是用标签git tag debug/20241028-xxx-issue标记方便后续查阅。五、为什么这样更有效聚焦性功能分支只对应一个任务提交记录清晰方便追溯调试分支隔离临时操作不影响核心代码。灵活性即使调试分支搞乱了也不会影响功能分支和主分支大不了删掉调试分支重新来。可扩展性若后续需要多人协作这种结构能无缝衔接每人在自己的功能分支开发通过dev分支整合。简单说核心就是 “按任务拆分按有效性分层”用功能分支保证代码的 “可追溯性”用调试分支承担 “试错成本”用主分支沉淀 “有效成果”。比单纯两个分支更有条理长期开发会更省力。六、如何将测试分支高效合并到功能分支关键原则减少 “调试提交” 的杂乱度与其事后整理不如在调试时养成习惯减少后续工作量调试代码单独标记在调试语句前统一标记如// DEBUG_LYRIX:方便后续全局搜索删除避免 “为调试而提交”非必要不提交纯调试代码可用git stash临时保存只在有有效进展时提交小步提交有效代码调试中一旦有明确的有效修改如修复一个逻辑错误立即提交并写清楚注释如 “修复 XX 条件判断错误”避免有效代码和调试代码混在一起。切换到调试分支基于功能分支的最新状态做 “交互式变基”用git cherry-pick精准提取有效提交
返回列表