Git 的常用方法简介

Git 的常用方法简介--主体是从网上抄来的,进行了些整编修改,向原作者致敬

 

使用git参与kernel开发

 

$  git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

 

其他的 git trees 可以在 http://git.kernel.org/ 找到 ,点击进去就能看到 GIT URL 


使用 git

自从 git-1.5.4  'git-xyz' 这种用法就不提倡了,而推荐 'git xyz' 风格。  git 的后续版本中将在make install

时不再安装 'git-xyz' 这些 hardlinks 

当如果执行 git --exec-path 输出的目录中依然有 git-xyz 这些脚本,你还是可以把这个路径加到 PATH 环境变量中,

这样还能够使用 git-xyz 形式的脚本。

config

   ------

    我的一些简单的配置:

 

   $ git-config user.name "Jike Song"

   $ git-config user.email [email]albcamus@gmail.com[/email]

   $ git-config core.editor vim

   $ git-config core.pager "less -N"

   $ git-config color.diff true  // 显示 diff 时色彩高亮

   $ git-config alias.co checkout  //  git checkout 取个别名,这样只输入 git co 即可

   $ git-config sendemail.smtpserver /usr/bin/msmtp

 

    注意,这会在当前 repository 目录下的 .git/config 中写入配置信息。   如果 git-config 加了 --global

    选项,配置信息就会写入到 ~/.gitconfig 文件中。   因为你可能用不同的身份参与不同的项目,而多个

    项目都用 git 管理,所以建议不用 --global 配置。

 

  $ git-val -l  // 列出 git 变量

 

 

   init

   ----

 

   $ git-init-db  // 创建一个 .git/ 目录,初始化一个空的 git 仓库

//这个目录在git-clone时也会创建。也就是说clone时会自动初始化git

//仓库里需要的东西

 

   clone

   -----

 

   $ git-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git [dir name]

   [dir name] 是你想让这个仓库叫什么名字。   如果不指定,就会等同于目标仓库的名字。

 

    注意,这种 git server 形式的 repository ,都有一个 filename.git 文件;   而对于 *.git 的操作,也可以

    针对 .git 所在的目录:

 

$  mkdir tmp/

$  cd tmp/

$  git-clone ~/Sources/linux-2.6

 

    或者通过 ssh 

 

$  git-clone [email]arc@host.xyz.com[/email]:/home/arc/Sources/linux-2.6

 

    此时当前目录下有一个 .git/ 目录  以下我们都在 linux-2.6/ 下演示:

 

   pull

   ----

   $ git-pull  // 更新本地的 git tree    如果自从你 clone  linus tree 之后, linus tree

//有新的改动,那么把这些更改更新到你的本地tree中

//类似于cvs  update

 

  FYI:  git-clone  git-pull 都会默认调用 git-merge 

 

  FYI:  每天 git-pull 更新技巧:

1)  git-describe ,例如目前是 v2.6.26-rc8-12

2)  git-pull -v

3)  git-describe ,例如是 v2.6.26-rc8-22

4)  git-log -p -10 查看变化

 

   diff

   ----

   $ git-diff  /* 列出自己本地的 tree 中已修改、但却未 commit 的改动

   这也是产生 patch 的方式 ( 用来提交的 patch 需要先 commit 到自己的 tree 里,

   然后 git-format-patch)    注意,使用 git-diff 产生的 patch 都应该在

  patch(1) 时指定 -p1 ,或者直接使用 git-apply 打补丁

 */

    选项:

     --color  diff 语法高亮 ( 可以 git-config color.diff true)

     --ignore-space-at-eol   忽略行尾的 whitespace

     -b

     --ignore-space-change   忽略行尾的 whitespace ,并且认为所有的 whitespace 都是一样的

     -w

     --ignore-all-space  比较两行的时候,完全忽略 whitespace 。这样,即使是一行有很多

      whitespaces ,另一行文字一样但是没有 whitespace  git 也认为这两

行内容一致。

 

 

   FYI: diff 不同的 branches

 

    /*  下面这两种写法是一样的,都是列出:与 jike 分支相比, master 分支有哪些不同  */

    $ git-diff jike..master

    $ git-diff jike master

 

    /*  列出自从 jike 分支从 master 分支脱离以来, master 分支又有过哪些改动  */

    $ git-diff jike...master

 

