Git 版本控制教程
从入门到协作,掌握现代开发的核心技能
开始之前
这是一个国内版本的GitHub,有着和Github类似的使用体验,但是更方便访问。
总有一天,我会聚集一群不输给这些人的伙伴,并找到世界第一的财宝,我要成为海贼王!
为什么需要版本控制?
版本控制在日常学术和工作中至关重要。以学术写作为例,你可能会面临:
- 论文的多次迭代:产生许多不同版本,需要从中挑选最终稿。
- 多方参与协作:多位作者需要同时编辑不同部分,并有效整合。
版本控制工具能帮我们记录历史、随时回退(时间回溯)、同步进度并解决冲突。
Git 的原理
Git 是一个为应对大型项目而生的分布式版本控制系统。它的包含四个工作区:
- 工作区 (Workspace):你当前编写代码的地方。
- 暂存区 (Stage/Index):临时存放你准备提交的改动。
- 本地仓库 (Repository):存储在你电脑上的项目所有版本的历史记录。
- 远程仓库 (Remote):托管在服务器上,用于团队协作和代码备份。
Git 的核心是分布式,每个人的电脑上都有一个完整的本地仓库,可以独立工作,然后将更新推送到远程仓库进行同步。
安装 Git
1. 下载与安装
前往Git官网下载最新的Windows安装包:https://git-scm.com/download/win
下载后双击安装包,选择合适的安装路径,然后一路点击 "Next" 即可完成安装。
安装 Git
2. 验证安装成功
在桌面或任意文件夹内点击鼠标右键,如果菜单中出现 "Git Bash Here" 和 "Git GUI Here" 选项,证明安装成功。
3. 初步配置
安装后,需要设置你的用户名和邮箱,这是你提交代码时的身份标识(一般是github或gitee的账号和邮箱)。
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
基本命令:创建本地仓库
我们可以将任意一个文件夹初始化为Git本地仓库。
- 进入目标文件夹。
- 右键点击 "Git Bash Here" 打开命令行。
- 输入初始化命令:
git init
这会在当前目录下创建一个隐藏的 .git 文件夹。然后,使用 git status 查看仓库状态。
git status
初次会显示 "No commits yet",表示这是一个空的仓库。
基本命令:添加与提交 (1/2)
我们创建一个 hello.txt 文件,并查看状态。
touch hello.txt
git status
Git会提示有一个 "Untracked file" (未追踪文件)。这意味着Git发现了这个新文件,但尚未开始管理它。
使用 git add 将文件添加到暂存区,使其变为被追踪状态。
git add hello.txt
基本命令:添加与提交 (2/2)
再次使用 git status 查看,文件已变为绿色,并位于 "Changes to be committed" 下方,表示已成功进入暂存区。
现在,使用 git commit 将暂存区的改动提交到本地仓库,形成一个新版本。-m 参数用于添加本次提交的描述信息。
git commit -m "Initial commit with hello.txt"
基本命令:忽略文件 (.gitignore)
并非所有文件都需要版本控制(如编译产物、日志文件)。
我们可以在项目根目录创建一个名为 .gitignore 的文件,列出需要忽略的文件或目录模式。
常用规则示例:
# 1. 忽略特定文件
config.txt
secret.key
# 2. 忽略特定后缀的所有文件
*.log # 所有 .log 文件
*.class # Java 编译文件
# 3. 忽略文件夹及其所有内容
build/ # build 目录
.vscode/ # VS Code 配置
# 4. 忽略所有子目录中的特定文件
**/logs/ # 任何位置的 logs 目录
**/*.backup # 任何位置的 .backup 文件
# 5. 忽略文件名包含特定字符串的文件
*temp* # 文件名包含 temp 的文件
*cache* # 文件名包含 cache 的文件
# 6. 忽略特定目录下的特定文件
src/*.class # 只忽略 src 目录下的 .class 文件
docs/*.pdf # 只忽略 docs 目录下的 PDF 文件
# 7. 例外规则(不忽略)
!important.log # 即使匹配 *.log,也不忽略这个文件
!build/keep.txt # 即使 build/ 被忽略,也保留这个文件
# 8. 系统文件
.DS_Store # macOS 系统文件
规则说明:
*匹配任意字符(除了 /)**匹配任意目录层级/结尾表示目录!开头表示例外(不忽略)#开头表示注释
.gitignore 练习题 (学会描述,AI生成)
题目
- 忽略名为
build的文件夹。 - 忽略所有的
.log文件。 - 已忽略
build/,但需跟踪build/deploy.txt。 - 忽略
src目录下所有.tmp文件。 - 忽略
docs目录下所有以~结尾的文件。 - 忽略
test目录下所有.pyc和test/results目录。 - 规则
*.log和!app.log叠加会怎样? - 忽略
.min.js,.env,.db,node_modules/,*.swp文件。
答案
build/*.logbuild/!build/deploy.txtsrc/*.tmpdocs/*~test/*.pyctest/results/- 除
app.log外所有.log文件被忽略。 -
*.min.js .env *.db node_modules/ *.swp
基本命令:回滚版本
如果提交了错误的代码或想回到之前的某个版本,可以使用 git reset。
# 回滚到指定的 commit ID
git reset --hard <commitID>
--hard 参数会使工作区、暂存区和版本库都回退到指定状态,之后的提交记录会丢失。
如何找回“丢失”的提交?
如果回滚后又后悔了,可以使用 git reflog 查看所有HEAD的移动记录,找到回滚前的commit ID,再次使用
git reset --hard 即可恢复。
git reflog
分支 (Branches)
分支是Git的“杀手锏”功能。它允许你从主开发线上分离出来,创建一条独立的开发路线,用于开发新功能或修复bug,而不会影响主线的稳定性。
分支就像是Git世界里的‘平行宇宙’。你可以随时打开一个‘副本世界’,在里面大胆尝试新想法、修修补补,哪怕翻个底朝天,也不会影响到主宇宙的安宁。等你觉得一切都完美了,再把成果‘合并’回主线,就像把平行宇宙的成功经验带回现实世界。
在Git内部,分支仅仅是一个指向特定提交的轻量级指针。
分支操作:创建与切换
查看所有分支 (* 表示当前所在分支):
git branch
基于当前分支创建一个名为 `test` 的新分支:
git branch test
切换到 `test` 分支进行工作:
git checkout test
# 或者使用新命令: git switch test
在 `test` 分支上的所有提交都与 `master` 分支隔离,互不影响。
切换回 `master` 分支后,文件内容会恢复到 `master` 分支的状态。
分支操作:合并与冲突
当 `test` 分支的功能开发完成后,我们希望将其合并回 `master` 主分支。
# 1. 首先切换回主分支
git checkout master
# 2. 执行合并命令
git merge test
示例:合并冲突的具体场景
假设我们有一个 `hello.txt` 文件,在不同分支中被修改:
# 在 master 分支中,hello.txt 的内容是:
234
# 在 test 分支中,hello.txt 被修改为:
123-test
# 当我们在 master 分支执行 git merge test 时:
git checkout master
git merge test
解决冲突
在上面的示例中,由于 `master` 和 `test` 分支都修改了 `hello.txt` 文件的同一部分,合并时就会产生冲突 (Conflict)。Git会暂停合并,并在冲突文件中用特殊标记标出冲突区域:
# Git 会在 hello.txt 中显示冲突标记:
<<<<<<< HEAD
234
=======
123-test
>>>>>>> test
其中 `<<<<<<< HEAD` 到 `=======` 之间是当前分支(master)的内容,`=======` 到 `>>>>>>> test` 之间是要合并分支(test)的内容。
手动编辑文件,保留需要的内容并删除冲突标记,然后再次 `git add` 和 `git commit` 即可完成合并(点击查看演示)
分支操作:变基 (Rebase)
除了合并,还可以使用 `rebase` (变基) 来整合分支。变基会提取当前分支的修改,然后将它们在目标分支的最新提交之后“重放”一遍,形成一条线性的提交历史。
git checkout test
git rebase master
Merge vs. Rebase: Merge保留了真实的分支历史,而Rebase创建了更整洁的线性历史。
选择哪种方式取决于团队的协作规范(查看演示)。
分支操作:优选 (Cherry-pick)
有时我们不需要合并整个分支,只想将另一个分支的某一个或几个特定的提交应用到当前分支。这时可以使用 cherry-pick。
# 将指定的 commit 应用到当前分支
git cherry-pick <commit_id>
这是一种非常灵活的分支内容整合方式(查看演示)。
* 使用IDEA进行版本控制 (1/6)
创建项目
虽然命令行很强大,但图形化界面(GUI)更直观。我们以IDEA为例。在创建新项目时,记得勾选“创建Git仓库”。
项目创建后,点击左下角的“版本控制”或“Git”标签,可以查看版本状态。
* 使用IDEA进行版本控制 (2/6)
添加文件到暂存区
新建一个 hello.txt 文件。此时文件名会显示为红色,表示它是一个未追踪的文件。
右键点击文件 -> Git -> 添加 (Add)。
添加后,文件名变为绿色,表示已进入暂存区。
* 使用IDEA进行版本控制 (3/6)
提交更改
点击工具栏上的提交按钮(通常是一个绿色的勾),打开提交窗口。
在窗口中输入提交信息,然后点击“提交”按钮。提交后,可以在Git日志中看到新的提交记录。
* 使用IDEA进行版本控制 (4/6)
分支操作
点击IDEA右下角的分支名称(如 `master`),可以方便地进行分支操作。
选择“新建分支”,输入分支名(如 `dev`)即可创建并切换到新分支。在 `dev` 分支修改并提交后,Git日志图会清晰地展示出分支的演进。
* 使用IDEA进行版本控制 (5/6)
合并与冲突解决
假设我们在 `master` 和 `dev` 分支上都修改了 `hello.txt`,现在要将 `dev` 合并到 `master`。
- 切换到 `master` 分支。
- 在分支菜单中选择 `dev` 分支,然后点击“合并到当前分支”。
如果出现冲突,IDEA会弹出一个冲突解决窗口。
* 使用IDEA进行版本控制 (6/6)
合并与冲突解决 (续)
在三栏视图中,左侧是你的更改,右侧是对方的更改,中间是最终合并结果。你可以点击箭头按钮选择接受哪个版本的更改,或者直接在中间一栏手动编辑。
解决所有冲突后,点击“应用”,然后完成合并提交。Git日志图会显示一个清晰的合并节点。
远程仓库
远程仓库是托管在服务器上的Git仓库,用于团队协作和代码备份。常见的平台有 GitHub, Gitee, GitLab 等。
远程账户认证 (SSH)
为了让远程仓库识别你的身份,通常使用SSH密钥进行认证。
- 生成SSH密钥对:
ssh-keygen -t rsa -C "your_email@example.com" - 查看并复制公钥:
cat ~/.ssh/id_rsa.pub(Linux/macOS)
type %USERPROFILE%\.ssh\id_rsa.pub(Windows CMD)
Get-Content $env:USERPROFILE\.ssh\id_rsa.pub(Windows PowerShell) - 将复制的公钥添加到Gitee或GitHub的 "SSH公钥" 设置中。
这样,当你通过SSH协议与远程仓库交互时,服务器就能验证你的身份。
远程操作:推送 (Push)
将本地仓库的提交推送到远程仓库。
- 在Gitee上创建一个新的空仓库。
- 将远程仓库地址关联到本地仓库,并命名为 `origin`:
git remote add origin git@gitee.com:username/repo.git - 将本地 `master` 分支的提交推送到 `origin`:
git push -u origin master-u选项会建立本地分支与远程分支的跟踪关系,之后可以直接使用git push。
远程操作:克隆 (Clone)
从远程仓库复制一个完整的项目到本地,包括所有历史记录。
git clone git@gitee.com:username/repo.git
克隆操作会自动将远程仓库设置为 `origin`,并建立本地 `master` 分支对远程 `master` 分支的跟踪。
远程操作:拉取 (Pull) & 抓取 (Fetch)
当团队其他成员向远程仓库推送了新的提交后,你需要更新你的本地仓库。
git fetch (抓取)
从远程仓库下载最新的历史记录,但**不**会自动合并到你当前的工作分支。这让你有机会在合并前查看更改。
git fetch origin
# 查看抓取下来的分支
git branch -r
# 手动合并
git merge origin/master
git pull (拉取)
这是一个复合命令,相当于 git fetch + git merge。它会抓取最新内容并立即尝试合并到当前分支。
git pull origin master
贡献开源社区
掌握了Git,你就可以参与到全球的开源项目中!通常的流程 (Fork & Pull Request) 如下:
- Fork: 在GitHub/Gitee上,将你感兴趣的项目“复刻”一份到你自己的账户下。
- Clone: 将你自己账户下的项目克隆到本地。
- Branch: 创建一个新的分支来开发你的新功能或修复bug。
- Commit & Push: 完成修改后,提交并推送到你自己远程仓库的新分支上。
- Pull Request (PR): 在GitHub/Gitee上,向原始项目发起一个“拉取请求”,请求项目维护者将你的修改合并到主项目中。
参考视频:如何向开源社区贡献代码
教程结束
恭喜你!你已经掌握了Git的核心概念和常用命令。
版本控制是一项实践技能,请务必在你的项目中多多使用,熟能生巧。
接下来做什么?
- 请通关这个游戏!!
- 尝试在自己的项目中使用Git进行版本管理。
- 学习使用图形化Git工具,如 SourceTree 或 VS Code 的 Git 插件。
- 参与一个简单的开源项目,提交你的第一个Pull Request!