Git是一种分布式版本控制系统,深受全球开发者喜爱。它的设计哲学简洁高效,能够处理从小到大的项目。基本上作为一个互联网开发者,都必须掌握这门技术,本文将带你探究Git的工作原理及实战处理一些常见问题
1.Git的核心概念
①分布式架构
- 与集中式版本控制系统不同,Git是分布式的
- 每个开发者的电脑上都有整个仓库的副本,包括所有的历史记录和版本信息
②快照,而非差异
- Git记录的是文件状态的“快照”,而非文件之间的差异
- 每次提交更新时,Git会记录一个文件集合的快照
③区域概念
- Git有三个主要的工作区域:工作目录(工作树)、暂存区(索引)、以及本地仓库
- 这些区域支持代码的不同阶段管理
2.Git的工作原理

以下面具体的示例来说明一下Git的工作原理图:
①工作目录(Working Directory)
- 文件直接在此处被编辑和修改
- 示例:创建了一个新的Java文件Example.java并写入代码
②暂存区(Staging Area)
- 执行git add Example.java后,Example.java的当前状态记录到暂存区
- 暂存区代表下一次提交的准备状态
- 继续修改Example.java并希望更新暂存区时,需重新执行git add,会自动覆盖之前已经提交到本地仓库的文件
③本地仓库(Local Repository)
- 对Example.java的修改完成后,通过执行git commit命令,将更改永久保存到本地仓库的历史记录中,确保本次修改的内容永远不会丢失
- 一次性提交所有更新可以使用git commit -a等价于 git add + git commit 命令组合
- 提交操作为更改集合提供了唯一的ID,以便可以轻松回溯到任何历史状态
④合并(Merge)和变基(Rebase)
- git merge命令允许将不同分支的更改合并到当前分支。
- git rebase用于将更改应用于其他分支的最新提交之上,有助于保持历史的清晰。
⑤远程仓库(Remote Repository)
- git push命令将本地仓库的更改上传到远程仓库,如GitHub
- 推送更改前,可能需要用git fetch拉取远程仓库的最新状态,再通过git merge或git rebase进行合并或变基
- git pull结合了git fetch与git merge,从远程仓库获取并自动合并到本地分支
- 开始新项目时,git clone会复制远程仓库的内容到本地
⑥分支切换(Checkout)和暂存(Stash)
- git checkout [branch-name]切换分支
- 在未完成的工作需要临时保存时,git stash能够存储当前进度,之后可通过git stash pop恢复这些更改
3.Git常见的问题及解决策略
Git作为强大的版本控制工具,其复杂性有时也会让用户头疼。然而,对于大多数问题,Git提供了简洁而优雅的解决方案。这里我们探索几个工作中常见的问题,并提供具体的解决策略
①遗忘提交:commit --amend
有时我们会在执行git commit后意识到忘记添加某些文件,或者提交信息写错了
解决方案:
使用
git commit --amend可以重新提交如果忘记添加文件到最近的提交,可以先用
git add添加文件,然后使用git commit --amend无需创建新的提交示例:
git add forgotten_file.java
git commit --amend -m "Correct commit message"
②跨分支的提交:Cherry-pick
想要将特定的提交从一个分支移动到另一个分支,而不影响其他内容,就可以使用cherry-pick命令
示例:
[原分支] A---B---C---D
\ \
[目标分支] X---Y---Z
想要将提交B从原分支复制到目标分支,具体操作:
1.切换到目标分支
git checkout 目标分支
2.cherry-pick操作 git cherry-pick B的哈希值
操作后的结果:
[原分支] A---B---C---D
\ \
[目标分支] X---Y---Z---B'
注意:cherry-pick可能会导致冲突,特别是当提交B中的改动与目标分支的现有改动不兼容时,解决冲突后, 可以通过git cherry-pick --continue完成操作,或者如果你决定不进行cherry-pick,可以通过 git cherry-pick --abort来取消操作
③强制回滚到指定提交点:git rest --hard + git push origin force
假设由于你过早的合并了master分支,但由于master分支代码出现了重大bug,导致回滚了master,这时候就需要回退到merge master之前的提交点
远程分支main状态:
main: A---B---C---D (错误的提交是C与D,需要强制回滚到B提交点)
强制回滚流程:
1. 在本地重置到正确的提交: git checkout main git reset --hard B 本地重置后状态: main: A---B
2. 强制推送到远程 由于远程分支包含额外的提交(C和D),普通的推送会被拒绝,因此需要使用强制推送 git push origin main --force
执行强制推送后,远程分支状态: main: A---B
注意事项:
强制推送会重写远程分支的历史。这可能对其他协作者造成影响,在执行这种操作前,请确保通知所有团队成员
如果远程分支被多人使用,考虑使用其他方法,如
git revert,来逆转错误的提交,而不是删除它们
④找回强制回退丢失的提交:git reflog + checkout + merge
假设不小心在分支feature上执行了一个硬重置(git reset --hard),导致一些重要的提交丢失了
示例: [原始状态] feature: A---B---C---D [执行硬重置后] feature: A---B (C和D丢失)
找回丢失的提交的流程:
1. 查看reflog
首先,你需要查看reflog来找到丢失提交的引用
git reflog
假设显示如下:
1c2e20a (HEAD -> feature) HEAD@{0}: reset: moving to HEAD^
abcd123 HEAD@{1}: commit: Add feature D
1234abc HEAD@{2}: commit: Add feature C ...
2. 创建一个新分支来恢复丢失的提交 接下来,创建一个新的分支,指向丢失的最新提交(在这个例子中是abcd123,即提交D)
git checkout -b recovery-branch abcd123
3.将recovery-branch分支merge到feature分支
git checkout feature
git merge recovery-branch
4. 执行完1,2,3操作后,最终状态,即找回了丢失的C D提交
feature: A---B---C---D
4.写在最后
通过这篇文章,我们一同探索了Git的神奇世界,从其核心概念,工作原理,再到实战问题的解决策略。Git不仅是一个工具,它是一种能力,一种与时俱进的开发文化。掌握Git,就是掌握了与众不同的协作和版本控制能力。
希望这篇文章不仅增强了读者对Git的理解,而且提供了实用的知识来解决日常工作中的常见问题。如果您觉得这篇文章对您有帮助,请不吝给予点赞、收藏、转发,让更多的开发者受益。记得关注我,一起成长,让技术成为推动创新的力量!
感谢阅读,期待在下一篇文章中再次与您相遇!