是程序员都可能用到版本控制,如何使用它?如何在Vim中使用Git?

版本控制是本章的重要内容之一。虽然本书选择的版本控制系统是Git,但是本章的知识也适用于其他版本控制系统。本章只提供了一节内容简略地介绍版本控制,如果读者想要更深入地了解,还需要有针对性地阅读相关材料,以精通自己需要的版本控制系统。

本章需要多次修改.vimrc文件,读者可以边阅读边修改,也可以从本书GitHub官方仓库PacktPublishing/Mastering-Vim中找到相关的设置代码。Git的安装和配置方法也可以在这个GitHub仓库中找到。

5.2 使用版本控制

本节以Git为示例讲解版本控制系统(Version Control System,VCS)

编写本书的时候,Git是最流行的版本控制系统。本节的建议也适用于读者选择的其他版本控制系统(或者读者被迫使用的VCS)。

现代的程序开发已经离不开版本控制了,只要是程序员,都有可能用到版本控制。本节将帮助读者回顾如何使用当前流行的版本控制系统Git。本章还将介绍如何在Vim中使用Git,使Git命令更直观和交互性。

5.2.1 版本控制和Git介绍

如果读者已经熟悉Git的相关知识,可以跳过本节。

Git可用于追踪文件修改的历史记录,并缓解多个用户同时工作于同一文件时的痛苦。Git是一个分布式版本控制系统,这意味着每个开发者在自己的系统里都拥有代码库的一个完整副本。

如果读者使用的是一个Debian系的Linux发行版,则可以通过如下命令安装Git。

$ sudo apt-get install git

对于其他系统,可以在Git官方网站上找到安装包的下载地址以及安装方法。在使用之前,读者需要配置用户名和邮件地址。

$ git config --global user.name 'Your Name'
$ git config --global user.email 'your@email'

Git安装成功。为了帮助用户解决问题,Git提供了相当详尽的文档(官网上还有很多教程)。查看Git文档的命令行如下。

$ git help

1.概念

Git用一系列的文件原子操作来表示文件的修改历史,这些原子操作在Git中称为提交(commit)。提交功能除了可以保存文件的变化,还包含额外添加的描述性消息,这样,读者就可以找到任意时间点的文件变动。

Git中提交的历史并不一定是线性的,它也可能是具有多个分支的图状结构,因此多个Git用户就可以独立地修改代码中的不同部分,而不用担心互相影响。比如,在下面的示例中(阅读顺序为由下向上),功能点A在主分支(master branch)中,而功能点B在一个平行的分支中,记为feature-b

* 将功能点B合并到主分支中
|\
* | 改进功能点A
| * 完成功能点B
| * 开始构建功能点B (feature-b分支)
|/
* 实现功能点A
* 初始提交 (主分支)

Git是一个分布式的版本控制系统,即不存在一个中心,每个开发者都拥有仓库(repository)的完整副本。

2.新建工程

本例采用的是官方仓库Chapter05/animal_farm中的代码。读者也可以使用自己的项目。创建好一个项目之后,可以按照下列步骤设置一个Git仓库。

(1)初始化Git仓库。

$ cd animal_farm/
$ git init

(2)将一个目录中的所有文件添加到暂存区(stage),为初始提交作准备。

$ git add 

(3)创建初始提交。

$ git commit -m "初始提交"

上述命令的结果如图5.1所示。

图5.1

现在,一个Git仓库就创建完成了。

如果读者想要将此仓库备份到其他机器上,可以考虑使用在线的Git服务,比如GitHub。在GitHub上创建一个新仓库的方法可参见GitHub官网。GitHub的仓库地址格式为https://github.com/<你的用户名>/animal-farm.git。然后,将GitHub上的这个远程仓库的地址添加到本地的仓库中去(这里的<url>换成GitHub仓库的地址)。

$ git remote add origin <url>

然后,读者将本地仓库推送(push)到远程仓库。

$ git push -u origin master

为了使两个仓库同步,每提交一次都需要重新推送,详细参见下面关于Git使用方法的介绍。

3.克隆一个已有仓库

