Archive

Posts Tagged ‘Tips’

vim 快速查找

December 3rd, 2009 BianJiang No comments

在用vim的时候要经常搜索,但是有的时候会忘记*和 # 这两个快捷键,所以记录如下

在通常模式下:

/ 向下查找

? 向上查找

* 向下查找当前光标下的单词

# 向上查找当前光标下的单词.

f{char} 跳到当前行,当前位置右边的{char}的位置. 如

using namespace std;

用f; 将会跳到;所在的位置.

F{char} 类似f{char},不过,是左边.

t{char} 类似f{char},不过,把光标放在{char}的前一个位置.

T{char} 类似t{char},不过,是左边.

; 重复t T f T 指令

, 朝相反方向重复t T f T 指令


Bian Jiang
Blog:  http://www.wifihack.net/

Categories: Tech.Notes Tags: , , ,

Create and push an annotated tag in Git

July 23rd, 2009 BianJiang No comments

# Create a tag on most current commit
git tag -a -m “tagging version 1.0″ v1.0

# Create a tag on a specific commit
git tag -a -m “tagging version 1.0″ v1.0 ec78b6b0778a1e02cb9554ce2dca4fcdd7a08a7d

# List tags
git tag -l

# Push tags to remote repository
git push –tags

# Push specific tag to remote repository
git push origin :tag_name

# Deleting a tag locally
git tag -d “v1.0″

# To push the deletion to remote repository
git push origin :refs/tags/v1.0

git tag options
-a
Make an unsigned, annotated tag object
-s
Make a GPG-signed tag, using the default e-mail address’s key
-u <key-id>
Make a GPG-signed tag, using the given key
-f
Replace an existing tag with the given name (instead of failing)
-d
Delete existing tags with the given names.
-v
Verify the gpg signature of the given tag names.
-l <pattern>
List tags with names that match the given pattern (or all if no pattern is given). Typing “git tag” without arguments, also lists all tags.
-m <msg>
Use the given tag message (instead of prompting). If multiple -m options are given, their values are concatenated as separate paragraphs. Implies -a if none of -a, -s, or -u <key-id> is given.

参考:
1. http://snipplr.com/view/16739/create-and-push-an-annotated-tag-in-git/
2. http://www.kernel.org/pub/software/scm/git/docs/git-push.html
3. http://www.kernel.org/pub/software/scm/git/docs/git-tag.html

Categories: Tech.Notes Tags: , ,

Git SVN 工作流程

June 7th, 2009 BianJiang No comments

From: http://andy.delcambre.com/2008/03/04/git-svn-workflow.html
Author: Andy Delcambre
翻译: Bian Jiang

尽管你可以从网上找到成千上万篇关于Git和git-svn,  但是本文主要介绍如何在一个以svn作为版本管理软件的项目里使用git。(假如你已经有了git-svn工具, 那我们就开始用git吧!)

先介绍些背景知识, GitLinus Torvalds 为Linux内核开发的一套版本控制软件。他对版本控制有些特殊的要求,但是没有一个能满足他的要求。Git 有两个最大的优点分布式和执行速度快,它的设计不仅有操作简单的分支(branch)还有功能强大的合并(merge).

声明:这并非是唯一“正确”的方式来使用git + svn, 只是我这样用的, 让我们开始吧。

首先: 假设我们有个subversion仓库(repository)在 http://example.com/svn/my_proj. 你需要创建一个git仓库(repo), 从subversion仓库中下载(pull).

git svn init -s http://example.com/svn/my_proj

这个命令是初始化git仓库从远程的svn上下载。 -s 参数表示 svn 仓库具有标准布局(trunk、branches、tags)。

git svn fetch

这个命令是从subversion取得所有的版本信息,在第一次运行的时候等待的时间比较长。当然你可以通过一些参数来控制只取得某些版本信息,但是我喜欢取得所以的历史版本信息。
现在你已经有了trunk所有版本信息,但是其他的分支的信息都在svn服务器上,你可以通过下面的命令查看所有的分支信息

git branch -a

显示了所有的分支信息,也包括远程的分支信息。
现在在你的本地已经有了完整的subversion历史信息,对你的仓库进行打包就显的非常重要。因为每一个版本就是一个单独的文件,下面的命令就是把这些信息打包到一个大的”pack”文件里面。这样你的仓库就会小很多,但是还是会有些小文件。

git repack -d

下一步就是在仓库里面做我们的工作,这里不推荐直接使用主干(master)分支来进行操作,因此我们要创建一个单独的分支new feature.

git checkout -b new_feature

