git-tutorial
Git 使用教程
从本地操作到远程协作的完整指南,涵盖日常开发中会遇到的所有场景。
前置要求:已安装并配置好 Git(参考 Git 安装与配置)
目录
1. 本地仓库基础操作
1.1 创建仓库
# 方式一:在现有目录中初始化
cd /path/to/your/project
git init
# 会在当前目录下创建一个隐藏的 .git 文件夹
# 方式二:创建新目录并初始化
git init my-project
cd my-project
1.2 查看状态
git status
这是你用得最多的命令。它会告诉你:
- 当前在哪个分支
- 哪些文件被修改了
- 哪些文件在暂存区
- 哪些文件还没被 Git 跟踪
# 简洁模式(推荐日常使用)
git status -s
# M README.md ← 已修改,未暂存
# M file.txt ← 已暂存
# ?? new-file.txt ← 未跟踪的新文件
# A added.txt ← 新增并已暂存
1.3 添加文件到暂存区
# 添加单个文件
git add README.md
# 添加多个文件
git add file1.txt file2.txt
# 添加当前目录下所有改动(包括新增、修改、删除)
git add .
# 添加所有 .py 文件
git add *.py
# 交互式添加(可以选择文件的部分改动)
git add -p
1.4 提交
# 提交(会打开编辑器写提交说明)
git commit
# 提交并附带提交说明(最常用)
git commit -m "添加用户登录功能"
# 跳过暂存区,直接提交所有已跟踪文件的修改
git commit -a -m "修复首页样式问题"
写好提交说明的建议:
- 用祈使语气("添加功能" 而非 "添加了功能")
- 第一行简短概括(50 字以内)
- 需要详细说明时,空一行后写正文
添加用户登录功能
- 实现了邮箱+密码登录
- 添加了登录表单验证
- 登录失败时显示错误提示
1.5 查看历史
# 查看提交历史
git log
# 简洁的单行显示(推荐)
git log --oneline
# 图形化显示分支合并历史
git log --oneline --graph --all
# 查看最近 5 次提交
git log -5
# 查看某个文件的修改历史
git log -- path/to/file
1.6 查看差异
# 查看工作区与暂存区的差异(还没 add 的修改)
git diff
# 查看暂存区与最新 commit 的差异(已 add 但没 commit 的)
git diff --staged
# 查看两次 commit 之间的差异
git diff commit1 commit2
# 查看某个文件的差异
git diff -- path/to/file
1.7 撤销操作
# 撤销工作区的修改(还没 add 的),恢复到上次 commit 的状态
git restore file.txt
# 把文件从暂存区移出(已 add 但想取消)
git restore --staged file.txt
# 修改最近一次 commit 的说明(或者补充遗漏的文件)
git add forgotten-file.txt
git commit --amend -m "新的提交说明"
# ⚠️ 回退到指定 commit(危险操作,会丢失后续 commit)
git reset --hard <commit-hash>
安全提示:
git reset --hard会丢失未提交的更改。如果只想回退 commit 但保留改动:git reset --soft HEAD~1 # 回退 commit,改动保留在暂存区 git reset --mixed HEAD~1 # 回退 commit,改动保留在工作区(默认)
2. 分支管理
分支是 Git 最强大的特性之一。你可以在不影响主线的情况下开发新功能。
2.1 基本操作
# 查看所有本地分支(当前分支前有 * 标记)
git branch
# 查看所有分支(包括远程)
git branch -a
# 创建新分支
git branch feature-login
# 切换分支
git checkout feature-login
# 或者用更新的命令(推荐)
git switch feature-login
# 创建并切换(一步到位)
git checkout -b feature-login
# 或者
git switch -c feature-login
# 删除分支(已合并的)
git branch -d feature-login
# 强制删除分支(未合并的)
git branch -D feature-login
# 重命名分支
git branch -m old-name new-name
2.2 合并分支
# 先切换到目标分支(通常是 main)
git switch main
# 将 feature-login 分支合并到当前分支
git merge feature-login
合并的三种情况:
快进合并(Fast-forward)
目标分支没有新的提交,直接移动指针:
合并前:
main: c1 ← c2
feature: c1 ← c2 ← c3 ← c4
合并后(快进):
main: c1 ← c2 ← c3 ← c4
三方合并(3-way merge)
两个分支都有新提交,Git 自动创建一个合并提交:
合并前:
main: c1 ← c2 ← c5
feature: c1 ← c2 ← c3 ← c4
合并后:
main: c1 ← c2 ← c5 ← c6(合并提交)
↑ ↑
feature: c3 ← c4 ─────┘
冲突(Conflict)
两个分支修改了同一个文件的同一部分,Git 无法自动合并。
2.3 解决冲突
当合并出现冲突时,Git 会在文件中标记冲突位置:
<<<<<<< HEAD
这是 main 分支的内容
=======
这是 feature 分支的内容
>>>>>>> feature-login
解决步骤:
- 打开有冲突的文件
- 找到
<<<<<<<、=======、>>>>>>>标记 - 手动编辑,保留你想要的内容,删除所有标记符号
- 保存文件
git add标记冲突已解决git commit完成合并
# 解决冲突后
git add conflicted-file.txt
git commit -m "解决 feature-login 合并冲突"
提示:VS Code 内置了可视化的冲突解决工具,能直观地选择「接受当前更改」、「接受传入更改」或「两者都保留」。
2.4 推荐的分支工作流
# 1. 从 main 创建功能分支
git switch main
git pull # 先拉最新代码
git switch -c feature-search # 创建功能分支
# 2. 在功能分支上开发
# 编辑文件...
git add .
git commit -m "实现搜索框 UI"
# 继续开发...
git add .
git commit -m "添加搜索结果列表"
# 3. 合并回 main
git switch main
git pull # 再次拉取,防止合并冲突
git merge feature-search
git push
# 4. 清理已合并的分支
git branch -d feature-search
3. 生成 SSH 密钥
SSH 密钥让你免密码与 GitHub 等远程仓库通信。这是管理私有仓库的必要步骤。
3.1 检查是否已有 SSH 密钥
ls -al ~/.ssh
# 如果看到 id_ed25519.pub 或 id_rsa.pub,说明已有密钥
3.2 生成新的 SSH 密钥对
# 推荐使用 Ed25519 算法(更安全、更快)
ssh-keygen -t ed25519 -C "your.email@example.com"
执行后会出现提示:
Generating public/private ed25519 key pair.
Enter file in which to save the key (/c/Users/你的用户名/.ssh/id_ed25519):
# 直接回车,使用默认路径
Enter passphrase (empty for no passphrase):
# 可以设置密码(更安全)或直接回车(方便但略不安全)
Enter same passphrase again:
# 再次输入密码或回车
生成后会产生两个文件:
~/.ssh/id_ed25519— 私钥(绝对不能泄露给任何人!)~/.ssh/id_ed25519.pub— 公钥(要添加到 GitHub)
3.3 将 SSH 密钥添加到 ssh-agent
# 启动 ssh-agent(Windows Git Bash)
eval "$(ssh-agent -s)"
# 输出:Agent pid 12345
# 添加私钥
ssh-add ~/.ssh/id_ed25519
Windows PowerShell 用户:
# 以管理员身份打开 PowerShell
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
# 添加私钥
ssh-add $env:USERPROFILE\.ssh\id_ed25519
3.4 将公钥添加到 GitHub
第一步:复制公钥内容
# Windows (Git Bash)
cat ~/.ssh/id_ed25519.pub | clip
# macOS
cat ~/.ssh/id_ed25519.pub | pbcopy
# Linux
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard
# 或者手动查看并复制
cat ~/.ssh/id_ed25519.pub
第二步:在 GitHub 中添加
- 打开 GitHub → 右上角头像 → Settings
- 左侧菜单 → SSH and GPG keys
- 点击 New SSH key
- Title:填一个有辨识度的名称(如
我的笔记本或公司电脑) - Key type:选择
Authentication Key - Key:粘贴你复制的公钥
- 点击 Add SSH key
3.5 测试 SSH 连接
ssh -T git@github.com
首次连接会提示:
The authenticity of host 'github.com (20.205.243.166)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
输入 yes。如果看到以下信息,说明 SSH 配置成功:
Hi 你的用户名! You've been authenticated, but GitHub does not provide shell access.
3.6 配置多个 SSH 密钥(可选,进阶)
如果你有多个 GitHub 账号或同时使用 GitHub 和 GitLab,创建或编辑 ~/.ssh/config:
# 个人 GitHub 账号
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
# 工作 GitHub 账号
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
# GitLab
Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/id_ed25519_gitlab
使用工作账号克隆时:
git clone git@github-work:company/project.git
4. 创建远程仓库(GitHub)
4.1 注册 GitHub 账号
- 访问 github.com
- 点击 Sign up
- 填写用户名、邮箱、密码
- 完成验证后登录
4.2 创建远程仓库
- 登录 GitHub 后,点击右上角 + → New repository
- 填写仓库信息:
- Repository name:仓库名称(如
my-project) - Description:简短描述(可选)
- Public / Private:
Public:所有人可见(开源项目选这个)Private:仅你和协作者可见(私有项目选这个)
- Initialize this repository with:
- 如果本地已有项目要推送,全部不勾选
- 如果是全新项目,可以勾选
Add a README file
- Repository name:仓库名称(如
- 点击 Create repository
创建后 GitHub 会显示如何关联本地仓库的指引。
4.3 为私有仓库添加协作者
如果你希望其他人也能访问你的私有仓库:
- 进入仓库页面 → Settings
- 左侧 Collaborators → Add people
- 输入对方的 GitHub 用户名或邮箱
- 对方会收到邀请邮件,接受后即可访问
5. 关联远程仓库并推送
5.1 场景一:本地已有项目 → 推送到远程
# 1. 进入项目目录
cd /path/to/my-project
# 2. 初始化 Git(如果还没有)
git init
# 3. 添加所有文件并提交
git add .
git commit -m "初始提交"
# 4. 添加远程仓库(使用 SSH 地址)
git remote add origin git@github.com:你的用户名/my-project.git
# 5. 推送到远程(-u 参数设置上游跟踪,以后只需 git push)
git push -u origin main
注意:如果你的默认分支名是
master(旧版 Git),先重命名:git branch -M main
5.2 场景二:从远程克隆到本地
# 使用 SSH(推荐,尤其是私有仓库)
git clone git@github.com:你的用户名/my-project.git
# 使用 HTTPS(需要输入密码或 Personal Access Token)
git clone https://github.com/你的用户名/my-project.git
# 克隆到指定目录
git clone git@github.com:你的用户名/my-project.git my-folder
5.3 日常推送和拉取
# 拉取远程最新代码(推荐:先拉后推)
git pull
# 推送本地提交到远程
git push
# 查看远程仓库信息
git remote -v
# 拉取远程所有分支信息(不合并)
git fetch
5.4 git pull vs git fetch
| 命令 | 作用 |
|---|---|
git fetch |
下载远程的更新信息,但不自动合并到你的工作区 |
git pull |
git fetch + git merge 的组合,自动合并 |
建议工作流:
# 方式一:直接 pull(简单,适合个人项目)
git pull
# 方式二:先 fetch 再 merge(更安全,适合团队协作)
git fetch
git log origin/main --oneline # 先看看远程有什么新提交
git merge origin/main # 确认后再合并
5.5 使用 Personal Access Token(HTTPS 备选方案)
如果因网络原因无法使用 SSH,可以用 HTTPS + Token:
- GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
- 点击 Generate new token (classic)
- 勾选
repo(完整仓库访问权限) - 生成后立即复制(只显示一次!)
# 克隆时使用 Token
git clone https://你的用户名:ghp_xxxx你的Token@github.com/你的用户名/my-private-project.git
# 或者配置凭证缓存,下次 push 时输入用户名和 Token
git config --global credential.helper store
安全提示:Token 等同于密码,不要提交到代码中或分享给他人。
credential.helper store会将凭证明文保存在~/.git-credentials,如果对安全性有要求,使用credential.helper cache --timeout=3600(缓存 1 小时后失效)。
6. .gitignore 配置
创建 .gitignore 文件来告诉 Git 忽略哪些文件:
# ─── 操作系统文件 ───
.DS_Store
Thumbs.db
# ─── IDE / 编辑器 ───
.idea/
.vscode/
*.swp
*.swo
# ─── 依赖目录 ───
node_modules/
vendor/
venv/
__pycache__/
# ─── 编译输出 ───
dist/
build/
*.o
*.pyc
# ─── 日志 ───
*.log
logs/
# ─── 环境配置(含敏感信息)───
.env
.env.local
.env.*.local
# ─── 但保留示例配置 ───
!.env.example
# ─── 其他 ───
*.tmp
*.bak
要点:
.gitignore只对未跟踪的文件生效。如果文件已经被 Git 跟踪,需要先git rm --cached <file>移除- 每行一条规则,
#开头的是注释 *通配符匹配任意字符,/匹配目录!取反,表示「不忽略」- gitignore.io 可以自动生成适合你项目的
.gitignore
7. 常见问题与排错
Q1: git push 被拒绝(rejected)
! [rejected] main -> main (non-fast-forward)
原因:远程仓库有你本地没有的提交(比如你在另一台电脑上推送过)。
解决:
git pull --rebase # 先拉取并变基
git push # 再推送
Q2: SSH 连接超时
ssh: connect to host github.com port 22: Connection timed out
解决:尝试使用 443 端口。编辑 ~/.ssh/config:
Host github.com
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519
然后重试 ssh -T git@github.com。
Q3: Permission denied (publickey)
可能原因:
- SSH 密钥没有添加到 GitHub → 重新按 3.4 步骤添加
- ssh-agent 没有加载密钥 →
ssh-add ~/.ssh/id_ed25519 - 密钥文件权限不对(Linux/Mac)→
chmod 600 ~/.ssh/id_ed25519
排查命令:
# 查看 ssh-agent 已加载的密钥
ssh-add -l
# 详细调试 SSH 连接
ssh -vT git@github.com
Q4: 不小心提交了敏感文件(密码、密钥)
# 从 Git 跟踪中移除(文件在工作区会保留)
git rm --cached secrets.txt
echo "secrets.txt" >> .gitignore
git commit -m "移除敏感文件并添加到 gitignore"
重要:如果敏感信息已推送到公开仓库,立即更换密码/密钥!Git 历史是公开的,即使删除了文件,别人可能已经看到了。如需从历史中彻底清除,使用 BFG Repo-Cleaner。
Q5: 中文文件名显示为乱码
git config --global core.quotepath false
Q6: 换行符警告 LF will be replaced by CRLF
# Windows 用户
git config --global core.autocrlf true
# Mac/Linux 用户
git config --global core.autocrlf input
Q7: 想要撤销最近一次 push
# 本地回退一个 commit(保留改动在工作区)
git reset --soft HEAD~1
# 强制推送覆盖远程(⚠️ 危险操作,团队协作慎用)
git push --force-with-lease
--force-with-lease比--force更安全:如果远程分支在你上次 fetch 后又有了新提交,它会拒绝推送,防止你覆盖别人的工作。
延伸阅读
最后更新:2026-04-19