Ubuntu 22.04 中的版本控制系统 Git 实战
Ubuntu 22.04 环境下 Git 版本控制系统的安装、配置及核心操作指南。涵盖分布式版本控制概念、仓库初始化与克隆、文件暂存与提交流程、分支管理与冲突解决、代码撤销与远程协作等实战步骤。通过具体命令示例演示工作区、暂存区与本地仓库的交互机制,提供 .gitignore 配置及常见误操作补救方案,帮助开发者掌握 Git 基础技能以提升团队协作效率。

Ubuntu 22.04 环境下 Git 版本控制系统的安装、配置及核心操作指南。涵盖分布式版本控制概念、仓库初始化与克隆、文件暂存与提交流程、分支管理与冲突解决、代码撤销与远程协作等实战步骤。通过具体命令示例演示工作区、暂存区与本地仓库的交互机制,提供 .gitignore 配置及常见误操作补救方案,帮助开发者掌握 Git 基础技能以提升团队协作效率。

版本控制(Version Control)是一种追踪文件变更、记录修改历史、协作管理项目的技术,核心作用是:
| 类型 | 代表工具 | 核心特点 |
|---|---|---|
| 集中式 | SVN、CVS | 所有版本存储在中央服务器,本地仅存当前版本,依赖网络,单点故障风险高 |
| 分布式 | Git、Mercurial | 每个开发者本地都有完整仓库(包含所有历史版本),离线可开发,协作灵活高效 |
.git/index 文件);.git 隐藏文件夹);main 分支,原 master 已逐步淘汰);Ubuntu 22.04 默认软件源包含 Git,通过 APT 安装即可,步骤如下:
# 1. 更新软件源(确保获取最新版本)
sudo apt update
# 2. 安装 Git(-y 自动确认安装)
sudo apt install -y git
# 3. 验证安装是否成功(查看版本号,Ubuntu 22.04 默认 3.2.0+)
git --version
# 输出示例:git version 2.34.1(版本号可能因系统更新略有差异)
Git 需要配置用户信息(用户名、邮箱),用于标识提交者身份,配置分为「全局配置」和「本地配置」:
# 1. 配置全局用户名(替换为你的用户名,如 GitHub 用户名)
git config --global user.name "Your Name"
# 2. 配置全局邮箱(替换为你的邮箱,如 GitHub 注册邮箱)
git config --global user.email "[email protected]"
# 3. (可选)配置默认文本编辑器(解决冲突、编写提交信息时使用)
# 可选编辑器:vim、nano、code(VS Code)等,这里以 vim 为例
git config --global core.editor "vim"
# 4. (可选)配置中文显示(解决中文文件名乱码问题)
git config --global core.quotepath false
# 5. 验证配置是否生效(查看所有全局配置)
git config --global --list
# 输出示例:
# user.name=Your Name
# [email protected]
# core.editor=vim
# core.quotepath=false
如果某个仓库需要单独配置用户信息(如工作仓库用公司邮箱),进入仓库目录后执行:
# 1. 进入目标仓库目录(先创建或克隆仓库,后续章节讲解)
cd ~/projects/my-project
# 2. 配置本地用户名和邮箱(覆盖全局配置)
git config user.name "Work Name"
git config user.email "[email protected]"
# 3. 查看本地配置
git config --list
# 输出会包含全局配置 + 本地配置(本地配置优先级更高)
~/.gitconfig(可直接编辑修改);仓库目录/.git/config(仓库内生效)。Git 仓库分为「本地仓库」和「远程仓库」,核心流程:本地仓库可独立使用,也可关联远程仓库实现协作/备份。
适用于全新项目,步骤如下:
# 1. 创建项目目录(自定义名称和路径)
mkdir -p ~/projects/git-demo
# -p 确保父目录存在
cd ~/projects/git-demo
# 进入项目目录
# 2. 初始化本地仓库(关键命令:在目录中创建.git 文件夹)
git init
# 输出:Initialized empty Git repository in /home/yourname/projects/git-demo/.git/
# 3. 查看仓库状态(验证初始化成功)
git status
# 输出:On branch main(默认分支 main)
# No commits yet(暂无提交)
# nothing to commit(无待提交文件)
# 说明:.git 文件夹是本地仓库核心,存储所有版本历史、配置等,切勿手动修改/删除
适用于已有远程仓库(如 GitHub、GitLab 上的项目),通过 git clone 复制到本地:
# 1. 克隆公开仓库(以 GitHub 上的测试仓库为例)
# 格式:git clone 远程仓库 URL [本地目录名(可选)]
git clone https://github.com/octocat/Hello-World.git ~/projects/hello-world
# 2. 进入克隆后的仓库目录
cd ~/projects/hello-world
# 3. 查看仓库信息(验证克隆成功)
git status
# 输出:On branch main
# Your branch is up to date with 'origin/main'(与远程分支同步)
# 4. 查看远程仓库关联(origin 是远程仓库的默认别名)
git remote -v
# 输出:
# origin https://github.com/octocat/Hello-World.git (fetch)
# origin https://github.com/octocat/Hello-World.git (push)
# 说明:克隆仓库会自动完成 3 件事:
# - 创建本地仓库目录;
# - 初始化本地仓库(.git 文件夹);
# - 关联远程仓库(别名 origin);
# - 拉取远程仓库的所有代码和历史版本。
如果远程仓库是私有(如公司 GitLab 仓库),克隆时需输入用户名和密码,或配置 SSH 密钥(免密登录):
# 方式 1:HTTPS 协议(输入用户名 + 密码)
git clone https://[email protected]/team/project.git
# 方式 2:SSH 协议(需提前配置 SSH 密钥,免密登录)
# 1. 生成 SSH 密钥(默认路径~/.ssh/id_rsa)
ssh-keygen -t rsa -C"[email protected]"
# 按回车默认即可,无需设置密码
# 2. 查看公钥内容(复制到远程仓库的 SSH 密钥配置中)
cat ~/.ssh/id_rsa.pub
# 复制输出的所有内容(以 ssh-rsa 开头,以邮箱结尾)
# 3. 克隆私有仓库(SSH 协议)
git clone [email protected]:team/project.git
新建仓库后,需将项目文件(源代码、配置文件等)导入仓库,核心步骤:工作区→暂存区→本地仓库。
以 C 语言项目为例,创建源代码文件和说明文档:
// 1. 创建主程序文件 hello.c(带详细注释)
vim hello.c
写入以下代码:
#include<stdio.h>
int main(){
// 初始版本:输出 Hello Git
printf("Hello Git! This is my first commit.\n");
return 0;
}
# 2. 创建项目说明文档 README.md
vim README.md
写入:
# Git Demo 项目
这是一个用于演示 Git 版本控制的 C 语言项目。
核心功能:输出问候语,展示 Git 的提交、修改、冲突解决等操作。
Git 导入文件需经过「添加到暂存区」和「提交到本地仓库」两个关键步骤:
# 查看当前工作区和暂存区状态
git status
# 输出:
# Untracked files:(未跟踪文件:Git 未管理的新文件)
# hello.c
# README.md
# 提示:使用 git add <file> 将文件添加到暂存区
将需要跟踪的文件添加到暂存区(可单个文件、多个文件或所有文件):
# 方式 1:添加单个文件
git add hello.c
# 方式 2:添加多个文件(空格分隔)
git add hello.c README.md
# 方式 3:添加当前目录所有文件(常用,注意不要添加临时文件)
git add .
"." 代表当前目录
# 再次查看状态(验证添加成功)
git status
# 输出:
# Changes to be committed:(待提交文件:已在暂存区)
# new file: hello.c
# new file: README.md
将暂存区的文件永久保存到本地仓库,生成唯一版本记录,必须填写提交信息(描述修改内容):
# 基本格式:git commit -m "提交信息"(-m 指定提交说明)
git commit -m"feat: 初始化项目,添加 hello.c 和 README.md"
# 输出示例(成功提交):
# [main (root-commit) 7a3f2d1] feat: 初始化项目,添加 hello.c 和 README.md
# 2 files changed, 10 insertions(+)(2 个文件变更,新增 10 行代码)
# create mode 100644 hello.c
# create mode 100644 README.md
# 说明:
# - 7a3f2d1:是提交的唯一版本号(哈希值前 7 位,用于定位版本);
# - 提交信息规范(推荐):类型:描述(如 feat-新功能、fix-修复 bug、docs-文档修改等);
# - 如果未加-m 参数,会自动打开编辑器(如 vim)让你编写提交信息,编写后保存退出即可。
验证提交是否成功,查看所有版本记录:
# 方式 1:查看完整提交历史
git log
# 输出示例:
# commit 7a3f2d1e890b49e7a23f5d5e321a87556b8f123 (HEAD -> main)
# Author: Your Name <[email protected]>
# Date: Tue Oct 10 14:30:00 2023 +0800
# # feat: 初始化项目,添加 hello.c 和 README.md
# 方式 2:简洁显示(仅显示版本号前 7 位和提交信息)
git log --oneline
# 输出:7a3f2d1 (HEAD -> main) feat: 初始化项目,添加 hello.c 和 README.md
# 方式 3:图形化显示(分支合并历史更清晰)
git log --graph --oneline
项目导入仓库后,日常开发的核心流程:修改文件→查看变更→添加暂存→提交仓库→(可选)推送到远程。
修改 hello.c,增加新功能(输出版本信息):
#include<stdio.h>
int main(){
// 初始版本:输出 Hello Git
printf("Hello Git! This is my first commit.\n");
// 新增功能:输出项目版本
printf("Project Version: v1.0.1\n");
// 新增代码行
return 0;
}
确认修改内容,避免误改:
# 查看工作区与暂存区的差异(未 add 的修改)
git diff hello.c
# 输出示例(+表示新增,-表示删除):
# 4,5d3
# < // 新增功能:输出项目版本
# < printf("Project Version: v1.0.1\n");
# 7a6
# > return 0;
# 说明:如果已执行 git add,git diff 无法查看差异,需用 git diff --cached(查看暂存区与本地仓库的差异)
# 1. 添加修改后的文件到暂存区
git add hello.c
# 2. 提交到本地仓库(提交信息说明修改内容)
git commit -m"feat: 新增版本输出功能,版本号 v1.0.1"
# 3. 查看提交历史(验证提交)
git log --oneline
# 输出:
# 9b2d5c7 (HEAD -> main) feat: 新增版本输出功能,版本号 v1.0.1
# 7a3f2d1 feat: 初始化项目,添加 hello.c 和 README.md
如果同时修改了多个文件(如 hello.c 和 README.md),可批量提交:
# 1. 修改 README.md,更新版本说明
vim README.md
# 新增内容:"当前版本:v1.0.1(支持版本号输出)"
# 2. 查看所有文件的变更
git diff
# 不指定文件名,查看所有修改文件的差异
# 3. 批量添加所有修改文件到暂存区
git add .
# 谨慎使用!确保只添加需要提交的文件(避免添加临时文件)
# 4. 提交(提交信息概括所有修改)
git commit -m"docs: 更新 README.md,添加 v1.0.1 版本说明"
# 5. 查看历史
git log --oneline
# 输出新增一条提交记录
项目中存在临时文件(如编译生成的 .o、可执行文件、日志文件等),无需 Git 跟踪,通过 .gitignore 文件配置:
vim .gitignore
写入以下内容(C 语言项目常用配置):
# 编译生成的可执行文件
hello
a.out
# 目标文件(.o)
*.o
# 日志文件
*.log
# 临时文件
*.tmp
.DS_Store
# Mac 系统临时文件
git add .gitignore
git commit -m"chore: 添加.gitignore,忽略编译文件和临时文件"
.gitignore 仅对「未跟踪文件」生效,如果文件已被 Git 跟踪(已 add/commit),修改 .gitignore 无法忽略,需先移除跟踪:
# 移除已跟踪文件的跟踪(不删除物理文件)
git rm --cached 不需要跟踪的文件
冲突是多人协作中最常见的问题,当多个开发者修改同一文件的同一行代码,或同一分支的不同提交修改同一处时,Git 无法自动合并,需手动解决。
假设两个开发者(A 和 B)同时基于 main 分支开发,流程如下:
# 1. 基于 main 分支创建新分支(模拟 A 的开发分支)
git checkout -b feature/A-dev
# -b 创建并切换分支
# 2. 修改 hello.c 的同一行(第 4 行)
vim hello.c
# 修改内容:printf("Hello Git! This is A's modification.\n");
# 3. 提交修改
git add hello.c
git commit -m"feat: A 修改问候语"
# 4. 切换回 main 分支,准备合并
git checkout main
# 1. 基于 main 分支创建新分支(模拟 B 的开发分支)
git checkout -b feature/B-dev
# 2. 修改 hello.c 的同一行(第 4 行,与 A 冲突)
vim hello.c
# 修改内容:printf("Hello Git! This is B's modification.\n");
# 3. 提交修改
git add hello.c
git commit -m"feat: B 修改问候语"
# 4. 切换回 main 分支,准备合并
git checkout main
# 1. 先合并 A 的分支到 main(无冲突)
git merge feature/A-dev
# 输出:Merge made by the 'ort' strategy. 成功合并
# 2. 再合并 B 的分支到 main(触发冲突)
git merge feature/B-dev
# 输出提示冲突:
# Auto-merging hello.c
# CONFLICT (content): Merge conflict in hello.c
# Automatic merge failed; fix conflicts and then commit the result.
git status
# 输出:
# You have unmerged paths.(存在未合并路径)
# (fix conflicts and run "git commit")
# Unmerged paths:
# both modified: hello.c(双方都修改了 hello.c)
打开冲突文件 hello.c,Git 会用特殊标记标注冲突位置:
#include<stdio.h>
int main(){
// 冲突位置:A 和 B 修改了同一行
<<<<<<< HEAD
// HEAD 表示当前分支(main)的内容(A 的修改)
printf("Hello Git! This is A's modification.\n");
=======
printf("Hello Git! This is B's modification.\n");
>>>>>>> feature/B-dev
// 待合并分支(B 的分支)的内容
printf("Project Version: v1.0.1\n");
return 0;
}
删除冲突标记(<<<<<<<、=======、>>>>>>>),修改为最终需要的内容(如协商后保留两者的修改,或选择其一):
#include<stdio.h>
int main(){
// 解决冲突:保留 A 和 B 的修改,添加标注
printf("Hello Git! This is A's modification.\n");
printf("Hello Git! This is B's modification.\n");
printf("Project Version: v1.0.1\n");
return 0;
}
# 1. 添加解决冲突后的文件到暂存区
git add hello.c
# 2. 提交合并结果(无需写-m,Git 自动生成合并提交信息)
git commit
# 自动打开编辑器,保存默认信息即可(或手动修改)
# 3. 验证冲突解决成功
git log --oneline --graph
# 输出会显示合并记录,分支已合并到 main
git pull)远程分支最新代码;开发中难免出现误修改、误提交,Git 提供多种撤销方案,需根据「修改所处阶段」选择对应命令。
误修改了文件,但还没添加到暂存区,想放弃修改,恢复到最近一次提交的状态:
# 示例:误修改了 hello.c,未 git add
git status
# 确认状态:modified: hello.c(未 add)
# 撤销单个文件的修改(核心命令)
git checkout -- hello.c
# 撤销当前目录所有文件的修改(谨慎使用)
git checkout -- .
# 验证:文件已恢复到最近提交的版本
git status
# 输出:nothing to commit, working tree clean
已执行 git add 将修改添加到暂存区,但想撤销暂存,恢复到工作区未 add 的状态:
# 示例:已 git add hello.c,未 commit
git status
# 确认状态:Changes to be committed: modified: hello.c
# 撤销暂存(核心命令:git reset HEAD <文件>)
git reset HEAD hello.c
# 验证:暂存区已撤销,修改回到工作区
git status
# 输出:modified: hello.c(未 add 状态)
# (可选)如果想同时放弃工作区的修改,再执行场景 1 的命令
git checkout -- hello.c
已提交到本地仓库,但发现提交错误(如提交信息写错、漏改代码),想撤销该提交:
如果只是提交信息错误,或漏加文件,可修正最近一次提交:
# 1. 补充修改(如漏加的文件,或修正代码)
git add 漏加的文件
# 如有漏加文件
# 2. 修正最近一次提交(--amend 修改上一次提交)
git commit --amend
# 自动打开编辑器,修改提交信息,保存退出即可
# 验证:提交历史中,上一次提交已被替换(无新提交记录)
git log --oneline
如果提交的代码有严重 bug,想彻底删除该提交,回滚到之前的版本:
# 1. 查看提交历史,找到要回滚的目标版本号(如 7a3f2d1)
git log --oneline
# 输出:9b2d5c7(错误提交)、7a3f2d1(目标版本)
# 2. 回滚到目标版本(--hard:彻底覆盖工作区和暂存区,谨慎使用!)
git reset --hard 7a3f2d1
# 验证:提交历史已删除错误提交,文件恢复到目标版本
git log --oneline
# 输出仅显示 7a3f2d1 及之前的提交
如果错误提交已推送到远程仓库(如 GitHub),切勿使用 git reset(会导致多人协作冲突),应使用 git revert 创建新提交,撤销旧提交的修改:
# 1. 查看远程提交历史,找到错误提交的版本号(如 9b2d5c7)
git log --oneline
# 2. 撤销指定提交(核心命令:git revert 版本号)
git revert 9b2d5c7
# 自动打开编辑器,编写撤销提交的信息(默认即可),保存退出
# 3. 推送撤销提交到远程仓库
git push origin main
# 说明:
# - git revert 不会删除历史提交,而是新增一个'撤销提交',安全可靠;
# - 远程仓库的错误提交依然存在,但修改已被撤销。
| 场景 | 推荐命令 | 风险等级 |
|---|---|---|
| 工作区修改(未 add) | git checkout -- <文件> | 低 |
| 暂存区修改(已 add 未 commit) | git reset HEAD <文件> + git checkout -- <文件> | 低 |
| 本地提交(未 push)- 修正信息 | git commit --amend | 中 |
| 本地提交(未 push)- 删除提交 | git reset --hard <版本号> | 高 |
| 远程提交(已 push) | git revert <版本号> + git push | 低 |
| 命令 | 功能描述 |
|---|---|
| git config --global user.name '姓名' | 配置全局用户名 |
| git config --global user.email '邮箱' | 配置全局邮箱 |
| git config --global core.editor 'vim' | 配置默认编辑器 |
| git config --global --list | 查看全局配置 |
| git config --list | 查看当前仓库配置(全局 + 本地) |
| 命令 | 功能描述 |
|---|---|
| git init | 初始化本地仓库 |
| git clone <远程 URL> [本地目录] | 克隆远程仓库到本地 |
| git remote -v | 查看远程仓库关联(origin 是默认别名) |
| git remote add <别名> <远程 URL> | 添加远程仓库关联(如 git remote add origin) |
| git remote remove <别名> | 删除远程仓库关联 |
| 命令 | 功能描述 |
|---|---|
| git status | 查看工作区、暂存区状态 |
| git diff [<文件>] | 查看工作区与暂存区的差异 |
| git diff --cached [<文件>] | 查看暂存区与本地仓库的差异 |
| git add <文件> / git add . | 添加文件到暂存区 |
| git commit -m '提交信息' | 提交暂存区到本地仓库 |
| git commit --amend | 修正最近一次提交 |
| git log | 查看提交历史(完整) |
| git log --oneline | 简洁查看提交历史(版本号 + 信息) |
| git log --graph --oneline | 图形化查看提交历史(分支合并清晰) |
| 命令 | 功能描述 |
|---|---|
| git branch | 查看所有本地分支(*表示当前分支) |
| git branch <分支名> | 创建新分支 |
| git checkout <分支名> | 切换分支 |
| git checkout -b <分支名> | 创建并切换分支 |
| git merge <分支名> | 合并指定分支到当前分支 |
| git branch -d <分支名> | 删除已合并的分支 |
| git branch -D <分支名> | 强制删除未合并的分支 |
| 命令 | 功能描述 |
|---|---|
| git status | 查看冲突文件 |
| git add <冲突文件> | 解决冲突后添加到暂存区 |
| git commit | 提交冲突解决结果 |
| 命令 | 功能描述 |
|---|---|
| git checkout -- <文件> | 撤销工作区修改(未 add) |
| git reset HEAD <文件> | 撤销暂存区修改(已 add 未 commit) |
| git reset --hard <版本号> | 回滚到指定版本(本地未 push) |
| git revert <版本号> | 撤销指定提交(已 push 到远程) |
| 命令 | 功能描述 |
|---|---|
| git pull <远程别名> <分支名> | 拉取远程分支最新代码并合并(如 git pull origin main) |
| git push <远程别名> <分支名> | 推送本地分支到远程仓库(如 git push origin main) |
| git push -u <远程别名> <分支名> | 推送并关联远程分支(后续可直接 git push) |
本章详细讲解了 Ubuntu 22.04 中 Git 版本控制系统的核心知识点与实战操作,核心要点总结如下:
git init)和克隆远程仓库(git clone),.git 文件夹是仓库核心,切勿手动修改;git add 添加到暂存区,git commit 提交到本地仓库,git log 查看历史,git diff 查看变更;git add→git commit 完成解决,预防冲突的关键是频繁同步和细分功能;git revert(安全无风险);Git 是程序员必备工具,建议在实际项目中多练习(如搭建个人 GitHub 仓库、模拟多人协作),熟练掌握后可大幅提升开发效率和代码管理能力。实际工作中,结合远程仓库(GitHub、GitLab)可实现跨团队协作、代码备份和版本管理,是大型项目开发的基础。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online