-b 参数创建一个新的分支并切换到这个分支(chackout). 在你有了新的分支后,就可以在这个分支里进行修改或增加文件。如果你增加了文件需要通过下面的命令告诉git,git将自动跟踪这些新文件。

git add path/to/new_file

现在你可以在你的新分支(new feature)里面工作,并且提交到Git. 你的修改并不会自动提交,如果你想提交上面你增加的文件,你有两个选择: 一个是提交所有修改过的文件,另一个是只提交你想提交(部分)的文件。如果你不想比较所有你修改过的文件可以通过下面的命令完成:

git add path/to/edited_file
git add another/edited/file
git commit -m “commit message”

如果你想提交你所有的操作, 并且已经通过git add增加了所有的新文件。可以通过下面的命令实现:

git commit -a -m “commit message”

-a 参数是提交所以的变更.
现在你已经提交到git里面,但是还没有提交到subversion服务器上。应该把你的内容提交到master分支上。你需要先取得master仓库,然后与你创建的分支(new feaure)合并

git checkout master
git merge new_feature

这次合并没有任何冲突(conflicts), 如果有冲突的话,你应该先修正冲突然后在提交。

一旦你提交到master仓库中,就需要让master分支与svn 仓库同步,并且不能有冲突(如果有冲突就必须修正)

git svn rebase

master 分支与subversion 的trunk同步后,就应该把master提交到subversion仓库。

git svn dcommit

上面简单的介绍了从初始化到提交的整个过程。在接下来的几周里,我将研究一下不同的git命令是怎么工作的。下面的是简单的计划:

  • git reset
  • git rebase
  • git log
  • git stash
  • git merge
  • git mergetool

如果我忘记了一些重要的东西? 请让我知道你是怎么使用git svn 的。

Categories: Translate Tags: ,

Git-svn workflow

April 3rd, 2009 BianJiang No comments

本文参考: http://notes.jimlindley.com/2008/3/25/git-svn-that-works-for-me
作者: Jim Lindley

The canonical git-svn workflow that I’ve seen goes like this:
标准的git-svn工作流程参考这里:

[code lang="C"]
git svn clone
git checkout -b
…hack…hack…

git commit -a
git checkout master
git merge #NOTE: no need for –squash anymore
git svn rebase
git svn dcommit -e # -e will let you enter a commit message for SVN

[/code]

I’ve had more luck with the following workflow, when integrating changes via SVN from other team members:
我从团队的其他成员学到了更好的工作流程:

[code lang="C"]
# initial setup
git svn clone

# 99% of daily workflow
git checkout -b
…hack…hack…
git commit -a

# switch back to master, then rebase against
# any revisions in the svn repo
git checkout master
git svn rebase

# now that master is current with svn,
# sync working branch to local master
git checkout # These two are the added steps
git rebase master # which help prevent conflicts

# final upstream commit after rebasing
git checkout master
git svn rebase # one last check for new svn check ins
git merge
git svn dcommit -e

[/code]

The extra rebase step seems to do a better job of integrating your patches into the tree. Merge should do the same thing, if I’m reading the man pages right, but splitting the steps is more idiot proof (me-proof) this way.

It also keeps the master local branch from getting messy dealing with conflicts. Instead conflict is kept in the side working branch.

上面虽然很罗嗦但是做的好处在于,我们把所有的工作和从svn代码的合并都放在本地的分支上进行。这样就能保证本地主干与svn服务器进行同步,并且在本地主干没有任何修改。

更多有关git, git-svn,  git-reset 的文章:
1. git-svn workflow
2. An introduction to git-svn for Subversion/SVK users and deserters
3. Git reset in depth

2009.4.3
Bian Jiang
–EOF–

Categories: Tech.Notes Tags: , , ,

cmake常见问题

March 31st, 2009 BianJiang No comments

CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,
可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。
文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法.

之前想用automake autoconf来管理项目,但是看了一天也没有搞明白是怎么回事。最后只好投奔cmake.

经过一天的努力终于把项目从Makefile移植到cmake. 在移植的过程中遇到了些问题,简单记录如下.

网上关于cmake的的资料比较少,官方网站上的资料也特别少,有好多看了还看不懂, 哎。

从网上找到一篇“Cmake Practice(cmake 实践)”国人Cjacker写的。可以从这不下载 http://www.scribd.com/doc/13774019/Cmake-Practicecmake-

1. 在cmake中通过EXEC_PROGRAM来调用命令行来取得一些参数. 比如你要想通过取得gtkmm一些头部文件和库的路径。
[code lang="C"]
pkg-config gtkmm –cflags –libs
[/code]

