Git的Patch功能和msg模板设置、git服务器搭建、KVM virsh常用命令

本文整理编辑自:

Git的Patch功能 - 老z的博客 - 博客园

http://yuxu9710108.blog.163.com/blog/static/2375153420101114488765/

一、前言

UNIX世界的软件开发大多都是协作式的,因此, Patch (补丁)是一个相当重要的东西,因为几乎所有的大型UNIX项目的普通贡献者,都是通过 Patch 来提交代码的。作为最重要的开源项目之一,Linux,也是这样的。普通开发者从软件仓库clone下代码,然后写入代码,做一个 Patch , 最后用E-mail发给Linux Kernel的维护者就好了。 Git 最初作为Linux的版本控制工具,提供了透明、完整、稳定的 Patch功能 。

   我们先介绍一下Patch是什么。如果一个软件有了新版本,我们可以完整地下载新版本的代码进行编译安装。然而,像Linux Kernel这样的大型项目,代码即使压缩,也超过70MB,每次全新下载是有相当大的代价的。然而,每次更新变动的代码可能不超过1MB,因此,我们只 要能够有两个版本代码的diff的数据,应该就可以以极低的代价更新程序了。因此,Larry Wall开发了一个工具:patch。它可以根据一个diff文件进行版本更新。

  不过在git中,我们没有必要直接使用diff和patch来做补丁,这样做既危险又麻烦。

git 提供了两种简单的 patch方案 。一是用 git diff 生成的 标准patch ,二是 git format-patch 生成的 Git专用Patch 。

二、git diff生成的标准patch

2.1、制作标准补丁

我们可以首先用 git diff 制作一个 patch 。

本文示例的工作目录里最初有一个 文件a ,内容是“This is the file a.”,放置在master分支中。为了修改代码,我们一般的做法是建立一个新分支:

sweetdum@sweetdum-ASUS:~/GitEx$  git   branch  Fix

sweetdum@sweetdum-ASUS:~/GitEx$  git   checkout  Fix

Switched to branch 'Fix'

接下来我们在a文件里面追加一行,然后执行 git diff 。

sweetdum@sweetdum-ASUS:~/GitEx$  echo 'Fix!!!'>> a

sweetdum@sweetdum-ASUS:~/GitEx$  git diff

diff --git a/a b/a

index 4add65f..0d295ac 100644

--- a/a

+++ b/a

@@ -1 +1,2 @@

This is the file a.

+Fix!!!

我们看到了Git diff的输出,这是一个非常典型的Patch式diff。这样我们可以直接把这个输出变为一个Patch:

sweetdum@sweetdum-ASUS:~/GitEx$  git   commit   -a   -m  " Fix "

[Fix b88c46b] Fix

1 files changed, 1 insertions(+), 0 deletions(-)

sweetdum@sweetdum-ASUS:~/GitEx$  git   diff   master  >  patch

sweetdum@sweetdum-ASUS:~/GitEx$  git   checkout   master

Switched to branch 'master'

2.2、应用标准补丁

我们现在有一个patch文件,并且签出了master,接下来我们可以使用git apply来应用这个patch。当然了,实际应用中,我们不会这样在一个分支建patch,到另一个分支去应用,因为只有merge一下就好了。我们现 在权当没有这个Fix分支。一般情况下,为了保护master,我们会建立一个名叫 PATCH 的分支来专门处理新提交来的patch的

sweetdum@sweetdum-ASUS:~/GitEx$  git   branch   PATCH

sweetdum@sweetdum-ASUS:~/GitEx$  git   checkout   PATCH

Switched to branch 'PATCH'

sweetdum@sweetdum-ASUS:~/GitEx$  git   apply   patch

sweetdum@sweetdum-ASUS:~/GitEx$  git   commit   -a -m   "Patch Apply"

[PATCH 9740af8] Patch Apply

1 files changed, 1 insertions(+), 0 deletions(-)

看,现在我们在PATCH分支中应用了这个补丁,我们可以把PATCH分支和Fix比对一下,结果肯定是什么也没有,说明PATCH分支和Fix分支完全一样。patch应用成功。即使有多个文件git diff 也能生成一个patch。

三、git format-patch生成的git专用补丁

3.1、制作git专用补丁

我们同样用上面那个例子的工作目录,这次,我们在Fix分支中的a添加了新行之后,用 git format-patch生成一个patch。