如果读者已经在远程仓库(如GitHub)中保存有代码,那么只需要克隆(clone)一份到本地。找到远程仓库的地址,地址可能是HTTPS协议或SSH协议。执行下列命令将<url>换成仓库的地址。

$ git clone <url>

执行此命令后,本地机器上就有了以项目名称命名的目录,其中保存了仓库的内容。

本地仓库和远程仓库是相互独立的。如果读者想要在远程仓库被修改之后更新本地仓库,则可以在曾经复制过的本地仓库中执行git pull --rebase

4.使用Git

Git的命令是相当繁杂的,但初学者只需掌握几条基本命令。本节还是以前面新创建的仓库animal_farm/为例。

(1)添加文件、提交和推送

将文件animals/lion.py添加到仓库中。文件内容如下。

"""A lion."""

import animal

class Lion(animal.Animal):

    def __init__(self):
        self.kind = 'lion'

    def get_kind(self):
        return self.kind

接下来,在animal_farm.py中调用lion.py(添加粗体的部分)。

...
from animals import dog
from animals import lion
from animals import sheep
...
    if kind == 'dog':
        return dog.Dog()
    if kind == 'lion':
        return lion.Lion()
    if kind == 'sheep':
        return sheep.Sheep()
...

修改完成之后,可以通过如下命令查看文件的状态(查看哪些修改将会被提交)。

$ git status

此处显示animal_farm.py被修改,而且添加了新的文件animals/ lion.py,如图5.2所示。

图5.2

若要将文件保存到Git历史记录中,则需要将文件先存放到暂存区。可以添加单个文件。

$ git add <filename>

也可以添加整个当前目录。

$ git add .

执行git status可以看到暂存区中的内容,如图5.3所示。

图5.3

将一个或多个文件提交到历史记录中,可执行如下命令。

$ git commit -m "<informative message describing the changes>"

图5.4中显示了修改animals/lion.pyanimal_farm.py之后的提交结果。

图5.4

如果已经创建好远程仓库,则将修改推送到远程仓库的命令如下。

$ git push

假如有多个人使用同一个远程仓库,则与其他人保持同步的命令如下[多人协作时最好是先拉取(pull)再推送(push)]。

$ git pull --rebase

如果想查看提交历史,可执行如下命令。

$ git log

到目前为止,本节中的animal_farm仓库的git log结果如图5.5所示。

图5.5

图5.5中,顶部为最新的提交,底部为初始的提交。

如果读者在本地工作副本(working copy)拉取某一个特定的提交(如查看初始提交的情况),则可以执行如下命令(这里的<sha1>为提交ID,它是一个十六进制的字符串,图5.5中的初始提交的ID为e1fec4ab2d14ee331498b6e5b2f2cca5b39daec0)。

$ git checkout <sha1>

(2)创建和合并分支

不同的分支通常对应于工作中不同的功能。一旦某个功能成熟了,该分支就可以被合并到主分支(master)。创建一个新分支的命令如下。

$ git checkout -b <branch-name>

比如,下面的命令将创建一个关于新的动物类型的分支。

$ git checkout -b feature-leopard

其结果如图5.6所示。

图5.6

然后,读者就可以在这个分支上正常操作了。比如,添加一个新文件animals/leopard.py,并修改animal_farm.py,如图5.7所示。

图5.7

一旦该功能完善了(这里的leopard),就可以将分支feature-leopard合并到主分支(master)。查看所有分支的命令如下。

$ git branch -a

当前分支前面有一个星号(*),如图5.8所示。

图5.8

切换到其他分支的命令如下。

$ git checkout <branch-name>

在这里,回到主分支的命令如下。

$ git checkout master

回到主分支后,就可以将之前的新分支合并到主分支,命令如下。

$ git merge feature-leopard

合并分支的结果如图5.9所示。

图5.9


如果读者有GitHub仓库,那么修改完成之后要执行git push命令,这样,修改内容才能同步到远程仓库。

5.2.2 Git与Vim的整合(vim-fugitive)

Tim Pope的vim-fugitive插件可以使用户在不离开Vim的情况下进行Git操作。读者在使用Vim编辑文件时,也可以同时利用版本管理系统记录编辑的位置


如果使用vim-plug安装插件,则可以在.vimrc中添加Plug 'tpope/vim-fugitive',并执行命令:w | source $MYVIMRC | PlugInstall

