在 PyCharm 里使用git

上一小节里介绍了 PyCharm 集成了哪些版本工具及常用的一些功能,其中一些功能介绍的比较简单,这小节将以 Git 为例,结合实际的工作场景,详细介绍在版本控制中常用功能。

1. 建立git 存储库

1.1 基于现有项目创建本地Git存储库

我们可以基于现有项目源创建本地 Git 存储库。将整个项目与单个 Git 存储库关联。

主菜单 VCS -> Enable Version Control Integration 或者 快捷键 ⌃V ( Ctrl + v) 在弹出窗口中选择 Enable Version Control Integration,选择 Git 作为版本控制系统,然后单击"确定"。

图片描述
启用 VCS 集成后,PyCharm 将询问您是否要通过 VCS 共享项目设置文件。您可以选择"Always Add"以与使用 PyCharm 的其他存储库用户同步项目设置。
图片描述
除此以外, 系统还提示创建 .gitgnore 文件,先直接创建。这个文件将用于记录那些排除在版本控制的文件。
图片描述

1.2 从远程主机(克隆)签出项目

主菜单: Preference/Settings -> Version Control -> GitHub, 输入用户名与密码,配置远程GitHub 帐户,确保登录成功。也可以选择其它版本工具。
图片描述
主菜单 VCS -> Get from Version Control, 选择选择主机与项目,克隆项目。
图片描述

1.3 增加文件到存储库

主菜单:PyCharm/File -> Preference/Settings -> Version Control -> Commit, 这样可以保证在Commit 窗口查看本地变化。
图片描述
可以在 View -> Tools -> Commit 工具窗口展开 Unversioned Files 节点, 选择要添加到 Gi的文件,然后按 ⌘⌥A (Ctrl + Alt + A) 或从上下文菜单中选择"Add to VCS"。也可以从 Project 工具选择要添加的文件,按 ⌘⌥A 或从上下文菜单中选择"Add to VCS"。(加到存储库的文件颜色由红色变为绿色)
图片描述

1.4 从版本控制中排除文件(ignore)

有时需要把一些文件排除在版本控制之外。这些文件可能是 VCS 管理文件、备份副本等。

Git 提供了两种配置文件中列出忽略的文件模式:

  1. .git/info/exclude file
    此文件中列出的模式仅适用于存储库的本地副本。当初始化或签出 Git 存储库时,将自动创建此文件。

  2. VCS 根目录 .gitignore 文件。
    这些文件被签入存储库,整个团队都可用其中忽略模式。因此,它是存储忽略的文件模式的最常见位置。上面在创建 Git 存储库时,就会提示创建这个文件,然后默认会创建在根目录。也可手动在Project 窗口中的任意位置右键单击, 选择 New -> File 和在 New File 对话框中键入.gitignore。

在 Local Changes 窗口 or Project 工具窗口,选择文件右击 Git -> Add to .gitignore or Git -> Add to .git/info/exclude。选择的文件将被填加对应配置文件当中。
图片描述

1.5 增加远程存储库

为了能够协作处理 Git 项目,您需要配置从中获取数据的远程存储库,并在需要共享工作时推送到这些存储库。我们在本地源创建了 Git 存储库,则需要为其他参与者添加一个远程存储库,以便能够将其更改推送到该存储库,并且能够共享工作的结果。

比如添加远程 GitHub 存储库,打开要共享的项目,VCS -> Import into Version Control -> Share Project on GitHub。前面的步骤我们已经了在 PyCharm 中注册了 Github 帐户,系统会自动 建立与 GitHub 的连接后,需要指定远程存储库名称、远程 的名称,并输入项目的说明。如果您不想允许其他 GitHub 用户公开访问存储库,可以选择"Private "选项。点击共享后,选择初次需要提交的文件就可以了。
图片描述
查看Github 网站,新的存储库被创建,我们选择的三个文件也被上传成功了。
图片描述
在某些情况下,您还需要添加第二个远程存储库。例如,如果克隆了一个没有写入访问权限的存储库,并且要将更改推送到自己的原始项目的分叉,这可能很有用。

主菜单 VCS -> Git -> Remotes, Git Remotes 对话框将被打开,此时可以增加新的远程连接。
图片描述

2. Pull 、Fetch 与 Update 项目

三者都用于更新代码,在前一小节已经讲解了三者的不同,在这不再详述。 这里分别演示一下三种方式更新代码的效果。

2.1 Pull Changes

在GitHub 编辑 rectangle.py 文件 (实际工作中,通常是团队成员更新了文件,然后 Push 到GitHub, 基本不会直接在GitHub 上更新)
图片描述
右键上下文菜单选择 Git -> Repository -> Pull , 本地文件会被直接更新。
图片描述

2.2 Fetch Change

