跳至主要内容

一个人用的 Git

Git 是目前比较时髦的版本控制系统,虽然 linux 内核源码是使用它来管理的,但系统非常小巧而且使用简单,比起 svn (subversion) 系统,git 有一个明显的优势就是在不联网的情况下也可以查阅或者回滚历史版本,有时带着笔记本出外工作这个功能是非常有用的。下面介绍一下用 Git 管理个人电脑上的个人文档文件。(@ivarptr)

这篇文章有几个假设前提:
a、你从事的工作有很多文档需要书写或者整理,而且文档篇幅比较大需要经常修修改改,有时还可能需要回档(即恢复到历史的某个版本)。
b、你的文档具有关联性的,比如一个项目策划书,有多份文本文档、电子表格、图片,希望平时能整体记录一个版本(快照)。
c、你有多台工作用的电脑,为了简单起见,下文假设只有两台电脑。
d、你有一台能够在互联网上访问的服务器,最好是跑 linux 系统而且有 ssh 登录权限。
e、为了简明,省略了安全权限设置和Git最为突出的特性“分支”。

1、几个必须厘清的概念
a、svn只有一个远程仓库集中管理所有的版本,而Git分有“本地仓库”和“远程仓库”之分,在提交你的最新文档过程中,需要两层提交,一次是提交到本地仓库,然后才可以提交到远程仓库。
b、svn的远程仓库保存的总是全局最新的版本,各个支点(小组成员)必须对此仓库负责。而Git则没有集中远程仓库之说,理论上每个人的地位是平等的,同时每个人的本地仓库也可以配置为给他人访问的“远程仓库”。不过对于个人或者一个小团队来说,为了简便起见我们通常会协商好让某个远程服务器上的仓库保持最新并且集中管理,这点跟Svn类似。
c、svn的每次提交会产生一个递增的数字作为版本号码,而git每次提交会产生一个“快照”,快照不是用一个递增的数字作为名称的,而是一个hash值,当然用一个hash值来呼叫某一次提交也太累赘了,所以在实际应用过程中我们往往只用hash指的头4~6位就可以了(类似一个人的昵称)。

2、在服务器上创建 Git 仓库
关于在 linux 系统里如何安装 Git 程序可以参考这篇《在CentOS 5.5里安装Git以及搭建Git服务器最简单教程》,要记住 Git 程序是不区分服务端或客户端的。

首先我们要创建一个Git仓库,使用 ssh 登录到你的服务器,在用户home文件夹里创建一个文件夹,为了容易识别,最好在文件夹名字后面加一个“.git”后缀,比如“homework.git”,然后进入这个文件夹并且执行命令
git --bare init

那么仓库就建立好了。远程访问这个仓库的地址是:
your_account_name@your_host_name:homework.git

假如你在用户home文件夹子层里创建仓库,那么就把上面的地址“homework.git”部分替换成完整的路径,比如“mydocuments/projects/homework.git”,当然也可以使用绝对路径。

3、在第一台电脑上创建本地仓库
首先在待版本控制的文件夹里(可以是刚刚新建的)执行下面命令创建本地仓库:
git init

然后将需要版本控制的文件和文件夹创建(或者从别处copy过来)并执行下面的命令将之逐一添加到本地仓库:
git add file1.txt
git add dir1
......

如果希望文件夹里所有的文件都加入本地仓库,那么只需简单执行:
git add .

需要注意的是,git add命令仅仅是将文件标识为“受版本控制”,并没有真正进入git仓库。在添加过程中可以使用 git status 命令查看哪些文件已经添加了,哪些还没有。

有时可能希望排除一些文件,可以把希望排除的文件或文件夹名字书写到文件夹根目录的 .gitignore 文件,没有这个文件的话则新建即可。内容如下:
bin/
.notes
/temp/

上面三行分别表示排除所有文件夹里面名字为 bin 的文件夹,排除所有文件夹里面名字为 .notes 的文件,排除首层文件夹里面名字为 temp 的文件夹。
当然别忘了把这个文件也添加到本地仓库:
git add .gitignore

所有文件和文件夹添加完毕之后,就可以提交了(要注意这次提交仅仅提交到本地仓库,接下来才是提交到服务器),提交之后就会形成一个快照:
git commit

上面的命令执行的时候你需要输入提交备忘文字,跟 svn 不同,git 每次提交的备忘文字是必须填写的。

你可以使用命令 git log 来查看这次提交的hash值。

4、把第一台电脑上的本地仓库提交(上传)到服务器
在受版本控制的文件夹里执行下面命令添加一个远程仓库
git remote add origin your_account_name@your_host_name:homework.git

这里的 origin 表示远程仓库的名字,默认的主要的远程仓库我们一般命名为 origin。然后就可以把本地仓库提交到远程仓库了:
git push