vim-fugitive提供的许多命令都是对外部Git命令的镜像,然而,输出通常更具交互性。以git status为例,执行如下命令。

:Gstatus

我们可以在一个分割窗口中看到熟悉的git status输出结果(显示的是修改但还未提交的情况),如图5.10所示。

图5.10

但和git status在命令行中的输出不同,分割窗口是可交互的。读者可以将光标移动到其中一个文件上(使用Ctrl + n组合键和Ctrl + p组合键),也可以尝试如下命令。

  • - 用于将文件移入或移出暂存区。
  • cc:Gcommit用于提交暂存区中的文件。
  • D:GDiff用于打开一个文件差异对比窗口。
  • g?用于显示更多命令的帮助信息。

:Glog将打开与当前打开文件相关的提交历史记录,它们被显示在一个快速恢复窗口,以便读者进一步查看,如图5.11所示。

图5.11


使用:copen可打开一个快速恢复窗口,用:cnext:cprevious命令可以在不同快速恢复窗口之间切换,以查看不同文件的历史版本。关于快速恢复窗口,参见5.5.1节。

命令行git blame可以快速提示每一行中修改操作的时间和用户。blame的意思是责怪某个编写了问题代码的开发者(很有可能是用户自己)。:Gblame在一个垂直分割窗口中交互式显示git blame的输出,如图5.12所示。

:Gblame在文件的每一行旁边显示了相关提交的ID、作者、日期和时间,图5.12中的部分内容被隐藏了。

图5.12

:Gblame窗口中可使用如下命令。

  • CAD可调整blame窗口到指定的大小(分别对应于看到提交、作者和日期为止)。
  • Enter键用于打开所选提交的文件差异。
  • o用于在分割窗口中打开所选提交的文件差异。
  • g?用于显示更多命令的帮助信息。

:Gblame非常有用,它对于确定出错时间很有帮助。同时,它还提供了其他方便用户使用的包装器。

  • :Gread可直接在缓冲区中预览指定文件的内容。
  • :Ggrep封装了git grep(Git提供了强大的grep命令,可以用于搜索某个文件在任意时刻的状态)。
  • :Gmove用于移动文件(同时重命名相应的缓冲区)。
  • :Gdelete封装了git remove命令。

Vim帮助(如:help fugitive)中包含各个插件详细的使用方法。

本文摘自《 Vim 8文本处理实战》

  • Vim8文本处理技术指南,vim实用技巧
  • 文本编辑器书籍,程序员编程开发技能
  • python语言结合

本书向读者介绍了 Vim 的奇妙世界,其中包含了许多Python代码示例和一些面向工程的工具。本书强烈建议读者将Vim作为主要集成开发环境(IDE),以便将本书中的经验推广应用到任意编程语言。

读者群
本书适用于初级、中级和高级程序员。本书将介绍如何高效地将Vim应用于日常工作流程的方方面面。虽然书中涉及了Python,但Python或Vim的经验并不是阅读本书所必需的。

内容提要

  • 第1章,开始Vim之旅。介绍了Vim的基本概念。
  • 第2章,高级编辑和文本浏览。介绍了光标移动方法和更复杂的编辑操作,另外,还介绍了几种插件。
  • 第3章,使用先导键——插件管理。介绍了模式、键盘映射和插件管理。
  • 第4章,理解文本。介绍如何基于语义地使用代码库,并在代码库中浏览文件。
  • 第5章,构建、测试和执行。介绍如何在编辑器内外运行代码。
  • 第6章,用正则表达式和宏来重构代码。深入介绍代码重构操作。
  • 第7章,定制自己的Vim。讨论了如何进一步定制个人的Vim工作流程。
  • 第8章,卓尔不凡的Vimscript。深入介绍了Vim提供的强大脚本语言。
  • 第9章,Neovim。推介了一种新的Vim变体。
  • 第10章,延伸阅读。本章为读者提供了一些建议以供参考,并推荐了一些读者可能会感兴趣的资源站点。
发布了556 篇原创文章 · 获赞 298 · 访问量 90万+

猜你喜欢

转载自blog.csdn.net/epubit17/article/details/104560023