在GitHub 编辑 rectangle.py 文件
图片描述
右键上下文菜单选择 Git -> Repository -> Fetch , 本地文件没有被直接更新。改变是被作为远程分支存储的,本地文件与远程分支比较 VCS -> Git -> Branches... 选择origin/master -> Compare with Current,在 版本控制工具 Git 查看异同,如果接受改变,然后VCS -> Git -> Branches... 选择origin/master -> Merge with Current。
图片描述

2.3 Update Change

如果整个项目有两个分支,master 与 xuxh, 在Github 分别在 两个分支上更新代码。
图片描述
切换到 xuxh 分支,修改代码。
图片描述
主菜单选择 VCS -> Update Project 或者 点击工具栏上的 Update Project 按钮, Event log 工具窗回会显示更新状态,本地master 作为当前分支,文件直接被更新。
图片描述
切换到xuxh 分支 VCS -> Git -> Branches... 选择 xuxh -> Check out,查看文件并没有被更新,相当执行了Fetch 操作。在合并之前先查看不同,然后再merge。图片描述

3. 本地更改的提交与推送(Commit and Push)

Git 需要用户名才能将提交与标识关联。如果尚未设置用户名,PyCharm 将在首次尝试提交更改时提示您指定它。

若要为计算机上的每个 Git 存储库设置名称

git config --global user.name "xuxh"

若要为单个存储库设置名称

git config user.name "xuxh"

3.1 提交本地更改

主菜单 VCS -> View -> Tool Windows -> Commit,选择要提交的文件或者changelist, 填写提交信息,选择 commit 或者 Amend Commit

图片描述
通过工具栏上按钮,可以Rollback 代码,可以比较文件,也可以设置提交前与提交后的操作。
图片描述
有时候我们可能只想提交部分文件更改,比如在 test_rectangle.py, 增加了两个方法 test_width 与 test_height, 然后只提交 test_width。未选择的改变仍然在当前的Changelist 里。
图片描述
除此以外,也可以将一个文件更改放入不同的更改列表,以实现文件的部分提交。
图片描述

3.2 将更改推送到远程存储库

在推送更改之前,请与远程同步,并确保存储库的本地副本是最新的,以避免冲突。PyCharm 允许将更改从任何分支上载到其跟踪的分支或任何其他远程分支。

要推送当前分支的更改, 主菜单 VCS -> Git -> Push, Push Commits 对话框将显示。
图片描述
关于Force Push 的应用场景,当你运行 push 时,如果远程存储库在你上次拉取最新代码后又有 更新,则 Git 将拒绝完成 Push 操作。此时选择Force Push 会用本地复本覆盖远程存储库。通常我们是不建议这样用Force Push 的,而应执行拉取与远程同步,然后才能使用更改进行更新。

4. 查看 Git 存储库中的更改

  1. 查看项目历史记录
    View -> Tool Windows -> Git 工具窗口的日志选项卡。它显示提交到所有分支和远程存储库的所有更改。
    图片描述
  2. 查看两个提交之间的差异
    在 Git 工具窗口的"日志"选项卡中选择两个提交,然后从上下文菜单中选择 Compare Version,
    打开在所选提交之间修改的文件列表, 单独选择文件查看差异。
    图片描述
  3. 查看单个文件、目录修改历史

有多个入口可以查修改历史, 从 Project 工具栏 或者编辑器的上下文菜单选择 Show History,也可以从主菜单 VCS -> Git -> Show History
图片描述

5. 分支管理

在 Git 中,分支是一种强大的机制,我们可以创建不同工作分支应对不同的人与工作用途。通常,除了主分支 master 外,至少还会建立 develop, test 以及程序员自己的个人分支。

可以在 Git 工具窗口的 Branch 窗格中管理分支
图片描述

5.1 创建分支

Branches 弹出窗口或 Git 工具窗口的 Branches 窗格选择某一分支,然后选择 New Branch, 也可以从某一次 Commit 创建分支。

图片描述

5.2 在分支间切换

Branches 弹出窗口或 Git 工具窗口的 Branches 窗格中,选择要在本地分支下切换到的分支,然后从可用操作列表中选择 Checkout
图片描述

5.3 比较分支

  1. 将分支与当前分支进行比较

Branches 弹出窗口或 Git 工具窗口的 Branches 窗格中,选择要与当前分支进行比较的分支,右键上下文菜单选择Compare With Current 。新的选项卡将添加到 Git 工具窗口,列出所选分支中存在且当前分支中不存在的所有提交。若要查看两个分支中不同的所有文件的列表,请单击 ⌘A Ctrl + A, 更改的文件窗格将列出包含差异的所有文件。