/*{{{*/    git-diff 的详细用法 :

 

    列出自己的 tree HEAD 和某一个 tag 的不同:

   $ git-diff v2.6.22

 

    列出某一个文件,和以前某个 tag 的该文件的不同:

   $ git diff v2.6.20 init/main.c

    注意结果中 + 表示自己的 tree  - 表示 2.6.20 的。

 

    列出两个 tags 之间的不同:

   $ git-diff v2.6.20..v2.6.21-rc1

 

    列出两个 commits 之间的不同 (Notes ,是这两次 commits 之间的 commits 引入的所有改动 ):

       $ git-diff 2a062ab483f5afd764fb20631ee960672946a4be..a44008f2372684bacfab03de5039f68b613c5b53

 

    列出两个 tags 的某一文件的不同:

   $ git-diff v2.6.23 v2.6.24-rc1 init/main.c

 

   or:

 

   $ git-diff v2.6.25-rc3:kernel/module.c v2.6.25-rc4:kernel/module.c

 

   or:

 

   $ git-diff v2.6.25-rc3:kernel/module.c HEAD:kernel/module.c

 

 

    事实上, git-log  git-whatchanged 等命令都可以这么用。

/*}}}*/

 

   apply

   -----

 

   $ git-apply  相当于 patch(1) 命令,不过 git-apply 专门用来 apply 那些用 git-diff 生成的补丁

   --check  // 不真正打补丁,而只是检查补丁是否能完美的打上

   -v       //verbose 模式

   -R  //reverse 模式,也就是拉出这个补丁来 ( 而不是打进去 )

 

   gui

   ---

   $ git-gui

 

or:

 

   $ gitk  //GUI 模式。还有一些不在 git 包中的 git GUI 前端。   我觉得基于 Qt  qgit 最好用

 

 

 

  revision list

  -------------

 

   $ git-rev-list <ID> 以时间为顺序,反向列出 revision ID    也就是先列最新的 commit ID 

    也可以指定列出的数目,例如:

 

   $ git-rev-list -2 971a71bdc9b42e74a5a8ed0433ac27ae92291024

  log

  ---

 

    查看某一文件都被哪些补丁改动过:

 

   $ git-whatchanged -p security/Kconfig

 

    查看某一文件的每一行的作者和 Revision ID 

 

   $ git-blame  security/Kconfig

 

     or:

 

   $ git-annotate security/Kconfig

 

    查看某一版本的某一文件:

 

   $ git-show v2.6.22:init/main.c

 

    查看两个 tags 之间的 log  (git-shortlog 也可以这么用 )

 

   $ git-log v2.6.25-rc3..v2.6.25-rc4

     :

   $ git-log -p v2.6.24..v2.6.25-rc1 arch/x86/kernel/smp_64.c

     :

   $ git-whatchanged v2.6.24..v2.6.25-rc1 arch/x86/kernel/smp_64.c

 

    查看某版本之后的 log 

 

   $ git-log v2.6.25-rc4..HEAD  //HEAD 可以省略,直接写成 git-log v2.6.25-rc4..

 

 

   撤销最近的 commit

  ----------------

 

   $ git-reset HEAD~1  //HEAD~1 这种方式也可以表示为 HEAD^

   $ git-diff |git-apply -R -v

 

    注意: 1) git-reset  git-revert 不同,后者是把补丁作为另一个 commit 反向打入 tree 中,而 reset

       是真正的撤销;  2)  如果撤销最近的 n  commits ,就用 git-reset HEAD~<n> ,例如 HEAD~2

 

 

   回退到某个 tag  commit

  --------------------

   例如目前我的 linux-2.6 里是 :

 

$  git-desribe 

v2.6.26-3465-g5b664cb

 

我想让它回退到v2.6.26时的状态(程序和ref  log 一起回退 )   git-log 搜索 "Linux 2.6.26"  commit ID为:

 

bce7f793daec3e65ec5c5705d2457b81fe7b5725

 

那么:

 

$  git-reset --hard bce7f793daec3e65ec5c5705d2457b81fe7b5725

--hard不但会reset你的working  tree ,而且联 index files 一起 reset :整个回到你指定的 commit 状态。

 

 

   reset/reflog

   ------------

         举例来说, reset 你的当前 branch  tip(HEAD 所在的那个 commit)

 

$  git-reset HEAD^

 

选项:

 

--mixed   只撤销掉 index 中的 commit ,却保留那个 commit 对应的内容

--hard   index  working dir 全撤销,也就是 commit 消失,并且其内容也消失

