git version 1.6.0.4
几个新手刚刚开始接触 Git,为了维护核心仓库的“纯洁”,避免太多无关信息被误提交进仓库(再次批评一些图形化工具默认的“Select All”),采用了核心仓库只读,邮件提交 patch,审核后再提交的工作流程。
期间有时会遇到合并冲突,正常的原因一般是未及时下载新版本产生了冲突,特殊一点的原因是手工修改 patch 内容导致的。有时候看注释写得不够准确,忍不住就改了,有时候是 Geany 保存时自动去除了 patch 原文中的行尾空格,有时候是文件回车格式、BOM 等变动了,总之合并 patch 的时候,如果生成 patch 的“原稿”找不到,一般就产生了冲突,比如:
$ git am 0001-BUG-Sybase.patch
Applying: CHG: 读取Sybase如果时间为空,设置默认时间的修改
error: patch failed: source.php:38
error: source.php: patch does not apply
Patch failed at 0001.
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
刚开始一看有些懵,因为没有任何冲突在哪里的提示,后来找到一种方法,am 操作出问题后先手工 apply:
$ git apply --reject 0001-BUG-Sybase.patch
Checking patch source.php...
error: while searching for:
// 注释
// 以下为几行代码片断
error: patch failed: source.php:38
Applying patch source.php with 1 rejects...
Rejected hunk #1.
这样,就把没有冲突的文件先合并了,剩下有冲突的作了标记。先看输出,error: while searching for: 说明是这段代码有冲突,error: patch failed: source.php:38 指明了产生冲突的代码片断的开始行号,相应的,patch 中应该有这么一段:
diff --git a/source.php b/source.php
index 8770441..4e77b8a 100644
--- a/source.php
+++ b/source.php
@@ -38,27 +38,23 @@ class Site extends Module
// 注释
// 以下为几行代码片断
同时,还会产生一个 source.php.rej 文件,里面也是上面这段因为冲突无法合并的代码片断。
现在,在这段代码中查找冲突原因,并对文件进行修改,source.php.rej 参考完了可以删掉。改好之后,用 git add 把 source.php 添加到缓冲区,同时也要把其他没有冲突合并成功了的文件也加进来,因为在作 apply 操作的时候他们也发生了变化:
$ git add source.php
$ git add 其他 apply 进来的文件们
最后:
$ git am --resolved
Applying: CHG: 读取Sybase如果时间为空,设置默认时间的修改
大功告成。
中间如果处理乱了,用 git reset 恢复即可,所以合并 patch 在一个“干净”的分支上处理更好。
Related posts
February 26th, 2007
Fwolf
虽然市面上有很多 WordPress 的插件,但未必能够满足我们那些稍微“变态”一些的需求,所以,参照wp官方的插件编写指南,写下这个简单的说明和小例子,希望对大家有所帮助。
插件编写需要php的基础知识,并且本说明的内容大多只适用于wp1.5以后版本。
插件程序建议放置在wp-content/plugins/目录,如果有多个程序文件的话,可以在这个目录下建立子目录,程序所需的资源文件建议也放在这个目录下,便于更新和管理。
wp插件主要分为两种:
- Action 对wp的行为事件进行修改,比如修改数据库,发送邮件或者修改显示结构等。
- Filter 对wp的输入输出内容进行修改。
在本例中,我们将建立一个简单的Filter插件,替换wp本来的文章摘要生成功能,把以前手工修改代码实现的内容,用插件来替代。
wp推荐在插件程序中加入这样的文件头,便于wp辨认插件的信息,就像下面这样:
<?php
/*
Plugin Name: 插件名称
Plugin URI: http://插件网址
Description: 插件说明
Version: 插件版本
Author: 插件作者
Author URI: http://作者网址
*/
插件的代码风格主要是基于过程方式的,所以要尽力避免函数重名,可以在函数名之前加上自己的名称前缀,也可以把自己的类包含在一个类当中,不过小型插件还不至于复杂到要使用类的程度吧?
函数的编写就是php代码了,注意Filter一定要返回数据,即使没有修改也要返回,不然后续的其他函数就没法干活了。更多的信息可以看官方的插件api。
编写完成之后,函数是不会自动执行的,wp为插件函数的执行提供了一种hook机制,就是在原始的wp程序中,预置了一些hook或者叫挂载点,通过把插件函数挂在这些hook上,就可以被执行,目前wp提供的挂载点一览见Hooks列表。
针对我编写的函数,是要挂在生成文章摘要的地方,查找了一下Hooks列表,发现和摘要(excerpt)相关的有:
default_excerpt
excerpt_edit_pre
excerpt_save_pre
get_the_excerpt
the_excerpt
从名称可以看出,default_excerpt是文章的默认摘要,excerpt_edit_pre和excerpt_save_pre是编辑文章是对摘要进行的预处理,get_the_excerpt是取摘要,the_excerpt是返回摘要。我编写的是生成摘要的功能,应该挂在get_the_excerpt或者是the_excerpt上,考虑the_excerpt可能更“底层”一些,挂在这里。
挂载的语法也是一个php函数调用,格式如下:
add_filter('hook_name', 'your_filter', [priority], [accepted_args]);
priority为优先级,默认为10,数字小的会先执行;accepted_args为参数个数,默认值为1,如果插件函数需要多个参数的话需要自行设定。这两个参数在使用默认值的时候都可省略。
基本上有这些就够了,我的插件程序完整代码如下:
<?php
/*
Plugin Name: Excerpt Trimmer
Plugin URI: http://www.fwolf.com/
Description: 替换wp本身的“摘要”生成功能,用于在列表或者查询页面显示文章部分内容。
Version: 1.0
Author: Fwolf
Author URI: http://www.fwolf.com/
*/
function fw_excerpt($text)
{
$excerpt_length = 4;
$words = explode("\n", $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, '<p />......<a href="' . get_permalink($post->ID) . '">[阅读全文]</a>');
$text = implode("\n", $words);
}
return $text;
} // end of func fw_excerpt
add_filter('the_excerpt', 'fw_excerpt');
?>
可以看出插件程序也就是由上面介绍的3部分组成:文件头,函数体,挂载声明。
其实就简单插件来讲,最关键的是找对相应的hook,这就要靠经验和摸索了,wp官方文档好像也没有对每个hook作出详细的解释。
现在,把我这个插件程序保存为wp-contents/plugin/excerpt.php,登录wp,进入plugin设置,就能够看到“Excerpt Trimmer”插件了,启用之就大功告成了。我还存了一份在这里,方便下载。
Related posts