Git 版本控制从入门到实战:一篇讲透仓库、分支、远程协作与 GitLab

适合人群:刚开始学 Java / 后端开发 / 前端开发、第一次接触 Git、想系统补齐 Git 命令和团队协作流程的同学。
关键词:Git 教程、Git 命令大全、Git 分支管理、GitHub、GitLab、多人协作、冲突解决、.gitignore

一、为什么开发者一定要学 Git?

写代码最怕的不是 bug,而是这几件事:

  • 改了半天,突然想回到昨天的版本。
  • 多个人同时改代码,不知道谁覆盖了谁。
  • 线上出了问题,想快速找到是哪一次提交引入的。
  • 新功能开发到一半,突然要先修一个紧急 bug。
  • 代码在自己电脑上能跑,团队其他人却拿不到最新版本。

Git 就是为了解决这些问题而出现的版本控制系统。它可以记录项目每一次变化,让你能随时查看历史、回退版本、创建分支、合并代码、和团队成员协作开发。

一句话理解 Git:

Git 是一个分布式版本控制系统,它把项目的每一次提交都保存成快照,并允许每个开发者在本地拥有完整仓库历史。

Git 最早由 Linux 作者 Linus Torvalds 开发。Linux 内核项目参与者众多,靠人工合并补丁已经无法支撑协作效率,于是 Git 诞生,并逐渐成为目前最主流的版本控制工具。后来 GitHub、GitLab、Gitee 等平台兴起,Git 也成为程序员的基础技能。

二、集中式版本控制 VS 分布式版本控制

学习 Git 之前,先弄清楚它和 SVN、CVS 这类集中式版本控制系统的区别。

1. 集中式版本控制

集中式版本控制系统把所有版本历史都放在一台中央服务器上,开发者通过客户端连接服务器,获取代码、提交修改。

典型代表:

  • CVS
  • SVN
  • Perforce

它的优点是模型简单,所有代码都在一个中心位置管理。但缺点也很明显:

  • 中央服务器宕机时,大家很难提交或拉取代码。
  • 如果中央仓库损坏且备份不完整,历史记录可能丢失。
  • 很多操作依赖网络,离线开发体验差。

2. 分布式版本控制

Git 属于分布式版本控制系统。每个开发者克隆项目时,拿到的不只是最新代码,而是整个仓库历史。

这意味着:

  • 本地就能提交代码。
  • 本地就能查看日志、比较差异、回退版本。
  • 远程仓库出问题时,其他人的本地仓库仍然保存了完整历史。
  • 没网时也能开发,有网后再推送。

可以把 Git 的协作关系理解成:

开发者 A 本地仓库  <---->  远程仓库  <---->  开发者 B 本地仓库
        |                              |
      工作区                          工作区

Git 的强大之处在于:它不是简单记录文件差异,而是按提交保存项目快照。文件没变时,Git 不会重复保存文件内容,而是通过引用复用之前的对象,所以速度快、空间利用率也高。

三、Git 安装与首次配置

Git 支持 Windows、macOS 和 Linux。安装完成后,建议先配置用户名和邮箱。它们会写入每一次提交记录中,用来标识是谁提交了代码。

git config --global user.name "your_name"
git config --global user.email "your_email@example.com"

查看配置:

git config --global -l

Git 配置分为三个级别:

级别 命令参数 配置文件位置 作用范围
仓库级 --local 当前仓库 .git/config 只对当前项目生效
用户级 --global 用户目录 ~/.gitconfig 对当前用户所有项目生效
系统级 --system Git 安装目录下的配置文件 对系统所有用户生效

优先级:

local > global > system

注意:配置邮箱时是 user.email,不是 user.mail

四、Git 仓库的四个核心区域

初学 Git 最容易混乱的地方,就是工作区、暂存区、本地仓库、远程仓库之间的关系。

区域 英文 说明
工作区 Workspace 项目目录里你能直接看到和编辑的文件
暂存区 Stage / Index git add 后临时保存改动的位置
本地仓库 Repository .git 目录,保存提交历史和版本信息
远程仓库 Remote GitHub、GitLab、Gitee 上的代码仓库

最常见的提交流程是:

修改文件
  ↓
git add
  ↓
暂存区
  ↓
git commit
  ↓
本地仓库
  ↓
git push
  ↓
远程仓库

对应命令:

git status
git add .
git commit -m "提交说明"
git push

如果从远程同步别人的代码,流程通常是:

git pull

或者拆成两步:

git fetch
git merge

五、创建本地仓库:git init

进入项目目录后,执行:

git init