--soft   index  working dir 都不动,只 "require them to be in a good order" (

这是man  git-reset 中的话,什么意思?  。这会让该 commit 修改的文件变

成"dded  but not yet committed" 的状态。

 

如果不加这3个参数之一,那git-reset默认就是--mixed方式。

 

 

/*{{{*/ [FYI]  git-reset --hard 之后又想恢复

 

        git 中,除非你运行了 git-gc --prune ,否则历史是永远不会被擦除的,你可以随意恢复到任何历史状态。   下面就是

       一个恢复被 git-reset --hard 擦除了的 commit 的例子:

 

//reset最近的commit

$  git-reset --hard HEAD^

HEAD  is now at bc45eb8 Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

 

//查看reflog

$  git-reflog

bc45eb8...  HEAD@{0}: HEAD^: updating HEAD

a7dc750...  HEAD@{1}: commit: [PCI] code cleanup : remove dead pci_remove_device_safe()

bc45eb8...  HEAD@{2}: checkout: moving from jike to bc45eb8950b8c14487385cfd2bda1613ca8d9703

 

//reset回去

$  git-reset --hard HEAD@{1}  // 注意, HEAD@{1} 就是我们要恢复的那个状态

HEAD  is now at a7dc750 [PCI] code cleanup : remove dead pci_remove_device_safe()

 

注意也可以把reflog列出来的历史状态checkout出来:

 

$  git-checkout HEAD@{30} -b new_branch

/*}}}*/

 

 

 

stash

-----

git-stash是个很有趣的功能,它可以让你把目前的dirty内容"隐藏"起来,使得你的仓库看起来是干净的。

这在两种情况下很有用:

 

1,修改了一个文件,尚未commit,此时又想去修改别的文件;

2,切换到别的branch之前,把尚未commit的改动stash一下,以防git-checkout命令丢弃了你的

    未提交的修改。

 

 

用法:

 

$  git-stash

 

参数:

list   // 列出所有 stash 了的项目,注意会显示 stash  ID

show  [-p] [stash@{<id>}] // 查看某个 stash  -p 会显示补丁。   如果不指定 id ,则 show 最近 stash 的那个

apply  [stash@{<id>}]  // 恢复某个 stash    如果不指定 id ,则 apply 最近 stash 的那个

save   //stash 当前的未提交的改动

clear   // 销毁所有 stash 了的未提交改动

 

不加参数的话,默认行为就是save。

 

 

例如:

$  git-stash list

stash@{0}:  WIP on test: 42bb109... a commit to fix. --fixed in git-rebase, "edit"

stash@{1}:  WIP on test2: 10253e6... Merge branch 'test' into test2

stash@{2}:  WIP on test2: 10253e6... Merge branch 'test' into test2

 

注意'test'和'test2'都是branch。

 

$  git-stash show -p stash@{2}

 

$  git-stash apply stash@{2}

 

注意,$  git-stash pop 相当于从 stash  栈里头 apply 一个 stash ,亦即: git-stash apply stash@{0}

 

可以把任一分支的stash给apply到当前分支上。

 

 

 

 

 

 

 

 add

 ---

  新加文件到 index 中,使得 git 可以跟踪它:

 

   $ git-add <filename>   // 类似于 cvs add <filename>    如果<filename>是目录,那么git-add

    // 会自动去递归地添加该目录下的所有文件和子目录

   $ git-add -a  // 本目录下所有文件和子目录

 

   git-add  实际上是对 git-update-index 的调用, git-add hello.c 就相当于:

 

$  git-update-index --add hello.c

 

commit

------

 

   $ git-commit -e -s -a

        -s   增加 Signed-off-by 

   -e  调用 vim( 我在 .git/config 里制定的 editor) 进行编辑  commit message

   -a  all

   -v   vim 中编辑 commit msg 时,连补丁本身也显示在其中

 

delete

------

删除文件:

 

   $ git-rm aa.c 

   $ git-commit 

 

 

撤销一次commit

--------------

 

   $ git-log   /*  找到要撤销的 commit ID */

   $ git-revert adb2f08089edac8bf1912a618a74485ab42f2b86  // 指定导致删除操作的 commit ID ,进行撤消

 

 

列出某一个commit  ID 对应的补丁

-----------------------------

 

   $ git-log -1 -p 721151d004dcf01a71b12bb6b893f9160284cf6e

   -1 的意思是只显示一个 commit 。如果你想显示 5 个,就 -5 。不指定的话, git log 会从该 commit 一直往后显示。

 

    选项 :

    --color  diff 语法高亮

 

or:

 

   $ git-format-patch --stdout -1 721151d004dcf01a71b12bb6b893f9160284cf6e

   --stdout 指定 git 写到标准输出,否则会写入到磁盘中。

 

or:

 

   $ git-show 721151d004dcf01a71b12bb6b893f9160284cf6e

 

 

git-shortlog

------------

 

类似于git-log,只是简略。

 

 

git-bisect的用法

----------------

/*{{{*/    $ git-bisect start

   $ git-bisect bad    // 该版本的 kernel 标记为 bad

 

    或者有针对性的:

 

   /*  只对 2.6.22-rc1 之后、 2.6.22-rc2 之间的 commits 进行 bisect */

   $ git-bisect bad v2.6.22-rc1

   $ git-bisect good v2.6.22-rc2

 

 

LABEL:     在你指定了 bad  good 之后,如果这两个版本之间有 1000  revisions  git 就默认剔除了 500个,你应该在此时测试该版本:

 

    创建一个临时性的 output 目录 :

 

   $ make ../git_bisect_output/

    编译:

 

   $ make O=../git_bisect_output/ menuconfig 

   $ make O=../git_bisect_output/ V=1 -j4 

   $ sudo make O=../git_bisect_output/ V=1 modules_install install

    注意,最好在 menuconfig 时,给 local version 加上一个 string ,例如 take1  take2 等。

 

    启动新编译的 kernel ,如果还有 BUG 

 

   $ git-bisect bad

 

    如果没有 BUG 了:

 

   $ git-bisect good

 

   goto LABEL;

 

 

    直到某个时候,只剩下一个 revision 可以怀疑,那时候就可以确认是它引入了 BUG   

 

     bisect 结束,恢复到 master 版本:

 

#  git-bisect reset

 

 

   [ 注意 ]

    git bisect 是一个漫长而痛苦的过程。我在 Dell Optiplex745(2G 内存 /Core2 双核 2G) 机器上足足做了一天,才定位到一个 BUG 

 

   [replay 的用法 ]

    如果应该输入 git-bisect good 的时候,不小心输入了 git-bisect bad    或者本应该输入 git-bisect bad 的时候不小心写成了

git-bisect  good    则可以这样回退:

 

1)  git-bisect log | tee ../git.bisect.log

