Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1695765
  • 博文数量: 584
  • 博客积分: 13857
  • 博客等级: 上将
  • 技术积分: 11883
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-16 09:34

分类: LINUX

2009-12-21 10:54:12

git的基本概念

git的四种对象

  • blob对象。即文件。注意只包含内容,没有名字,权限等属性(但包含大小)
  • tree对象。相当于文件夹。所包含的文件(blob对象)/文件夹(tree对象)的名字及其基本属性(比如权限、是否符号链接等)的列表。
  • commit对象。表示修改历史。commit对象可以视为类似矢量的概念,由父commit(可能不只一个,合并情形下)指向新的tree对象。子commit的直接父commit,使用“子commit^n“来引用。
  • tag对象。可以指向blob、tree、commit并包含签名,最常见的是指向commit的PGP签名的标签。
blob,tree,commit 都是用其存储内容的 SHA-1 值命名的(不是简单的对整个文件取 SHA-1 值),tag 自然使用的是普通名字。

git快速上手三步曲

创建一个目录,建立一个版本库(进入目录,运行 git-init-db

一个版本库是就是一组代码或文本的集合。一般来说,在文件系统的层面上,通常是将其放入同一个目录下。与之相适应,我们让一个版本库与一个文件目录相对应,将一组相关(一个工程的)代码建立版本库,并储存于一个目录中。
mkdir gittutorcn

cd gittutorcn

git-init-db

放入要加入版本库中的文件,并植入跟踪系统(git-add

执行了git-init-db后,只是做了一些版本库的初始化工作,还没有任何实质性的内容加进里面去。下面我们就要将一些代码文件拷到刚才建立的那个目 录中去(更通常的方式是先拷入这些文件,再运行上面的 git-init-db),然后运行git-add *(*也可以替换成具体的文件名或目录名), 就将那些文件加入到git的版本跟踪库里面去了。不过此时还只是告诉git“我们有哪些(新)文件要加入”(会自动进行修改时间比较,然后自动判断哪些文 件该加入),并没有提交这些文件的具体内容到版本库中去。
git-add *

提交内容到版本库中去(git-commit

现在我们要把内容提交到版本库中去。用
git-commit -m "Initial commit of gittutor reposistory" -a
可以将工程目录下的文件全部提交(当然最好当前的位置处于工程根目录下)。

一些常用的命令

查看当前版本库的状态(git-status

分支管理命令(git-branch

前面的所有操作都没有涉及到版本管理的一个重要方面──多人协作开发所带来的分支管理。git上有一个默认的分支名master,之前所有的操作都是在master分支上进行,即你是以这个版本库的管理员的身份来操作的。引入分支管理基于如下情况:

  • 创建一个属于自己的个人工作分支,以避免对主分支 master 造成太多的干扰,也方便与他人交流协作。
  • 当进行高风险的工作时,创建一个试验性的分支,扔掉一个烂摊子总比收拾一个烂摊子好得多。
  • 合并别人的工作的时候,最好是创建一个临时的分支,关于如何用临时分支合并别人的工作的技巧,将会在后面讲述。

创建分支

#创建了一个名叫“b1"的分支。

git-branch b1



#把刚才创建的那个叫"b1"的分支给删除了。

git-branch -D b1

查看分支

git-branch

会把所有的分支名称列出来。前面打“*”号的就是你当前所在的分支。

导出分支内容,切换分支(git-checkout

运行git-checkout后,会将当前所在的分支的最新版本内容导出来(如果你在修改后还没有提交的话,那种这种导出将直接覆盖你的修改)。 而如果运行

git-checkout master

那么,就会从当前分支切换到master分支上去。

查看版本库中每个分支的世系发展状态(git-show-branch

git-show-branch 命令可以使我们看到版本库中每个分支的世系发展状态,并且可以看到每次提交的内容是否已进入每个分支。不过格式不敢恭维,眼花缭乱的。

查看差别(git-diff

查看当前工作与版本库中的差别 运行 git-diff 将给出当前工作目录中的文件与版本库的头节点(最新提交的)数据的差别,差异将以典型的 patch 方式表示出来:

git-diff master b2

可查看master和b2两个分支的差别。

查看某个分支的发展过程(git-whatchanged

运行 git-whatchanged 可以显示当前所在分支的发展状况(版本提交状况)。

分支合并与冲突解决方式

git-checkout master

git-merge "Merge work in robin" HEAD b2

git-checkout master

git-pull . b2

作用都是将b2这个分支的最新版本内容(提交后的)合并到master分支中去。如果在合并的过程中出现了冲突(具体通俗点说,就是在 master, b2这两个分支中的某个文件的某些相同的行中的内容不一样),我们就需要手动解决这些冲突,用编辑器把发生冲突的那个文件的内容编辑一下(会在里面看到 diff的文件格式)。然后再执行

 git-commit -i XXXX (XXXX就是发生冲突的那个文件名)

就可以提交此冲突文件,并且将未合并完的过程继续做完

逆转与恢复命令(git-reset

项目跟踪工具的一个重要任务之一,就是使我们能够随时逆转(Undo)和恢复(Redo)某一阶段的工作。git-reset 命令就是为这样的任务准备的。它可以将当前的工作分支的“头”定位到以前提交的任何版本中。

git-reset 参数 版本标号



其中,参数项可以有以下3个。

--mixed

仅是重置索引的位置,而不改变你的工作树中的任何东西(即,文件中的所有变化都会被保留,也不标记他们为待提交状态),并且会提示什么内容还没有被更新了。这个是默认的选项。

--soft

既不触动索引的位置,也不改变工作树中的任何内容。这个选项使你可以将已经提交的东西重新逆转至“已更新但未提交(Updated but not Check in)”的状态。就像已经执行过 git-add 命令,但是还没有执行git-commit 命令一样。

--hard

将工作树中的内容和头索引都切换至指定的版本位置中,也就是说自“版本标号”项之后的所有的跟踪内容和工作树中的内容都会全部丢失。因此,这个选项要慎用,除非你已经非常确定你的确不想再看到那些东西了。

其中,版本标号通常可以用 HEAD, HEAD^ 之类的标号表示。

与其它人交换代码

通 常的情况下,合并其他的人的工作的情况会比合并自己的分支的情况要多,这在 git 中是非常容易的事情,和你运行 git-merge命令没有什么区别。事实上,远程合并的无非就是“抓取(fetch)一个远程的版本库中的工作到本地”,然后再使用 git-merge 命令。

项目克隆命令(git-clone)

此命令会将项目库中的所有内容(包括版本数据记录和所有的文件)都拷贝到本地。 它支持5种协议:

**本地目录**: git-clone /root/workspace/projects/kernel/kernel-2f/ 

下载,单向操作



**SSH服务**: git-clone git@172.16.2.56:/root/workspace/projects/kernel/kernel-2f/

上传下载,双向操作



**GIT服务**: git-clone git://172.16.2.56/root/workspace/projects/kernel/kernel-2f/

下载,单向操作



**Rsync**: git-clone rsync://172.16.2.56/root/workspace/projects/kernel/kernel-2f/

上传下载,双向操作



**HTTP**: git-clone


下载,单向操作

抓取版本记录(git-fetch)

将远程版本库中相对于本地库的origin的版本更新信息下载下来。更新索引。 与 git-clone 一样,它也支持上面5种协议。如 git-clone git@172.16.2.56:/root/workspace/projects/kernel/kernel-2f/

获取实际文件(git-pull)

git-pull与git-fetch的区别在于git-pull将版本记录下载下来后,还要与本地分支进行合并。所以相当于 git-pull = git-fetch + git-merge。

利用服务器进行协同开发工作(代码管理模式探讨)

一个团队进行项目开发,必须要有清晰的开发交互管理模式。一般来讲,一个团队总是要用一个服务器来做为代码的存储和下载中心。如何将基于分布式概念 的git用活成为一个方便的团队版本管理工具,是一个值得研究的问题。下面以一个实例来探讨一下: 现有A,B,C,D四个员工,一台服务器。服务器IP为172.16.1.50,A的计算机IP为172.16.1.51,B的计算机IP为 172.16.1.52,C的计算机IP为172.16.1.53,D的计算机IP为172.16.1.54。有一个项目,名叫GOD,A是管理员。可以 有如下几种工作方式。 一: A在本地机器上建立GOD的代码库。其他三位员工直接从A的机器上克隆(利用SSH,需要知道用户和密码)代码和版本信息。然后,B,C,D分别在各自的 master分支里进行工作。等到要提交的时候,比如说B要提交,则B给A发封邮件,提醒一下,我这儿有些工作要提交给你。A收到提示后,就主动去B的机 器(通过SSH)上去取(需要知道用户名,密码)master分支,取的时候,将取回的版本信息存放到本地的一个新的分支中去。然后,再将这个新的分支与 自己的工作分支(可能是master分支)进行合并,产生新的代码。合并完成后,再通知B,我已经合并完成了,请你同步到最新的代码来。于是,B用 git-fetch或git-pull将A的合并后的代码同步到本地机器上来。这样就完成了一个交互。C,D也类似。 这样做的特点就是:

  1. 没有使用独立的服务器;
  2. 需要B,C,D和A知道互相知道对方的机器帐号,密码;
  3. 不需使用邮件来交互;
  4. 需要管理员A来主动取各个员工的代码。

二: A在服务器上建立一个GOD的公开版本库。利用git协议,或http协议(匿名的)。A在本机上工作的内容,首先是推到服务器上去(git- push)。其它员工,从服务器上去克隆(git-clone)代码。B,C,D在下载代码后,在各自的master分支上开发。B做了一些工作后,再提 醒A来我这里取代码,A主动去取。取回后,再合并。最后,把合并好的代码再Push到服务器上去。其他员工从服务器上来pull代码,进行同步更新。这样 做的特点是:

  1. 使用了独立的服务器;
  2. 需要A知道B,C,D的机器帐号,密码。不需要B,C,D知道A的机器帐号,密码;
  3. 不需使用邮件来交互;
  4. 需要管理员A来主动取各个员工的代码。

三: A在服务器上建立一个GOD的公开版本库。利用git协议,或http协议(匿名的)。A在本机上工作的内容,首先是推到服务器上去(git- push)。其它员工,从服务器上去克隆(git-clone)代码。B,C,D在下载代码后,在各自的master分支上开发。B做了一些工作后,利用 git-format-patch origin 打自己的版本与origin版本的补丁(最好在打补丁之前运行一下git-fetch origin,跟进的最新的版本记录),生成后,通过Email的形式,将补丁发给A。A收到后,对自已的工作代码打补丁。最后,把打补丁(合并)好的代 码再Push到服务器上去。其他员工从服务器上来pull代码,进行同步更新。这样做的特点是:

  1. 使用了独立的服务器;
  2. 不需要A知道B,C,D的机器帐号,密码。不需要B,C,D知道A的机器帐号,密码。只需要知道各自的邮箱即可。
  3. 需使用邮件来交互;
  4. 不需要管理员A来主动取各个员工的代码。由员工主动向管理员发送补丁文件。
阅读(1321) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~