Use the EXEC_PROGRAM command and then use the CACHE option of the SET
command to save the output to a variable like GTK_PKG_FLAGS.  Then use
the SET command to add the value.  Something like this:

[code lang="C"]
IF(NOT GTK_PKG_FLAGS)
EXEC_PROGRAM(pkg-config ARGS –cflags –libs gtkmm
OUTPUT_VARIABLE GTK_PKG_FLAGS)
SET(GTK_PKG_FLAGS “${GTK_PKG_FLAGS}” CACHE STRING “GTK Flags”)
ENDIF(NOT GTK_PKG_FLAGS)
SET(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} ${GTK_PKG_FLAGS}”)
[/code]

2. 通过execute_process来实现文件, 目录的拷贝
[code lang="C"]
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/path/to/www
${CMAKE_BINARY_DIR}/path/to/www)
[/code]

PS: EXECUTE_PROCESS 和 EXEC_PROGRAM 基本相同,  EXECUTE_PROCESS是用来替代EXEC_PROGRAM的。
参见:  http://www.cmake.org/pipermail/cmake/2006-February/008250.html

参考:  http://www.cmake.org/pipermail/cmake/2009-March/028299.html

3. 常用的几个内置变量

通过set语句可以自定义变量,然而,CMake还包含大量的内置变量,这些变量和自定义变量的用法没有区别,下面就列出一些常用的变量:

* CMAKE_C_COMPILER

指定C编译器,通常,CMake运行时能够自动检测C语言编译器。进行嵌入式系统开发时,通常需要设置此变量,指定交叉编译器。
* CMAKE_CXX_COMPILER

指定C++编译器
* CMAKE_C_FLAGS

指定编译C文件时编译选项,比如-g指定产生调试信息。也可以通过add_definitions命令添加编译选项。
* EXECUTABLE_OUTPUT_PATH

指定可执行文件存放的路径。
* LIBRARY_OUTPUT_PATH

指定库文件放置的路径

4. 常用的命令

除了内置变量,我们还可以通过命令来修改编译选项,现将一些常用的命令列出来:

* include_directories

指定头文件的搜索路径,相当于指定gcc编译器的-I参数
* link_directories

动态链接库或静态链接库的搜索路径,相当于指>定gcc的-L参数
* add_subdirectory

包含子目录,当工程包含多个子目录时,此命令有用
* add_definitions

添加编译参数,比如add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义
* add_executable

编译可执行程序
* target_link_libraries

指定链接库,相同于指定-l参数

* AUX_SOURCE_DIRECTORY 将指定目录中的源文件名称赋值给变量DIR_SRCS

AUX_SOURCE_DIRECTORY(. DIR_SECS)

把当前目录下面的所有源文件名称赋值给变量DIR_SRCS

Cmake Practice(cmake 实践)   http://www.scribd.com/full/13774019?access_key=key-hkil010h7nnglwgk8×5

Links:
1. http://www.cmake.org/pipermail/cmake/2005-January/006051.html
2.  CMake Useful Variables http://www.vtk.org/Wiki/CMake_Useful_Variables
3.  http://www.cmake.org/pipermail/cmake/2009-March/028299.html
4.  http://www.scribd.com/doc/13774019/Cmake-Practicecmake-

Categories: Tech.Notes Tags: , , , ,

snmp学习笔记之二trap——分析notification.c文件

November 19th, 2008 BianJiang No comments

需要文件:

NET-SNMP-EXAMPLES-MIB.txt
notification.c

这两个文件都在net-snmp源码包里,我的版本是5.4.1

NET-SNMP-EXAMPLES-MIB.txt net-snmp-5.4.1.2/mibs目录下
notification.c net-snmp-5.4.1.2/agent/mibgroup/examples目录下

  1. 安装notification:

    ./configure --with-mib-modules="examples/notification"
    make
    sudo make install
  2. 配置snmp.conf文件,在文件中增加NET-SNMP-EXAMPLES-MIB mib库

    sudo vim /usr/local/share/snmp/snmp.conf

    在文件中增加: mibs +NET-SNMP-EXAMPLES-MIB

  3. 验证netSnmpExampleNotifications mib库是否正常加载:

    snmptranslate -IR -Tp netSnmpExampleNotifications
    +--netSnmpExampleNotifications(3)
       |
       +--netSnmpExampleNotificationPrefix(0)
       |  |
       |  +--netSnmpExampleHeartbeatNotification(1)
       |
       +-- ---N String    netSnmpExampleNotification(1)
       |        Textual Convention: SnmpAdminString
       |        Size: 0..255
       |
       +--netSnmpExampleNotificationObjects(2)
          |
          +-- ---N Integer32 netSnmpExampleHeartbeatRate(1)
          +-- ---N String    netSnmpExampleHeartbeatName(2)
                   Textual Convention: SnmpAdminString
                   Size: 0..255
  4. 配置snmptrapd.conf

    建立/usr/share/snmp/snmptrapd.conf(我的机器上是这个,不同机器不同,可能有的放在/etc/snmp,/usr/local/share/snmp/下,视不同情况慢慢实验),加入以下一行:

    authcommunity execute,log,net public