2)   修改 ../git.bisect.log ,删掉最后两行  --  也就是回退 1 步。   如果需要回退 N 步,那就删掉 N 个最后两行

3)  git-bisect replay ../git.bisect.log

 

   [visualize 的用法 ]

    git-bisect 的时间很长,因为可能需要编译 N 次内核。   在此期间,可以用:

 

$  git-bisect visualize

 

来在gitk中查看目前还待检验的那些Revs。  

FYI:   如果你象我一样更喜欢 qgit ,可以修改 `which git-bisect` 脚本,将 'gitk' 字样替换成 'qgit' 

/*}}}*/

 

 

修改上次commit的log  message

---------------------------

 

   // 下面这个方法真土 .. 事实上, git-citool 只是 git-commit  GUI 形式

   $ git-citool  GUI 界面的 git-commit    不但可以提交,而且可以编辑上次 commit 的信息。

 

or:

 

   // 修改

   $ git-commit --amend

 

同理,使用git-commit的--amend模式还可以修改last  commit   * 内容 *.

 

->  git-stash    // 藏起未提交的工作, make your branch looks `clean'

->   修改文件,直到你满意

->  git-commit -a --amend  // 编辑 msg

->  git-stash apply  //undo the stash

 

 

修改某个commit的msg和内容!!

---------------------------

 

[WARNING]   修改一个已经不在 HEAD 位置的 commit ,无论是修改其 msg 还是内容,都必须发生在  *  commit尚未被

    2 人看到  的情况下,也就是说,没有 push 给别人,也没有被别人 pull 过。

   否则,这种修改会造成开发社区的混乱 (think about that...) 

 

 

假定我们同时修改msg和内容:

[FYI]   对于只修改 msg 的情形,也走这个步骤,但是注意 "5, rebase" 的时候,选 edit( 而不是 squash) 即可。

 

1,   记住那个要修改的 commit ID  SHA1 串的前 5 个字母即可。   例如它是 27675 

 

2,   记住 27675 的前一个 commit ,例如它是 534e3 

 

3,  git-show 27675 看看它的内容,并用 Vim 修改相应的文件,改到自己满意为止;

 

4,   提交改动

 

$  git-commit -a -m "a new commit, just to be combined with 27675"

 

假设其ID是12345。

 

5,  rebase

 

$  git-rebase -i 534e3

 

    这时 git 会调用 vim 来让你编辑,你会看到一行行 "pick 1acb3e <commit msg>" ,这些 commits 都是发生在

    我们要在 git-rebase  指定的 534e3 之后的。   此时:

 

->   如果你删除一行,那么 git-rebase 就会让这个 commit 消失;

->   如果你删除所有行,那么 git-rebase 就放弃这次操作;

->   如果你把某一行的 "pick" 改成了 "squash" ,那么 git-rebase 就会把这个 commit * 合并  到它的上一行

     commit 里,并再次调用 Vim 让你编辑合并后的 commit msg 

->   如果你把某一行的 "pick" 改成 "edit" ,那么 git 就会让你执行 : a) git-commit --amend   b) git-rebase

   --continue ,这样可以修改其 msg    注意 SHA1 ID 会改变。

 

    我们需要的就是上面的第 3 种情形。   找到 12345 那行,把 pick 改成 squash ,然后 dd 删除该行, p 命令粘贴在 27675

    那行的下面, :wq 退出 Vim 

 

    马上 Git 会再次调用 Vim ,让你编辑合并后的 commit  msg     编辑后保存退出。

 

6,   再次查看合并后的 commit

 

