写点什么

Git 历险记(一)

2011 年 1 月 05 日

【编者按】作为分布式版本控制系统的重要代表——Git 已经为越来越多的人所认识,它相对于我们熟悉的 CVS、SVN 甚至同时分布式控制系统的 Mercurial,有哪些优势和不足呢。这次 InfoQ 中文站有幸邀请到《Git Community Book》的译者刘辉,在 InfoQ 开辟《Git 历险记》专栏,分享他使用 Git 的经验,以及他对 Git 的看法。


Git 是 Linus.Torvald 为了管理 Linux 内核发起并开发的一个开源分布式版本控件系统(DVCS)。从 2002 年起,Linux 内核一直使用 BitKeeper 来进行版本管理,但是在 2005 年 BitKeeper 和 Linux 内核开源社区的合作关系结束,BitKeeper 再也不能免费使用了,这迫使 Linus 决定开发一个开源界自已的版本控制系统。

传统的 SVN、CVS 等版本控制系统,只有一个仓库(repository),用户必须要连上这个仓库才能开始提交;而 Git 之类的分布式版本控制系统(当然也还包括 BitKeeper、 Mercurial 等等),它的每个工作目录都包含一个完整的仓库,它们可以支持离线工作,先把工作提交到本地仓库后再提交上远程的服务器上的仓库里。分布式的处理也让开发更为便捷,开发人员可以很方便的在本地创建分支来进行日常开发,每个人的本地仓库都是平等且独立,不会因为你的本地提交而直接影响别人。

老实说,Git 的速度是我用的版本控制系统中最快的(SVN Mercurial Git)。我这里说的速度,包括本地提交 (commit)、本地签出 (checkout)、提交到远程仓库 (git push) 和从远程仓库获取(git fetch ,git pull);它的本地操作速度和本地文件系统在一个级别,远程仓库的操作速度和 SFTP 文件传输在一个级别。这当然和 Git 的内部实现机制有关,这里就不多展开了,有兴趣的朋友可以看一下这里: Git is the next Unix

我们在学一门新的语言时,往往是从一个“hello world” 程序开始的,那么 Git 历程也就从一个“hello Git”开始吧。

在这里假设各位同学的电脑都装好了 Git,如果没有装好,可以先看一下这里(安装Git )。当然,后面的章节我会专门讲安装可能会碰到的问题。

我们首先打开Git 的命令行:windows 下是点击“Git Bash 快捷方式”;Linux 或是Unix like 平台的话就直接打开命令行界面就可以了。

备注: $ 符号后面的字符串代表的是命令行输入;命令行输入后的以#开始的黑体字符串代表注释;其它的部分则是命令行输出。

我们先用建一个仓库吧:

复制代码
$mkdir testGit <b>#建立仓库目录 </b>
$cd testGit <b>#进入仓库目录 </b>
$git init<b> #这会在当前的目录下建一个仓库 </b>
Initialized empty Git repository in e:/doc/Git/test/testGit/.git/

好的,前面的三行命令就建立了一个本地的 Git 仓库。这个仓库现在是一个空的仓库。

我们在命令行下执行:

复制代码
$ git status <b>#查看当前仓库的状态 </b>
# On branch master (在 master 分支上)
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)
(现在没有任何台被提交的文件,复制或创建新的文件,再用”git add” 命令添加到暂存区中)
$ git log <b>#查看当前仓库的历史日志 </b>
fatal: bad default revision 'HEAD'
(由于仓库里没有任提交在里面,所以它会报这个错。BTW: 这种提示是不是有点不友好呀:) )

现在就让我们在这个仓库里添加点内容吧。

复制代码
$ echo “hello Git” > readme.txt <b>#建立一个含有 hello Git 的文本文件 </b>
$ git add readme.txt <b>#将 readme.txt 添加到 <a href="http://www.google.com/url?q=http%3A%2F%2Fprogit.org%2Fbook%2Fzh%2Fch2-2.html&sa=D&sntz=1&usg=AFQjCNEYEQ9ebcoED7X5W658v903gnBUaQ"> 暂存区 </a> 中 </b>
$ git status <b>#查看当前仓库的状态 </b>
# On branch master
#
# Initial commit
#
# Changes to be committed:(暂存里下次将被提交的修改)
# (use "git rm --cached <file>..." to unstage)
#
# new file: readme.txt
#

好的,文件即然被暂存到暂存区中,我们现在就可以把它提交到仓库里面去:)

复制代码
$ git commit -m "project init" <strong>#将刚才的修改提交到本地仓库中 </strong>
[master (root-commit) 8223db3] project init
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 readme.txt
$ git status
# On branch master
nothing to commit (working directory clean)
(现在这个工作目录里没有什么要提交的东东,它是整洁的)

现在你执行一下 git log 命令就会看到刚才的提交记录

复制代码
$ git log
commit 8223db3b064a9826375041c8fea020cb2e3b17d1
Author: liuhui998 <liuhui998@gmail.com>
Date: Sat Jan 1 18:12:38 2011 +0800
project init

“8223db3b064a9826375041c8fea020cb2e3b17d1”这一串字符就是我们这次创建的提交的名字。看起来是不是很熟,如果经常用电驴的朋友就会发现它就是和电驴里内容标识符一样,都是 SHA1 串。Git 通过对提交内容进行 SHA1 Hash 运算,得到它们的 SHA1 串值,作为每个提交的唯一标识。根据一般的密码学原理来说,如果两个提交的内容不相同,那么它们的名字就不会相同;反之,如果它们的名字相同,就意味着它们的内容也相同。

现在我想改一下仓库里文件的内容,现提交到仓库中去