设置所有用户的访问权限:可执行,记录,传递,

如果相对接受到的信息处理可以增加:

traphandle .1.3.6.1.4.1.2021.251.2  page_me down
# 默认处理函数
traphandle default                  log_it
  1. agent自动产生trap

配置agent的snmpd.conf,加入以下几行:(参考:
http://www.net-snmp.org/wiki/index.php/FAQ:Agent_17 ):

# From: http://www.net-snmp.org/wiki/index.php/FAQ:Agent_17
# send v1 traps
trapsink   127.0.0.1:162
# also send v2 traps
trap2sink  127.0.0.1:162
informsink 127.0.0.1:162
  1. 启动snmptrapd

    sudo snmptrapd –d –f –Lo

  2. 启动snmpd

    sudo snmpd -f -L

snmpd 会每隔30秒给snmptrapd发送一个信息。收到的信息如下:

Received 64 bytes from UDP: [127.0.0.1]:56929
0000: 30 3E 02 01  00 04 06 70  75 62 6C 69  63 A4 31 06    0>.....public.1.
0016: 09 2B 06 01  04 01 BF 08  02 03 40 04  AC 10 81 01    .+........@.....
0032: 02 01 06 02  01 01 43 03  03 CC BC 30  13 30 11 06    ......C....0.0..
0048: 0C 2B 06 01  04 01 BF 08  02 03 02 01  00 02 01 1E    .+..............

2008-11-11 15:43:11 172.16.129.1(via UDP: [127.0.0.1]:56929) TRAP, SNMP v1, community public
        NET-SNMP-EXAMPLES-MIB::netSnmpExampleNotifications Enterprise Specific Trap
        (NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification) Uptime: 0:41:30.20
        NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatRate.0 = INTEGER: 30
  1. notification.c 源码如下:

    /** @example notification.c
     *  This example shows how to send a notification from inside the
     *  agent.  In this case we do something really boring to decide
     *  whether to send a notification or not: we simply sleep for 30
     *  seconds and send it, then we sleep for 30 more and send it again.
     *  We do this through the snmp_alarm mechanisms (which are safe to
     *  use within the agent.  Don't use the system alarm() call, it won't
     *  work properly).  Normally, you would probably want to do something
     *  to test whether or not to send an alarm, based on the type of mib
     *  module you were creating.
     *
     *  When this module is compiled into the agent (run configure with
     *  --with-mib-modules="examples/notification") then it should send
     *  out traps, which when received by the snmptrapd demon will look
     *  roughly like:
     *
     *   可以通过 --with-mib-modules="examples/notification" 把这个模块
     * 编译到agent模块中,snmptrapd可以接收到他发送的traps, 接收到的信息
     * 如下:
     *
     *  2002-05-08 08:57:05 localhost.localdomain [udp:127.0.0.1:32865]:
     *      sysUpTimeInstance = Timeticks: (3803) 0:00:38.03 \
     *      snmpTrapOID.0 = OID: netSnmpExampleNotification
     *
     */
    
    /*
     * start be including the appropriate header files
     */
    #include <net-snmp/net-snmp-config.h>
    #include <net-snmp/net-snmp-includes.h>
    #include <net-snmp/agent/net-snmp-agent-includes.h>
    
    /*
     * contains prototypes
     */
    #include "notification.h"
    
    /*
     * our initialization routine 初始化
     * (to get called, the function name must match init_FILENAME()
     * 函数的名字必须是 init_FILENAME() 这种格式
     */
    void
    init_notification(void)
    {
        DEBUGMSGTL(("example_notification",
                    "initializing (setting callback alarm)\n"));
        snmp_alarm_register(30,     /* seconds, 秒 */
                            SA_REPEAT,      /* repeat (every 30 seconds). 每隔30秒发送一个trap*/
                            send_example_notification,      /* our callback 我们的回调函数 */
                            NULL    /* no callback data needed */
            );
    }
    
    /** here we send a SNMP v2 trap (which can be sent through snmpv3 and
     *  snmpv1 as well) and send it out.
     *
     *     The various "send_trap()" calls allow you to specify traps in different
     *  formats.  And the various "trapsink" directives allow you to specify
     *  destinations to receive different formats.
     *  But *all* traps are sent to *all* destinations, regardless of how they
     *  were specified.
     *
     *
     *  I.e. it's
     * @verbatim
     *                                           ___  trapsink
     *                                          /
     *      send_easy_trap \___  [  Trap      ] ____  trap2sink
     *                      ___  [ Generator  ]
     *      send_v2trap    /     [            ] ----- informsink
     *                                          \____
     *                                                trapsess
     *
     *  *Not*
     *       send_easy_trap  ------------------->  trapsink
     *       send_v2trap     ------------------->  trap2sink
     *       ????            ------------------->  informsink
     *       ????            ------------------->  trapsess
     * @endverbatim
     */
    void
    send_example_notification(unsigned int clientreg, void *clientarg)
    {
        /*
         * define the OID for the notification we're going to send
         * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatNotification
         */
        oid             notification_oid[] =
            { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 0, 1 };
        size_t          notification_oid_len = OID_LENGTH(notification_oid);
        static u_long count = 0;
    
        /*
         * In the notification, we have to assign our notification OID to
         * the snmpTrapOID.0 object. Here is it's definition.
         */
        oid             objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
        size_t          objid_snmptrap_len = OID_LENGTH(objid_snmptrap);
    
        /*
         * define the OIDs for the varbinds we're going to include
         *  with the notification -
         * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatRate  and
         * NET-SNMP-EXAMPLES-MIB::netSnmpExampleHeartbeatName
         */
        oid      hbeat_rate_oid[]   = { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 2, 1, 0 };
        size_t   hbeat_rate_oid_len = OID_LENGTH(hbeat_rate_oid);
        oid      hbeat_name_oid[]   = { 1, 3, 6, 1, 4, 1, 8072, 2, 3, 2, 2, 0 };
        size_t   hbeat_name_oid_len = OID_LENGTH(hbeat_name_oid);
    
        /*
         * here is where we store the variables to be sent in the trap
         */
        netsnmp_variable_list *notification_vars = NULL;
        const char *heartbeat_name = "A girl named Maria";
        #ifdef  RANDOM_HEARTBEAT
        int  heartbeat_rate = rand() % 60;
        #else
        int  heartbeat_rate = 30;
        #endif
    
        DEBUGMSGTL(("example_notification", "defining the trap\n"));
    
        /*
         * add in the trap definition object
         */
        snmp_varlist_add_variable(&notification_vars,
                                  /*
                                   * the snmpTrapOID.0 variable
                                   */
                                  objid_snmptrap, objid_snmptrap_len,
                                  /*
                                   * value type is an OID
                                   */
                                  ASN_OBJECT_ID,
                                  /*
                                   * value contents is our notification OID
                                   */
                                  (u_char *) notification_oid,
                                  /*
                                   * size in bytes = oid length * sizeof(oid)
                                   */
                                  notification_oid_len * sizeof(oid));
    
        /*
         * add in the additional objects defined as part of the trap
         */
    
        snmp_varlist_add_variable(&notification_vars,
                                   hbeat_rate_oid, hbeat_rate_oid_len,
                                   ASN_INTEGER,
                                  (u_char *)&heartbeat_rate,
                                      sizeof(heartbeat_rate));
    
        /*
         * if we want to insert additional objects, we do it here
         */
        if (heartbeat_rate < 30 ) {
            snmp_varlist_add_variable(&notification_vars,
                                   hbeat_name_oid, hbeat_name_oid_len,
                                   ASN_OCTET_STR,
                                   heartbeat_name, strlen(heartbeat_name));
        }
    
        /*
         * send the trap out.  This will send it to all registered
         * receivers (see the "SETTING UP TRAP AND/OR INFORM DESTINATIONS"
         * section of the snmpd.conf manual page.
         */
        ++count;
        DEBUGMSGTL(("example_notification", "sending trap %ld\n",count));
        send_v2trap(notification_vars); // 发送snmpv2的trap
    
        /*
         * free the created notification variable list
         */
        DEBUGMSGTL(("example_notification", "cleaning up\n"));
        snmp_free_varbind(notification_vars);
    }
参考:
  1. How can I get the agent to generate a trap http://www.net-snmp.org/wiki/index.php/FAQ:Coding_15
  2. http://www.net-snmp.org/docs/mibs/NET-SNMP-EXAMPLES-MIB.txt
  3. http://www.net-snmp.org/dev/agent/notification_8c-example.html
  4. http://www.net-snmp.org/wiki/index.php/FAQ:Agent_17

–EOF–

Categories: Tech.Notes Tags: , , ,