$  git-log  查找 msg  或者  git-whatchanged -p <file> 查找补丁

 

    这时你发现新 commit  ID 变了,既不是 27675 也不是 12345 ,而是一个新的SHA1  ID 

 

 

 

 

desribe

-------

 

   $ git-describe

   v2.6.25-rc2-347-g97f7905

 

merge

-----

   git-pull/git-push 会默认调用 git-merge ,一般会成功;   如果失败,那就要:

 

   1,  该命令必然失败,因为 confilicts 存在:

 

    $ git-merge

 

   2,  查看冲突 ( 冲突的地方已经像 CVS update 冲突那样,在冲突文件中用>>>>和<<<<标记了):

 

$  git-diff

 

   3,  修改冲突文件,改成你想要的样子

 

   4,  更新 index

 

$  git-update-index

 

   5, commit 这次 merge

 

$  git-commit -a -e -s

 

 

archive

-------

可以把当前版本(HEAD所处的位置)给export出来。  e.g.

 

   $ git-describe

   v2.6.25-rc4-155-g10c36be

 

   $ mkdir ../linux-2.6.25-rc2-347-g97f7905

   $ git-archive -v v2.6.25-rc2-347-g97f7905 | (cd ../linux-2.6.25-rc2-347-g97f7905/ && tar xf -)

   $ head -4 ../linux-2.6.25-rc2-347-g97f7905/Makefile

   VERSION = 2

   PATCHLEVEL = 6

   SUBLEVEL = 25

   EXTRAVERSION = -rc2

 

 

从本地git仓库中提取某个版本的kernel:

 

   $ git-archive -v v2.6.18 | (cd ../linux-2.6.18/ && tar xf -)

   -v 表示 --verbose ,注意 'v2.6.18' 可以是 git-tag -l 列出来的 tags 中的一个,也可以是其他 Rev ID 例如 HEAD 等。

 

导出最新的kernel:

 

   $ git-archive -v HEAD | (cd ../linux-HEAD/ && tar xf -)

 

或者打成tarball:

 

   $ git-archive -v --format=tar v2.6.24 |bzip2 > ../linux-2.6.24.tar.bz2

 

tag

---

 

列出当前已有的tags:

 

   $ git-tag [-l]

 

添加tag:

 

   $ git-tag v2.6.26-test

 

删除:

 

   $ git-tag -d v2.6.26-test

 

 

branch/checkout

---------------

 

添加/删除分支:

 

添加一个叫jike的分支:

 

   $ git-branch jike

 

删除该branch:

 

   $ git-branch -d jike

 

列出所有分支:

 

   $ git-branch    // 列出所有本地分支

   $ git-branch -a  // 列出所有分支,包括 remote    local branches

   $ git-branch -r  // 列出 remote branches

 

查看目前在哪个branch上

 

$  git-branch

jike

*master

 

切换到某个branch:

 

   $ git-checkout jike    /*  从当前分支 ( 一般是 master)  checkout 并切换到 jike 分支  */ 

   -f  表示覆盖 jike 分支里未提交的内容 (FIXME: 是不是连 master 分支里未提交的内容也都丢失了 ?)

 

/*{{{*/   例子:从 remote 的分支 checkout 到一个新的本地 branch 

 

    例如我 clone 了一个远程的仓库,进入那个目录,看看有哪些 branches 

 

$  git-branch -a

*  master

origin/multiple-msi-20080711

 

    这时候我有可能想把 origin/multiple-msi-20080711 这个 remote branch  checkout 出来,并

    为它新建一个叫做 msi 的本地 branch 

 

$  git-checkout origin/multiple-msi-20080711 -b msi

 

    再看看:

 

$  git-branch -a

master

*  msi

origin/multiple-msi-20080711

 

/*}}}*/

 

/*{{{*/ Linux自从2.6.24-rc1,就开始把i386和x86-64合并为x86的工作,有时候需要track旧的代码。

(say,   我不知道 git-whatchanged -p arch/x86/kernel/apic_32.c 怎么能够连以前的arch/i386/kernel/apic.c

也跟踪到)   这时候可以有一个 workaround   checkout v2.6.23 这个 tag 

 

$  git-checkout v2.6.23

注意,只有在git  1.5.x 以及更新的版本上才支持这个操作。   这样 checkout 之后, HEAD  detach 掉了,

亦即:你不在任何branch上。git-branch会告诉你你在(no  branch) 上。

那么,怎么切换到原来的状态?   再次 git-checkout master 即可。

 

在1.5之前,也包括现在,还可以为v2.6.23创建一个branch,用于查看i386或者x86-64的版本历史:

 

$  git-checkout v2.6.23 -b v2.6.23

/*}}}*/

 

注意,有了master和jike两个分支之后,所有的修改、commit、revert工作,都在jike这个branch

