提取版本库中的数据
这是个很有用的小技巧,如果你对你现在的工作目录下的东西已经不耐烦了,随时可以取出你提交过的东西覆盖掉当前的文件,譬如:
$ git-checkout -f foo.c
在 git 中,有两种类型的标签,“轻标签”和“署名标签”。
技术上说,一个“轻标签”和一个分支没有任何区别,只不过我们将它放在了 .git/refs/tags/ 目录,而不是 heads 目录。因此,打一个“轻标签”再简单不过了。
$ git-tag my-first-tag
如果你打算针对某个commit ID来打标签,虽然该命令可以通过gitk里的右键菜单来实现,但是该命令对实际应用是很有帮助的。
$ git-tag mytag f0af6283824688f9d23426031734657661b54388
“署名标签”是一个真正的 git 对象,它不但包含指向你想标记的状态的指针,还有一个标记名和信息,可选的 PGP 签名。你可以通过 -a 或者是 -s 选项来创建“署名标签”。
$ git-tag -s <tag-name>
通常的情况下,合并其他的人的工作的情况会比合并自己的分支的情况要多,这在 git 中是非常容易的事情,和你运行 git-merge 命令没有什么区别。事实上,远程合并的无非就是“抓取(fetch)一个远程的版本库中的工作到一个临时的标签中”,然后再使用 git-merge 命令。
可以通过下面的命令来抓取远程版本库:
$ git-fetch <remote-repository>
根据不同的远程版本库所使用的通讯协议的路径来替代上面的 remoted-repository 就可以了。
Rsync
rsync://remote.machine/patch/to/repo.git/
SSH
remote.machine:/path/to/repo.git
or
ssh://remote.machine/patch/to/repo.git/
这是可以上传和下载的双向传输协议,当然,你要有通过 ssh 协议登录远程机器的权限。它可以找出两端的机器提交过的对象集之中相互缺少了那些对象,从而得到需要传输的最小对象集。这是最高效地交换两个版本库之间的对象的方式(在 git 兼容的所有传输协议当中)。
下面是个取得 SSH 远程版本库的命令例子:
$ git-fetch robin@192.168.1.168:/path/to/gittutorcn.git (1)
(1) 这里 robin 是登录的用户名,192.168.1.168 是保存着主版本库的机器的 IP 地址。
Local directory
/path/to/repo.git/
本地目录的情况和 SSH 情况是一样的。
git Native
git://remote.machine/path/to/repo.git/
git 自然协议是设计来用于匿名下载的,它的工作方式类似于 SSH 协议的交换方式。
HTTP(S)
http://remote.machine/path/to/repo.git/
到这里可能有些朋友已经想到,实际上,我们可以通过 Rsync, SSH 之类的双向传输方式来建立类似 CVS,SVN 这样的中心版本库模式的开发组织形式。
读过上一节之后,有的朋友可能要问,如果版本库是通过单向的下载协议发布的,如 HTTP,我们就无法将工作上传到公共的版本库中。别人也不能访问我的机器来抓取我的工作,那怎么办呢?
不必担心,我们还有 email !别忘了 git 本来就是为了管理 Linux 的内核开发而设计的。所以,它非常适合像 Linux Kernel 这样的开发组织形式高度分散,严重依赖 email 来进行交流的项目。
下面模拟你参加到《Git 中文教程》的编写工作中来,看看我们可以怎么通过 email 进行工作交流。你可以通过下面的命令下载这个项目的版本库。
$ git-clone http://www.bitsun.com/git/gittutorcn.git
之后,你会在当前目录下得到一个叫 gittutorcn 的目录,这就是你的项目的工作目录了。默认地,它会有两个分支: master 和 origin,你可以直接在 master 下展开工作,也可以创建你自己的工作分支,但是千万不要修改 origin 分支,切记!因为它是公共版本库的镜像,如果你修改了它,那么就不能生成正确的对公共版本库的 patch 文件了。
Note
|
如果你的确修改过 origin 分支的内容,那么在生成 patch 文件之前,请用 git-reset --hard 命令将它逆转到最原始的,没经过任何修改的状态。
|
你可以直接在 master 下开展工作,也可以创建你自己的工作分支。当你对项目做了一定的工作,并提交到库中。我们用 git-show-branch 命令先看下库的状态。
* [master] your buddy's contribution
! [origin] degining of git-format-patch example
--
* [master] your buddy's contribution
*+ [origin] degining of git-format-patch example
上面就假设你已经提交了一个叫 "your buddy's contribution" 的工作。现在我们来看看怎么通过 email 来交流工作了。
$ git-fetch origin (1)
$ git-rebase origin (2)
$ git-format-patch origin (3)
(1)更新 origin 分支,防止 origin 分支不是最新的公共版本,产生错误的补丁文件;
(2)将你在 master 上提交的工作迁移到新的源版本库的状态的基础上;
(3)生成补丁文件;
上面的几个命令,会在当前目录下生成一个大概名为 0001-your-buddy-s-contribution.txt 补丁文件, 建议你用文本工具查看一下这个文件的具体形式,然后将这个文件以附件的形式发送到项目维护者的邮箱: vortune@gmail.com
当项目的维护者收到你的邮件后,只需要用 git-am 命令,就可以将你的工作合并到项目中来。
$ git-checkout -b buddy-incomming
$ git-am /path/to/0001-your-buddy-s-contribution.txt
假设 Alice 在一部机器上自己的个人目录中创建了一个项目 /home/alice/project, Bob 想在同一部机器自己的个人目录中为这个项目做点什么。
Bob 首先这样开始:
$ git-clone /home/alice/project myrepo
这样就创建了一个保存着 Alice 的版本库的镜像的新目录 "myrepo"。这个镜像保存着原始项目的起点和它的发展历程。
接着 Bob 对项目做了些更改并提交了这些更改:
(编辑一些文件)
$ git-commit -a
(如果需要的话再重复这个步骤)
当他搞定之后,他告诉 Alice 将他的东西从 /home/bob/myrepo 中引入,她只需要这样:
$ cd /home/alice/project
$ git pull /home/bob/myrepo
这样就将 Bob 的版本库中的 "master" 分支的变化引入了。 Alice 也可以通过在 pull 命令的后面加入参数的方式来引入其他的分支。
在导入了 Bob 的工作之后,用 "git-whatchanged" 命令可以查看有什么信的提交对象。如果这段时间里以来,Alice 也对项目做过自己的修改,当 Bob 的修改被合并进来的时候,那么她需要手动修复所有的合并冲突。
谨慎的 Alice 在导入 Bob 的工作之前,希望先检查一下。那么她可以先将 Bob 的工作导入到一个新创建的临时分支中,以方便研究 Bob 的工作:
$ git fetch /home/bob/myrepo master:bob-incoming
这个命令将 Bob 的 master 分支的导入到名为 bob-incoming 的分支中(不同于 git-pull 命令,git-fetch 命令只是取得 Bob 的开发工作的拷贝,而不是合并经来)。接着:
$ git whatchanged -p master..bob-incoming
这会列出 Bob 自取得 Alice 的 master 分支之后开始工作的所有变化。检查过这些工作,并做过必须的调整之后, Alice 就可以将变化导入到她的 master 分支中:
$ git-checkout master
$git-pull . bob-incoming
最后的命令就是将 "bob-incoming" 分支的东西导入到 Alice 自己的版本库中的,稍后,Bob 就可以通过下面的命令同步 Alice 的最新变化。
$ git-pull
注意不需为这个命令加入 Alice 的版本库的路径,因为当 Bob 克隆 Alice 的版本库的时候, git 已经将这个路径保存到 .git/remote/origin 文件中,它将会是所以的导入操作的默认路径。
Bob 可能已经注意到他并没有在他的版本库中创建过分支(但是分支已经存在了):
$ git branch
* master
origin
"origin" 分支,它是运行 "git-clone" 的时候自动创建的,他是 Alice 的 master 分支的原始镜像, Bob 应该永远不要向这个分支提交任何东西。
如果 Bob 以后决定在另外一部主机上开展工作,那么他仍然需要通过 SSH 协议从新克隆和导入( Alice 的版本库):
$ git-clone alice.org:/home/alice/project/ myrepo
我们可以使用 git 自然协议,或者是 rsync, http 等协议的任何一种,详情请参考 git-pull。
Git 同样可以建立类似 CVS 那样的开发模式,也就是所有开发者都向中心版本库提交工作的方式,详情参考 git_push 和 git for CVS users 。