系列:版本控制基础
背景
开发项目时,最怕的情况通常不是代码写不出来,而是:
- 修改后发现新版本有问题,却不知道如何回到旧版本;
- 多台电脑之间复制项目文件,最后不知道哪一份才是最新;
- 多人同时修改同一个项目,文件互相覆盖;
- 想查看某个功能或 Bug 是哪次修改引入的;
- 部署服务器上的代码和本地代码不一致。
Git 是分布式版本控制工具。它会记录文件变化,并把每一次有意义的修改保存为提交记录(commit)。
可以把 Git 的核心工作流理解为:
工作区(Working Directory) ↓ git add暂存区(Staging Area) ↓ git commit本地仓库(Local Repository) ↓ git push远程仓库(GitHub / GitLab / Gitea 等)Git 本身是版本控制工具;GitHub、GitLab、Gitea 等则是托管 Git 仓库的平台或服务。即使不连接任何平台,也可以在本地使用 Git 管理项目历史。
本文介绍 Git 在 Linux 和 Windows 上的安装、初始配置、日常命令、分支协作和常见问题。
步骤
1. 在 Linux 安装 Git
Debian / Ubuntu:
sudo apt updatesudo apt install -y gitFedora / Rocky Linux / AlmaLinux:
sudo dnf install -y gitCentOS 7:
sudo yum install -y gitArch Linux:
sudo pacman -S git安装完成后,确认版本:
git --version如果能看到类似下面的输出,说明安装成功:
git version 2.x.x2. 在 Windows 安装 Git
Windows 推荐安装 Git for Windows。
安装流程:
- 进入 Git 官方网站的 Windows 安装页面,下载 Git for Windows 安装程序;
- 运行安装程序;
- 一般保持默认选项即可;
- 安装完成后,打开 Git Bash、PowerShell 或 Windows Terminal;
- 执行以下命令确认安装:
git --versionGit for Windows 会提供 Git 命令行工具,也通常会安装 Git Bash。Git Bash 提供接近 Linux Shell 的命令环境,因此本文中大部分命令都可以直接在 Git Bash、PowerShell、Windows Terminal 和 Linux 终端中使用。
3. 配置用户名和邮箱
Git 会把用户名和邮箱写入每一条提交记录。首次安装后,需要为当前电脑配置身份信息。
全局配置用户名:
git config --global user.name "你的名字"全局配置邮箱:
git config --global user.email "your-email@example.com"查看配置:
git config --global --list只查看身份信息:
git config --global user.namegit config --global user.email例如:
git config --global user.name "test"git config --global user.email "test@example.com"邮箱最好与代码托管平台中绑定的邮箱保持一致,否则平台可能无法将提交记录正确关联到你的账户。
4. 配置默认分支、编辑器和换行符
新项目默认分支建议使用 main:
git config --global init.defaultBranch main如果你使用 VS Code,可以将其设为 Git 提交信息编辑器:
git config --global core.editor "code --wait"Windows 和 Linux 的换行符不同。一般建议:
Linux:
git config --global core.autocrlf inputWindows:
git config --global core.autocrlf true含义:
Linux 的 input:提交时将 CRLF 转为 LF,检出时保持 LFWindows 的 true:检出时使用 CRLF,提交时统一转为 LF如果项目已经通过 .gitattributes 统一管理换行符,应优先遵循项目自身的规则,不要随意修改团队约定。
5. 创建第一个本地 Git 仓库
进入项目目录:
mkdir my-projectcd my-project初始化 Git 仓库:
git init查看当前状态:
git status创建一个 README 文件:
echo "# My Project" > README.md查看改动:
git status将文件加入暂存区:
git add README.md把当前目录的所有需要提交的变更加入暂存区:
git add .创建第一次提交:
git commit -m "feat: initialize project"查看提交历史:
git log --oneline推荐的日常循环:
修改文件→ git status→ git diff→ git add→ git commit→ git push6. 理解 git status、git diff 和 git add
查看当前工作区状态:
git status查看尚未暂存的修改:
git diff查看已暂存但未提交的修改:
git diff --staged暂存一个文件:
git add app/main.py暂存多个文件:
git add README.md docker-compose.yml暂存当前目录所有修改:
git add .在提交前,建议养成下面的习惯:
git statusgit diffgit add .git diff --stagedgit commit -m "feat: add user login endpoint"这样可以减少把临时文件、密钥文件或无关修改误提交到仓库的风险。
7. 编写 .gitignore 排除不应提交的文件
.gitignore 用于告诉 Git 忽略不需要纳入版本控制的文件。
一个 Python + Node.js 项目的示例:
# Python.venv/__pycache__/*.py[cod].pytest_cache/
# Node.jsnode_modules/dist/build/
# Environment variables and secrets.env.env.*!.env.example
# IDE and OS files.vscode/.idea/.DS_Store
# Logs*.log创建文件:
nano .gitignore添加后提交:
git add .gitignoregit commit -m "chore: add gitignore rules"
.gitignore只能忽略“尚未被 Git 跟踪”的文件。一个文件如果已经提交过,后来才加入.gitignore,Git 仍会继续跟踪它。
停止跟踪已经提交的文件,但保留本地文件:
git rm --cached .env然后提交变更:
git add .gitignoregit commit -m "chore: stop tracking environment file"如果 .env 曾经被推送到远程仓库,不能只靠删除当前文件解决泄露风险,应立即轮换其中的密码、Token、API Key 和其他凭据。
8. 克隆远程仓库
如果远程仓库已经存在,可以直接克隆:
git clone https://github.com/用户名/仓库名.git进入项目目录:
cd 仓库名查看远程仓库地址:
git remote -v通过 SSH 克隆:
git clone git@github.com:用户名/仓库名.gitHTTPS 和 SSH 的常见区别:
HTTPS:上手简单;推送时可能需要 Token 或凭据管理器SSH:配置一次密钥后,日常推送通常更方便对于长期开发的个人项目和服务器项目,通常推荐配置 SSH。
9. 配置 SSH 密钥连接远程仓库
在 Linux 或 Windows Git Bash 中生成 Ed25519 SSH 密钥:
ssh-keygen -t ed25519 -C "your-email@example.com"一路按 Enter 会默认生成:
~/.ssh/id_ed25519~/.ssh/id_ed25519.pub启动 SSH Agent:
eval "$(ssh-agent -s)"加入私钥:
ssh-add ~/.ssh/id_ed25519查看公钥并复制:
cat ~/.ssh/id_ed25519.pub把公钥添加到 GitHub、GitLab、Gitea 或其他代码托管平台的 SSH Key 设置中。
以 GitHub 为例,测试连接:
ssh -T git@github.com连接成功后,可以使用 SSH 地址配置远程仓库:
git remote add origin git@github.com:用户名/仓库名.git将本地 main 分支首次推送到远程:
git push -u origin main-u 会设置上游分支。以后在当前分支上通常只需要:
git push10. 从本地项目推送到远程仓库
假设你已经在代码托管平台创建了一个空仓库。
在本地项目目录执行:
git initgit branch -M maingit add .git commit -m "feat: initial commit"git remote add origin git@github.com:用户名/仓库名.gitgit push -u origin main之后的日常推送流程:
git statusgit add .git commit -m "feat: add new feature"git push如果远程仓库已经有 README、LICENSE 等提交,而本地仓库也有独立提交,先拉取远程历史:
git pull origin main --rebase解决冲突后再推送。
11. 使用分支开发功能
不要把所有开发都直接提交到 main。为新功能、修复和实验创建独立分支,更容易回滚、审查和协作。
创建并切换到新分支:
git switch -c feature/login旧写法:
git checkout -b feature/login查看本地分支:
git branch切换分支:
git switch main提交功能后推送分支:
git add .git commit -m "feat: add login page"git push -u origin feature/login然后在 GitHub、GitLab 或 Gitea 上创建 Pull Request / Merge Request,完成代码审查和合并。
本地合并分支:
git switch maingit pull --rebasegit merge feature/login删除已经合并的本地分支:
git branch -d feature/login删除远程分支:
git push origin --delete feature/login12. 拉取、推送和同步远程更新
查看远程信息:
git remote -v获取远程更新但不合并:
git fetch拉取并合并当前分支:
git pull推荐使用 rebase 方式拉取,以减少不必要的合并提交:
git pull --rebase推送当前分支:
git push推送新分支并建立跟踪关系:
git push -u origin 分支名查看本地与远程分支:
git branch -a一个较稳妥的日常同步流程:
git statusgit pull --rebasegit add .git commit -m "fix: correct validation logic"git push13. 处理合并冲突
当两个人或两个分支修改了同一段代码时,Git 可能无法自动合并,出现冲突。
先查看冲突文件:
git status冲突内容通常类似:
<<<<<<< HEAD当前分支的内容=======另一分支的内容>>>>>>> feature/login处理步骤:
- 打开冲突文件;
- 决定保留哪一部分内容,或手动整合两边逻辑;
- 删除
<<<<<<<、=======、>>>>>>>标记; - 保存文件;
- 标记冲突已解决;
- 继续合并或变基过程。
普通合并冲突:
git add 冲突文件git commitgit pull --rebase 产生冲突时:
git add 冲突文件git rebase --continue不想继续本次变基:
git rebase --abort不想继续本次合并:
git merge --abort14. 撤销改动、暂存和恢复
撤销某个尚未暂存文件的修改:
git restore 文件路径撤销当前目录所有尚未暂存的修改:
git restore .将文件从暂存区撤回工作区,但保留文件修改:
git restore --staged 文件路径临时保存当前未提交的修改:
git stash查看临时保存列表:
git stash list恢复最近一次暂存:
git stash pop在使用破坏性命令前,先执行:
git statusgit diff尤其不要在没有确认修改是否需要保留时,随意执行:
git reset --hardgit clean -fd这类命令可能删除尚未提交的内容。
15. 查看历史与定位问题
查看简洁提交历史:
git log --oneline --graph --decorate --all查看某个文件的提交历史:
git log -- path/to/file查看某次提交具体修改:
git show 提交哈希查看某一行最后由谁修改:
git blame path/to/file查看两个分支之间的差异:
git diff main...feature/login查看当前工作区差异:
git diff这些命令适合排查“某段代码是什么时候改的”“哪个提交引入了问题”“功能分支与主分支有什么不同”等问题。
16. 常用 Git 命令速查
# 配置身份git config --global user.name "你的名字"git config --global user.email "邮箱"
# 初始化与克隆git initgit clone 仓库地址
# 查看状态与差异git statusgit diffgit diff --staged
# 暂存与提交git add 文件名git add .git commit -m "提交说明"
# 分支git branchgit switch -c feature/名称git switch maingit merge feature/名称
# 远程协作git remote -vgit fetchgit pull --rebasegit pushgit push -u origin 分支名
# 历史git log --oneline --graph --decorate --allgit show 提交哈希git blame 文件路径
# 撤销与暂存git restore 文件路径git restore --staged 文件路径git stashgit stash pop常见问题
1. git commit 提示 Please tell me who you are
说明还没有配置用户名和邮箱。
执行:
git config --global user.name "你的名字"git config --global user.email "your-email@example.com"然后重新提交:
git commit -m "feat: initial commit"2. Windows 中 git 命令找不到怎么办?
先关闭并重新打开 Git Bash、PowerShell 或 Windows Terminal,然后执行:
git --version如果仍提示找不到命令,通常是 Git for Windows 没有正确安装,或者安装时没有将 Git 添加到 PATH。重新运行安装程序并选择默认的 PATH 配置通常可以解决。
3. 为什么 .env 加入 .gitignore 后仍然显示被修改?
这是因为 .env 已经被 Git 跟踪。
停止跟踪但保留本地文件:
git rm --cached .envgit add .gitignoregit commit -m "chore: stop tracking env file"如果敏感信息已经推送到远程仓库,请立即轮换相关密钥和密码。
4. git push 被拒绝,提示 remote contains work that you do not have locally
说明远程分支已经有新提交,本地还没有同步。
先拉取:
git pull --rebase origin main如果产生冲突,先解决冲突,再继续:
git add 冲突文件git rebase --continue最后推送:
git push除非你明确理解影响,否则不要用 git push --force 覆盖远程分支历史。
5. 提交后发现写错了提交信息怎么办?
只修改最近一次提交说明,并且还没有推送时:
git commit --amend -m "feat: correct commit message"如果已经推送到多人共享分支,不建议随意修改历史。更稳妥的做法是新建一次提交修正问题。
6. Git 和 GitHub 有什么区别?
Git:安装在本地电脑上的版本控制工具GitHub:托管 Git 仓库并支持协作的平台GitLab:托管 Git 仓库并支持 CI/CD、权限管理等的平台Gitea:可自行部署的轻量级 Git 服务可以只使用 Git,不使用 GitHub;也可以把同一个本地 Git 仓库推送到 GitHub、GitLab 或自建 Gitea。
7. Linux 和 Windows 的 Git 命令有区别吗?
大部分 Git 命令完全相同:
git statusgit add .git commit -m "feat: add feature"git pull --rebasegit push主要区别在于:
安装方式不同文件路径写法不同换行符处理可能不同终端环境不同在 Windows 上使用 Git Bash 时,很多 Shell 命令也和 Linux 相似;在 PowerShell 中则需要使用 PowerShell 自己的文件操作命令,但 Git 命令本身不变。
总结
Git 是开发过程中最基础、最值得尽早养成习惯的工具之一。它不仅能保存代码历史,也能让多台电脑、多人协作和部署流程更可靠。
先掌握下面的主流程即可:
git statusgit add .git commit -m "feat: describe your change"git pull --rebasegit push再逐步学习:
.gitignore:避免提交依赖、缓存和密钥branch:让功能开发与主分支隔离SSH:减少远程推送认证摩擦pull --rebase:更清晰地同步远程更新restore / stash:安全处理未完成修改log / diff / blame:定位历史变更和问题无论你在 Linux 服务器、Windows 电脑,还是使用 VS Code、Claude Code、Codex 等开发工具,Git 都是管理项目和保护代码历史的基础能力。
掌握基础流程后,可以继续看 Git 进阶:你迟早要会的几个救急命令,重点补上 stash、reflog、bisect、worktree 这些救急场景。命令细节建议同时参考 Git 官方文档。