上进行;而master这个branch,只用来每天git  pull 保持和 upstream 的同步。

 

 

 

rebase

------

 

当jike这个分支有自己的commit、自己的改动,要重新和master分支同步一下

(将自己的local  commits 重新 rebase  master 里新引入的改动之上 ) 

 

$  git-checkout jike

$  git-rebase -i master 

-i,表示interactive

/*   如果 rebase 失败,说明有冲突 (jike  master 冲突 ) ,修改,然后:

 *       $ git-rebase --continue

 */

 

/*{{{*/   一个 git-rebase 的例子:

 

//目前有master和jike两个branches

[arc@localhost  linux-2.6]$ git-branch

  jike

*  master

 

//master分支比jike新

[arc@localhost  linux-2.6]$ git-describe

v2.6.27-rc5-361-g82a28c7

[arc@localhost  linux-2.6]$ git-checkout jike

Switched  to branch "jike"

[arc@localhost  linux-2.6]$ git-describe

v2.6.27-rc5-320-gf8a561a

 

//jike分支的HEAD位于一个local  commit 

[arc@localhost  linux-2.6]$ git log -1

      1 commit f8a561aa5fef94becc76a5509a369b742f925058

      2 Author: Jike Song <[email]albcamus@gmail.com[/email]>

      3 Date:   Mon Sep 8 22:26:14 2008 +0800

      4

      5     PCI: utilize calculated results when detecting MSI features

      6

      7     in function msi_capability_init, we can make use of the calculated

      8     results instead of calling is_mask_bit_support and is_64bit_address

      9     twice, in spite of the fact that they are macros.

     10

     11     Signed-off-by: Jike Song <[email]albcamus@gmail.com[/email]>

 

//在jike分支里执行git-rebase,-i表示interactive

[arc@localhost  linux-2.6]$ git-rebase -i master

Successfully  rebased and updated refs/heads/jike.

 

//已经rebase了master分支,现在jike分支除了作为HEAD的local  commit 之外,和 master 一样了

//注意,这里jike分支是rc5-362,此时master分支是rc5-361,正好多一个commit,就是我本地的这个

[arc@localhost  linux-2.6]$ git-describe

v2.6.27-rc5-362-gedaa7ca

[arc@localhost  linux-2.6]$ git log -1

      1 commit edaa7ca47705cc6ca695e267f88f91dbe958da44

      2 Author: Jike Song <[email]albcamus@gmail.com[/email]>

      3 Date:   Mon Sep 8 22:26:14 2008 +0800

      4

      5     PCI: utilize calculated results when detecting MSI features

      6

      7     in function msi_capability_init, we can make use of the calculated

      8     results instead of calling is_mask_bit_support and is_64bit_address

      9     twice, in spite of the fact that they are macros.

     10

     11     Signed-off-by: Jike Song <[email]albcamus@gmail.com[/email]>

/*}}}*/

 

 

pull

----

(pull的访问方式也适用于clone)

 

pull某一个分支:

 

例如我想在/mnt/usb3/linux-2.6的master分支上,来pull  ~/Sources/linux-2.6  jike 分支:

 

   $ cd /mnt/usb3/linux-2.6

   $ git-pull -v /home/arc/Sources/linux-2.6 jike:master

   --no-commit  告诉 git 不要真正 commit ,就像出现 merge confilict 了一样。   这样可以给执行

   git pull 的用户一个机会来 review 他从别人那里 pull 来的这些代码。

 

FYI:通过SSH协议:

 

   $ git-pull [email]root@myhost.xyz.com[/email]:/export/home/Sources/linux-2.6 master:master

 

把同一仓库中的master分支pull到jike分支:

 

   $ git-pull -v . master:jike

 

 

pull  request

------------

 

   $ git-request-pull <start commit> <url> [<end>]

 

    产生 pull request 信息,打印到标准输出。   其中<end>可以不指定,这样就默认为HEAD。  <url> 应该是

    一个 git url ,例如 "git://git.infradead.org/users/jaswinder/linux-2.6-tip.git" ,这个 url 会包含

     git-request-pull 的输出中 .

 

push

-----

例如我在/mnt/usb3/linux-2.6上,想把push到~/Sources/linux-2.6中:

 

   $ cd /mnt/usb3/linux-2.6

   $ git-push  ~/Sources/linux-2.6  master:refs/remotes/jike

 

"master:refs/remotes/master"是传给git-push的refspec,告诉git把我这里的master分支push到<url>指定

的仓库(这里是~/Sources/linux-2.6)的jike分支上。  

 

然后,并不是说在~/Sources/linux-2.6上的jike分支已经merge了/mnt/usb3/linux-2.6的master分支了,还

需要这样:

 

   $ cd ~/Sources/linux-2.6

 

   $ git-pull -v .  refs/remotes/jike:jike  // 真正 pull  jike 分支上

 