sweetdum@sweetdum-ASUS:~/GitEx$  git   checkout  Fix

Switched to branch 'Fix'

sweetdum@sweetdum-ASUS:~/GitEx$  echo 'Fix!!!'>>a

sweetdum@sweetdum-ASUS:~/GitEx$  git   commit -a  -m  "Fix1"

[Fix 6991743] Fix1

1 files changed, 1 insertions(+), 0 deletions(-)

sweetdum@sweetdum-ASUS:~/GitEx$  git   format-patch   -M   master

0001-Fix1.patch

git  format-patch 的-M选项表示这个patch所在的当前分支要和那个分支比对。现在它生成了一个patch文件,我们看看那是什么:

sweetdum@sweetdum-ASUS:~/GitEx$  cat  0001-Fix1.patch

From 6991743354857c9a6909a253e859e886165b0d90 Mon Sep 17 00:00:00 2001

From: Sweetdumplings <linmx0130@163.com>

Date: Mon, 29 Aug 2011 14:06:12 +0800

Subject: [PATCH] Fix1

---

a |    1 +

1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/a b/a

index 4add65f..0d295ac 100644

--- a/a

+++ b/a

@@ -1 +1,2 @@

This is the file a.

+Fix!!!

--

1.7.4.1

看,这次多了好多东西,不仅有diff的信息,还有提交者,时间等等,仔细一看你会发现,这是个E-mail的文件,你可以直接发送它!

注意 : 如果master与Fix分支中间有多次提交,它会针对每次提交生成一个 patch 。

3.2、应用git专用补丁

git format-patch 生成的补丁,必须使 用 git am命令 来应用。

sweetdum@sweetdum-ASUS:~/GitEx$  git   checkout  master

Switched to branch 'master'

sweetdum@sweetdum-ASUS:~/GitEx$  git   branch   PATCH

sweetdum@sweetdum-ASUS:~/GitEx$  git  checkout   PATCH

sweetdum@sweetdum-ASUS:~/GitEx$  git   am   0001-Fix1.patch

Applying: Fix1

sweetdum@sweetdum-ASUS:~/GitEx$  git   commit -a -m  " PATCH apply"

在提交了补丁之后,我们可以再看看目前文件a的情况:

sweetdum@sweetdum-ASUS:~/GitEx$  cat   a

This is the file a.

Fix!!!

果然,多了一个Fix!!!

3.3、应用多个git专用patch

因为在git使用当中,会有很多时候别人(供应商或者其他的开发人员)发过来一系列的patch,这些patch通常的是类似这样的名字:

git-am  可以一次合并一个文件,或者一个目录下所有的patch,或者你的邮箱目录下的patch.

在使用git-am之前, 你要首先 git am –abort  一次,来放弃掉以前的am信息,这样才可以进行一次全新的am。

不然会遇到这样的错误。

.git/rebase-apply still exists but mbox given.

下面举两个例子:

示例1

你现在有一个code base: small-src, 你的patch文件放在~/patch/0001-trival-patch.patch

cd small-src

git am ~/patch/0001-trival-patch.patch

如果成功patch上去, 你就可以去喝杯茶了。

如果失败了, git 会提示错误, 比如:

error: patch failed: android/mediascanner.cpp:452

error: android/mediascanner.cpp: patch does not apply

这样你就需要先看看patch, 然后改改错误的这个文件,让这个patch能够patch上去。

示例2

你有一堆patch, 名字是上面提到的那一堆patch, 你把他们放在~/patch-set/目录下(路径随意)

cd opencore