复制代码
$ echo "Git is Cool" >> readme.txt <strong>#在文件的最后添加一行 </strong>
$ git status <strong>#查看当前仓库的状态 </strong>
# On branch master
# Changed but not updated: (修改了,但是还没有暂存的内容)
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
<p>(没有修改可以被提交,使用 “git add” 命令添加文件到暂存区,或是使用“git commit -a” 命令强制提交当前目录下的所有文件)</p>

OK,即然我们修改了仓库里被提交的文件,那么我想看一下我们

到底改了哪些地方,再决定是否提交。

复制代码
$ git diff <strong>#查看仓库里未暂存内容和仓库已提交内容的差异 </strong>
diff --git a/readme.txt b/readme.txt
index 7b5bbd9..49ec0d6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
hello Git
+Git is Cool

很好,正如我们所愿,我们只是在 readme.txt 的最后一行添加了一行“Git is Cool”。

好的,我们现在再把 readme.txt 放到暂存区里:

复制代码
$ git add readme.txt

我们现在看一下仓库的状态:

复制代码
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readme.txt
#

可以提交了:

复制代码
$ git commit -m "Git is Cool"
[master 45ff891] Git is Cool
1 files changed, 1 insertions(+), 0 deletions(-)
(一个文件被修改,一行插入,零行删除)

再看一下新的日志:

复制代码
$ git log
commit 45ff89198f08365bff32364034aed98126009e44
Author: liuhui998 <liuhui998@gmail.com>
Date: Sat Jan 1 18:17:07 2011 +0800
Git is Cool
commit 8223db3b064a9826375041c8fea020cb2e3b17d1
Author: liuhui998 <liuhui998@gmail.com>
Date: Sat Jan 1 18:12:38 2011 +0800
project init

“45ff89198f08365bff32364034aed98126009e44” 这个就是我们刚才提交修改时创建的提交。

大家这么一路看过来,是不是有点糊涂了。不过没有关系,如果你的电脑装了 Git,那么你把上面的这些命令全部执行一下遍就会对它有感性的认识了。

下面的的章节,我会讲一下如何在 windows 和 Linux 安装配置 Git,以及需要注意的问题:)

参考

GitCommunityBook 中文版

ProGit 中文版

Git is the next Unix

关于作者

刘辉,开源技术爱好者,现居长沙,从事软件开发行业 7 年。关注 Linux 平台的相关技术,曾经参与开发过高性能网框架 spserver 。2009 年起开始关注 Git 相关应用,与朋友合作翻译了《Git Community Book 中文版》。我的个人博客是: liuhui998.com


感谢许晓斌对本文的编写过程中的鼎力支持。

感谢张凯峰对本文的策划及审校。

2011 年 1 月 05 日 07:2022467

评论

发布
暂无评论
发现更多内容

寻找伴侣最重要的是什么?

二爷

用声音在一起,听荔枝CTO丁宁聊UGC声音互动平台的技术世界

ONES 王颖奇

内容 企业架构 互联网

业务代码必须要做的事情

Objectivezt

FormattableString 取代特定区域字符串

喵叔

C# .net 编码习惯

对话 CTO〡和 PingCAP CTO 黄东旭聊开源数据库新蓝海

ONES 王颖奇

数据库 分布式 开发者

面试被问finally 和 return,到底谁先执行?

Damon

Java

OKR实践中的痛点(1):老板的KR我的O,怎么办?

大叔杨

OKR Scrum 敏捷

分享多年积累的 macOS 效率工具

张晓辉

macos

【Vue3.0 Beta】尝鲜

学习委员

CSS Java html5 Vue 前端

一文讲清楚 MySQL 事务隔离级别和实现原理,开发人员必备知识点

古时的风筝

MySQL 数据库 事务隔离级别 mysql事务 数据库事务

【gRPC】Python调用Java的gRPC服务

遇见

Java Python gRPC

翻译: Effective Go (1)

申屠鹏会

go golang 翻译

电子书:《Linux Perf Master》

RiboseYim

Linux 性能优化

一个创业者的途中思考

非著名程序员

创业 读书笔记 程序员 重新理解创业 思考

毕竟,一生很短,少有圆满

泰稳@极客邦科技

创业 身心健康 个人成长

WebSphere Application Server运维实践 --从入门到监控

hafe

Java WAS perfservlet visualVM JMX

此为开卷

范学雷

越是困难,越是要做有分析判断能力的人

泰稳@极客邦科技

创业 团队管理 个人成长

Flink初体验

数据社

大数据 flink 流计算

芋道 Spring Cloud Alibaba 介绍

艿艿

阿里巴巴 分布式 微服务 Spring Cloud Spring Boot

归去来兮:递归

曲镇

算法

写一个开源的 macOS 程序可以赚多少钱?

子骅 luin

node.js redis GitHub 开源 赚钱

人们喜欢彼此制造困难让大家难过

Fenng

2020了,各家小程序发展的怎么样?

崔红保

小程序 uni-app

uni-app黑魔法:小程序自定义组件运行到H5平台

崔红保

小程序 uni-app

近两年影响我的两个重要原则

Selina

Linux 性能诊断:负载评估入门

RiboseYim

Linux 性能优化

为什么你的创业公司应该运行在Kubernetes上

云原生

云原生 k8s

Spring cloud 之熔断机制

Damon

Java spring Kubernetes rqi

【数据结构】双向链表插入操作的时间复杂度分析

遇见

数据结构 算法 时间复杂度

业务系统开发程序员常用linux知识

Objectivezt

Linux

演讲经验交流会|ArchSummit 上海站

演讲经验交流会|ArchSummit 上海站

Git历险记(一)-InfoQ