grep

----

例如我看到dmesg的一个报错:

evdev.c(EVIOCGBIT):  Suspicious buffer size 511, limiting output to 64 bytes. 

See   http://userweb.kernel.org/~dtor/eviocgbit-bug.html 

想看看内核中哪里报的(当然这个例子都给出文件名了):

 

   $ git-grep "limiting output to"

         1 drivers/input/evdev.c:                          "limiting output to %zu bytes. See "

 

 

优化

----

git使用一段时间之后,仓库会越来越大,需要隔一段时间就手工执行命令来优化(FIXME:  TBD)

 

   $ git-gc

   FYI: 'gc' stands for 'garbage collection'

 

   $ git-prune

 

   $ git-fsck

 

alias

-----

git允许自定义命令的alias,在.git/config中添加:

 

[alias]

co  = checkout

 

那么执行git  co 就相当于 git checkout 

 

 

 

mailinfo  & am

-------------

 

   $ git-mailinfo msg patch  <   /path/to/your/filename.eml

    分析邮件,把 commit log 写到 msg 文件,补丁写到 patch 文件。   其他信息打印到标准输出。

 

从mail文件中打补丁:

 

   $ git-am --utf8 -s  <  /path/to/your/filename.eml

   -s 等价于 --signoff

 

   git-am 会在当前目录下产生一个 .dotest/ 目录,如果成功 apply ,这个目录会消失;如果 git-am 失败,则需要手工

    解决冲突,修改到一个自己满意的状态,然后执行:

 

   $ git-am --resolved

 

    这时会继续尝试从 .dotest 目录中 apply 这个邮件中的补丁。   或者,作为 maintainer ,你认为这个补丁需要重写,

    现在放弃 apply 它:

 

   $ git-am --skip

 

 

send-email

----------

 

在普通的网络环境里(我用mail.hit.edu.cn的SMTP  server)    有时出现错误:

 

Need  MIME::Base64 and Authen::SASL todo auth

 

这说明需要安装MIME::Base64和Authen::SASL两个包:

 

$  sudo yum -y install perl-Email-MIME-Encodings perl-Authen-SASL

 

然后:

 

$  git-send-email --to [email]someone@somewhare.com[/email] --compose /

--smtp-server  202.118.224.153 --smtp-server-port 25 /

--smtp-user  albcamus /

/path/to/your/filename.patch

 

只要指定了--smtp-user,如果需要密码,会在命令行提示输入(不回显).

 

 

用gmail的smtp账户发邮件

-----------------------

1.   安装 msmtp

2.   建立 ~/.msmtprc 文件, chmod  0600 ,内容为 :

 

   // 一种配置。   已验证此 ~/.msmtprc 文件在公司内网可用,但 Linux 上不行

defaults

tls  on

account  gmail

host  smtp.gmail.com

from  [email]albcamus@gmail.com[/email]

auth  on

user  [email]albcamus@gmail.com[/email]

password  [mypasswd]

port  587

account  default:gmail

 

   // 另一种配置。    Linux 上,公司里和家里都能用

   // 注意 /etc/pki/tls/certs/ca-bundle.crt 在我的 FC8 上是 openssl 包中的

       defaults

       tls on

       tls_trust_file /etc/pki/tls/certs/ca-bundle.crt

       logfile ~/.msmtp.log

       # My email service

       account gmail

       host smtp.gmail.com

       port 587

       from [email]albcamus@gmail.com[/email]

       auth on

       user [email]albcamus@gmail.com[/email]

       password 

       # Set a default account

       account default : gmail

 

 

    注意上面的 ~/.msmtprc 文件中, password 命令后面,或者跟上真正的 SMTP 密码 ( 只能以明文保存 !) ,或者

    留空。   如果留空,而你的 SMTP server 要求一个密码, msmtp 会去查询 ~/.netrc 文件;   如果还找不到,那

    么就会在命令行 ( 当然我们是在 git-send-email 的提示下,因为并不直接调用 msmtp 命令 ) 提示你输入,并

    且不回显密码。

 

   FIXME:  为什么我用 git-send-email 发送补丁时,总是会发送两封邮件?   第一封是什么内容都没有的,

      (subject 则是 --subject 指定的,或者 --compose 调用 Vim 编写的 ) ,第 2 封才是真正的补丁?

 

 

3.   发送

 

$  cd ~/Sources/linux-2.6

$  git-send-email --to <[email]someone@xx.com[/email]> --compose --smtp-server /usr/bin/msmtp  </path/to/your/patch/file>

 

    也可以把 msmtp 写到 .git/config 中去:

 

$  git-config sendemail.smtpserver /usr/bin/msmtp

 

    这样在调用 git-send-email 的时候默认就会以 msmtp 程序作为 smtp server --  当然如果你又指定了 "--smtp-server" 的话,就

    不会采用 .git/config 里的配置了。

 

 

 

 

