3. Git 基本操作:从零开始搭版本库

Git 这东西,说白了就是个时间机器。你每做一次提交,就等于拍了一张快照。哪天代码改崩了,直接坐时光机回去就行。

我刚开始带团队的时候,有个同事死活不习惯用 Git,觉得麻烦。结果有一次他改了一整天,把整个模块搞挂了,回退不了,差点通宵重写。嗯,从那以后,他比谁都积极用 Git。

这一章,咱们就把最常用的六个命令讲透。你跟着敲一遍,基本就能应付日常开发了。

本章核心命令速览:git init / git clone / git add / git commit / git status / git log
Git 基本操作流程 远程仓库 (Remote) 工作区 (Working) 暂存区 (Staging) 本地仓库 (Local) git clone git init git add git commit git push git pull git status git log 查看状态与历史 随时可用的安全网

3.1 git init — 从零创建仓库

git init 是最基础的命令。它会在当前目录下创建一个 .git 隐藏文件夹,里面装着版本库的全部家当。

# 创建一个新项目
mkdir my-project
cd my-project
git init

# 输出:Initialized empty Git repository in /path/to/my-project/.git/

执行完 git init 后,你的项目就变成了一个 Git 仓库。但注意,这时候仓库是空的,还没有任何文件被跟踪。

我的习惯:每次新建项目,第一件事就是 git init。哪怕只写了一行代码,也要先初始化版本库。这样后面每一步改动都有记录。

3.2 git clone — 把远程仓库搬下来

如果你要参与一个已有的项目,不需要从头 init。直接用 git clone 把远程仓库整个复制到本地。

# 克隆一个远程仓库
git clone https://github.com/username/repo.git

# 克隆并指定本地目录名
git clone https://github.com/username/repo.git my-local-folder

git clone 会自动做三件事:

  • 创建本地目录
  • 初始化 .git 仓库
  • 把远程所有分支和历史记录都拉下来
注意:克隆下来的仓库默认只有一个远程引用叫 origin。如果你要同时往多个远程仓库推送,需要手动添加远程地址。

3.3 git status — 随时查看仓库状态

我个人觉得,git status 是使用频率最高的命令。你改了什么、新增了什么、删除了什么,它都会告诉你。

# 查看当前状态
git status

# 输出示例:
# On branch main
# Changes not staged for commit:
#   modified:   src/main.c
# Untracked files:
#   README.md

状态信息分几类:

状态 含义 下一步操作
Untracked 新文件,未被跟踪 git add
Modified 已跟踪文件被修改 git add → git commit
Staged 已加入暂存区 git commit
Unmodified 文件无变化 无需操作
避坑指南:我曾经在提交前忘了 git status,结果把调试用的临时文件也提交上去了。从那以后,每次 git commit 之前,我都会先跑一遍 git status,确认只有想提交的文件。

3.4 git add — 把改动放进暂存区

git add 的作用是把工作区的改动「打包」到暂存区。暂存区就像购物车,你先挑好要提交的文件,最后统一结账。

# 添加单个文件
git add src/main.c

# 添加所有改动(慎用)
git add .

# 添加当前目录所有 .c 文件
git add *.c

# 交互式添加(推荐)
git add -p

为什么要有暂存区?你想想看,有时候你改了三个文件,但只想先提交其中两个。暂存区让你可以精细控制每次提交的内容。

我的建议:尽量少用 git add .。我习惯用 git add -p 交互式添加,它会逐块显示改动,让你确认是否加入暂存区。这样能避免把调试代码或临时文件带进去。

3.5 git commit — 拍一张快照

暂存区准备好了,就用 git commit 正式提交。每次提交都会生成一个唯一的 SHA-1 哈希值,作为这次快照的身份证。

# 提交并写提交信息
git commit -m "修复了登录模块的空指针异常"

# 跳过暂存区,直接提交已跟踪文件的改动
git commit -a -m "紧急修复"

# 写多行提交信息(会打开编辑器)
git commit

提交信息怎么写?我有个简单的原则:

  • 第一行:不超过 50 字,概括这次提交做了什么
  • 空一行
  • 正文:详细说明改动原因和影响
曾经踩过的坑:有一次我提交时写了 git commit -m "fix bug",结果两周后回来看,完全想不起来修了什么。现在我的提交信息都会写清楚「为什么改」和「怎么改的」。

3.6 git log — 查看版本历史

git log 是时光机的控制面板。它能展示所有提交记录,包括作者、时间、提交信息。

# 查看完整历史
git log

# 简洁模式(一行一个提交)
git log --oneline

# 图形化显示分支
git log --graph --oneline --all

# 查看最近 3 条记录
git log -3

输出示例:

commit a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
Author: Zhang San <zhangsan@example.com>
Date:   Mon Mar 10 14:30:00 2025 +0800

    修复了登录模块的空指针异常

commit b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0a
Author: Li Si <lisi@example.com>
Date:   Mon Mar 10 10:00:00 2025 +0800

    新增用户注册功能
实用技巧:我经常用 git log --oneline --graph --all 来查看整个项目的分支结构。一眼就能看出谁在哪个分支上做了什么,特别适合多人协作时理清脉络。

3.7 实战演练:一个完整的提交流程

把上面六个命令串起来,就是一个标准的 Git 工作流。咱们模拟一个场景:

  1. 初始化或克隆
    git init my-app
    cd my-app
  2. 创建文件并查看状态
    echo "# My App" > README.md
    git status
    # 输出:Untracked files: README.md
  3. 添加到暂存区
    git add README.md
    git status
    # 输出:Changes to be committed: new file: README.md
  4. 提交
    git commit -m "初始化项目,添加 README"
    git log --oneline
    # 输出:a1b2c3d 初始化项目,添加 README
  5. 修改文件并再次提交
    echo "## 版本 1.0" >> README.md
    git add README.md
    git commit -m "更新 README,添加版本信息"
    git log --oneline
    # 输出:
    # b2c3d4e 更新 README,添加版本信息
    # a1b2c3d 初始化项目,添加 README
我的工作流:每天开始工作前,先 git pull 拉取最新代码。每完成一个小功能,就 git add + git commit。下班前再 git push。这样即使电脑坏了,最多丢一天的工作量。

3.8 常见问题与避坑

问题 原因 解决方法
提交后发现有文件忘了加 只 git add 了部分文件 git add 漏掉的文件 → git commit --amend
提交信息写错了 手误或描述不清 git commit --amend -m "正确的信息"
想撤销暂存区的文件 不小心 git add 了不该加的文件 git reset HEAD 文件名
想撤销工作区的修改 改乱了想恢复原样 git checkout -- 文件名
重要提醒:git commit --amend 会修改最近一次提交的哈希值。如果这个提交已经推送到远程仓库,并且别人已经基于它做了工作,千万不要用 --amend。否则你会把别人的历史搞乱。

好了,这六个命令你掌握了吗?说白了,Git 的核心就是「改文件 → 加到暂存区 → 提交快照」。你只要把这个循环跑熟了,版本管理就入门了。

我个人建议,今天就在你的项目里试一遍。从 git init 开始,到 git log 结束。亲手敲一遍,比看十遍教程都管用。