图片描述
Tips: 可以单击 Swap branches 链接来更改哪个分支被视为比较其他分支的基础。

  1. 将分支与Working Tree 进行比较
    Working Tree 可以理解为当前分支的本地状态。如果您有本地未提交的更改,这非常有用。

Branches 弹出窗口或 Git 工具窗口的 Branches 窗格中,选择要与本地工作树进行比较的分支,然后选择 Show Diff with Working Tree。所选分支和当前分支的本地状态中不同的所有文件的列表将显示在单独的窗口中。
图片描述

5.4 删除分支

Branches 弹出窗口或 Git 工具窗口的 Branches 窗格中, 选择要删除的分支,然后选择 Delete 。
图片描述

6. 将更改从一个 Git 分支应用于另一个分支

6.1 Merge Branch

Branches 弹出窗口或 Git 工具窗口的 Branches 窗格中,选择目标分支,然后从可用操作列表中选择 Checkout

如果不需要为合并指定选项,请选择要合并到当前分支的分支,然后从子菜单选择 Merge into Current。如果工作树是干净的(没有未提交的更改),并且功能分支和目标分支之间没有冲突,Git 将合并两个分支,合并提交将显示在 Git 工具窗口中。
图片描述
如果需要为合并指定选项, 主菜单 VCS -> Git -> Merge Changes 去打开 Merge 对话框。
图片描述

6.2 Rebase 分支

正如他的名字所隐含的意思:rebase存在的价值是:对一个分支做“变基”操作,这意味着改变这个branch的初始commi。它会在新的base上一个一个地运行这个分支上的所有commits。这个概念理解起来可能稍微有点困难,请参考官网 git-rebase, 里面有更详尽的介绍。

比如当我试图将本地 xuxh 分支的改变 commit and push到remote对应分支时,被拒绝了,原因是自从上次和origin同步(通过git pull)后, remote xuxh分支又有了新的改变。这种情况下,如果我们强行将我们的代码push过去将会覆盖remote 分支上代码,而这往往是不允许的,所以push总会给出下面的提示

图片描述
点击Rebase, 弹出下面的 Conflicts 窗口, 通常都会选择 Merge… 。如果选择 Accept Yours, 相当于把本地代码强行推到远程分支,会覆盖远程分支上一些改变,选择 Accept Theirs, 相当于放弃本地的改变。

图片描述
选择Merge… , 下面的窗口会列出分支的不同
图片描述
根据代码的情况,进行合并,然后点击Apply, 查看本地代码,远程改变已经合并到本地。
图片描述
在event log 工具栏会看类似的信息:

**11:52 AM	Push rejected
				Push has been cancelled, because there were conflicts during update.
				Check that conflicts were resolved correctly, and invoke push again.
				View received commits**

第一次的Push 操作已经取消了, 上面的操作已经与远程分支同步了,此时再次 Push 代码就能正常了。

【注意】通常我们只建议在自己的私有分支上做rebase, 永远不要rebase一个已经分享的分支,比如rebase到master,develop,release分支上,如果几个人对同一个分支做了rebase 以后,会造成后来的push 与同步困难,还有许多相同的changeset。

前面讲了同一分支上的 rebase,我们也可以基于另一分支上作同样的“变基”操作,xuxh 个人分支是从master 创建的, 当我们在个人分支上开发的时候,master 分支可能一直在变化,此时可以通过rebase 把 master 最新代码 merge 到个人分支上。主菜单: VCS -> Git -> Rebase

图片描述
后面的操作与前面介绍的一致,会有 conflics 窗口弹出,然后 merge 代码,然后点击rebase。
rebase 成功后会在 Event log 显示类似的信息。

12:22 PM	Rebase Successful: Rebased xuxh on refs/heads/master

6.3 应用单独的更改

假设你对一个文件做了更改,现在想把这个更改应用到其它分支当中去。比如下面在xuxh分支的test_rectangle.py 增加一个新方法 test_resize_positive, 现在想应用到 master 分支
图片描述

  1. Branches 弹出窗口或 Git 工具窗口的 Branches 窗格中,选择目标分支master,然后从可用操作列表中选择 Checkout
  2. 然后选择xuxh 分支, 找到包含要应用的更改的提交。
  3. 在 Commit Details 面板右侧, 选择包含要应用于目标分支的更改的文件,然后在上下文菜单里选择 Apply Selected Changes
  4. 在弹出对话框中输入 changelist 名字。
  5. Commit and push 到目标分支。

图片描述

7. 小结

本小节应该是本课程内容最多的一节,详细讲述了在PyCharm里,如何使用Git进行版本管理,包括更新、提交代码,查看历史,如何进行分支合并等等。对于程序员来说,这几乎是每天都要做的事情,对于没用过任何版本控制工具同学来说,需要不断实践,在解决各种各样的情况过程中才能真正掌握,所以这可能需要一点时间。
图片描述