不过先等等,由于服务器上的版本库是刚刚创建的,也就是说里面是空的,所以第一次提交需要指定一个远程仓库分支名称,默认主分支名称为 master,所以上面的命令要改为:
git push origin master

而以后的第二次第N次提交就可以省略“master”这个分支名称了。“分支”是Git的重要特性,建议读者阅读文章末尾的书籍,而此文为了简便则省略了。

5、在第二台电脑上创建本地仓库并拉取(下载)远程仓库

转到待版本控制的文件夹里(可以是刚刚新建的)执行下面命令创建本地仓库:
git init

添加远程仓库:
git remote add origin your_account_name@your_host_name:homework.git

拉取远程仓库的最新版本下来
git fetch origin master

拉取下来之后会发现本地文件夹里面仍然没有任何改变(假如文件夹是新建的,则里面是空荡荡的),那是因为本地仓库仍然停留在旧时状态,只要把远程最新的提交合并到本地仓库就好了:
git merge origin/master

6、第一台电脑上有文档发生更改,或者有新文档需要增加
对于新增加的文档,需要用 git add 命令标识它受版本控制,否则使用 git commit 命令提交时是不会自动包含新增加文件的。比如新增加 readme.txt:
git add readme.txt

对于修改过的文档,同样需要用 git add 命令标识它需要重新提交到本地仓库,否则提交时不会自动提交发生更改的文档。比如 file1.txt 发生了更改:
git add file1.txt

然后提交到本地仓库
git commit

如果没有新文档需要增加,仅仅是提交发生过更改的文档,则上面的命令可以简化为:
git commit -a

合并到远程分支
git merge origin/master

提交到远程仓库
git push (默认提交到origin/master分支,此命令相等于 git push origin master)

7、第二台电脑也有文档发生更改
通常我们在提交新的更改之前,最好先拉取一下远程仓库,以保证你得到最新的版本,你的工作是在最新版本的基础之上开始进行的,所以上面的第6步其实缺少了下面的两个操作。
git fetch (默认拉取origin/master分支,此命令相等于 git fetch origin master)


把远程分支合并到本地分支:
git merge origin/master



对于修改过和新增的文件需要先使用 git add 和 git commit 提交到本地仓库,然后合并到远程分支,再提交:


git merge origin/master
git push

日常操作流程
往后第一台和第二台电脑的操作都跟上面的第7步一样了,实际上日常的操作大致如下:
a、(工作开始之前,或者上班之后第一件事)拉取远程仓库最新的提交,合并到本地分支。
b、工作中途时不时提交到本地仓库,以制造更多的快照以便日后能更细粒度地回档。
c、一个阶段完毕之后(或者下班之前),把本地分支合并到远程分支,并提交到远程仓库。

补充1、简化第二台电脑的初始化工作
即上面的第5步,可以用下面命令一步完成:
git clone your_account_name@your_host_name:homework.git

补充2、一些常用的命令
a、修正最后一次提交,比如刚刚提交完毕之后发现漏掉添加一个文件了,或者备注文字写错了:
先把该添加的文件添加上(git add),然后:
git commit --amend

b、取消不小心添加进入暂存的文件
git status (先查看是否被暂存了)
git reset HEAD some.file

c、还原文件的修改
git checkout -- some.file (两个减号)

d、恢复到某次快照(即回档)
git log (查看所有修改记录,记住快照的hash值,一般记住hash值前头4到6位就足够了)
git checkout HASH (把HASH替换成相应的hash值)

e、恢复到最新版本
git checkout master

f、已经修改了一些文件,希望创建多一个分支来处理这些修改(这点已经有少许超纲了,不过因为很常用所以在此列出来)
先用 git status 看看是否真的已经修改过文件了,确定之后再继续。
git stash (创建临时储存堆栈)
现在用 git status 查看应该是干净了。
git branch NAME(创建一个新分支,名字为 NAME)
git apply (调出临时储存堆栈)
git commit -a (提交到新的分支)

对于临时储存堆栈,还有 git stash list, git stash drop 这两个常用命令,看名字就知道他们的作用了。

补充3、Git 的学习资料
《Pro Git》可以在这里免费获取:
还有中文版

评论

此博客中的热门博文

Apache Cassandra 0.7 的集群配置