执行后,当前目录会多出一个隐藏目录 .git。这个目录非常重要,里面保存着 Git 管理版本所需的所有数据,包括对象、分支、HEAD 指针、暂存区索引等。

不要手动乱改 .git 目录,否则仓库可能损坏。

查看当前仓库状态:

git status

如果看到 Untracked files,说明文件还没有被 Git 跟踪。

六、添加与提交文件:addcommit

假设新建了一个 readme.txt

echo "hello git" > readme.txt
git status

把文件加入暂存区:

git add readme.txt

一次添加多个文件:

git add a.txt b.txt c.txt

添加当前目录全部改动:

git add .

提交到本地仓库:

git commit -m "first commit"

提交说明一定要写清楚,不要只写 updatefixaa。推荐写成:

git commit -m "feat: add user login page"
git commit -m "fix: resolve order amount calculation bug"
git commit -m "docs: update git learning notes"

这样团队成员看日志时,能快速知道这次提交做了什么。

七、查看日志与版本历史

查看提交历史:

git log

简洁显示:

git log --pretty=oneline

更常用的图形化日志:

git log --oneline --graph --decorate --all

输出大概长这样:

* 9fceb02 (HEAD -> dev) feat: add order module
* 61a3b21 fix: repair login bug
* 35cc0f4 (main) first commit

其中:

  • HEAD 表示当前所在位置。
  • HEAD^ 表示上一次提交。
  • HEAD~3 表示往前数第 3 次提交。
  • 一串哈希值,比如 9fceb02,是提交版本号的简写。

八、查看文件差异:git diff

git diff 用来查看改动内容,是排查问题和提交前自查的高频命令。

1. 工作区 VS 暂存区

查看工作区中还没有 add 的修改:

git diff
git diff readme.txt

2. 暂存区 VS 最近一次提交

查看已经 add,但还没有 commit 的内容:

git diff --cached
git diff --cached readme.txt

3. 工作区 VS 指定提交

git diff HEAD
git diff HEAD readme.txt
git diff <commit_id> readme.txt

4. 两个提交之间比较

git diff <commit_id_1> <commit_id_2>

建议每次提交前执行:

git status
git diff --cached

这样可以确认自己即将提交的内容是否符合预期。

九、撤销修改与版本回退

Git 的撤销命令很多,新手最容易用错。可以按场景记。

场景 命令 说明
撤销工作区某个文件的修改 git restore file.txt 文件回到暂存区或最近提交的状态
取消暂存 git restore --staged file.txt 文件从暂存区退回工作区
回退到上一个提交 git reset --hard HEAD^ 工作区、暂存区、本地仓库一起回退
回退到指定提交 git reset --hard <commit_id> 直接回到某个版本
查看操作历史 git reflog 找回被 reset 掉的提交

示例:

git reset --hard HEAD^

回退到上上个版本:

git reset --hard HEAD^^

回退到前 100 个版本:

git reset --hard HEAD~100

回到指定提交:

git reset --hard 8d95a43

如果回退后又后悔了,可以用:

git reflog

找到之前的提交号,再执行:

git reset --hard <commit_id>

重点提醒:git reset --hard 会丢弃工作区未提交的修改,执行前一定要确认没有重要代码。

十、删除文件

如果要从 Git 仓库中删除文件:

git rm test.txt
git commit -m "remove test file"

如果只是手动删除了文件,也可以用:

rm test.txt
git add test.txt
git commit -m "remove test file"

如果删除后想撤销:

git restore test.txt

如果文件已经进入暂存区,想取消暂存:

git restore --staged test.txt

老版本 Git 也常见这些写法:

git checkout -- test.txt
git reset HEAD test.txt

checkout 还能用,但新版本 Git 更推荐用 restoreswitch 来区分“恢复文件”和“切换分支”。

十一、.gitignore:哪些文件不应该提交?

项目里并不是所有文件都应该交给 Git 管理。

通常不提交:

  • 编译产物,比如 .classtarget/build/
  • 日志文件,比如 *.log
  • 临时文件,比如 *.tmp
  • IDE 配置,比如 .idea/
  • 操作系统文件,比如 .DS_StoreThumbs.db
  • 密码、密钥、生产配置等敏感文件

在项目根目录创建 .gitignore

touch .gitignore

常见规则:

# 忽略所有 .class 文件
*.class

# 忽略 target 目录
target/

# 忽略所有 log 文件
*.log

# 不忽略某个指定文件
!important.log

# 忽略任意层级下的 foo 目录或文件
**/foo

Java 项目常用模板:

# Java
*.class
*.war
*.ear
*.jar

