• 用 git 维护 vim 代码



    众所周知的是,vim 的代码是 Bram 用 patch 的方式维护的,一种典型的集约式管理,虽然 edyfox 在 https://vim.svn.sourceforge.net/svnroot/vim 维护了 svn 版本,但这也只是导入 CVS 的内容而已,别人无法往里面加入代码,问题是,当你想开发一系列试验性功能时,没法直接在 vim 的 svn 仓库上工作 (比如创建分支),而只能用自己的版本管理仓库。

    这便造成了一个显然的维护问题,以我自己为例,vim-cocoa 的代码原本使用 code.google.com 提供的 svn 服务进行维护,但 Subversion 是以目录为单位跟踪修改的,所以,同一个代码目录,要么来自 vim 的代码仓库,要么来自 google code 的代码仓库,二者不可兼得。

    所以我原来使用了一套非常麻烦的维护方式:

    $ svn co https://vim.svn.sourceforge.net/svnroot/vim/vim7
    $ cp -r vim7/ vim-cocoa/
    $ cd vim-cocoa; find . -name ".svn/*" -exec rm -rf {};
    $ svn import src/gui_mac.m https://vim-cocoa.googlecode.com/gui_mac.m
    ...

    也就是说,抓下一份 vim 的代码来,复制一份,去掉其 svn 的数据,然后将我修改过的部分导入 google code 的版本仓库。在我完成一部分修改,代码达到稳定之后,再返回 vim7 目录,更新原来用 svn 下载的代码,然后将我在 vim-cocoa/ 下做出的修改 back port 回最新的 vim7 代码里,生成针对最新版本的 patch,并编译,发布。

    显然这里要花大量的时间在没有必要的手工操作上,而且很容易出错。这便是 git 该出现的时候了。再简单复述一下我的需求:

    1. 能够通过 svn 经常更新到最新的 vim 代码
    2. 自己正在工作的 vim-cocoa 分支代码不受影响
    3. 能把主干代码和分枝代码按需合并
    4. vim 的 svn 库里有些自动生成的文件,应该删除,因为 Bram 不愿意,所以我应该可以在自己的分支里删除,这样可以避免每次 commit 之前需要恢复这些自动生成的文件

    下面是用 git 完成的步骤,主要就是利用了 git-svn 这套方便的工具:

    $ mkdir vim; cd vim
    $ git-svn init https://vim.svn.sourceforge.net/svnroot/vim/vim7
    $ git-svn fetch -r 625 # 这里为了减少消耗,不复制整个 svn 版本仓库,只抓最新的 revision

    这时 git-svn 会产生一个叫做 git-svn 的 remote branch,并让本地的 master 指向这个 branch。所以,我们可以从 master 分支出一个自己的版本来:

    $ git checkout -b cocoa
    # 下面是把所有原来 vim-cocoa 做的修改在这个最新版的 vim 代码中打上
    $ git commit -m "import vim-cocoa changes into git repo"

    此后,如果上游的 vim svn 库更新了,我们可以用 git fetch git-svn 把更新下载下来,然后,用 git merge git-svn 将这些更新 merge 到当前的 branch 里,当然,也可以用 git pull git-svn 把两步合在一起完成,只要你确定 merge 不会出现冲突。

    那么,现在就有很好的一个的平台来做本地修改了,但 vim 的一个问题是,src/auto/ 中自动生成的文件也被放在 svn repo 里,这是一个很麻烦的问题,因为 vim 也不支持 off-directory build,所以在我们测试、调试过后,如果要生成 patch,就不得不先把这些 (configure/make 过程中) 必然会生成的文件先恢复到初始状态,无谓的增加了操作,如果在 git 里 commit,也会提示你这些文件更新了,但你显然不愿意把这些改动都算进你的 commit 里,那怎么让这些文件不烦人呢?

    简单,我们不管上游的 vim svn 库怎么维护,可以在本地 git 仓库中把这些文件删除,也就是不跟踪的改动了:

    # --cached 表示只删除 git 缓存,不删除实际文件
    $ git rm --cached src/auto/config.h
    $ git rm --cached src/auto/config.mk
    $ git rm --cached src/auto/configure
    ...
    $ git commit -m "stop tracking auto generated files"

    因为就算这些文件不在跟踪中,一旦它们修改过了,git status 还是会提示你它们更新了,而且这样用 git commit -a 把所有修改过的文件加入下一次 commit 也不方便,怎么办呢?用 .gitignore 文件:

    $ vi .gitignore

    加入以下内容:

    .*.swp
    .DS_Store
    src/TAGS
    src/tags
    src/Vim
    src/auto/*
    src/auto/configure
    src/auto/config.h
    src/auto/config.mk
    src/auto/if_perl.c
    src/auto/link.log
    src/auto/link.sed
    src/auto/osdef.h
    src/auto/pathdef.c
    src/config.log
    src/config.status
    src/objects
    src/xxd/*
    src/Vim.app/*

    这样不管这些文件怎么变,git 都不会提示了。

    现在我们需要一个用来作为参考的分支,以定期生成 patch,这个分支必须随着上游 svn 的更新而更新,但我们这里删除这些自动生成文件的记录又不应该包含在内,怎么办呢?可以用 git-svn 自动生成的 master branch 来做这件事情:

    $ git checkout master
    $ git rm --cached src/auto/config.h
    ...
    $ git commit -m "blahblahblah"

    这样,以后每次要生成一个独立的 vim-cocoa 分支相对 vim 主干的 patch 时,我都可以先在 master 分支上:

    $ git-svn rebase
    $ git pull git-svn

    然后切换回 cocoa 分支:

    $ git checkout cocoa
    $ git diff master > vim-cocoa.patch

    这样便完整了 patch 的生成。

    最后,如果我们需要把现在这个 vim-cocoa 像原来 google code 的代码仓库一样,随时公布到网上该怎么办呢?http://repo.or.cz 提供了公开的代码仓库,申请以后可以获得一个 push 地址:

    git+ssh://repo.or.cz/srv/git/vim-cocoa.git

    push 需要添加一个用户,然后上传它的 ssh 公钥 (在本地用 ssh-keygen 生成)。然后,如果我要把本地的 cocoa 分支发布到网上,就可以执行:

    $ git push git+ssh://repo.or.cz/srv/git/vim-cocoa.git cocoa:master

    其中 cocoa 指的是来源 (本地) 分支,master 指的是目的 (远程) 分支,为什么要 push 到另一个名字的分支去呢?因为 master 是 git 默认 clone 下来的分支,为了方便其他用户的抓取,以及 gitweb 的信息显示,还是保持公开仓库里的 master 分支是你最常更新的那个分支为好。

  • 相关阅读:
    Java第二十五天,多线程之等待唤醒机制
    Java第二十四天,线程安全
    多线程第二十三天,多线程
    Java第二十二天,异常
    数据结构之广义表
    MS Office使用技巧
    标准C++中的String类的使用
    SQL中创建外键约束
    关系数据标准语言SQL之数据查询
    Windows命令
  • 原文地址:https://www.cnblogs.com/huqingyu/p/1066283.html
Copyright © 2020-2023  润新知