git   am   ~/patch-set/*.patch

(这里git就会按照文件名的顺序一次am这些patch)

如果一切顺利, 你所有的patch都OK了, 你又Lucky了。

3.4、应用git专用补丁失败

在使用 git  am 打补丁时,如果中间遇到了应用某个patch失败,那么 git   am 就会停到打这个 patch的地方, 告诉你是哪个patch打不上去。

比如我现在有一个文件file,有两个patch.

file 的内容是

the text

more text

两个patch分别是:

0001-add-line.patch补丁文件 :

From 48869ccbced494e05738090afa5a54f2a261df0f Mon Sep 17 00:00:00 2001

From: zhangjiejing <zhangjiejing@zhangjiejing-desktop.(none)>

Date: Thu, 22 Apr 2010 13:04:34 +0800

Subject: [PATCH 1/2] add line

---

 file |    2 ++

 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/file b/file

index 067780e..685f0fa 100644

--- a/file

+++ b/file

@@ -3,3 +3,5 @@ file:

 some text

 more text

+

+add line

--

1.6.3.3

0002-change-line.patch 补丁文件:

From f756e1b3a87c216b7e0afea9d15badd033171578 Mon Sep 17 00:00:00 2001

From: zhangjiejing <zhangjiejing@zhangjiejing-desktop.(none)>

Date: Thu, 22 Apr 2010 13:05:19 +0800

Subject: [PATCH 2/2] change line

---

 file |    2 +-

 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/file b/file

index 685f0fa..7af7852 100644

--- a/file

+++ b/file

@@ -1,6 +1,6 @@

 file:

-some text

+Change line text

 more text

--

1.6.3.3

运行

git am *.patch 来应用这些patch, 报错,  Patch failed at  0001 add line

这样我们看0001这 个patch,原来patch需要的是 some text , 而file里面是 the text,  所以我们用编 辑器把这行改成some text,

vi file

git apply  0001-add-line.patch

git add file

git am --resolved

在解决完冲突以后, 比如用git add来让git知道你已经解决完冲突了。

如果你发现这个冲突是无法解决的, 要撤销整个am的东西。 可以运行 git am –abort ,

如果你想只是忽略这一个 patch ,可以运行 git am –skip 来跳过这个patch.

四、两种patch的比较

兼容性 :很明显,git diff生成的Patch兼容性强。如果你在修改的代码的官方版本库不是Git管理的版本库,那么你必须使用git diff生成的patch才能让你的代码被项目的维护人接受。

除错功能 :对于git diff生成的patch,你可以用 git apply --check  查看补丁是否能够干净顺利地应用到当前分支中;如果git format-patch 生成的补丁不能打到当前分支,git am会给出提示,并协助你完成打补丁工作,你也可以使用git am -3进行三方合并,详细的做法可以参考git手册或者《Progit》。从这一点上看,两者除错功能都很强。

版本库信息 :由于git format-patch生成的补丁中含有这个补丁开发者的名字,因此在应用补丁时,这个名字会被记录进版本库,显然,这样做是恰当的。因此,目前使用Git的开源社区往往建议大家使用format-patch生成补丁。

五、msg模板设置


但是你又不想那么麻烦每次提交都输入这些标识。我们可以设置一个提交模板。
编写一个commit.template文件,如上面内容,然后做如下操作

cp commit.template ~/.gitmessage
git config --global commit.template ~/.gitmessage


执行git config -l,可以看到多了一行commit.template=~/.gitmessage 的信息
那么提交代码时还是执行git commit
这时就会交互出现提交模板,照既定的格式填写必要的内容保存就可以了。

六、git服务器搭建

上一章节中我们远程仓库使用了 Github,Github 公开的项目是免费的,2019 年开始 Github 私有存储库也可以无限制使用。

这当然我们也可以自己搭建一台 Git 服务器作为私有仓库使用。

接下来我们将以 Centos 为例搭建 Git 服务器。

1、安装Git

$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git

接下来我们 创建一个git用户组和用户,用来运行git服务:

$ groupadd git
$ useradd git -g git

2、创建证书登录

收集所有需要登录的用户的公钥,公钥位于id_rsa.pub文件中,把我们的公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。

如果没有该文件创建它:

$ cd /home/git/
$ mkdir .ssh
$ chmod 755 .ssh
$ touch .ssh/authorized_keys
$ chmod 644 .ssh/authorized_keys

3、初始化Git仓库

首先我们选定一个目录作为Git仓库,假定是/home/gitrepo/runoob.git,在/home/gitrepo目录下输入命令:

$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo

$ git init --bare runoob.git
Initialized empty Git repository in /home/gitrepo/runoob.git/

以上命令Git创建一个空仓库,服务器上的Git仓库通常都以.git结尾。然后,把仓库所属用户改为git:

$ chown -R git:git runoob.git

4、克隆仓库

$ git clone git@192.168.45.4:/home/gitrepo/runoob.git
Cloning into 'runoob'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

192.168.45.4 为 Git 所在服务器 ip ,你需要将其修改为你自己的 Git 服务 ip。

这样我们的 Git 服务器安装就完成。

七、KVM virsh常用命令

KVM virsh常用命令 - 简书

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值