# Maven / Gradle
target/
build/
.gradle/

# IntelliJ IDEA
.idea/
*.iml
*.ipr
*.iws

# Eclipse
.settings/
.project
.classpath

# Logs
*.log

# Temp
*.tmp
*.cache
*.diff
*.patch

# System
.DS_Store
Thumbs.db

全局 .gitignore

git config --global core.excludesfile ~/.gitignore

.gitignore 不生效的常见原因:

文件已经被 Git 跟踪了。.gitignore 只能忽略未被跟踪的新文件。

解决办法:

git rm --cached file.txt
git commit -m "remove tracked ignored file"

如果是目录:

git rm -r --cached target/
git commit -m "remove target from git tracking"

十二、分支管理:Git 的灵魂

分支是 Git 最重要的能力之一。它可以让你在不影响主线代码的情况下开发新功能、修复 bug、验证想法。

查看分支:

git branch

创建分支:

git branch dev

切换分支:

git switch dev

老写法:

git checkout dev

创建并切换分支:

git switch -c dev

老写法:

git checkout -b dev

删除已经合并的分支:

git branch -d dev

强制删除未合并分支:

git branch -D dev

Git 的分支本质上是指向提交对象的指针。HEAD 指向当前分支,当前分支再指向最新提交。

HEAD -> main -> commit3 -> commit2 -> commit1

创建新分支时,Git 并不会复制一份完整代码,而是创建一个新的指针。所以 Git 分支非常轻量,创建和切换都很快。

十三、分支合并与冲突解决

假设你在 dev 分支开发完功能,要合并回 main

git switch main
git merge dev

如果两个分支修改了不同文件,通常会自动合并。如果两个分支修改了同一个文件的同一位置,就可能出现冲突。

冲突文件里会出现类似内容:

<<<<<<< HEAD
main 分支上的内容
=======
dev 分支上的内容
>>>>>>> dev

解决步骤:

  1. 打开冲突文件。
  2. 手动选择保留哪部分内容,或整合两边内容。
  3. 删除 <<<<<<<=======>>>>>>> 标记。
  4. 重新添加并提交。
git add conflict-file.txt
git commit -m "fix: resolve merge conflict"

查看分支合并图:

git log --oneline --graph --decorate --all

冲突不可怕,可怕的是不知道自己保留了什么。解决冲突后,一定要重新运行项目或测试。

十四、git stash:临时保存未完成代码

stash 适合两个典型场景:

  • 正在开发新功能,突然要切分支修紧急 bug,但当前代码还不想提交。
  • 不小心在错误分支上开发了,需要先把改动临时存起来,再切到正确分支恢复。

保存当前工作区和暂存区修改:

git stash

查看 stash 列表:

git stash list

恢复最近一次 stash,并从列表删除:

git stash pop

恢复但不删除 stash:

git stash apply

删除某条 stash:

git stash drop stash@{0}

清空所有 stash:

git stash clear

建议给 stash 加说明:

git stash push -m "half-done order export feature"

这样以后看 git stash list 时不会一头雾水。

十五、推荐的团队分支管理策略

实际团队开发中,常见分支可以这样设计:

