Git 在 PyCharm 中的使用完全指南:从配置到分支、冲突与回滚
一句话总结 :PyCharm 内置了非常完整的 Git 图形化集成------改文件、暂存、提交、推送、拉取、切分支、合并、解冲突、看历史、回滚 全流程都能在 IDE 里点完,不用切窗口敲命令。本文以 PyCharm 2023/2024 版为例,把每个操作对应到菜单位置与 Git 命令,让你既能「点得明白」,也能「随时退回命令行」。
📋 目录
- [一、先搞清楚:PyCharm 与 Git 是什么关系](#一、先搞清楚:PyCharm 与 Git 是什么关系)
- [1.1 为什么要在 IDE 里用 Git](#1.1 为什么要在 IDE 里用 Git)
- [1.2 前置条件与版本说明](#1.2 前置条件与版本说明)
- [1.3 界面叫法与 Git 命令对照表](#1.3 界面叫法与 Git 命令对照表)
- [二、第一步:让 PyCharm 认识你的 Git](#二、第一步:让 PyCharm 认识你的 Git)
- [2.1 检查 Git 是否被识别](#2.1 检查 Git 是否被识别)
- [2.2 手动指定 Git 可执行文件路径](#2.2 手动指定 Git 可执行文件路径)
- [2.3 在 PyCharm 里配置用户名与邮箱](#2.3 在 PyCharm 里配置用户名与邮箱)
- 三、绑定代码托管账号(GitHub、Gitee)
- [3.1 GitHub 登录(Token 与授权两种方式)](#3.1 GitHub 登录(Token 与授权两种方式))
- [3.2 Gitee 账号绑定](#3.2 Gitee 账号绑定)
- [3.3 用 SSH 免密(复用已有密钥)](#3.3 用 SSH 免密(复用已有密钥))
- [四、三种方式把项目接进 Git](#四、三种方式把项目接进 Git)
- [4.1 方式一:克隆远程仓库](#4.1 方式一:克隆远程仓库)
- [4.2 方式二:把已有本地项目变成 Git 仓库](#4.2 方式二:把已有本地项目变成 Git 仓库)
- [4.3 方式三:新建项目时创建仓库](#4.3 方式三:新建项目时创建仓库)
- [4.4 三种方式对比](#4.4 三种方式对比)
- [五、认识 PyCharm 的 Git 界面](#五、认识 PyCharm 的 Git 界面)
- [5.1 五大核心区域总览](#5.1 五大核心区域总览)
- [5.2 Commit 工具窗口](#5.2 Commit 工具窗口)
- [5.3 Git 工具窗口(Alt+9)](#5.3 Git 工具窗口(Alt+9))
- [5.4 状态栏与分支弹窗](#5.4 状态栏与分支弹窗)
- [5.5 编辑器里的颜色标记含义](#5.5 编辑器里的颜色标记含义)
- 六、日常核心操作:提交、推送与拉取
- [6.1 完整流程总览](#6.1 完整流程总览)
- [6.2 提交 Commit](#6.2 提交 Commit)
- [6.3 推送 Push](#6.3 推送 Push)
- [6.4 拉取更新 Update Project](#6.4 拉取更新 Update Project)
- [6.5 推送被拒绝怎么办](#6.5 推送被拒绝怎么办)
- 七、分支管理
- [7.1 创建与切换分支](#7.1 创建与切换分支)
- [7.2 合并分支](#7.2 合并分支)
- [7.3 变基 Rebase](#7.3 变基 Rebase)
- [7.4 删除、重命名与比较分支](#7.4 删除、重命名与比较分支)
- [7.5 分支操作命令对照表](#7.5 分支操作命令对照表)
- 八、图形化解决代码冲突
- [8.1 冲突是怎么产生的](#8.1 冲突是怎么产生的)
- [8.2 冲突提示与三个选项](#8.2 冲突提示与三个选项)
- [8.3 三窗格合并工具详解](#8.3 三窗格合并工具详解)
- [8.4 编辑区里的冲突标记](#8.4 编辑区里的冲突标记)
- [8.5 完成合并与放弃合并](#8.5 完成合并与放弃合并)
- 九、查看历史与追责
- 十、撤销与回滚(最容易出事的一章)
- [10.1 撤销未提交的改动(Rollback)](#10.1 撤销未提交的改动(Rollback))
- [10.2 撤销已提交的内容](#10.2 撤销已提交的内容)
- [10.3 危险操作对照表](#10.3 危险操作对照表)
- [10.4 用 reflog 找回误删的提交](#10.4 用 reflog 找回误删的提交)
- [十一、储藏 Stash 与 Shelve](#十一、储藏 Stash 与 Shelve)
- [11.1 Stash(Git 原生储藏)](#11.1 Stash(Git 原生储藏))
- [11.2 Shelve(PyCharm 私有暂存)](#11.2 Shelve(PyCharm 私有暂存))
- [十二、.gitignore 与忽略文件不生效](#十二、.gitignore 与忽略文件不生效)
- [12.1 创建 .gitignore](#12.1 创建 .gitignore)
- [12.2 Python 与 PyCharm 项目常用忽略项](#12.2 Python 与 PyCharm 项目常用忽略项)
- [12.3 已跟踪文件的忽略失效(重点)](#12.3 已跟踪文件的忽略失效(重点))
- [12.4 临时忽略本地文件(不进仓库)](#12.4 临时忽略本地文件(不进仓库))
- 十三、进阶功能
- [13.1 内置 Terminal 直接用命令](#13.1 内置 Terminal 直接用命令)
- [13.2 Cherry-Pick(挑一个提交搬过来)](#13.2 Cherry-Pick(挑一个提交搬过来))
- [13.3 Tag(标签)](#13.3 Tag(标签))
- [13.4 Patch(补丁文件)](#13.4 Patch(补丁文件))
- [13.5 GitHub 插件提 PR](#13.5 GitHub 插件提 PR)
- [13.6 多仓库项目与子模块](#13.6 多仓库项目与子模块)
- [十四、常见问题 FAQ](#十四、常见问题 FAQ)
- 十五、快捷键速查表
- 十六、总结
一、先搞清楚:PyCharm 与 Git 是什么关系
1.1 为什么要在 IDE 里用 Git
PyCharm 自带 VCS(版本控制系统)集成 ,它不是 一个 Git 替代品,而是一层图形化外壳------底层调用的仍然是你本机安装的 Git 命令。
#mermaid-svg-nw5fQtVJR0MwMqAd{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nw5fQtVJR0MwMqAd .error-icon{fill:#552222;}#mermaid-svg-nw5fQtVJR0MwMqAd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nw5fQtVJR0MwMqAd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nw5fQtVJR0MwMqAd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nw5fQtVJR0MwMqAd .marker.cross{stroke:#333333;}#mermaid-svg-nw5fQtVJR0MwMqAd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nw5fQtVJR0MwMqAd p{margin:0;}#mermaid-svg-nw5fQtVJR0MwMqAd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd .cluster-label text{fill:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd .cluster-label span{color:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd .cluster-label span p{background-color:transparent;}#mermaid-svg-nw5fQtVJR0MwMqAd .label text,#mermaid-svg-nw5fQtVJR0MwMqAd span{fill:#333;color:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd .node rect,#mermaid-svg-nw5fQtVJR0MwMqAd .node circle,#mermaid-svg-nw5fQtVJR0MwMqAd .node ellipse,#mermaid-svg-nw5fQtVJR0MwMqAd .node polygon,#mermaid-svg-nw5fQtVJR0MwMqAd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nw5fQtVJR0MwMqAd .rough-node .label text,#mermaid-svg-nw5fQtVJR0MwMqAd .node .label text,#mermaid-svg-nw5fQtVJR0MwMqAd .image-shape .label,#mermaid-svg-nw5fQtVJR0MwMqAd .icon-shape .label{text-anchor:middle;}#mermaid-svg-nw5fQtVJR0MwMqAd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nw5fQtVJR0MwMqAd .rough-node .label,#mermaid-svg-nw5fQtVJR0MwMqAd .node .label,#mermaid-svg-nw5fQtVJR0MwMqAd .image-shape .label,#mermaid-svg-nw5fQtVJR0MwMqAd .icon-shape .label{text-align:center;}#mermaid-svg-nw5fQtVJR0MwMqAd .node.clickable{cursor:pointer;}#mermaid-svg-nw5fQtVJR0MwMqAd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nw5fQtVJR0MwMqAd .arrowheadPath{fill:#333333;}#mermaid-svg-nw5fQtVJR0MwMqAd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nw5fQtVJR0MwMqAd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nw5fQtVJR0MwMqAd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nw5fQtVJR0MwMqAd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nw5fQtVJR0MwMqAd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nw5fQtVJR0MwMqAd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nw5fQtVJR0MwMqAd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nw5fQtVJR0MwMqAd .cluster text{fill:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd .cluster span{color:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nw5fQtVJR0MwMqAd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nw5fQtVJR0MwMqAd rect.text{fill:none;stroke-width:0;}#mermaid-svg-nw5fQtVJR0MwMqAd .icon-shape,#mermaid-svg-nw5fQtVJR0MwMqAd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nw5fQtVJR0MwMqAd .icon-shape p,#mermaid-svg-nw5fQtVJR0MwMqAd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nw5fQtVJR0MwMqAd .icon-shape .label rect,#mermaid-svg-nw5fQtVJR0MwMqAd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nw5fQtVJR0MwMqAd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nw5fQtVJR0MwMqAd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nw5fQtVJR0MwMqAd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 你的鼠标点击
PyCharm 界面
PyCharm 的 Git 集成层
把操作翻译成命令
本机 Git 内核
git.exe / git
.git 仓库
本地提交历史
远程仓库
GitHub / Gitee / GitLab
在 IDE 里用 Git 的好处:
| 好处 | 说明 |
|---|---|
| 不用切窗口 | 改完代码直接在下方 Commit 窗口提交 |
| 可视化差异 | 左右并排的 Diff 对比,比 git diff 更直观 |
| 图形化解冲突 | 三窗格合并工具,点箭头就能选「用谁」 |
| 拓扑化历史 | 分支图一目了然,比 git log --graph 好看 |
| 改行级提交 | 可以只勾选文件里某几行改动来提交 |
| 快捷键快 | Ctrl+K 提交、Ctrl+Shift+K 推送,比敲命令快 |
| 随时退回命令行 | 内置 Terminal(Alt+F12),复杂操作直接敲 Git 命令 |
💡 重要认知 :PyCharm 的 Git 集成完全等价于命令行。你在界面里做的每一次提交、合并、回滚,效果和敲命令一模一样,两者可以随意混用------这一点理解了,后面所有操作都不会心虚。
1.2 前置条件与版本说明
| 项目 | 要求 |
|---|---|
| PyCharm 版本 | 社区版(Community)与专业版(Professional)都支持 Git 集成,本文截图/菜单以 2023/2024 版为准 |
| Git 版本 | 建议 Git 2.20 以上(越新越好),需已安装并配好 SSH(参见本工作区《Git 安装 + SSH 密钥配置超详细教程》) |
| 操作系统 | Windows / macOS / Linux 全平台一致,仅快捷键的 Ctrl 与 ⌘ 不同 |
| ⚠️ 注意事项 | PyCharm 不含 Git,必须先在本机装好 Git 才能用 IDE 集成 |
⚠️ 菜单名称会随版本变化 :2020.1 起原来的 Local Changes 标签合并进了 Commit 工具窗口;2023.1 起换了新 UI(New UI)。如果你找不到某个菜单,请用
Ctrl+Shift+A(macOS⌘⇧A)打开 Find Action ,输入关键词(如commit、push、rebase)直接搜索执行------这是万能入口。
1.3 界面叫法与 Git 命令对照表
这张表建议收藏,它解决了「界面操作到底等于哪条命令」的困惑:
| PyCharm 界面叫法 | 对应的 Git 命令 | 说明 |
|---|---|---|
| Commit(提交) | git commit |
把暂存的改动记入本地仓库 |
| Commit and Push | git commit + git push |
提交后立即推送 |
| Push(推送) | git push |
把本地提交送到远程 |
| Update Project(更新项目) | git fetch + git merge(或 git rebase) |
拉取远程最新并合入当前分支 |
| Pull | git pull |
同上,但明确是合并模式 |
| Rollback(回滚改动) | git checkout -- <file> / git restore |
丢弃未提交的本地改动 |
| Show Diff | git diff |
查看差异 |
| Annotate(注解) | git blame |
逐行显示「谁在哪个提交改了这行」 |
| Stash(储藏) | git stash |
临时保存未提交改动 |
| Cherry-Pick | git cherry-pick |
把某个提交「摘」到当前分支 |
| Revert Commit | git revert |
用一次新提交来反向抵消旧提交 |
| Reset Current Branch to Here | git reset --soft/--mixed/--hard |
把分支指针移到某个提交(危险) |
| Interactively Rebase from Here | git rebase -i |
交互式整理提交历史 |
| Amend(修改提交) | git commit --amend |
修改最后一次提交 |
| New Branch | git checkout -b |
新建并切换分支 |
| Merge into Current | git merge |
合并到当前分支 |
| Tag | git tag |
打标签 |
二、第一步:让 PyCharm 认识你的 Git
2.1 检查 Git 是否被识别
打开设置:
- Windows / Linux :
File→Settings(快捷键Ctrl+Alt+S) - macOS :
PyCharm→Settings/Preferences(⌘,)
依次进入 Version Control → Git ,查看 Path to Git executable(Git 可执行文件路径)一栏:
- ✅ 自动填好了 (例如
git或C:\Program Files\Git\cmd\git.exe)→ 说明 PyCharm 已识别,直接点Test按钮验证; - ❌ 是空的或显示红色报错
Git is not installed/Cannot run program "git"→ 跟着 2.2 手动指定路径。
点击 Test 后,底部会弹出绿色提示:
text
Git executed successfully
Git version is 2.43.0
看到这一行就说明 PyCharm ↔ Git 通道打通了 ✅。
💡 注意 :PyCharm 报
Git is not installed但你在命令行里git --version明明能用------这不是 Git 没装 ,而是 PyCharm 找不到它的路径,按 2.2 配好即可。
2.2 手动指定 Git 可执行文件路径
在 Version Control → Git 页面,点击 Path to Git executable 右侧的 文件夹图标,选择下表对应路径:
| 系统 | 典型路径 |
|---|---|
| Windows(官方安装包默认) | C:\Program Files\Git\cmd\git.exe |
| Windows(用户目录安装) | C:\Users\你的用户名\AppData\Local\Programs\Git\cmd\git.exe |
| macOS(Homebrew) | /opt/homebrew/bin/git(Apple Silicon)或 /usr/local/bin/git(Intel) |
| macOS(系统自带) | /usr/bin/git |
| Linux | /usr/bin/git |
⚠️ Windows 选哪一层目录很关键 :请选
cmd\git.exe,不要选bin\git.exe(那是给 Git Bash 用的),也不要选mingw64\bin\git.exe。选错会出现能 Test 通过但推送行为异常的情况。路径中若含中文或空格,建议重装到纯英文路径。
选好后点 Test 验证,再点 Apply → OK。
2.3 在 PyCharm 里配置用户名与邮箱
Git 提交必须记录「作者是谁」,否则提交会报错:
text
*** Please tell me who you are.
Run: git config --global user.email "you@example.com"
git config --global user.name "Your Name"
如果你还没配过,有两种方式:
方式一:PyCharm 界面配置(推荐,所见即所得)
在 Version Control → Git 页面下方找到:
| 字段 | 填什么 | 对应命令 |
|---|---|---|
| Name | 你的昵称/用户名 | git config --global user.name "xxx" |
| 你注册托管平台的邮箱 | git config --global user.email "xxx@xx.com" |
填完 Apply 即可,无需敲命令。
方式二:命令行配置(内置 Terminal)
按 Alt+F12 (macOS ⌥F12)打开 PyCharm 内置 Terminal,输入:
bash
git config --global user.name "你的用户名"
git config --global user.email "你的邮箱@xxx.com"
# 查看是否设置成功
git config --global --list
text
user.name=你的用户名
user.email=你的邮箱@xxx.com
💡 小贴士:邮箱建议与 GitHub / Gitee 注册邮箱一致,否则平台无法把你的提交关联到你的账号头像和贡献图。
三、绑定代码托管账号(GitHub、Gitee)
在 PyCharm 里绑定平台账号后,就能实现一键创建远程仓库、一键提 PR、IDE 内浏览远程仓库,体验会顺畅很多。
3.1 GitHub 登录(Token 与授权两种方式)
进入 Settings → Version Control → GitHub (或 Settings → Plugins 确认 GitHub 插件已启用,该插件为内置):
方式一:授权登录(最简单)
- 点击
Add account或Log In to GitHub; - 选择
Log in via GitHub...; - 浏览器自动打开 GitHub 授权页 → 点击
Authorize; - 回到 PyCharm,账号即显示为已登录 ✅。
方式二:Token 登录(网络受限时可靠)
- 登录 GitHub 网页 → 头像 → Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token;
- 勾选权限:至少勾
repo(仓库读写),如需操作工作流再加workflow; - 生成后复制 Token(只显示一次,务必保存);
- 回到 PyCharm,在
Add account里选择Log In with Token,粘贴 Token →Add Account。
⚠️ 重点 :GitHub 从 2021 年 8 月起已废弃账号密码认证 。如果你在推送时输入 GitHub 登录密码,必然报
Authentication failed------必须改用 Personal Access Token 或 SSH 密钥。
💡 国内网络提示 :GitHub 访问不稳定时,可以优先使用 Gitee(国内平台,速度快),或在本机 Git 里配置代理。PyCharm 本身不提供代理,代理需配在 Git 层。
3.2 Gitee 账号绑定
Gitee 不在 PyCharm 内置插件里,需要先安装插件:
Settings→Plugins→ 切换到Marketplace标签;- 搜索
Gitee→ 点击Install→ 按提示重启 IDE; - 重启后进入
Settings→Version Control→Gitee→Add account; - 输入 Gitee 账号密码,或到 Gitee 网页生成私人令牌后使用 Token 登录。
💡 更省事的做法(不装插件) :直接用 SSH 方式 (见 3.3)或命令行 + 内置 Terminal 推送,效果完全一样,只是少了个 IDE 内的账号面板。
3.3 用 SSH 免密(复用已有密钥)
只要本机已经配好 SSH 密钥并添加到平台,PyCharm 会自动复用 ------因为它调用的就是你本机的 Git 和 SSH 配置,不需要在 PyCharm 里额外配置。
验证方式:Alt+F12 打开 Terminal,执行:
bash
ssh -T git@github.com
text
Hi 你的用户名! You've successfully authenticated, but GitHub does not provide shell access.
看到 successfully authenticated 就说明免密已生效 ✅,之后在 PyCharm 里的所有推送都不再需要输入账号密码。
克隆仓库时,记得把 URL 换成 SSH 格式:
text
SSH 格式(推荐):git@github.com:用户名/仓库名.git
HTTPS 格式: https://github.com/用户名/仓库名.git
💡 如果你的密钥不是默认文件名(如
id_ed25519),而是自定义名字,需要在~/.ssh/config里配置IdentityFile指向它,PyCharm 才能用上。
四、三种方式把项目接进 Git
4.1 方式一:克隆远程仓库(Get from VCS)
适用场景:仓库已经在 GitHub / Gitee 上,你想拉到本地开发。
操作步骤:
- 打开 PyCharm 欢迎界面 → 点击
Get from VCS(旧版叫Checkout from Version Control);- 若已在项目里:菜单
File→Project from Version Control或VCS→Get from Version Control;
- 若已在项目里:菜单
- 在
URL栏粘贴仓库地址(SSH 或 HTTPS 均可); Directory选择本地存放路径(务必选纯英文、无空格的路径);- 点击
Clone; - 首次克隆大型仓库会提示是否信任项目 → 选
Trust Project; - 等待进度条完成,项目自动打开。
#mermaid-svg-v9VDBOsaHc4vOAmj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-v9VDBOsaHc4vOAmj .error-icon{fill:#552222;}#mermaid-svg-v9VDBOsaHc4vOAmj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-v9VDBOsaHc4vOAmj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-v9VDBOsaHc4vOAmj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-v9VDBOsaHc4vOAmj .marker.cross{stroke:#333333;}#mermaid-svg-v9VDBOsaHc4vOAmj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-v9VDBOsaHc4vOAmj p{margin:0;}#mermaid-svg-v9VDBOsaHc4vOAmj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj .cluster-label text{fill:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj .cluster-label span{color:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj .cluster-label span p{background-color:transparent;}#mermaid-svg-v9VDBOsaHc4vOAmj .label text,#mermaid-svg-v9VDBOsaHc4vOAmj span{fill:#333;color:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj .node rect,#mermaid-svg-v9VDBOsaHc4vOAmj .node circle,#mermaid-svg-v9VDBOsaHc4vOAmj .node ellipse,#mermaid-svg-v9VDBOsaHc4vOAmj .node polygon,#mermaid-svg-v9VDBOsaHc4vOAmj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-v9VDBOsaHc4vOAmj .rough-node .label text,#mermaid-svg-v9VDBOsaHc4vOAmj .node .label text,#mermaid-svg-v9VDBOsaHc4vOAmj .image-shape .label,#mermaid-svg-v9VDBOsaHc4vOAmj .icon-shape .label{text-anchor:middle;}#mermaid-svg-v9VDBOsaHc4vOAmj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-v9VDBOsaHc4vOAmj .rough-node .label,#mermaid-svg-v9VDBOsaHc4vOAmj .node .label,#mermaid-svg-v9VDBOsaHc4vOAmj .image-shape .label,#mermaid-svg-v9VDBOsaHc4vOAmj .icon-shape .label{text-align:center;}#mermaid-svg-v9VDBOsaHc4vOAmj .node.clickable{cursor:pointer;}#mermaid-svg-v9VDBOsaHc4vOAmj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-v9VDBOsaHc4vOAmj .arrowheadPath{fill:#333333;}#mermaid-svg-v9VDBOsaHc4vOAmj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-v9VDBOsaHc4vOAmj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-v9VDBOsaHc4vOAmj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v9VDBOsaHc4vOAmj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-v9VDBOsaHc4vOAmj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v9VDBOsaHc4vOAmj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-v9VDBOsaHc4vOAmj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-v9VDBOsaHc4vOAmj .cluster text{fill:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj .cluster span{color:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-v9VDBOsaHc4vOAmj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-v9VDBOsaHc4vOAmj rect.text{fill:none;stroke-width:0;}#mermaid-svg-v9VDBOsaHc4vOAmj .icon-shape,#mermaid-svg-v9VDBOsaHc4vOAmj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v9VDBOsaHc4vOAmj .icon-shape p,#mermaid-svg-v9VDBOsaHc4vOAmj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-v9VDBOsaHc4vOAmj .icon-shape .label rect,#mermaid-svg-v9VDBOsaHc4vOAmj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v9VDBOsaHc4vOAmj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-v9VDBOsaHc4vOAmj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-v9VDBOsaHc4vOAmj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Get from VCS
粘贴 URL
GitHub / Gitee 仓库
PyCharm 克隆到本地
自动识别为 Git 项目
打开 Log / Commit 窗口
开始开发
等价的命令行操作(在 Terminal 里):
bash
git clone git@github.com:用户名/仓库名.git
💡 克隆后如果提示「解释器未配置」 :这是 Python 环境问题,不是 Git 问题。去
Settings→Project→Python Interpreter配好解释器即可。
4.2 方式二:把已有本地项目变成 Git 仓库
适用场景:你已经写了一堆代码,现在想纳入 Git 管理。
操作步骤:
- 用 PyCharm 打开你的项目文件夹;
- 菜单
VCS→Enable Version Control Integration...(新版可能显示为VCS→Enable Version Control Integration); - 在弹出的下拉框中选择
Git→ 点击OK; - 此时 PyCharm 已在项目根目录执行了
git init,所有文件变成红色(未版本控制状态); - 配置
.gitignore(强烈建议先做这一步 ,见第十二章),把__pycache__/、.idea/、虚拟环境目录等排除掉; - 按
Ctrl+K提交你的第一批代码。
⚠️ 顺序很重要 :先写
.gitignore再提交 。如果先把venv/、__pycache__/提交进去,后面再想忽略就得先git rm --cached清理,很麻烦。
等价的命令行操作:
bash
git init
git add .
git commit -m "initial commit"
如果你还想同时创建远程仓库并推上去:
菜单 VCS → Git → Share Project on GitHub(需已登录 GitHub 账号),按向导填写仓库名 → PyCharm 会自动创建远程仓库并推送。等价命令:
bash
git remote add origin git@github.com:用户名/仓库名.git
git branch -M main
git push -u origin main
4.3 方式三:新建项目时创建仓库
操作步骤:
File→New Project;- 在新建项目对话框里勾选
Create Git repository(旧版是Create a Git repository); - 填好项目名与解释器 →
Create。
PyCharm 会自动 git init,并自动生成一份 Python 项目的 .gitignore 模板 (包含 .idea/、__pycache__/ 等),非常省心。
4.4 三种方式对比
| 方式 | 适用场景 | 入口 | 底层命令 |
|---|---|---|---|
| 克隆远程仓库 | 仓库已存在,拉下来开发 | Get from VCS |
git clone |
| 本地项目纳入 Git | 已有代码,想开始用 Git | VCS → Enable Version Control Integration |
git init |
| 新建项目建仓库 | 全新项目,从零开始 | New Project → 勾选 Create Git repository |
git init(含 .gitignore 模板) |
五、认识 PyCharm 的 Git 界面
熟悉界面布局是用好 PyCharm Git 的第一步,也是最关键的一步。很多人觉得「IDE 里 Git 不好用」,其实只是没找到对应面板。
5.1 五大核心区域总览
#mermaid-svg-HGvMzeyrZndGDVH6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HGvMzeyrZndGDVH6 .error-icon{fill:#552222;}#mermaid-svg-HGvMzeyrZndGDVH6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HGvMzeyrZndGDVH6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HGvMzeyrZndGDVH6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HGvMzeyrZndGDVH6 .marker.cross{stroke:#333333;}#mermaid-svg-HGvMzeyrZndGDVH6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HGvMzeyrZndGDVH6 p{margin:0;}#mermaid-svg-HGvMzeyrZndGDVH6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 .cluster-label text{fill:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 .cluster-label span{color:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 .cluster-label span p{background-color:transparent;}#mermaid-svg-HGvMzeyrZndGDVH6 .label text,#mermaid-svg-HGvMzeyrZndGDVH6 span{fill:#333;color:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 .node rect,#mermaid-svg-HGvMzeyrZndGDVH6 .node circle,#mermaid-svg-HGvMzeyrZndGDVH6 .node ellipse,#mermaid-svg-HGvMzeyrZndGDVH6 .node polygon,#mermaid-svg-HGvMzeyrZndGDVH6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HGvMzeyrZndGDVH6 .rough-node .label text,#mermaid-svg-HGvMzeyrZndGDVH6 .node .label text,#mermaid-svg-HGvMzeyrZndGDVH6 .image-shape .label,#mermaid-svg-HGvMzeyrZndGDVH6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-HGvMzeyrZndGDVH6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HGvMzeyrZndGDVH6 .rough-node .label,#mermaid-svg-HGvMzeyrZndGDVH6 .node .label,#mermaid-svg-HGvMzeyrZndGDVH6 .image-shape .label,#mermaid-svg-HGvMzeyrZndGDVH6 .icon-shape .label{text-align:center;}#mermaid-svg-HGvMzeyrZndGDVH6 .node.clickable{cursor:pointer;}#mermaid-svg-HGvMzeyrZndGDVH6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HGvMzeyrZndGDVH6 .arrowheadPath{fill:#333333;}#mermaid-svg-HGvMzeyrZndGDVH6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HGvMzeyrZndGDVH6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HGvMzeyrZndGDVH6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HGvMzeyrZndGDVH6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HGvMzeyrZndGDVH6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HGvMzeyrZndGDVH6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HGvMzeyrZndGDVH6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HGvMzeyrZndGDVH6 .cluster text{fill:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 .cluster span{color:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HGvMzeyrZndGDVH6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HGvMzeyrZndGDVH6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-HGvMzeyrZndGDVH6 .icon-shape,#mermaid-svg-HGvMzeyrZndGDVH6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HGvMzeyrZndGDVH6 .icon-shape p,#mermaid-svg-HGvMzeyrZndGDVH6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HGvMzeyrZndGDVH6 .icon-shape .label rect,#mermaid-svg-HGvMzeyrZndGDVH6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HGvMzeyrZndGDVH6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HGvMzeyrZndGDVH6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HGvMzeyrZndGDVH6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} PyCharm 主窗口
① 编辑器
左侧竖条显示行级改动
右键可 Show Diff / Annotate
② 状态栏(右下角)
显示当前分支名
点开是分支弹窗
③ Commit 工具窗口
Alt+0
看改动 / 暂存 / 提交
④ Git 工具窗口(Log)
Alt+9
看历史 / 分支图 / 右键操作
⑤ 内置 Terminal
Alt+F12
直接敲 git 命令
| 区域 | 打开快捷键 | 主要用途 |
|---|---|---|
| ① 编辑器 | --- | 看行级改动、Diff、Blame 注解 |
| ② 状态栏 | --- | 看/切分支、看当前分支状态 |
| ③ Commit 工具窗口 | Alt+0 |
查看改动、勾选行、暂存、提交 |
| ④ Git 工具窗口(Log) | Alt+9 |
提交历史、分支图、合并、回滚、Cherry-Pick |
| ⑤ 内置 Terminal | Alt+F12 |
执行任何 Git 命令,与界面互为补充 |
5.2 Commit 工具窗口(Alt+0)
这是你每天用得最多 的窗口。按 Alt+0 打开(macOS ⌘0),它通常分几个区域:
| 区域 | 说明 |
|---|---|
| 改动文件列表 | 列出所有发生变化的文件;新版会分组显示为 Changes(未暂存)/ Staged(已暂存)/ Unversioned Files(未跟踪) |
| 文件前的勾选框 | 勾上 = 加入暂存区(等价 git add <file>);不勾 = 不进本次提交 |
| 提交信息框 | 填写 commit message,右侧有历史信息按钮可复用旧信息 |
Commit 按钮 |
提交到本地仓库(等价 git commit) |
Commit and Push... |
提交后立刻推送(等价 commit + push) |
| 文件上的右键菜单 | Rollback(丢弃改动)、Show Diff、Add to Changelist、Move to Another Changelist |
| ⚙️ 齿轮按钮 | 可开启 Group by Directory 、Show Diff Preview in Commit Area(提交前预览差异) |
💡 改行级提交(超实用) :双击一个文件打开 Diff 视图,在左侧栏勾选具体的代码块(hunk)或行 ,然后提交------这样就能只提交文件里的部分改动 ,剩下的继续留在本地。等价于
git add -p。
💡 Changelist(变更列表) :可以把改动按「任务」分组,比如「修 bug」和「新功能」分成两个列表分别提交。右键文件 →Move to Another Changelist。这个功能在同时改多个需求时极其好用。
5.3 Git 工具窗口(Alt+9)
按 Alt+9 (macOS ⌘9)打开,这里是 Log(日志)面板 ,是功能最全的地方:
| 功能 | 位置 | 说明 |
|---|---|---|
| 提交历史列表 | 左侧/中间主区 | 每次提交一行:提交信息、作者、时间 |
| 分支拓扑图 | 主区左侧彩色线条 | 直观看到分支的分叉与合并 |
Branches 下拉 |
左上角 | 切换查看 Local / Remote / 全部分支 |
User 过滤 |
工具栏 | 只显示某个人的提交 |
Paths 过滤 |
工具栏 | 只看某个文件/目录的历史 |
| 搜索框 | 工具栏 | 按提交信息、作者、哈希搜索 |
| 选中提交 → 右侧文件列表 | 中右 | 看到这次提交改了哪些文件 |
| 右键提交 → 菜单 | --- | Cherry-Pick、Revert Commit、Reset Current Branch to Here、Interactively Rebase from Here、Copy Revision Number、Create Patch |
#mermaid-svg-YAJdPnrVt8vaNG63{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YAJdPnrVt8vaNG63 .error-icon{fill:#552222;}#mermaid-svg-YAJdPnrVt8vaNG63 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YAJdPnrVt8vaNG63 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YAJdPnrVt8vaNG63 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YAJdPnrVt8vaNG63 .marker.cross{stroke:#333333;}#mermaid-svg-YAJdPnrVt8vaNG63 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YAJdPnrVt8vaNG63 p{margin:0;}#mermaid-svg-YAJdPnrVt8vaNG63 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 .cluster-label text{fill:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 .cluster-label span{color:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 .cluster-label span p{background-color:transparent;}#mermaid-svg-YAJdPnrVt8vaNG63 .label text,#mermaid-svg-YAJdPnrVt8vaNG63 span{fill:#333;color:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 .node rect,#mermaid-svg-YAJdPnrVt8vaNG63 .node circle,#mermaid-svg-YAJdPnrVt8vaNG63 .node ellipse,#mermaid-svg-YAJdPnrVt8vaNG63 .node polygon,#mermaid-svg-YAJdPnrVt8vaNG63 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YAJdPnrVt8vaNG63 .rough-node .label text,#mermaid-svg-YAJdPnrVt8vaNG63 .node .label text,#mermaid-svg-YAJdPnrVt8vaNG63 .image-shape .label,#mermaid-svg-YAJdPnrVt8vaNG63 .icon-shape .label{text-anchor:middle;}#mermaid-svg-YAJdPnrVt8vaNG63 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YAJdPnrVt8vaNG63 .rough-node .label,#mermaid-svg-YAJdPnrVt8vaNG63 .node .label,#mermaid-svg-YAJdPnrVt8vaNG63 .image-shape .label,#mermaid-svg-YAJdPnrVt8vaNG63 .icon-shape .label{text-align:center;}#mermaid-svg-YAJdPnrVt8vaNG63 .node.clickable{cursor:pointer;}#mermaid-svg-YAJdPnrVt8vaNG63 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YAJdPnrVt8vaNG63 .arrowheadPath{fill:#333333;}#mermaid-svg-YAJdPnrVt8vaNG63 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YAJdPnrVt8vaNG63 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YAJdPnrVt8vaNG63 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YAJdPnrVt8vaNG63 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YAJdPnrVt8vaNG63 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YAJdPnrVt8vaNG63 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YAJdPnrVt8vaNG63 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YAJdPnrVt8vaNG63 .cluster text{fill:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 .cluster span{color:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YAJdPnrVt8vaNG63 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YAJdPnrVt8vaNG63 rect.text{fill:none;stroke-width:0;}#mermaid-svg-YAJdPnrVt8vaNG63 .icon-shape,#mermaid-svg-YAJdPnrVt8vaNG63 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YAJdPnrVt8vaNG63 .icon-shape p,#mermaid-svg-YAJdPnrVt8vaNG63 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YAJdPnrVt8vaNG63 .icon-shape .label rect,#mermaid-svg-YAJdPnrVt8vaNG63 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YAJdPnrVt8vaNG63 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YAJdPnrVt8vaNG63 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YAJdPnrVt8vaNG63 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Git 窗口 Log 面板
看历史 / 看分支图
右键提交
回滚 / Cherry-Pick / 变基
右键分支
合并 / 变基 / 删除 / 比较
右键标签
打 Tag / 签出
⚠️ 小技巧 :如果 Git 窗口里看不到远程分支,点一下工具栏的
Fetch All Remotes(或Alt+F12执行git fetch --all)刷新即可。
5.4 状态栏与分支弹窗
状态栏(右下角) 始终显示当前分支名,例如:
text
main
点击它 会弹出分支弹窗 (Branches Popup),这是切分支最快的入口:
| 弹窗里的操作 | 说明 | 等价命令 |
|---|---|---|
Local Branches |
本机所有分支,点一下就切换 | git checkout <branch> |
Remote Branches |
远程分支,点一下会创建同名本地分支并跟踪 | git checkout -b <b> origin/<b> |
New Branch |
新建分支 | git checkout -b <name> |
Checkout Tag or Revision... |
切到某个标签或某个提交(游离 HEAD) | git checkout <tag/hash> |
Update Project |
拉取更新 | git fetch + merge/rebase |
Push... |
推送 | git push |
Show Git Log |
打开 Log | git log |
Merge into Current |
把选中分支合并进来 | git merge <branch> |
Rebase Current onto Selected |
变基 | git rebase <branch> |
Compare with Current |
与当前分支比较差异 | git diff <a> <b> |
💡 状态栏还能看「落后/领先」 :拉取后如果本地领先远程,会显示
↑1(有 1 个提交待推送);落后会显示↓2。一眼就知道该推送还是该拉取。
5.5 编辑器与项目视图里的颜色标记含义
这是新手最容易困惑的地方------文件旁边的彩色竖条到底什么意思?
| 颜色 | 含义 | 状态说明 |
|---|---|---|
| 蓝色 | 已修改(Modified) | 文件已跟踪,且内容有改动 |
| 绿色 | 已添加(Added) | 新文件已加入版本控制 |
| 红色 | 未版本控制(Unversioned) | 新文件还没 git add;冲突时也是红色 |
| 灰色 | 已删除(Deleted) | 文件被删除,等待提交 |
| 黄色/橄榄色 | 被忽略(Ignored) | 被 .gitignore 排除的文件 |
- 编辑器左侧的窄竖条 :显示行级改动,蓝色=修改行,绿色=新增行,灰色三角=删除行;点一下竖条可查看该行的 Diff;
- 项目视图里的文件名颜色 :与上表一致,可在
Settings→Version Control→File Status Colors自定义配色; - 编辑器右上角的彩色小方块:新版 UI 中用于指示本文件的 VCS 状态,鼠标悬停有详细提示。
💡 如果颜色没出现 :检查文件是否真的在 Git 管理下(
git status有没有它),以及Settings→Version Control→Directory Mappings里项目根目录是否映射到了<Project Root>。
六、日常核心操作:提交、推送与拉取
6.1 完整流程总览
先建立整体心智模型------一次改动的完整生命周期:
#mermaid-svg-qUj6Sx875RDyqpxD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qUj6Sx875RDyqpxD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qUj6Sx875RDyqpxD .error-icon{fill:#552222;}#mermaid-svg-qUj6Sx875RDyqpxD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qUj6Sx875RDyqpxD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qUj6Sx875RDyqpxD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qUj6Sx875RDyqpxD .marker.cross{stroke:#333333;}#mermaid-svg-qUj6Sx875RDyqpxD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qUj6Sx875RDyqpxD p{margin:0;}#mermaid-svg-qUj6Sx875RDyqpxD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qUj6Sx875RDyqpxD .cluster-label text{fill:#333;}#mermaid-svg-qUj6Sx875RDyqpxD .cluster-label span{color:#333;}#mermaid-svg-qUj6Sx875RDyqpxD .cluster-label span p{background-color:transparent;}#mermaid-svg-qUj6Sx875RDyqpxD .label text,#mermaid-svg-qUj6Sx875RDyqpxD span{fill:#333;color:#333;}#mermaid-svg-qUj6Sx875RDyqpxD .node rect,#mermaid-svg-qUj6Sx875RDyqpxD .node circle,#mermaid-svg-qUj6Sx875RDyqpxD .node ellipse,#mermaid-svg-qUj6Sx875RDyqpxD .node polygon,#mermaid-svg-qUj6Sx875RDyqpxD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qUj6Sx875RDyqpxD .rough-node .label text,#mermaid-svg-qUj6Sx875RDyqpxD .node .label text,#mermaid-svg-qUj6Sx875RDyqpxD .image-shape .label,#mermaid-svg-qUj6Sx875RDyqpxD .icon-shape .label{text-anchor:middle;}#mermaid-svg-qUj6Sx875RDyqpxD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qUj6Sx875RDyqpxD .rough-node .label,#mermaid-svg-qUj6Sx875RDyqpxD .node .label,#mermaid-svg-qUj6Sx875RDyqpxD .image-shape .label,#mermaid-svg-qUj6Sx875RDyqpxD .icon-shape .label{text-align:center;}#mermaid-svg-qUj6Sx875RDyqpxD .node.clickable{cursor:pointer;}#mermaid-svg-qUj6Sx875RDyqpxD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qUj6Sx875RDyqpxD .arrowheadPath{fill:#333333;}#mermaid-svg-qUj6Sx875RDyqpxD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qUj6Sx875RDyqpxD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qUj6Sx875RDyqpxD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qUj6Sx875RDyqpxD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qUj6Sx875RDyqpxD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qUj6Sx875RDyqpxD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qUj6Sx875RDyqpxD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qUj6Sx875RDyqpxD .cluster text{fill:#333;}#mermaid-svg-qUj6Sx875RDyqpxD .cluster span{color:#333;}#mermaid-svg-qUj6Sx875RDyqpxD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qUj6Sx875RDyqpxD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qUj6Sx875RDyqpxD rect.text{fill:none;stroke-width:0;}#mermaid-svg-qUj6Sx875RDyqpxD .icon-shape,#mermaid-svg-qUj6Sx875RDyqpxD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qUj6Sx875RDyqpxD .icon-shape p,#mermaid-svg-qUj6Sx875RDyqpxD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qUj6Sx875RDyqpxD .icon-shape .label rect,#mermaid-svg-qUj6Sx875RDyqpxD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qUj6Sx875RDyqpxD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qUj6Sx875RDyqpxD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qUj6Sx875RDyqpxD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} git add
勾选框
git commit
Ctrl+K
git push
Ctrl+Shift+K
git fetch + merge
Ctrl+T
① 工作区
你改代码
② 暂存区
Staged
③ 本地仓库
.git
④ 远程仓库
GitHub/Gitee
对应到 PyCharm 日常操作就是四步循环:改代码 → 提交(Ctrl+K)→ 推送(Ctrl+Shift+K)→ 拉取更新(Ctrl+T)。
6.2 提交 Commit
操作步骤:
- 修改代码(此时编辑器左侧出现蓝色竖条);
- 按
Ctrl+K(macOS⌘K)打开 Commit 工具窗口; - 勾选 要提交的文件(默认全部勾选);
- 💡 不想提交某个文件?取消勾选即可;
- 💡 只想提交某几行?双击文件打开 Diff,勾选具体代码块;
- 在提交信息框 里写清楚本次改动(例如
feat: 新增用户登录接口); - 点击
Commit(提交到本地)或Commit and Push...(提交并推送); - 提交成功后,文件颜色恢复为正常,竖条消失。
提交信息规范建议(团队协作必备):
| 前缀 | 含义 | 示例 |
|---|---|---|
feat |
新功能 | feat: 支持手机号登录 |
fix |
修复 bug | fix: 修复分页越界报错 |
docs |
文档改动 | docs: 补充接口说明 |
style |
格式调整(不影响逻辑) | style: 统一缩进为 4 空格 |
refactor |
重构 | refactor: 拆分订单服务 |
test |
测试相关 | test: 补充登录单测 |
chore |
构建/工具链 | chore: 升级依赖版本 |
提交时的常用按钮:
| 按钮/选项 | 作用 | 等价命令 |
|---|---|---|
Amend |
修改上一次提交(改信息或补充文件) | git commit --amend |
Sign-off |
添加签名行 | git commit -s |
Run Git hooks |
执行 pre-commit 钩子 | 默认执行 |
Commit and Push... |
提交后直接推送 | commit + push |
⚠️ Amend 的坑 :
Amend会重写 上一次提交的哈希。如果那次提交已经推送 到远程,amend 后必须push --force才能覆盖,而这会影响其他协作者。已推送的提交尽量别 amend。
6.3 推送 Push
操作步骤:
- 按
Ctrl+Shift+K(macOS⌘⇧K)打开 Push 对话框; - 对话框里会列出即将推送的提交列表(确认内容对不对);
- 点击
Push; - 首次推送新分支时,PyCharm 会自动设置上游跟踪(等价
git push -u origin <branch>)。
Push 对话框里的关键项:
| 选项 | 说明 |
|---|---|
Current branch |
只推当前分支(最常用) |
All branches |
推送所有本地分支 |
Push tags |
是否同时推送标签 |
| 提交列表 | 看清要推哪些提交,别把不想推的提交推上去 |
等价的命令行操作:
bash
# 推送到默认跟踪的远程分支
git push
# 首次推送并建立跟踪关系
git push -u origin main
# 强推(⚠️ 危险,会覆盖远程,团队协作慎用)
git push --force-with-lease
💡 推荐用
--force-with-lease而不是--force:前者会在远程被别人更新过时拒绝强推,避免覆盖同事的提交。
6.4 拉取更新 Update Project(Pull 的区别)
为什么不用 git pull? 因为 PyCharm 推荐用 Update Project ,它比裸 git pull 更智能。
| 对比项 | Update Project(PyCharm) |
git pull |
|---|---|---|
| 底层动作 | fetch + merge(或 rebase,可配置) |
fetch + merge |
| 能否配 rebase | ✅ 可在设置里选 Merge / Rebase | ❌ 固定 merge(除非加 --rebase) |
| 本地有改动时 | ✅ 可用 Smart Update 自动 stash 再恢复 |
❌ 直接报错 |
| 推荐度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
操作步骤:
- 按
Ctrl+T(macOS⌘T)打开 Update Project 对话框; - 选择更新方式:
| 选项 | 含义 | 适用场景 |
|---|---|---|
Merge(默认) |
把远程改动合并进当前分支,会产生 merge 提交 | 团队协作、公共分支 |
Rebase |
把你的提交「挪」到远程最新提交之后,历史更线性 | 个人分支、整理历史 |
Branch Default |
跟随各分支自己的默认配置 | 多分支混用 |
- 勾选
Use Stash/Smart Update(本地有未提交改动时使用,PyCharm 会先 stash 再更新再恢复); - 点击
OK,等待完成。
改默认更新方式 :Settings → Version Control → Git → Update method 选择 Merge / Rebase。
等价命令行:
bash
# 等价于 Update Project(Merge 模式)
git fetch --all
git merge origin/main
# 等价于 Update Project(Rebase 模式)
git fetch --all
git rebase origin/main
⚠️ 重要区别 :
Update Project会明确列出 更新策略,而git pull是「一锅端」。在多人协作的公共分支上,建议用 Merge ;在自己独占的 feature 分支上,用 Rebase 让历史更干净。
6.5 推送被拒绝怎么办(Push Rejected)
这是最高频的问题。报错长这样:
text
Push rejected
rejected: non-fast-forward
Updates were rejected because the remote contains work that you do not have locally.
原因:远程仓库有你本地没有的提交(同事推了新代码),Git 拒绝覆盖。
PyCharm 里的解决办法(超方便) :报错后弹出的 Push Rejected 对话框里,直接给你两个按钮:
| 按钮 | 作用 | 等价命令 |
|---|---|---|
Merge |
先拉取远程改动并合并,再推送 | git pull → git push |
Rebase |
把你的提交挪到远程最新之后,再推送 | git pull --rebase → git push |
点一下就好了------不用去命令行折腾。
如果对话框没弹出来 ,手动按 Ctrl+T(Update Project)拉取,解决完冲突后再推送。
⚠️ 千万不要 为了图省事直接用
git push --force把同事的提交冲掉。除非你 100% 确认那个分支只有你一个人在用。
七、分支管理
7.1 创建与切换分支
创建分支(三种入口,任选):
| 入口 | 操作 |
|---|---|
| 状态栏 | 点右下角分支名 → New Branch → 输入名字 → Create |
| Git 窗口 | 右键某次提交 → New Branch from Selected...(从指定提交拉分支) |
| 菜单 | Git → New Branch(或 Ctrl+Shift+A 搜 New Branch) |
创建时会有一个勾选项 Checkout branch ------勾上则创建后立即切换过去。
切换分支:点状态栏分支名 → 在弹窗里点目标分支名即可。
⚠️ 如果本地有未提交改动 ,切换时会弹出 Smart Checkout 提示:
| 选项 | 作用 |
|---|---|
Smart Checkout(推荐) |
PyCharm 自动把改动 stash 起来、切完分支后再自动恢复 |
Force Checkout |
直接丢弃本地改动切换(⚠️ 改动会丢) |
Don't Checkout |
取消切换 |
💡 Smart Checkout 的坑 :如果改动与目标分支冲突,自动 stash 恢复时仍可能报错。此时去
Git→Uncommitted Changes→Stash Changes手动 stash 更稳妥。
等价命令行:
bash
git checkout -b feature/login # 新建并切换
git checkout main # 切换已有分支
git switch main # 新版命令,语义更清晰
7.2 合并分支
场景 :feature/login 开发完了,要合并回 main。
操作步骤:
- 先切到目标分支 (本例切到
main); - 点状态栏分支名 → 在弹窗的
Local Branches里找到feature/login; - 鼠标悬停展开子菜单 → 选择
Merge into Current; - 若无冲突,合并立即完成(会产生一个 merge 提交);
- 若有冲突 → 进入第八章的冲突解决流程。
或者从 Git 窗口操作 :在 Log 里右键那个要合并的分支 → Merge into Current。
合并模式说明:
| 模式 | 何时产生 | 说明 |
|---|---|---|
| Fast-forward(快进) | 目标分支没有新提交 | 直接把指针前移,不产生 merge 提交 |
| Merge commit(三方合并) | 两个分支都有新提交 | 产生一个 merge 提交,历史有分叉 |
强制不产生 merge 提交 (保持线性历史):合并时勾选 Merge... 对话框里的 --no-commit 或改用 Rebase。
等价命令行:
bash
git checkout main
git merge feature/login
7.3 变基 Rebase
Rebase 的作用:把你的提交「搬家」到另一个分支的最新提交之后,让历史变成一条直线。
普通变基 :点状态栏分支名 → 悬停目标分支 → Rebase Current onto Selected。
交互式变基(整理历史,功能强大):
Alt+9打开 Git 窗口 → 找到要整理的起始提交;- 右键 →
Interactively Rebase from Here...; - 在弹出的列表里对每个提交选择动作:
| 动作 | 含义 |
|---|---|
Pick |
保留该提交 |
Reword |
保留但修改提交信息 |
Edit |
停下来让你修改内容 |
Squash |
合并到上一个提交,并合并提交信息 |
Fixup |
合并到上一个提交,丢弃本条信息 |
Drop |
删除该提交 |
- 调整顺序、选择动作 → 点
Rebase开始。
等价命令行 :git rebase -i HEAD~5
⚠️ Rebase 黄金法则 :永远不要 rebase 已经推送到公共分支的提交 。Rebase 会重写历史哈希,导致同事的分支出问题。个人 feature 分支随便 rebase,
main/develop这类公共分支绝对不要。
7.4 删除、重命名与比较分支
| 操作 | 入口 | 等价命令 |
|---|---|---|
| 删除分支 | 状态栏分支弹窗 → 悬停分支 → Delete |
git branch -d <b> |
| 强制删除 | 同上(未合并分支会提示) | git branch -D <b> |
| 重命名分支 | Git 窗口右键分支 → Rename |
git branch -m <old> <new> |
| 删除远程分支 | Git 窗口 Remote 下右键 → Delete |
git push origin --delete <b> |
| 比较分支 | Git 窗口右键分支 → Compare with Current |
git diff <a>..<b> |
| 查看分支差异文件 | 同上,弹出 Diff 视图 | --- |
| 检出为本地分支 | Remote 下右键 → Checkout |
git checkout -b <b> origin/<b> |
⚠️ 删除分支前 :确认它已经合并。如果误删了,别慌------只要提交还在,用
git reflog+git branch <name> <hash>就能找回(见 10.4)。
7.5 分支操作命令对照表
| PyCharm 操作 | Git 命令 |
|---|---|
状态栏 → New Branch |
git checkout -b <name> |
| 状态栏 → 点分支名 | git checkout <name> |
Merge into Current |
git merge <branch> |
Rebase Current onto Selected |
git rebase <branch> |
Interactively Rebase from Here |
git rebase -i <commit> |
分支弹窗 → Delete |
git branch -d <name> |
Git 窗口 → Rename |
git branch -m <old> <new> |
Compare with Current |
git diff <a>..<b> |
Fetch All Remotes |
git fetch --all |
Checkout Tag or Revision |
git checkout <tag/hash> |
八、图形化解决代码冲突
这是 PyCharm 相对命令行最大的优势 ------三窗格可视化合并工具,让冲突处理从「看花眼的 <<<<<<<」变成「点箭头选择」。
8.1 冲突是怎么产生的
当两个人修改了同一个文件的同一部分,Git 无法自动判断该保留谁,就产生了冲突:
#mermaid-svg-X2NmLsYhWKFzQXrI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-X2NmLsYhWKFzQXrI .error-icon{fill:#552222;}#mermaid-svg-X2NmLsYhWKFzQXrI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-X2NmLsYhWKFzQXrI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-X2NmLsYhWKFzQXrI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-X2NmLsYhWKFzQXrI .marker.cross{stroke:#333333;}#mermaid-svg-X2NmLsYhWKFzQXrI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-X2NmLsYhWKFzQXrI p{margin:0;}#mermaid-svg-X2NmLsYhWKFzQXrI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI .cluster-label text{fill:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI .cluster-label span{color:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI .cluster-label span p{background-color:transparent;}#mermaid-svg-X2NmLsYhWKFzQXrI .label text,#mermaid-svg-X2NmLsYhWKFzQXrI span{fill:#333;color:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI .node rect,#mermaid-svg-X2NmLsYhWKFzQXrI .node circle,#mermaid-svg-X2NmLsYhWKFzQXrI .node ellipse,#mermaid-svg-X2NmLsYhWKFzQXrI .node polygon,#mermaid-svg-X2NmLsYhWKFzQXrI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-X2NmLsYhWKFzQXrI .rough-node .label text,#mermaid-svg-X2NmLsYhWKFzQXrI .node .label text,#mermaid-svg-X2NmLsYhWKFzQXrI .image-shape .label,#mermaid-svg-X2NmLsYhWKFzQXrI .icon-shape .label{text-anchor:middle;}#mermaid-svg-X2NmLsYhWKFzQXrI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-X2NmLsYhWKFzQXrI .rough-node .label,#mermaid-svg-X2NmLsYhWKFzQXrI .node .label,#mermaid-svg-X2NmLsYhWKFzQXrI .image-shape .label,#mermaid-svg-X2NmLsYhWKFzQXrI .icon-shape .label{text-align:center;}#mermaid-svg-X2NmLsYhWKFzQXrI .node.clickable{cursor:pointer;}#mermaid-svg-X2NmLsYhWKFzQXrI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-X2NmLsYhWKFzQXrI .arrowheadPath{fill:#333333;}#mermaid-svg-X2NmLsYhWKFzQXrI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-X2NmLsYhWKFzQXrI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-X2NmLsYhWKFzQXrI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-X2NmLsYhWKFzQXrI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-X2NmLsYhWKFzQXrI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-X2NmLsYhWKFzQXrI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-X2NmLsYhWKFzQXrI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-X2NmLsYhWKFzQXrI .cluster text{fill:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI .cluster span{color:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-X2NmLsYhWKFzQXrI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-X2NmLsYhWKFzQXrI rect.text{fill:none;stroke-width:0;}#mermaid-svg-X2NmLsYhWKFzQXrI .icon-shape,#mermaid-svg-X2NmLsYhWKFzQXrI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-X2NmLsYhWKFzQXrI .icon-shape p,#mermaid-svg-X2NmLsYhWKFzQXrI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-X2NmLsYhWKFzQXrI .icon-shape .label rect,#mermaid-svg-X2NmLsYhWKFzQXrI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-X2NmLsYhWKFzQXrI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-X2NmLsYhWKFzQXrI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-X2NmLsYhWKFzQXrI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
main 分支
原始文件
同事改了第 10 行
并推送到远程
你改了第 10 行
还没推送
你执行 Update Project
拉取远程改动
同一行被两边改过?
⚠️ 冲突
PyCharm 弹出 Merge Conflicts
✅ 自动合并成功
8.2 冲突提示与三个选项
拉取(Ctrl+T)或合并后若有冲突,PyCharm 会弹出 Merge Conflicts 对话框,列出所有冲突文件,并提供:
| 选项 | 作用 | 什么时候用 |
|---|---|---|
Merge... |
打开三窗格合并工具,逐处精细处理 | ⭐ 推荐,最稳妥 |
Accept Yours |
整个文件全用你自己的版本 | 确认远程改动不重要 |
Accept Theirs |
整个文件全用远程版本 | 确认自己的改动可以丢弃 |
同时,编辑器顶部会出现黄色横幅:
text
2 files have merge conflicts
点击横幅上的 Resolve 链接,可以看到 Accept Yours / Accept Theirs / Merge 三个按钮。
⚠️ 别盲目点
Accept Yours!这会让远程同事的改动全部消失 。除非你非常确定那些改动不需要,否则永远选Merge手动逐个处理。
8.3 三窗格合并工具详解
选择 Merge 后打开合并窗口,布局如下:
#mermaid-svg-79mLQyELtAF7UZTq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-79mLQyELtAF7UZTq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-79mLQyELtAF7UZTq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-79mLQyELtAF7UZTq .error-icon{fill:#552222;}#mermaid-svg-79mLQyELtAF7UZTq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-79mLQyELtAF7UZTq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-79mLQyELtAF7UZTq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-79mLQyELtAF7UZTq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-79mLQyELtAF7UZTq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-79mLQyELtAF7UZTq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-79mLQyELtAF7UZTq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-79mLQyELtAF7UZTq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-79mLQyELtAF7UZTq .marker.cross{stroke:#333333;}#mermaid-svg-79mLQyELtAF7UZTq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-79mLQyELtAF7UZTq p{margin:0;}#mermaid-svg-79mLQyELtAF7UZTq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-79mLQyELtAF7UZTq .cluster-label text{fill:#333;}#mermaid-svg-79mLQyELtAF7UZTq .cluster-label span{color:#333;}#mermaid-svg-79mLQyELtAF7UZTq .cluster-label span p{background-color:transparent;}#mermaid-svg-79mLQyELtAF7UZTq .label text,#mermaid-svg-79mLQyELtAF7UZTq span{fill:#333;color:#333;}#mermaid-svg-79mLQyELtAF7UZTq .node rect,#mermaid-svg-79mLQyELtAF7UZTq .node circle,#mermaid-svg-79mLQyELtAF7UZTq .node ellipse,#mermaid-svg-79mLQyELtAF7UZTq .node polygon,#mermaid-svg-79mLQyELtAF7UZTq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-79mLQyELtAF7UZTq .rough-node .label text,#mermaid-svg-79mLQyELtAF7UZTq .node .label text,#mermaid-svg-79mLQyELtAF7UZTq .image-shape .label,#mermaid-svg-79mLQyELtAF7UZTq .icon-shape .label{text-anchor:middle;}#mermaid-svg-79mLQyELtAF7UZTq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-79mLQyELtAF7UZTq .rough-node .label,#mermaid-svg-79mLQyELtAF7UZTq .node .label,#mermaid-svg-79mLQyELtAF7UZTq .image-shape .label,#mermaid-svg-79mLQyELtAF7UZTq .icon-shape .label{text-align:center;}#mermaid-svg-79mLQyELtAF7UZTq .node.clickable{cursor:pointer;}#mermaid-svg-79mLQyELtAF7UZTq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-79mLQyELtAF7UZTq .arrowheadPath{fill:#333333;}#mermaid-svg-79mLQyELtAF7UZTq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-79mLQyELtAF7UZTq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-79mLQyELtAF7UZTq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-79mLQyELtAF7UZTq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-79mLQyELtAF7UZTq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-79mLQyELtAF7UZTq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-79mLQyELtAF7UZTq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-79mLQyELtAF7UZTq .cluster text{fill:#333;}#mermaid-svg-79mLQyELtAF7UZTq .cluster span{color:#333;}#mermaid-svg-79mLQyELtAF7UZTq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-79mLQyELtAF7UZTq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-79mLQyELtAF7UZTq rect.text{fill:none;stroke-width:0;}#mermaid-svg-79mLQyELtAF7UZTq .icon-shape,#mermaid-svg-79mLQyELtAF7UZTq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-79mLQyELtAF7UZTq .icon-shape p,#mermaid-svg-79mLQyELtAF7UZTq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-79mLQyELtAF7UZTq .icon-shape .label rect,#mermaid-svg-79mLQyELtAF7UZTq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-79mLQyELtAF7UZTq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-79mLQyELtAF7UZTq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-79mLQyELtAF7UZTq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 三窗格合并窗口
▶ 接受左边改动
◀ 接受右边改动
左窗格
Local Changes
你的版本
中间窗格
Result
合并结果
右窗格
Changes from Server
远程版本
| 窗格 | 名称 | 内容 |
|---|---|---|
| 左 | Local Changes |
你本地的版本 |
| 中 | Result |
最终合并结果(你在这里编辑确认) |
| 右 | Changes from Server |
远程服务器的版本 |
工具栏按钮:
| 按钮 | 作用 | 等价操作 |
|---|---|---|
▶(左箭头) |
接受左侧改动到结果区 | 保留你的版本 |
◀(右箭头) |
接受右侧改动到结果区 | 保留远程版本 |
Accept Left / Accept Right |
同上,整块应用 | --- |
X(忽略) |
两边都不要这块 | 手动删除 |
Abort |
放弃整个合并 | git merge --abort |
Apply |
应用结果并关闭 | --- |
操作流程:
- 从第一个冲突点开始(通常是红色高亮区域);
- 分别看左右两边的代码,判断该用哪边(或手动改中间结果);
- 点
▶或◀把选定的版本放进中间; - 如果两边都要,就点两次(或手动在中间拼);
- 处理完所有冲突点后,点
Apply; - 回到 Commit 窗口,PyCharm 已经帮你把文件标记为已解决(等价
git add <file>); - 提交这次合并(
Ctrl+K),提交信息通常默认是Merge branch 'xxx'。
💡 右侧那个
X按钮的用途 :当某一块两边都不要 时(比如两边都删了同一段代码,只是删法不同),点X忽略它,让中间结果里这块消失。
8.4 编辑区里的冲突标记
如果直接打开有冲突的文件(没用合并工具),你会看到 Git 的标准冲突标记:
text
<<<<<<< HEAD
print("这是你本地的代码")
=======
print("这是远程同事的代码")
>>>>>>> origin/main
含义:
| 标记 | 含义 |
|---|---|
<<<<<<< HEAD |
冲突开始,下面是你本地的版本 |
======= |
分隔线 |
>>>>>>> origin/main |
冲突结束,上面是远程的版本 |
PyCharm 的便捷处理:在这种文件里,代码块左侧会显示小图标,点击后弹出菜单:
| 菜单项 | 作用 |
|---|---|
Accept Yours |
保留上面那块(你的) |
Accept Theirs |
保留下面那块(远程的) |
Accept Both |
两块都保留(注意顺序) |
选完后记得手动删除 <<<<<<<、=======、>>>>>>> 这三行标记,否则文件语法就坏了。
⚠️ 常见事故 :忘了删冲突标记就提交了,结果代码里残留
<<<<<<<导致程序报SyntaxError。提交前搜一下这几个符号确认清干净。
8.5 完成合并与放弃合并
完成合并:
- 所有冲突文件都处理完(文件颜色恢复正常);
- 打开 Commit 窗口,确认没有残留冲突文件;
Ctrl+K提交,Ctrl+Shift+K推送。
放弃合并(回到合并前):
| 方式 | 操作 |
|---|---|
| 菜单 | Git → Merge / Rebase → Abort Merge (或 Abort Rebase) |
| 命令行 | git merge --abort / git rebase --abort |
| Git 窗口 | 合并进行中时,Log 顶部会有横幅,点 Abort |
💡 合并到一半想重来 :
Abort会把工作区恢复到合并前的状态,你自己的改动不会丢(因为你的改动本来就是已提交的),放心用。
九、查看历史与追责
PyCharm 的历史查看功能比命令行强很多,日常排查问题非常依赖它。
| 功能 | 入口 | 作用 | 等价命令 |
|---|---|---|---|
| 提交历史 | Alt+9(Git 窗口) |
看所有提交、分支图 | git log --graph --oneline |
| 按用户过滤 | Git 窗口 User 下拉 |
只看某人的提交 | git log --author=xxx |
| 按路径过滤 | Git 窗口 Paths 下拉 |
只看某个文件/目录的历史 | git log -- <path> |
| 搜索提交 | Git 窗口搜索框 | 按信息/哈希搜索 | git log --grep=xxx |
| 文件历史 | 右键文件 → Git → Show History |
该文件的全部变更记录 | git log --follow <file> |
| 行的历史(Blame) | 编辑器左侧栏右键 → Annotate with Git Blame |
逐行显示「谁在哪个提交改的」 | git blame <file> |
| 查看某行所属提交 | Blame 模式下点行号 | 弹出该提交详情 | --- |
| 查看某次提交的详情 | Git 窗口选中提交 → 右侧文件列表 | 看这次改了哪些文件 | git show <hash> |
| 查看文件差异 | 右键文件 → Git → Show Diff |
与 HEAD 对比 | git diff <file> |
| 比较两个提交 | Git 窗口选中两个提交(Ctrl 多选)→ Compare Versions |
差异对比 | git diff <a> <b> |
| 复制提交哈希 | 右键提交 → Copy Revision Number |
拿到完整哈希 | --- |
💡 Blame 的实战价值 :线上出了 bug,想知道「这行代码是谁什么时候为什么加的」------Blame 一开,立刻定位到提交和作者,然后看那个提交的完整改动和提交信息,排查效率极高。
💡 Annotate 颜色深浅 :PyCharm 的 Blame 视图里,越早的提交颜色越浅、越新的越深(可调),能快速看出哪些代码是「老代码」哪些是「最近才改的」。
十、撤销与回滚(最容易出事的一章)
这一章是全文最需要谨慎的部分。很多「代码丢了」的惨案都源于搞错了回滚方式。
先记住这张决策图:
#mermaid-svg-h6vRFS7JWvPuqYkR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-h6vRFS7JWvPuqYkR .error-icon{fill:#552222;}#mermaid-svg-h6vRFS7JWvPuqYkR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-h6vRFS7JWvPuqYkR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-h6vRFS7JWvPuqYkR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-h6vRFS7JWvPuqYkR .marker.cross{stroke:#333333;}#mermaid-svg-h6vRFS7JWvPuqYkR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-h6vRFS7JWvPuqYkR p{margin:0;}#mermaid-svg-h6vRFS7JWvPuqYkR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR .cluster-label text{fill:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR .cluster-label span{color:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR .cluster-label span p{background-color:transparent;}#mermaid-svg-h6vRFS7JWvPuqYkR .label text,#mermaid-svg-h6vRFS7JWvPuqYkR span{fill:#333;color:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR .node rect,#mermaid-svg-h6vRFS7JWvPuqYkR .node circle,#mermaid-svg-h6vRFS7JWvPuqYkR .node ellipse,#mermaid-svg-h6vRFS7JWvPuqYkR .node polygon,#mermaid-svg-h6vRFS7JWvPuqYkR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-h6vRFS7JWvPuqYkR .rough-node .label text,#mermaid-svg-h6vRFS7JWvPuqYkR .node .label text,#mermaid-svg-h6vRFS7JWvPuqYkR .image-shape .label,#mermaid-svg-h6vRFS7JWvPuqYkR .icon-shape .label{text-anchor:middle;}#mermaid-svg-h6vRFS7JWvPuqYkR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-h6vRFS7JWvPuqYkR .rough-node .label,#mermaid-svg-h6vRFS7JWvPuqYkR .node .label,#mermaid-svg-h6vRFS7JWvPuqYkR .image-shape .label,#mermaid-svg-h6vRFS7JWvPuqYkR .icon-shape .label{text-align:center;}#mermaid-svg-h6vRFS7JWvPuqYkR .node.clickable{cursor:pointer;}#mermaid-svg-h6vRFS7JWvPuqYkR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-h6vRFS7JWvPuqYkR .arrowheadPath{fill:#333333;}#mermaid-svg-h6vRFS7JWvPuqYkR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-h6vRFS7JWvPuqYkR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-h6vRFS7JWvPuqYkR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-h6vRFS7JWvPuqYkR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-h6vRFS7JWvPuqYkR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-h6vRFS7JWvPuqYkR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-h6vRFS7JWvPuqYkR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-h6vRFS7JWvPuqYkR .cluster text{fill:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR .cluster span{color:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-h6vRFS7JWvPuqYkR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-h6vRFS7JWvPuqYkR rect.text{fill:none;stroke-width:0;}#mermaid-svg-h6vRFS7JWvPuqYkR .icon-shape,#mermaid-svg-h6vRFS7JWvPuqYkR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-h6vRFS7JWvPuqYkR .icon-shape p,#mermaid-svg-h6vRFS7JWvPuqYkR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-h6vRFS7JWvPuqYkR .icon-shape .label rect,#mermaid-svg-h6vRFS7JWvPuqYkR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-h6vRFS7JWvPuqYkR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-h6vRFS7JWvPuqYkR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-h6vRFS7JWvPuqYkR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 你想撤销什么?
还没提交的改动
已经提交但没推送
已经提交且推送了
Rollback
丢弃本地改动
Undo Commit
或 Reset Soft/Mixed
Revert Commit
生成反向提交
安全:不影响他人历史
会重写历史
需强推,慎用
10.1 撤销未提交的改动(Rollback)
场景:你改了代码,但改乱了,想恢复到上次提交的样子。
操作步骤:
Alt+0打开 Commit 窗口;- 右键那个文件 →
Rollback; - 弹出确认框,点
Rollback; - 文件恢复到上次提交的状态。
等价命令行:
bash
git restore <file> # 新版命令(推荐)
git checkout -- <file> # 旧版命令
⚠️ Rollback 不可恢复! 因为改动从没进过 Git ,回滚后就真的没了。如果改动重要,先 commit 再回滚(或者先 stash),至少让它进过 Git 才好找回。
10.2 撤销已提交的内容(三种方式)
| 方式 | 入口 | 效果 | 是否重写历史 | 安全性 |
|---|---|---|---|---|
Undo Commit |
Git 窗口右键最后一次提交 | 撤销提交,改动回到暂存区 | 是(本地) | ⚠️ 仅未推送时用 |
Revert Commit |
Git 窗口右键任意提交 | 新增一个反向提交抵消它 | ❌ 否 | ✅ 安全,推荐 |
Reset Current Branch to Here |
Git 窗口右键提交 | 把分支指针移到该提交 | 是 | ⚠️ 危险 |
① Undo Commit(撤销提交,改动保留)
Alt+9打开 Git 窗口;- 右键最上面那次提交(必须是最后一次);
- 选择
Undo Commit; - 提交被撤销,文件改动回到 Commit 窗口的暂存区,可以重新修改后再提交。
等价命令:git reset --soft HEAD~1
② Revert Commit(安全回滚,团队协作首选)
- Git 窗口里找到要回滚的那次提交;
- 右键 →
Revert Commit; - 若该提交与当前代码有冲突,会进入第八章的合并流程;
- 完成后会产生一个新的提交,内容是把原提交的改动反向抵消。
为什么推荐 Revert? 因为它不重写历史 ,别人 pull 一下就同步了,不会造成团队混乱 。这就是为什么在公共分支上回滚线上 bug,标准做法是 git revert 而不是 git reset。
等价命令:git revert <hash>
③ Reset Current Branch to Here(危险,慎用)
- Git 窗口里右键目标提交;
- 选择
Reset Current Branch to Here...; - 在弹出的对话框里选择模式:
| 模式 | 效果 | 等价命令 |
|---|---|---|
Soft |
移动指针,改动保留在暂存区 | git reset --soft <hash> |
Mixed |
移动指针,改动保留在工作区(未暂存) | git reset --mixed <hash> |
Hard |
移动指针,丢弃所有改动 | git reset --hard <hash> |
Keep |
移动指针,保留未提交改动(不覆盖) | git reset --keep <hash> |
⚠️
Hard模式极其危险 :目标提交之后的所有改动全部消失 。虽然能用 reflog 找回,但过程麻烦。执行前务必确认没有未推送的重要提交。
10.3 危险操作对照表
把这张表贴在显眼位置,操作前对照一下:
| 操作 | 影响范围 | 可恢复性 | 团队影响 |
|---|---|---|---|
Rollback(未提交改动) |
仅本地未提交内容 | ❌ 无法恢复 | 无 |
Undo Commit |
本地最后一次提交 | ✅ reflog 可找回 | 仅未推送时无影响 |
Amend |
重写最后一次提交 | ✅ reflog 可找回 | ⚠️ 已推送则影响他人 |
Revert Commit |
新增反向提交 | ✅ 完全安全 | ✅ 无不良影响 |
Reset --soft/--mixed |
本地提交历史 | ✅ reflog 可找回 | ⚠️ 已推送会分叉 |
Reset --hard |
本地提交 + 工作区改动 | ⚠️ 提交可 reflog 找回,未提交改动永久丢失 | ⚠️⚠️ 已推送则严重 |
Push --force |
远程历史 | ⚠️ 可能丢失他人提交 | 🔴 严重,可能被团队骂 |
Rebase(公共分支) |
重写已推送历史 | ⚠️ 麻烦 | 🔴 严重 |
| 删除分支(未推送) | 本地分支引用 | ✅ reflog 可找回 | 无 |
🔴 三条铁律:
- 已推送到公共分支的提交,永远不要
rebase或reset;- 强推用
--force-with-lease,永不用--force;- 回滚线上问题时,用
Revert而不是Reset。
10.4 用 reflog 找回误删的提交
救命技能 :即使你 Reset --hard 或误删了分支,只要提交还在 Git 的「回收站」(reflog)里,就能找回来。
PyCharm 没有 reflog 的图形界面 ,需要用内置 Terminal(Alt+F12):
bash
# 1. 查看所有 HEAD 的移动历史(这就是「回收站」)
git reflog
# 输出示例(最上面是最新的):
# a1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~2
# e4f5g6h HEAD@{1}: commit: feat: 新增订单导出功能
# i7j8k9l HEAD@{2}: commit: fix: 修复金额计算错误
bash
# 2. 找到你要恢复的提交哈希(例如 e4f5g6h),把它恢复成一个新分支
git branch rescue e4f5g6h
# 3. 切过去看看内容是不是你要的
git checkout rescue
# 4. 确认无误后,合并回主分支(或直接重置主分支到该提交)
git checkout main
git merge rescue
恢复误删的分支(同样原理):
bash
# 找到该分支最后一次提交的哈希(用 reflog 或 git log --all)
git branch 被删的分支名 <那个哈希>
💡 reflog 的保留期限 :默认保留 90 天 (不可达对象 30 天)。所以尽快找回 ,别拖太久。而且 reflog 是纯本地的------如果你还没推送,又过了期限,就真没了。
十一、储藏 Stash 与 Shelve
场景 :你在 feature/a 分支写了一半,突然要紧急切到 main 修 bug,但不想提交半成品代码。
解决方案:把当前改动「暂存到一边」。
11.1 Stash(Git 原生储藏)
操作步骤:
- 菜单
Git→Uncommitted Changes→Stash Changes...; - 填写一个能看懂的名字(如
登录功能的半成品); - 可选勾选
Include untracked files(是否也储藏未跟踪的新文件); - 点
Create Stash; - 工作区恢复到干净状态,可以自由切分支了。
恢复 Stash:
| 操作 | 菜单路径 | 效果 | 等价命令 |
|---|---|---|---|
Unstash Changes |
Git → Uncommitted Changes → Unstash Changes... |
恢复并保留 stash | git stash apply |
| 恢复后删除 | 在 Unstash 对话框里勾选 Drop stash |
恢复并删除该 stash | git stash pop |
| 查看 stash 列表 | Git 窗口 → Stashes 节点 |
列出所有储藏 | git stash list |
| 删除某个 stash | Git 窗口右键 stash → Drop |
删除 | git stash drop |
| 查看 stash 内容 | Git 窗口右键 stash → Show Diff |
看它改了什么 | git stash show -p |
#mermaid-svg-LMmmBvyJbk6eqJBh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LMmmBvyJbk6eqJBh .error-icon{fill:#552222;}#mermaid-svg-LMmmBvyJbk6eqJBh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LMmmBvyJbk6eqJBh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LMmmBvyJbk6eqJBh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LMmmBvyJbk6eqJBh .marker.cross{stroke:#333333;}#mermaid-svg-LMmmBvyJbk6eqJBh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LMmmBvyJbk6eqJBh p{margin:0;}#mermaid-svg-LMmmBvyJbk6eqJBh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh .cluster-label text{fill:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh .cluster-label span{color:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh .cluster-label span p{background-color:transparent;}#mermaid-svg-LMmmBvyJbk6eqJBh .label text,#mermaid-svg-LMmmBvyJbk6eqJBh span{fill:#333;color:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh .node rect,#mermaid-svg-LMmmBvyJbk6eqJBh .node circle,#mermaid-svg-LMmmBvyJbk6eqJBh .node ellipse,#mermaid-svg-LMmmBvyJbk6eqJBh .node polygon,#mermaid-svg-LMmmBvyJbk6eqJBh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LMmmBvyJbk6eqJBh .rough-node .label text,#mermaid-svg-LMmmBvyJbk6eqJBh .node .label text,#mermaid-svg-LMmmBvyJbk6eqJBh .image-shape .label,#mermaid-svg-LMmmBvyJbk6eqJBh .icon-shape .label{text-anchor:middle;}#mermaid-svg-LMmmBvyJbk6eqJBh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LMmmBvyJbk6eqJBh .rough-node .label,#mermaid-svg-LMmmBvyJbk6eqJBh .node .label,#mermaid-svg-LMmmBvyJbk6eqJBh .image-shape .label,#mermaid-svg-LMmmBvyJbk6eqJBh .icon-shape .label{text-align:center;}#mermaid-svg-LMmmBvyJbk6eqJBh .node.clickable{cursor:pointer;}#mermaid-svg-LMmmBvyJbk6eqJBh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LMmmBvyJbk6eqJBh .arrowheadPath{fill:#333333;}#mermaid-svg-LMmmBvyJbk6eqJBh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LMmmBvyJbk6eqJBh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LMmmBvyJbk6eqJBh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LMmmBvyJbk6eqJBh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LMmmBvyJbk6eqJBh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LMmmBvyJbk6eqJBh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LMmmBvyJbk6eqJBh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LMmmBvyJbk6eqJBh .cluster text{fill:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh .cluster span{color:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LMmmBvyJbk6eqJBh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LMmmBvyJbk6eqJBh rect.text{fill:none;stroke-width:0;}#mermaid-svg-LMmmBvyJbk6eqJBh .icon-shape,#mermaid-svg-LMmmBvyJbk6eqJBh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LMmmBvyJbk6eqJBh .icon-shape p,#mermaid-svg-LMmmBvyJbk6eqJBh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LMmmBvyJbk6eqJBh .icon-shape .label rect,#mermaid-svg-LMmmBvyJbk6eqJBh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LMmmBvyJbk6eqJBh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LMmmBvyJbk6eqJBh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LMmmBvyJbk6eqJBh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Stash Changes
切分支 / 修 bug / 切回来
勾选 Drop stash
半成品改动
储藏区
Stash
Unstash Changes
改动回到工作区
储藏条目被删除
💡 Stash 是 Git 原生的 ,存在
.git里,任何 Git 工具都能看到(命令行、其他 IDE、TortoiseGit)。
11.2 Shelve(PyCharm 私有暂存)
PyCharm 还有个自己的功能叫 Shelve Changes:
| 对比项 | Stash(Git 原生) | Shelve(PyCharm 私有) |
|---|---|---|
| 存储位置 | .git(Git 原生) |
.idea/shelf(PyCharm 自己的文件) |
| 其他工具可见 | ✅ 命令行、其他 IDE 都能看到 | ❌ 只有 PyCharm 能识别 |
| 是否进 Git 历史 | 有一定关联 | 完全不进 Git |
| 能否按文件部分暂存 | ❌ 整体储藏 | ✅ 可只 shelve 部分文件 |
| 推荐度 | ⭐⭐⭐⭐⭐ 跨工具通用 | ⭐⭐⭐ 仅 PyCharm 内用 |
菜单路径 :Git → Uncommitted Changes → Shelve Changes...
💡 什么时候用 Shelve :只想在 PyCharm 内临时放一下、且不想污染 Git 时用。但团队协作中推荐 Stash,因为同事用命令行能看懂。
十二、.gitignore 与忽略文件不生效
12.1 创建 .gitignore
操作步骤:
- 右键项目根目录 →
New→File; - 文件名输入
.gitignore; - PyCharm 会弹出模板选择 ,可以选
Python模板; - 按需调整内容后提交。
12.2 Python 与 PyCharm 项目常用忽略项
text
# ---------- Python ----------
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
dist/
*.egg-info/
.eggs/
# ---------- 虚拟环境 ----------
venv/
.venv/
env/
ENV/
.python-version
# ---------- PyCharm / IDE ----------
.idea/
*.iml
*.iws
*.ipr
out/
# ---------- 测试与覆盖率 ----------
.pytest_cache/
.coverage
htmlcov/
.tox/
.mypy_cache/
.ruff_cache/
# ---------- 环境变量与密钥 ----------
.env
.env.local
*.pem
*.key
# ---------- 数据与模型(按需)----------
data/
logs/
*.log
*.pth
*.ckpt
*.h5
# ---------- 系统文件 ----------
.DS_Store
Thumbs.db
desktop.ini
⚠️
.idea/到底要不要忽略?
- 纯个人项目:忽略掉,清爽;
- 团队项目 :视情况------如果团队想共享运行配置、代码风格设置,可以只忽略
.idea/workspace.xml而保留其他(如codeStyles/、inspectionProfiles/)。- 注意:
.idea/*.iml、.idea/workspace.xml几乎必忽略(含个人环境信息)。
12.3 已跟踪文件的忽略失效(重点)
问题 :你在 .gitignore 里加了 config.py,但 PyCharm 里它还是蓝色的(还是被跟踪)。为什么?
原因 :.gitignore 只对「未跟踪」的文件生效 。如果文件已经被提交过 ,它就已经在 Git 的跟踪列表里了,.gitignore 对它无效。
解决办法 :需要先把它从 Git 索引中移除(但保留本地文件):
bash
# --cached 表示只从 Git 索引移除,不删本地文件
git rm --cached config.py
# 如果是整个目录
git rm -r --cached .idea/
# 然后提交这次「移除」操作
git commit -m "chore: 停止跟踪 config.py"
在 PyCharm 里操作:
- 确保
.gitignore已写好规则; Alt+F12打开 Terminal,执行上面的git rm --cached命令(这一步必须用命令行,界面没有直接等价操作);- 回到 Commit 窗口,会看到该文件显示为「已删除」,勾选并提交。
⚠️ 千万注意别漏
--cached!如果敲成git rm config.py,会把本地文件一起删掉。
12.4 临时忽略本地文件(不进仓库)
场景 :你本机有个文件想忽略,但不想改 .gitignore 影响同事。
办法 :用 .git/info/exclude(本地私有忽略规则,不进版本控制)。
PyCharm 里的便捷做法 :右键文件 → Git → Add to .gitignore (添加到项目级规则)或选择加到 .git/info/exclude(仅本地)。
💡 如果文件已经被跟踪,右键菜单里会看到
Add to .gitignore后仍需git rm --cached,PyCharm 会给出提示。
十三、进阶功能
13.1 内置 Terminal 直接用命令
按 Alt+F12 (macOS ⌥F12)打开,它与 PyCharm 的 Git 集成共享同一个仓库状态------你在命令行提交后,界面会立即刷新。
适用场景:
- 界面没有的复杂操作(
git reflog、git worktree、git submodule); - 想用
git log --oneline --graph --all这种自定义格式; - 执行批量操作(
git add -A、循环处理多个仓库)。
💡 配置默认 Shell :
Settings→Tools→Terminal→Shell path,Windows 上可填C:\Program Files\Git\bin\bash.exe换成 Git Bash。
13.2 Cherry-Pick(挑一个提交搬过来)
场景 :同事在别的分支修了个 bug,你只想把这一个提交拿过来,不想合并整个分支。
操作步骤:
Alt+9打开 Git 窗口,先切到接收方分支;- 在 Log 里找到那个目标提交(可通过
Branches下拉切到同事分支查看); - 右键 →
Cherry-Pick; - 如有冲突按第八章解决,然后提交。
等价命令:git cherry-pick <hash>
⚠️ Cherry-Pick 会产生新的哈希 ,原提交仍然存在。频繁 cherry-pick 会导致同一改动在多分支重复出现,后续合并时容易冲突。能合并就合并,cherry-pick 是应急手段。
13.3 Tag(标签)
打标签 :Alt+9 → 右键某次提交 → New Tag... → 输入标签名(如 v1.0.0)→ 可填注释 → OK。
推送标签 :Ctrl+Shift+K 打开 Push 对话框时勾选 Push tags;或在 Terminal 里执行:
bash
git push origin --tags
查看/删除标签 :Git 窗口的 Tags 节点下可查看,右键可删除或签出。
13.4 Patch(补丁文件)
创建补丁 :Git 窗口右键提交 → Create Patch... → 保存为 .patch 文件。
应用补丁 :菜单 Git → Apply Patch... → 选择 .patch 文件。
适用场景:不能直接推送代码时(如内网环境),用补丁文件传递改动;或给开源项目提修改建议。
13.5 GitHub 插件提 PR
已登录 GitHub 账号后(见 3.1):
- 创建 PR :菜单
Git→GitHub→Create Pull Request;或在 Git 窗口右键分支 →Create Pull Request; - 查看 PR :
Git→GitHub→View Pull Requests,可以在 IDE 内评论、审查、合并; - 拉取 PR 到本地 :在 PR 列表里右键 →
Checkout Branch。
💡 这就是专业版/社区版都有的实用功能------不用切浏览器来回看 PR 了。
13.6 多仓库项目与子模块
| 场景 | PyCharm 处理方式 |
|---|---|
| 一个窗口多个仓库 | Settings → Version Control → Directory Mappings → + 添加更多仓库根目录 |
| 只做只读浏览 | 在 Directory Mappings 里可配置某个目录不被 VCS 管理(减少索引压力) |
| Git Submodule | Git 窗口会显示 Submodules 节点,可 Update / Init;复杂操作用 Terminal |
| Git Worktree | PyCharm 无图形支持,用 Terminal 操作 |
十四、常见问题 FAQ
Q1:PyCharm 提示 Git is not installed,但命令行能用?
不是没装,是 PyCharm 找不到路径。Settings → Version Control → Git → 手动指定 C:\Program Files\Git\cmd\git.exe(Windows),点 Test 验证通过即可。
Q2:提交时报 Please tell me who you are?
没配用户名邮箱。Settings → Version Control → Git 里填 Name 和 Email,或 Terminal 执行 git config --global user.name/user.email。
Q3:推送报 Authentication failed?
GitHub 已废弃密码认证,必须改用 Personal Access Token 或 SSH 密钥 。检查 Settings → Version Control → GitHub 里的账号是否有效,或改成 SSH 地址(git@github.com:...)。
Q4:推送报 Push rejected: non-fast-forward?
远程有你没有的提交。在弹窗里点 Merge 或 Rebase (一键完成拉取+推送),或手动 Ctrl+T 更新后再推。
Q5:.gitignore 加了但文件还是被跟踪?
因为文件已被提交过 。执行 git rm --cached <file> 从索引移除(保留本地文件)后提交。
Q6:切分支提示 Your local changes would be overwritten?
本地有未提交改动。选 Smart Checkout (自动 stash 再恢复)比较方便;或者先手动 Stash Changes 再切,最稳妥。
Q7:误删了分支/误 reset 了代码,能找回吗?
能。在 Terminal 用 git reflog 找到提交哈希,然后 git branch <name> <hash> 恢复。reflog 默认保留 90 天,但要尽快操作。
Q8:想修改上次提交的信息怎么办?
Commit 窗口勾选 Amend 后重新提交,或 Git 窗口右键最后一次提交 → Edit Commit Message。⚠️ 若已推送,改完需要强推,会影响他人。
Q9:文件颜色一直是红色,怎么变成已跟踪?
红色=未版本控制。在文件上右键 → Git → Add (等价 git add <file>),或直接在 Ctrl+K 提交时勾选它。
Q10:PyCharm 变得很卡,Git 索引慢怎么办?
Settings → Version Control → 在 Directory Mappings 里排除大目录 (如 data/、node_modules/、虚拟环境);也可在项目视图里右键大文件夹 → Mark Directory as → Excluded;必要时减少 Version Control 里注册的根目录数量。
Q11:中文文件名显示为 \344\270\255 这种乱码?
Git 默认对非 ASCII 文件名做转义。在 Terminal 执行:
bash
git config --global core.quotepath false
即可正常显示中文文件名。
Q12:提交信息里的中文乱码?
执行 git config --global i18n.commitEncoding utf-8 和 git config --global i18n.logOutputEncoding utf-8。另外确认 PyCharm 的 Settings → Editor → File Encodings 全部设为 UTF-8。
Q13:Windows 上总提示 CRLF/LF 换行符警告?
执行 git config --global core.autocrlf true(Windows 推荐),并可在项目里加 .gitattributes 统一换行符规则。
Q14:推送大文件失败?
GitHub 单文件上限 100MB。方案:用 Git LFS (git lfs track "*.pth")管理大文件,或把数据/模型文件加入 .gitignore。
Q15:能同时推送到多个远程仓库吗?
可以。Terminal 执行 git remote set-url --add --push origin <第二个地址>,或在 Git 窗口右键 Remote → Manage Remotes 添加。之后一次 push 会推到所有配置的地址。
Q16:怎么只提交文件里的部分改动?
Ctrl+K 打开 Commit 窗口 → 双击文件打开 Diff → 在左侧勾选具体的代码块 或行 → 提交。等价于 git add -p。
Q17:合并时不小心点了 Accept Yours,同事的改动没了怎么办?
别慌,别提交。用 Git → Merge → Abort Merge 放弃本次合并,回到合并前状态,重新用 Merge 手动处理。
Q18:Update Project 和 Pull 有什么区别?
Update Project(Ctrl+T)是 PyCharm 的推荐方式,支持 Merge/Rebase 选择、支持 Smart Update 自动 stash;Pull 更接近裸 git pull。日常用 Ctrl+T 就好。
十五、快捷键速查表
Windows / Linux:
| 功能 | 快捷键 |
|---|---|
| 提交 Commit | Ctrl+K |
| 推送 Push | Ctrl+Shift+K |
| 更新项目 Update Project | Ctrl+T |
| Commit 工具窗口 | Alt+0 |
| Git 工具窗口(Log) | Alt+9 |
| 内置 Terminal | Alt+F12 |
| VCS 操作弹出菜单 | Alt+`` (Alt + 反引号) |
| Find Action(万能搜索) | Ctrl+Shift+A |
| 打开设置 | Ctrl+Alt+S |
| 撤销(编辑器) | Ctrl+Z |
macOS:
| 功能 | 快捷键 |
|---|---|
| 提交 Commit | ⌘K |
| 推送 Push | ⌘⇧K |
| 更新项目 Update Project | ⌘T |
| Commit 工具窗口 | ⌘0 |
| Git 工具窗口(Log) | ⌘9 |
| 内置 Terminal | ⌥F12 |
| VCS 操作弹出菜单 | ⌥`` (Option + 反引号) |
| Find Action | ⌘⇧A |
| 打开设置 | ⌘, |
💡 忘记快捷键? 按
Ctrl+Shift+A(⌘⇧A)输入功能名(如push、rebase、stash),直接搜索并执行------这是 PyCharm 里最值得记住的一个快捷键。
💡 自定义快捷键 :Settings→Keymap→ 搜索功能名 → 右键Add Keyboard Shortcut。
十六、总结
最后把全文要点串起来:
- PyCharm 的 Git 集成只是「图形外壳」 ,底层调用的仍是你本机的 Git,所有操作与命令行完全等价,可随时混用;
- 第一步是配好 Git :
Settings→Version Control→Git指定git.exe路径(Windows 选cmd\git.exe)→ 点Test验证 → 填好用户名邮箱; - 五大会用区域必须记住 :
Alt+0提交窗口、Alt+9历史窗口、状态栏分支弹窗、编辑器颜色标记、Alt+F12命令行; - 日常四步循环 :改代码 →
Ctrl+K提交 →Ctrl+Shift+K推送 →Ctrl+T拉取更新; - 提交流程可精细控制 :能按文件勾选、按 changelist 分组、甚至按行级提交 (
git add -p); - 冲突解决是 PyCharm 的最大优势 :三窗格合并工具(左=你的、中=结果、右=远程),点箭头选择,比看
<<<<<<<舒服太多------别图省事点Accept Yours; - 回滚要分清三种情况 :未提交用
Rollback(不可恢复)、已提交未推送用Undo Commit、已推送用Revert Commit(安全首选); - 三条铁律 :公共分支不
rebase/reset、强推用--force-with-lease、回滚线上问题用Revert; reflog是救命稻草 :误删分支、误reset --hard都能找回,但要在 90 天内操作;.gitignore只对未跟踪文件生效 :已提交过的文件要先git rm --cached才能忽略;- 善用
Ctrl+Shift+A:忘记菜单在哪、忘记快捷键,搜一下就能执行------这是效率最高的入口; - 界面搞不定的复杂操作,直接
Alt+F12敲命令 :两者不是替代关系,而是互补。
🚀 上手建议 :先花 10 分钟把第二章(配置 Git 路径)+ 第五章(认识界面)过一遍,然后用一个自己的小项目走一遍完整流程------克隆 → 改代码 → 提交 → 推送 → 建分支 → 合并 → 故意制造一次冲突并解决。走完这一圈,PyCharm 的 Git 就算真正会用了。
配套阅读:
- 本工作区《Git 安装 + SSH 密钥配置超详细教程(全平台通用)》------装 Git、配 SSH 免密的前置步骤
- 本工作区《TortoiseGit 安装配置与完整使用教程》------纯图形化的另一种选择(右键菜单式)
- Git 官方文档:https://git-scm.com/doc
- PyCharm 官方 VCS 文档:https://www.jetbrains.com/help/pycharm/version-control-integration.html