2005年,Linus Torvalds不满足于当时任何一个可用的开源版本控制系统,于是就亲手开发了一个全新的版本控制软件——git。git发展到今天,已经成为全世界最流行的代码版本管理软件之一,微软公司的开发工具也支持git。
早年,Linus Torvalds选择了一个商业版本的代码控制系统BitKeeper来管理Linux内核代码。BitKeeper是由BitMover公司开发的,授权Linux社区免费使用。到了2005年,Linux社区中有人试图破解BitKeeper协议时被BitMover公司发现,因此BitMover公司收回了BitKeeper的授权,于是Linus花了两周时间用C语言写了一个分布式版本控制系统,git就这样诞生了。
在学习git这个工具之前,有必要了解一下集中式版本控制系统和分布式版本控制系统。
集中式版本控制系统是把版本库集中存放在中央服务器里,当我们需要编辑代码时,从中央服务器中获取最新的版本,然后编写或者修改代码。代码修改和测试完成之后,需要把修改的东西推送到中央服务器中。集中式版本控制系统需要每次都连接中央服务器,如果有很多人协同工作,网络带宽是一个瓶颈。
和集中式版本控制系统相比,分布式版本控制系统没有中央服务器的概念,每个人的电脑就是一个完整的版本库,这样工作时就不需要联网,和网络带宽无关。分布式版本便于多人协同工作,比如A修改了文件1,B也修改了文件1,那么A和B只需要把各自的修改推送给对方,就可以相互看到对方的修改内容了。
使用git进行开源工作的流程一般如下。
复制项目git仓库到本地工作目录。
在本地工作目录里添加或者修改文件。
提交修改之前检查补丁格式等。
提交修改。
生成补丁发给评审,等待评审意见。
评审发送修改意见,再次修改并提交。
直到评审同意该补丁并且合并到主干分支上。
下面介绍一下git常用的命令。
在优麒麟Linux中使用apt-get工具来安装git。
$ sudo apt-get install git
在使用git之前需要配置用户信息,如用户名和邮箱信息。
$ git config --global user.name "xxx"
$ git config --global user.email xxx@xxx.com
设置git默认使用的文本编辑器,一般使用Vi或者Vim,当然,也可以设置为Emacs。
$ git config --global core.editor emacs
要检查已有的配置信息,可以使用 git config --list 命令。
$ git config --list
版本库又名仓库,英文是repository,可以简单理解成一个目录。这个目录中所有的文件都由git来管理,每个文件的修改、删除都可以被git跟踪,并且可以追踪提交的历史和详细信息,还可以还原到历史中某个提交,以便做回归测试。
git clone命令可以从现有的git仓库中下载代码到本地,类似svn工具的 checkout功能。如果你需要参与开源项目或者查看开源项目代码,就需要git clone这个项目的仓库到本地进行浏览或者修改。
我们以Linux内核官方的git仓库为例,通过下面的命令可以把Linux官方内核的代码仓库下载到本地。
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
上述命令执行完成之后,会在本地当前目录创建一个名为linux的目录,其中包含一个.git目录,用来保存该仓库的版本记录。
Linux内核的官方git仓库以Linus Torvalds创建的git仓库为准。每隔2~3个月,Linus就会在自己的git仓库中发布新的Linux内核版本,读者也可以到网页版本上浏览。
本书配套的代码仓库已上传到GitHub上。GitHub是一个面向开源以及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管,所以名为GitHub。
$ git clone https://github.com/figozhang/runninglinuxkernel_4.0.git
该代码仓库最大的特点是支持GCC的“O0”的方式编译内核,即去掉GCC编译优化选项。因为内核编译的默认优化选项是O2,在使用gdb进行单步调试内核时会出现光标乱跳并且无法打印有些变量的值(例如出现<optimized out>)等问题,使用“O0”来编译内核可以解决这些问题,很方便Linux内核初学者进行内核调试和学习。
通过git clone下载代码仓库到本地之后,就可以通过git log命令来查看提交(commit)的历史。
$ git log
commit d081107867b85cc7454b9d4f5aea47f65bcf06d1
Author: Michael S. Tsirkin <mst@redhat.com>
Date: Fri Apr 13 15:35:23 2018 -0700
mm/gup.c: document return value
__get_user_pages_fast handles errors differently from
get_user_pages_fast: the former always returns the number of pages
pinned, the later might return a negative error code.
Link: http://lkml.kernel.org/r/1522962072-182137-6-git-send-email- mst@redhat. com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
比如上面的git log命令,显示了一条git提交的相关信息。
一条git提交的信息包含如下。
commit id:由git生成唯一的散列值。
Author:提交的作者。
Date:提交的日期。
Message:提交的日志,比如代码修改的原因,Message中包含标题和日志正文。
Signed-off-by:对这个补丁的修改有贡献的人。
Reviewed-by:对这个补丁进行维护的人。
cc:一般需要把补丁发送给代码的维护者。
可以使用--oneline的选项来查看简洁的信息。
$ git log --oneline
d081107 mm/gup.c: document return value
c61611f get_user_pages_fast(): return -EFAULT on access_ok failure
09e35a4 mm/gup_benchmark: handle gup failures
60bb83b resource: fix integer overflow at reallocation
16e205c Merge tag 'drm-fixes-for-v4.17-rc1' of git://people.freedesktop.org/~airlied/linux
如果只想查找指定用户提交的日志,可以使用命令git log --author 。例如我们要找Linux内核源码中 Linus的提交,可以使用如下命令。
$ git log --author=Linus --oneline
16e205c Merge tag 'drm-fixes-for-v4.17-rc1' of git://people.freedesktop.org/~airlied/linux
affb028 Merge tag 'trace-v4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
0c314a9 Merge tag 'pci-v4.17-changes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
681857e Merge branch 'parisc-4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
git log还有一个参数“--patch-with-stat”,可以显示提交代码的差异、增改文件以及行数等信息。
$ git log --patch-with-stat
commit d081107867b85cc7454b9d4f5aea47f65bcf06d1
Author: Michael S. Tsirkin <mst@redhat.com>
Date: Fri Apr 13 15:35:23 2018 -0700
mm/gup.c: document return value
__get_user_pages_fast handles errors differently from
get_user_pages_fast: the former always returns the number of pages
pinned, the later might return a negative error code.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
arch/mips/mm/gup.c | 2 ++
arch/s390/mm/gup.c | 2 ++
arch/sh/mm/gup.c | 2 ++
arch/sparc/mm/gup.c | 4 ++++
mm/gup.c | 4 +++-
mm/util.c | 6 ++++--
6 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
index 1e4658e..5a4875ca 100644
--- a/arch/mips/mm/gup.c
+++ b/arch/mips/mm/gup.c
…
对某个提交进行查看,可以使用git show命令。git show命令后面需要添加某个提交的commit id,可以是缩减版本的id,如下面的例子所示。
$ git show d0811078
使用git进行提交的流程如下。
修改、增加或者删除一个或者多个文件。
使用git diff查看当前修改。
使用git status查看当前工作目录的状态。
使用git add把修改、增加或者删除的文件添加到本地版本库。
使用git commit命令生成一个提交。
git diff命令可以显示在缓存中或者未在缓存中的改动,常用的选项如下。
显示尚未缓存的改动:git diff。
查看已经缓存的改动:git diff --cached。
查看所有的改动:git diff HEAD。
显示摘要:git diff --stat。
git add命令可以把修改的文件添加到缓存中。
git rm命令删除本地仓库的某个文件。不建议直接使用rm命令。同样,需要移动一个文件或者目录,使用git mv命令。
git status命令查看当前本地仓库的状态,会显示工作目录和缓存区的状态,也会显示被缓存的修改文件以及还没有被git跟踪到的文件或者目录。
git commit命令用来将更改记录提交到本地仓库中。提交一个commit通常需要编写一个简短的日志信息,告诉其他人为什么要做这个修改。
git commit命令添加“-s”会在该提交中自动添加“Signed-off-by:”的签名。
如果需要对提交内容做修改,可以使用“git commit --amend”命令。
分支的英文名叫作branch,意味着可以从开发主线中分离出一个分支,然后在不影响主线的同时继续开发工作。分支管理在实际项目开发中非常有用,比如你要开发某个功能A,预计需要一个月时间才能完成编码和测试工作。假设你在完成编码工作时把补丁提交到主干上,没经过测试代码可能会影响项目中的其他模块,这时通常的做法是在本地建一个属于自己的分支,然后把补丁提交到这个分支上,等完成了最后的测试验证工作之后,再把补丁合并到主干上。
在管理分支之前,先要使用git branch命令查看当前git仓库里有哪些分支。
$ git branch
*master
比如Linux内核官方仓库显示只有一个分支,叫作“master”(主分支),该分支也是当前分支。当创建一个新的git仓库时,在缺省情况下git会创建“master”分支。
下面我们创建使用git branch branchname一个属于自己的分支,名为linux-benshushu。
$ git branch linux-benshushu
$ git branch
linux-benshushu
* master
“*”表示当前的分支,我们创建了一个名为linux-benshushu的分支,但是当前分支还是在master分支上。
我们可以使用git checkout branchname命令来切换分支。
$ git checkout linux-benshushu
Switched to branch 'linux-benshushu'
$ git branch
* linux-benshushu
master
另外,我们可以使用git checkout -b branchname命令来合并上述两个步骤,也就是创建新的分支并立即切换到该分支上。
如果想删除一个分支,可以使用git branch -d branchname命令。
$ git branch -d linux-benshushu
error: Cannot delete the branch 'linux-benshushu' which you are currently on.
这里显示不能删除当前的分支,所以需要切换到其他分支上才能删除该分支。
$ git checkout master
Switched to branch 'master'
$ git branch -d linux-benshushu
Deleted branch linux-benshushu (was d081107).
git merge命令用来合并指定分支到当前分支,如有一个linux-benshushu的分支,我们通过下面命令把该分支合并到主分支上。
$ git checkout master
$ git branch
linux-benshushu
* master
$ git merge linux-benshushu
Updating 60cc43f..6e82d42
Fast-forward
Makefile | 1 +
1 file changed, 1 insertion(+)
推送分支就是把本地创建的新分支上的提交推送到远程仓库中。在推送过程中,需要指定本地分支,这样才能把本地分支上的提交推送到远程仓库里对应的远程分支上。推送分支的命令格式如下。
git push <远程主机名> <本地分支名>:<远程分支名>
首先查看远程有哪些分支。
$ git branch –a
linux-benshushu
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
远程分支是以remotes开头的,可以看到远程分支只有一个,也就是origin仓库的主分支。通过下面命令可以把本地的主分支的改动推送到远程仓库的主分支上。本地分支名和远程分支名同名,因此可以忽略远程分支名。
$ git push origin master
当本地分支名和远程分支名不相同时,需要明确指出远程的分支名。如下这条命令可把本地的主分支推送到远程的dev分支上。
$ git push origin master:dev
本文摘自《奔跑吧Linux内核 入门篇》
按字母顺序浏览:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
→我们致力于为广大网民解决所遇到的各种电脑技术问题 如果您认为本词条还有待完善,请 编辑词条
上一篇买房必须懂的15个专业术语
下一篇房产证上写子女名字的影响