分支 作用
main / master 主分支,保存稳定代码
develop 日常开发分支,集成新功能
feature/* 功能分支,从 develop 拉出,完成后合并回 develop
release/* 预发布分支,用于测试和发布准备
bugfix/* 普通 bug 修复分支
hotfix/* 线上紧急修复分支,通常从稳定分支拉出

现在很多平台新仓库默认主分支叫 main,旧教程里常见 master。两者本质都是普通分支,使用时以自己仓库实际分支名为准。

一个常见开发流程:

# 从 develop 创建功能分支
git switch develop
git pull
git switch -c feature/user-login

# 开发、提交
git add .
git commit -m "feat: add user login"

# 推送远程
git push -u origin feature/user-login

# 提交合并请求,代码评审后合并到 develop

线上 bug 修复流程:

git switch main
git pull
git switch -c hotfix/login-error

# 修复后提交
git add .
git commit -m "fix: repair login error"

# 合并回 main 和 develop

十六、关联远程仓库并推送代码

本地仓库创建完成后,如果想推送到 GitHub / GitLab / Gitee,需要先关联远程仓库。

git remote add origin https://github.com/yourname/your-repo.git

查看远程仓库:

git remote -v
git remote show origin

第一次推送并建立上游关联:

git push -u origin main

如果你的主分支叫 master

git push -u origin master

之后再推送:

git push

或者明确指定:

git push origin main

-u 的作用是建立本地分支和远程分支的追踪关系。建立后,当前分支直接执行 git pullgit push 就知道对应哪个远程分支。

十七、克隆远程仓库与多人协作

克隆远程仓库:

git clone https://github.com/yourname/your-repo.git

指定本地目录名:

git clone https://github.com/yourname/your-repo.git my-project

多人协作时最常见的日常流程:

git pull

# 修改代码

git status
git add .
git commit -m "feat: add payment callback"
git push

如果推送失败,提示远程有别人提交的新内容,一般先拉取:

git pull

如果发生冲突,就按前面冲突解决流程处理,然后再:

git add .
git commit -m "fix: resolve pull conflict"
git push

更稳的做法是先抓取远程信息:

git fetch origin

查看本地和远程差异后再决定是否合并。

十八、远程分支管理

查看所有本地分支:

git branch

查看本地和远程分支:

git branch -a

查看分支最后一次提交:

git branch -av

把本地分支推送到远程,并建立追踪:

git push -u origin develop

基于远程分支创建本地分支:

git switch -c develop origin/develop

老写法:

git checkout -b develop origin/develop

直接追踪远程分支:

git checkout --track origin/feature

删除远程分支:

git push origin --delete feature

清理本地已经失效的远程分支引用:

git remote prune origin

十九、标签管理:给版本打标记

标签通常用来标记发布版本,比如 v1.0.0v2.3.1

创建轻量标签:

git tag v1.0.0

创建带说明的标签:

git tag -a v1.0.0 -m "release version 1.0.0"

查看标签:

git tag

删除本地标签:

git tag -d v1.0.0

推送指定标签:

git push origin v1.0.0

推送所有标签:

git push origin --tags

删除远程标签:

git push origin :refs/tags/v1.0.0

或者:

git push origin --delete tag v1.0.0

基于标签检出一个新分支:

git checkout -b hotfix-v1.0.0 v1.0.0

标签和分支的区别:

  • 分支会随着提交继续向前移动。
  • 标签固定指向某一次提交,通常用于版本发布。

二十、GitHub、GitLab 和 Gitee 的关系

Git 是版本控制工具,GitHub、GitLab、Gitee 是基于 Git 的代码托管平台。

平台 特点
GitHub 全球最大开源代码托管平台,开源项目多
GitLab 支持私有化部署,企业内部常用
Gitee 国内访问速度较友好,中文生态好

无论使用哪个平台,核心 Git 命令基本一致:

git clone
git pull
git add
git commit
git push
git branch
git merge

区别主要在账号、权限、仓库地址、合并请求流程、CI/CD 配置等平台能力上。

二十一、配置 SSH 免密推送

HTTPS 地址可以直接使用账号认证,但团队开发更常见的是配置 SSH。

生成 SSH 密钥:

ssh-keygen -t rsa -C "your_email@example.com"

一路回车后,会在用户目录下生成:

~/.ssh/id_rsa
~/.ssh/id_rsa.pub

其中:

  • id_rsa 是私钥,不能泄露。
  • id_rsa.pub 是公钥,可以添加到 GitHub / GitLab / Gitee。

查看公钥:

cat ~/.ssh/id_rsa.pub

把公钥内容复制到平台的 SSH Keys 设置中。之后远程地址可以使用:

git@github.com:yourname/your-repo.git

测试连接:

ssh -T git@github.com

二十二、IDEA 中集成 Git

在 IntelliJ IDEA 中配置 Git:

  1. 打开 Settings
  2. 进入 Version Control -> Git
  3. 配置 Path to Git executable,选择本机 Git 安装目录下的 git.exe
  4. 点击 Test,看到 Git 版本号说明配置成功。

常见操作:

  • Commit:提交到本地仓库。
  • Push:推送到远程仓库。
  • Pull:拉取远程代码。
  • Branches:创建、切换、合并分支。
  • Resolve Conflicts:图形化解决冲突。

建议初学者先掌握命令行,再使用 IDEA 图形界面。因为图形界面只是把命令包装起来,真正出问题时,命令行能力更可靠。

二十三、Git 图形工具:gitkgit gui

Git 自带两个图形工具。

查看提交历史:

gitk

打开图形化提交界面:

git gui

这些工具可以直观看到提交链路、分支合并、标签等信息。对于理解 Git 分支指针很有帮助。

二十四、GitLab 常用管理命令

如果是企业内部自建 GitLab,常见管理命令如下:

# 启动所有 GitLab 组件
gitlab-ctl start

# 停止所有 GitLab 组件
gitlab-ctl stop

# 重启所有 GitLab 组件
gitlab-ctl restart

# 查看服务状态
gitlab-ctl status

# 重新加载配置
gitlab-ctl reconfigure

# 查看日志
gitlab-ctl tail

# 检查 GitLab
gitlab-rake gitlab:check SANITIZE=true --trace

修改配置文件:

vim /etc/gitlab/gitlab.rb

修改后通常需要:

gitlab-ctl reconfigure
gitlab-ctl restart

如果只是普通开发者,不需要掌握 GitLab 安装部署细节;重点掌握建仓库、加成员、配置 SSH、克隆、推送、提交合并请求即可。

二十五、Git 常见问题速查

1. git add .git add -Agit add -u 有什么区别?

命令 作用
git add . 添加当前目录下的新文件和修改文件,新版 Git 也会处理删除
git add -A 添加所有变化,包括新增、修改、删除
git add -u 添加已跟踪文件的修改和删除,不包括新文件

日常开发中,最常用:

git add .

更严谨时使用:

git add -A

2. 为什么 .gitignore 配了还是会提交?

因为文件已经被 Git 跟踪。先取消跟踪:

git rm --cached file.txt

目录则使用:

git rm -r --cached target/

3. 推送时提示 rejected 怎么办?

通常是远程有新提交,本地落后了。

git pull
git push

如果有冲突,先解决冲突再推送。

4. 不小心提交错了分支怎么办?

如果还没推送,可以先记录提交号,再切到正确分支 cherry-pick:

git log --oneline
git switch correct-branch
git cherry-pick <commit_id>

然后回到错误分支回退:

git switch wrong-branch
git reset --hard HEAD^

如果已经推送到公共分支,不要随便 reset --hard 后强推,先和团队沟通。

5. 代码写到一半需要切分支怎么办?

git stash push -m "unfinished feature"
git switch other-branch

回来后:

git switch original-branch
git stash pop

二十六、Git 高频命令速查表

目标 命令
初始化仓库 git init
查看状态 git status
添加文件 git add file.txt
添加全部改动 git add .
提交 git commit -m "message"
查看日志 git log --oneline --graph --decorate --all
查看差异 git diff
查看暂存区差异 git diff --cached
撤销工作区修改 git restore file.txt
取消暂存 git restore --staged file.txt
回退版本 git reset --hard <commit_id>
查看历史操作 git reflog
查看分支 git branch
创建分支 git branch dev
切换分支 git switch dev
创建并切换分支 git switch -c dev
合并分支 git merge dev
删除分支 git branch -d dev
强制删除分支 git branch -D dev
临时保存修改 git stash push -m "message"
查看 stash git stash list
恢复 stash git stash pop
添加远程仓库 git remote add origin <url>
查看远程仓库 git remote -v
克隆仓库 git clone <url>
拉取远程代码 git pull
推送代码 git push
第一次推送分支 git push -u origin main
查看远程分支 git branch -a
删除远程分支 git push origin --delete <branch>
创建标签 git tag v1.0.0
创建附注标签 git tag -a v1.0.0 -m "release"
推送标签 git push origin v1.0.0
推送所有标签 git push origin --tags
删除本地标签 git tag -d v1.0.0
删除远程标签 git push origin :refs/tags/v1.0.0

二十七、建议的新手学习路线

如果你是第一次学 Git,不建议一上来就背所有命令。可以按这个顺序学:

  1. 先理解工作区、暂存区、本地仓库、远程仓库。
  2. 掌握 initstatusaddcommit
  3. 学会 logdiffrestorereset
  4. 学会创建、切换、合并、删除分支。
  5. 学会解决冲突。
  6. 学会 remoteclonepullpush
  7. 学会 stashtag
  8. 最后再学 GitHub / GitLab 的团队协作流程。

把 Git 学透后,你会发现它不是一个“上传代码工具”,而是一个完整的版本管理和团队协作系统。

总结

Git 的核心可以浓缩成三句话:

  1. 本地开发靠工作区、暂存区、本地仓库完成版本记录。
  2. 团队协作靠远程仓库、分支、合并和冲突解决完成代码同步。
  3. 项目发布靠标签、稳定分支和规范提交保证版本可追踪。

真正掌握 Git,不是记住所有命令,而是理解每条命令在“哪个区域之间移动代码”。只要搞清楚工作区、暂存区、本地仓库、远程仓库之间的流转关系,再复杂的分支协作和冲突处理都会变得清晰。

建议收藏本文,后续遇到 Git 问题时直接按场景查命令。等你能熟练使用 statusdifflogbranchmergepullpushstash,日常开发中的大多数 Git 问题基本都能自己解决。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