使用git-tools来处理mbox里的patch:

---------------------------------

 

$  git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/git-tools.git 

然后编译、安装。  

 

它提供了applypatch,  cvs2git, dotest, mailinfo, mailsplit, stripspace 这些工具。

 

 

email注意事项

-------------

 

1)   可以用 xclip 程序来复制补丁

 

  $ git-format-patch -1 --stdout <SHA1 ID> | xclip

  Note, xclip 程序目前似乎不能处理 UTF-8 字符。

 

    然后鼠标中键粘贴。

 

2)   确认你的编辑器不 wrap word

 

    如使用 thunderbird 的插件: External Editor 指定 Vim 编辑器 (say, "konsole -e vim") 等,确认不wrap word 

 

   FYI:  不知道为什么 External Editor 指定 konsole -e vim ,会自动 set tw=72 ,即使是 ~/.vimrc 设置了tw=0 

    不行。   这时候给 vim 加上参数 -c "set tw=0" 就可以了,亦即告诉 vim  load 完文件后执行 "set tw=0"这个

命令。

 

    我是这么指定 external editor 的:

 

konsole  --noframe --nomenubar --noscrollbar --notabbar -e vim -c "set tw=0"

 

3)  thunderbird 设置

 

   1, View > Sort by  选择 Threaded ,可以把同一主题的 Re:xxx 分层列出。

 

   2, View Settings for this account > composition & addressing,

 

uncheck  "Compose messages in HTML format"

 

   3,  编辑 ~/.thunderbird/92r39mnp.default/prefs.js 文件,加两行:

 

user_pref("mailnews.wraplength",  0);

user_pref("mailnews.send_plaintext_flowed",  false);

 

       注意  92r39mnp.default   ~/.thunderbird/profiles.ini 中的 Path 字段的值。

 

 4) NOTE:  即使用了这些设置,用了 Vim 编辑邮件,使用 thunderbird 发补丁依然会遇到 malformed 问题 :(  我真是

     没办法了,只好只用 git-send-email...

 

 

 

 

 

使用free  git hosting

--------------------

 

Internet上有很多免费的git  hosting sites ,你可以把自己的项目放在上边,以便和别人协同开发。  git 官方站点

有一个页面列出了常用的站点:

 

http://git.or.cz/gitwiki/GitHosting

 

其中最老的site是:

 

http://repo.or.cz

 

该站点要求项目必须是*free  software* 

 

另一个现在最受欢迎(没用过,看别人的评论)的是:

 

http://github.com/

 

GITHUB把projects分为3种:  a) opensource projects ,免费;  b) personal projects ,收费; c) business projects 

当然收费:)

 

 

 

 

 

 

 

 

 

88,  AKA 2007 Linux 内核开发者大会  Bryan Wu 的演讲 'living rules in kernel community'

 

    kernel.org   3 方面重要功能:  1, git trees

          各个 git trees 的地址和说明:

         http://git.kernel.org/

      2, bugzilla

 3, LKML

     各个邮件列表的地址:

    http://vger.kernel.org/vger-lists.html

 

     一个 lkml 的归档下载:

    http://userweb.kernel.org/~akpm/lkml-mbox-archives/

      2000 年的都有。

 

    TERM:

 

    mailine == linus tree

    vanilla == stable kernel

 

    rcX     == linus tree 上的 git tag ,每个 rc 版本会持续 1-2 

 

    merge window  :  例如从 2.6.22  2.6.23-rc1 ,此时称为 merge window is open.

          一般情况下 merge window  2 周时间。

     这时可以发有很大改动的 patch(es).

      2.6.23-rc1 开始,称做 merge window is closed.  只有 bugfix

     等,不接受大的改动。

 

    -mm   : Andrew Morton  git tree ,实际上是 patches 的打包,每个 rc 版会有 1-3 

    mm trees 

    http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/

 

    2.6.x.y  : stable tree ,由 Greg KH 维护的稳定版本,主要是引入对 2.6.x 

   一些漏洞修正等补丁。  ([email]stable@kernel.org[/email])

 

    -git<N> :  一些 git  snapshots ,可以从这里下载:

http://www.kernel.org/pub/linux/kernel/v2.6/snapshots/

 

 

     补丁的注意事项:

     1,  一行不能超过 80 列,这是硬规定

2,    scripts/checkpatch.pl 检查自己的 patch

3,   所有的 patch 都要通过 LKML

 

 

    git 及其他:

     1, quilt   -mm tree 用它管理 patches

2,  guilt   quilt for git

http://www.kernel.org/pub/linux/kernel/people/jsipek/guilt/

3,  git-gui, gitk, qgit, gitweb, etc...

 

Pasted from <http://www.chinaunix.net/jh/4/920610.html >

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值