跟 Hadoop/HBase 一样, Apache Cassandra 也是 NoSQL 产品中最为重要的成员之一,跟 HBase 相比,因为 Cassandra 使用了一种去中心化的模式(类似memcached集群), 使用 Cassandra 搭建 NoSQL 集群更为简单容易,特别是在 0.7 版本之后,下面简述使用 Cassandra 0.7 搭建一个集群。 @ivarptr 前提条件 a、准备3台或以上的计算机。下面假设有3台运行Linux操作系统的计算机,局域网的IP地址分别为 192.168.0.100, 192.168.0.101 和 192.168.0.102。 b、Java 1.6。 c、到 这里下载 0.7.x 版本的Cassandra 二进制发行包。 1、基本配置 挑选其中的一台机开始配置,先展开 cassandra 发行包: $ tar -zxvf apache-cassandra-$VERSION.tar.gz $ cd apache-cassandra-$VERSION 其中的 conf/cassandra.yaml 文件为主要配置文件,由于 0.7 版不再采用XML格式配置文件,如果对 YAML 格式不熟悉的话最好先到 这里 了解一下。 Cassandra 在配置文件里默认设定了几个目录: data_file_directories: /var/lib/cassandra/data commitlog_directory: /var/lib/cassandra/commitlog saved_caches_directory: /var/lib/cassandra/saved_caches data_file_directories 可以一次同时设置几个不同目录,cassandra 会自动同步所有目录。另外在日志配置文件 log4j-server.properties 也有一个默认设定日志文件的目录: log4j.appender.R.File=/var/log/cassandra/system.log 一般情况下采用默认的配置即可,除非你有特殊的数据储存要求,所以现在有两种方案:一是按照默认配置创建相关的目录,二是修改配置文件采用自己指定的目录。 下面为了简...

日志工具 SLF4J 的来龙去脉

J ava 界里有许多实现日志功能的工具,最早得到广泛使用的是 log4j ,许多应用程序的日志部分都交给了 log4j,不过作为组件开发者,他们希望自己的组件不要紧紧依赖某一个工具,毕竟在同一个时候还有很多其他很多日志工具,假如一个应用程序用到了两个组件,恰好两个组件使用不同的日志工具,那么应用程序就会有两份日志输出了。 为了解决这个问题, Apache Commons Logging  (之前叫 Jakarta Commons Logging,JCL)粉墨登场,JCL 只提供 log 接口,具体的实现则在运行时动态寻找。这样一来组件开发者只需要针对 JCL 接口开发,而调用组件的应用程序则可以在运行时搭配自己喜好的日志实践工具。 所以即使到现在你仍会看到很多程序应用 JCL + log4j 这种搭配,不过当程序规模越来越庞大时,JCL的动态绑定并不是总能成功,具体原因大家可以 Google 一下,这里就不再赘述了。解决方法之一就是在程序部署时静态绑定指定的日志工具,这就是  SLF4J  产生的原因。 跟 JCL 一样,SLF4J 也是只提供 log 接口,具体的实现是在打包应用程序时所放入的 绑定器 (名字为 slf4j-XXX-version.jar)来决定,XXX 可以是 log4j12, jdk14, jcl, nop 等,他们实现了跟具体日志工具(比如 log4j)的绑定及代理工作。举个例子:如果一个程序希望用 log4j 日志工具,那么程序只需针对 slf4j-api 接口编程,然后在打包时再放入 slf4j-log4j12-version.jar 和 log4j.jar 就可以了。 现在还有一个问题,假如你正在开发应用程序所调用的组件当中已经使用了 JCL 的,还有一些组建可能直接调用了 java.util.logging,这时你需要一个 桥接器 (名字为 XXX-over-slf4j.jar)把他们的日志输出重定向到 SLF4J,所谓的桥接器就是一个假的日志实现工具,比如当你把 jcl-over-slf4j.jar 放到 CLASS_PATH 时,即使某个组件原本是通过 JCL 输出日志的,现在却会被 jcl-over-slf4j “骗到”SLF4J 里,然后 SLF4J 又会根据绑定器把日志交给具体的...

如何在应用程序里使用 Hadoop HDFS ——分布式计算Hadoop配置及实践(二)

上一篇 讲到 Hadoop 的配置,我们在搭建分布式计算系统的同时也已经搭建好分布式储存系统了。下面简述如何在应用程序(可以是 Console Application,也可以是 Web Application)调用 Hadoop HDFS。 我们除了可以使用 Hadoop 命令行 管理里面的文件和目录之外,也可以通过 Hadoop API 管理。 1、先创建一个Java Application (Console) 程序,然后引用 hadoop-core-0.20.2.jar ,因为这个包同时引用非常多其他包,所以最好使用 Maven 引用这个包。 2、在项目根目录创建 core-site.xml : <?xml version="1.0"?> <configuration> <property>   <name>fs.default.name</name>   <value>hdfs://192.168.0.10:9000</value> </property> </configuration> 程序会自动寻找 CLASS_PATH 里面的 core-site.xml 文件,假如缺少这个文件的话,程序会使用本地文件系统。 3、创建 Helloworld.java: import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; public class HelloWorld { public static void main(String[] args) { try { HelloWorld helloWorld = new He...