CVS及SVN都是集中式的版本控制系统,而Git是分布式版本控制系统,集中式和分布式版本控制系统有什么区别呢?

先说集中式版本控制系统,版本库是集中存放在中央服务器的,而大家工作的时候,用的都是自己的电脑,所以要先从中央服务器取得最新的版本,然后开始工作,工作完成,再把自己的修订推送给中央服务器。这类系统,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。

那分布式版本控制系统与集中式版本控制系统有何不同呢?首先,分布式版本控制系统根本没有“中央服务器”,每个人的电脑上都是一个完整的版本库,这样,你工作的时候,就不需要联网了,因为版本库就在你自己的电脑上。既然每个人电脑上都有一个完整的版本库,那多个人如何协作呢?比方说你在自己电脑上改了文件A,你的同事也在他的电脑上改了文件A,这时,你们俩之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。

git的初始化

在使用git进行代码管理之前,首先要对git进行初始化。

Git 配置

使用Git的第一件事就是设置名字和email,这些就是在提交commit时的签名,每次提交记录里都会包含这些信息。使用git config命令进行配置:

$ git config --global user.name ""

$ git config --global user.email ""

一般配置方法是git config --global <配置名称> <配置的值>

如果想使项目里的某个值与前面的全局设置有区别,可以在项目中使用git config 命令不带 --global 选项来设置. 这会在当前的项目目录下创建 .git/config,从而使用针对当前项目的配置。

获得一个Git仓库

有两种方法可以得到一个Git仓库:一种是从已有的Git仓库中clone (克隆,复制);还有一种是新建一个仓库,把未进行版本控制的文件进行版本控制。

Clone一个仓库

为了得一个项目的拷贝(copy),需要知道这个项目仓库的地址(Git URL). Git能在许多协议下使用,所以Git URL可能以ssh://, http(s)://, git://. 有些仓库可以通过不只一种协议来访问。

$git clone url

初始化一个新的仓库

可以对一个已存在的文件夹用下面的命令让它置于Git的版本控制管理之下。

创建代码目录project

$mkdir project

进入到代码目录,创建并初始化Git仓库:

$cd project

$git init

正常的工作流程

正常的工作流程

git的基本流程如下:

  1. 创建或修改文件
  2. 使用git add命令添加新创建或修改的文件到本地的缓存区(Index)
  3. 使用git commit命令提交到本地代码库
  4. (可选,有的时候并没有可以同步的远端代码库)使用git push命令将本地代码库同步到远端代码库

使用git status命令查看当前git仓库的状态。

文件处于untracked状态,需要用git add命令将文件加入到缓存区(Index)。

$git add file

使用 git diff 命令再加上 --cached 参数,看看缓存区中哪些文件被修改了。进入到git diff --cached界面后需要输入q才可以退出:

$git diff --cached

如果没有--cached参数,git diff 会显示当前所有已做的但没有加入到索引里的修改。

当所有新建,修改的文件都被添加到了缓存区,使用git commit提交到本地仓库:

$git commit -m "message"

需要使用-m添加本次修改的注释,完成后就会记录一个新的项目版本。除了用git add命令,还可以用下面的命令将所有没有加到缓存区的修改也一起提交,但-a命令不会添加新建的文件。

$git commit -a -m "message"

需要注意的是如果是修改文件,也需要使用git add命令添加到缓存区才可以提交。如果是删除文件,则直接使用git rm命令删除后会自动将已删除文件的信息添加到缓存区,git commit提交后就会将本地仓库中的对应文件删除。

这个时候如果本地的仓库连接到了远程Git服务器,可以使用下面的命令将本地仓库同步到远端服务器:

$git push origin master

这时候可能需要你输入在Git服务器上的用户名和密码。

分支与合并

Git的分支可以在主线(master分支)之外进行代码提交,同时又不会影响代码库主线。分支的作用体现在多人协作开发中,比如一个团队开发软件,你负责独立的一个功能需要一个月的时间来完成,你就可以创建一个分支,只把该功能的代码提交到这个分支,而其他同事仍然可以继续使用主线开发,你每天的提交不会对他们造成任何影响。当你完成功能后,测试通过再把你的功能分支合并到主线。

分支

一个Git仓库可以维护很多开发分支。创建一个新的分支:

$git branch branchname

运行git branch命令可以查看当前的分支列表,以及目前的开发环境处在哪个分支上:星号标识了你当工作在哪个分支下。输入git checkout 分支名可以切换到其他分支。

将多个分支进行合并:可以通过下面的git merge命令来合并分支到主线分支master:

#切换到master分支

$git checkout master

#将分支合并到master

$git merge -m "message" branchname

-m参数仍然是需要填写合并的注释信息。

由于两个branch修改了两个不同的文件,所以合并时不会有冲突,执行上面的命令后合并就完成了。

如果有冲突,比如两个分支都改了一个文件file3,则合并时会失败。

合并失败后先用git status查看状态,会发现file3显示为both modified,查看file3内容会发现:

$ cat file3
test
<<<<<<< HEAD
master: update file3
=======
experimental: update file3
>>>>>>> experimental

上面的内容也可以使用git diff查看,先前已经提到git diff不加参数可以显示未提交到缓存区中的修改内容。

可以看到冲突的内容都被添加到了file3中,使用vim编辑这个文件,去掉git自动产生标志冲突的<<<<<<等符号后,根据需要只保留需要的内容后保存,然后使用git add file3git commit命令来提交合并后的file3内容,这个过程是手动解决冲突的流程。

下面的命令删除分支:

$git branch -d branchname

git branch -d只能删除那些已经被当前分支合并的分支. 如果要强制删除某个分支的话就用git branch –D

撒销一个合并

如果想把当前的修改都放弃,可以用下面的命令回到合并之前的状态:

$ git reset --hard HEAD^

# 查看file3的内容,已经恢复到合并前的master上的文件内容

$ cat file3

快速向前合并

通常,一个合并会产生一个合并提交(commit), 把两个父分支里的每一行内容都合并进来。

但是,如果当前的分支和另一个分支没有内容上的差异,就是说当前分支的每一个提交(commit)都已经存在另一个分支里了,git 就会执行一个“快速向前"(fast forward)操作;git 不创建任何新的提交(commit),只是将当前分支指向合并进来的分支。

Git日志

查看日志

git log命令可以显示所有的提交(commit):

$git log

如果提交的历史纪录很长,回车会逐步显示,输入q可以退出。

git log有很多选项,可以使用git help log查看。

Git会根据git log命令的参数,按时间顺序显示相关的提交(commit)。

日志统计

如果用--stat选项使用'git log',它会显示在每个提交(commit)中哪些文件被修改了, 这些文件分别添加或删除了多少行内容,这个命令相当于打印详细的提交记录:

$ git log --stat

格式化日志

按要求来格式化日志输出。--pretty 参数可以使用若干表现格式,如oneline:

$ git log --pretty=oneline

也可以使用 short 格式:

$ git log --pretty=short

也可用medium,full,fuller,email 或raw。 如果这些格式不完全符合要求, 也可以用--pretty=format参数定义格式。

--graph 选项可以可视化提交图(commit graph),会用ASCII字符来画出一个很漂亮的提交历史(commit history)线:

$ git log --graph --pretty=oneline

日志排序

日志记录可以按不同的顺序来显示。如果要指定一个特定的顺序,可以为git log命令添加顺序参数。

按默认情况,提交会按逆时间顺序显示,可以指定--topo-order参数,让提交按拓扑顺序来显示(就是子提交在它们的父提交前显示):

$ git log --pretty=format:'%h : %s' --topo-order --graph

也可以用 --reverse参数来逆向显示所有提交日志。

小结

基本命令:

  • git config:配置相关信息
  • git clone:复制仓库
  • git init:初始化仓库
  • git add:添加更新内容到索引中
  • git diff:比较内容
  • git status:获取当前项目状况
  • git commit:提交
  • git branch:分支相关
  • git checkout:切换分支
  • git merge:合并分支
  • git reset:恢复版本
  • git log:查看日志

比较内容

比较提交 - Git Diff

查看修改的文件内容需要使用git diff命令。git diff命令的作用是比较修改的或提交的文件内容。

上面的命令执行后需要使用q退出。命令输出当前工作目录中修改的内容,并不包含新加文件,请注意这些内容还没有添加到本地缓存区。

将修改内容添加到本地缓存区,通配符可以把当前目录下所有修改的新增的文件都自动添加:

$ git add *

再执行git diff会发现没有任何内容输出,说明当前目录的修改都被添加到了缓存区,查看缓存区内与上次提交之间的差别需要使用--cached参数:

$ git diff --cached

提交代码:

$ git commit

提交后git diffgit diff --cached都不会有任何输出了。

比较分支

可以用 git diff 来比较项目中任意两个分支的差异。

首先创建一个新的分支test,并在该分支上提交一些修改:

然后查看test分支和master之间的差别:

$ git diff master test

git diff 是一个难以置信的有用的工具,可以找出项目上任意两个提交点间的差异。可以使用git help diff详细查看其他参数和功能。

更多的比较选项

如果要查看当前的工作目录与另外一个分支的差别,可以用下面的命令执行:

# 切换到master

$ git checkout master

# 查看与test分支的区别

$ git diff test

也以加上路径限定符,来只比较某一个文件或目录:

$ git diff test file1

--stat 参数可以统计一下有哪些文件被改动,有多少行被改动:

$ git diff test --stat

分布式的工作流程

分布式的工作流程

合并修改到gitproject的git仓库:可以在仓库中把改给拉 (pull)下来。执行下面几条命令:

$ git pull /tmp/myrepo master

这就把myrepo的主分支合并到了gitproject的当前分支里了。

如果gitprojectmyrepo修改文件内容的同时也做了修改的话,可能需要手工去修复冲突。

如果要经常操作远程分支(remote branch)可以定义它们的缩写:

$ git remote add myrepo /tmp/myrepo

git pull命令执行两个操作: 它从远程分支(remote branch)抓取修改git fetch的内容,然后把它合并git merge进当前的分支。

gitproject里可以用git fetch 来执行git pull前半部分的工作, 但是这条命令并不会把抓下来的修改合并到当前分支里:

$ git fetch myrepo

获取后,可以通过git log查看远程分支做的所有修改。

当检查完修改后,gitproject可以把修改合并到它的主分支中:

$ git merge myrepo/master

如果在myrepo目录下执行git pull,myrepo会从克隆的位置拉取代码并更新本地仓库,就是把gitproject上的修改同步到本地。

因为myrepo是从gitproject仓库克隆的,那么他就不需要指定gitproject仓库的地 址。因为Git把gitproject仓库的地址存储到myrepo的配置文件中,这个地址就是在git pull时默认使用的远程仓库:

$ git config --get remote.origin.url

如果myrepogitproject在不同的主机上,可以通过ssh协议来执行clone 和pull操作:

$ git clone localhost:/home/shiyanlou/gitproject test

公共Git仓库

开发过程中,通常大家都会使用一个公共的仓库,并clone到自己的开发环境中,完成一个阶段的代码后可以告诉目标仓库的维护者来pull自己的代码。

如果和维护者都在同一台机器上有帐号,那么可以互相从对方的仓库目录里直接拉所作的修改,git命令里的仓库地址也可以是本地的某个目录名:

$ git clone /path/to/repository

$ git pull /path/to/other/repository

也可以是一个ssh地址:

$ git clone ssh://yourhost/~you/repository

将修改推到一个公共仓库

通过http或是git协议,其它维护者可以通过远程访问的方式抓取(fetch)你最近的修改,但是他们没有写权限。如何将本地私有仓库的最近修改主动上传到公共仓库中呢?

最简单的办法就是用git push命令,推送本地的修改到远程Git仓库,执行下面的命令:

$ git push ssh://yourserver.com/~you/proj.git master:master

或者

$ git push ssh://yourserver.com/~you/proj.git master

git push命令的目地仓库可以是sshhttp/https协议访问。

当推送代码失败时要怎么办

如果推送(push)结果不是快速向前fast forward,可能会报像下面一样的错误:

error: remote 'refs/heads/master' is not an ancestor of
local 'refs/heads/master'.
Maybe you are not up-to-date and need to pull first?
error: failed to push to 'ssh://yourserver.com/~you/proj.git'

这种情况通常是因为没有使用git pull获取远端仓库的最新更新,在本地修改的同时,远端仓库已经变化了(其他协作者提交了代码),此时应该先使用git pull合并最新的修改后再执行git push

$ git pull

$ git push ssh://yourserver.com/~you/proj.git master

Git标签

轻量级标签

可以用 git tag不带任何参数创建一个标签(tag)指定某个提交(commit):

# 进入到gitproject目录

$ cd /home/shiyanlou/gitproject

# 查看git提交记录

$ git log

# 选择其中一个记录标志位stable-1的标签,注意需要将后面的8c315325替换成仓库下的真实提交内,commit的名称很长,通常我们只需要写前面8位即可

$ git tag stable-1 8c315325

# 查看当前所有tag

$ git tag

stable-1

这样,可以用stable-1 作为提交 8c315325 的代称。

前面这样创建的是一个“轻量级标签”。

如果想为一个tag添加注释,或是为它添加一个签名, 需要创建一个 "标签对象"。

标签对象

git tag中使用-a-s 或是 -u三个参数中任意一个,都会创建一个标签对象,并且需要一个标签消息(tag message)来为tag添加注释。 如果没有-m 或是 -F 这些参数,命令执行时会启动一个编辑器来让用户输入标签消息。

当这样的一条命令执行后,一个新的对象被添加到Git对象库中,并且标签引用就指向了一个标签对象,而不是指向一个提交,这就是与轻量级标签的区别。

下面是一个创建标签对象的例子:

$ git tag -a stable-2 8c315325 -m "stable 2"

$ git tag

stable-1

stable-2

签名的标签

签名标签可以让提交和标签更加完整可信。如果配有GPG key,那么很容易创建签名的标签。首先要在 .git/config 或~/.gitconfig 里配好key。

下面是示例:

[user]

  signingkey = <gpg-key-id>

也可以用命令行来配置:

$ git config (--global) user.signingkey <gpg-key-id>

现在可以在创建标签的时候使用-s 参数来创建“签名的标签”:

$ git tag -s stable-1 1b2e1d63ff

如果没有在配置文件中配GPG key,可以用-u参数直接指定。

$ git tag -u <gpg-key-id> stable-1 1b2e1d63ff

Git 实战教程的更多相关文章

  1. 实验楼-Git实战教程

    实验1-git介绍 1.版本控制系统: 1)集中式版本控制系统:版本库是集中存放在中央服务器的,工作时需要先从中央服务器取得最新的版本,然后工作完成后把自己的修订推送给中央服务器.这类系统都有一个单一 ...

  2. Github 快速上手实战教程

    一.实验介绍 1.1 实验内容 本次课程讲的是在实验楼的在线环境中,如何使用 Github 去管理在在线环境中使用的代码.配置.资源等实验相关文件,怎样去添加.同步和下拉在远程仓库中的实验文件,以此来 ...

  3. ActiveReports 9实战教程(3): 图文并茂的报表形式

    基于上面2节内容,我们搭建了AR9的开发环境,配置好了数据源.在本节,我们以官方提供的3个中文图文并茂的报表来展示AR9的功能,并通过实战的方式一一分享. 以往做报表相关的工作时,最害怕的是报表的UI ...

  4. Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(三)--前后端环境配置

    前言 之前都是介绍一些基础知识,在这一节,我们就要开始实战coding了.正所谓磨刀不误砍柴工,准备工作显得尤为重要.很多demo只是追求效果的实现,并不注重整个demo的架构性.从我个人的角度看来, ...

  5. 【ASP.NET实战教程】ASP.NET实战教程大集合,各种项目实战集合

    [ASP.NET实战教程]ASP.NET实战教程大集合,各种项目实战集合,希望大家可以好好学习教程中,有的比较老了,但是一直很经典!!!!论坛中很多小伙伴说.net没有实战教程学习,所以小编连夜搜集整 ...

  6. [译]Atlassian Git系列教程

    国庆期间把Atlassian的Git系列教程看完了.边看边翻译了相关文章. 原教程: https://www.atlassian.com/git/tutorials/ 我翻译的: git init g ...

  7. 【转】mybatis实战教程(mybatis in action),mybatis入门到精通

    MyBatis 目录(?)[-] mybatis实战教程mybatis in action之一开发环境搭建 mybatis实战教程mybatis in action之二以接口的方式编程 mybatis ...

  8. Git使用教程【转】

    Git使用教程 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是 ...

  9. Git 使用教程

    Git 使用教程 更详细请参考:廖雪峰的官方网站 - Git教程 1. 安装Git客户端软件 Git for Windows http://msysgit.github.io/ 2. 创建版本库 两点 ...

随机推荐

  1. iOS App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.

    You can easily add it to the plist using the GUI: On the last line add the + Enter the name of the g ...

  2. Wordpress如何开启用户注册功能

    登录你的Wordpress管理员帐号,并进入管理后台,点击左侧菜单栏的"设置"--"常规"   在打开的设置页面,下方找到"允许任何人注册" ...

  3. spring框架设计理念(上)

    一.前言    spring的应用非常的广泛,在开发过程中我们经常接触,可能会有一种感觉:对spring即熟悉又陌生,熟悉体现在我们几乎每天都在使用,对spring的IOC.AOP功能都有了基本的了解 ...

  4. ACM 变态最大值

    变态最大值 时间限制:1000 ms  |  内存限制:65535 KB 难度:1   描述 Yougth讲课的时候考察了一下求三个数最大值这个问题,没想到大家掌握的这么烂,幸好在他的帮助下大家算是解 ...

  5. JS性能优化笔记搜索整理

    通过网上查找资料了解关于性能优化方面的内容,现简单整理,仅供大家在优化的过程中参考使用,如有什么问题请及时提出,再做出相应的补充修改. 一. 让代码简洁:一些简略的表达方式也会产生很好的优化 eg:x ...

  6. [深入浅出Windows 10]模拟实现微信的彩蛋动画

    9.7 模拟实现微信的彩蛋动画 大家在玩微信的时候有没有发现节日的时候发一些节日问候语句如“情人节快乐”,这时候会出现很多爱心形状从屏幕上面飘落下来,我们这小节就是要模拟实现这样的一种动画效果.可能微 ...

  7. Android --日期控件使用并显示选择的日期

    1. main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: ...

  8. tornado 学习笔记1 引言

    从事软件开发这行业也快5年啦,其实从事的工作也不完全是软件开发,软件开发只是我工作中的一部分.其中包括课题研究.信息化方案设计.软件开发.信息系统监理.项目管理等工作,比较杂乱.开发的软件比较多,但是 ...

  9. Jquery_jquery中attr和prop的区别

    在高版本的jquery引入prop方法后,什么时候该用prop?什么时候用attr?它们两个之间有什么区别?这些问题就出现了. 关于它们两个的区别,网上的答案很多.这里谈谈我的心得,我的心得很简单: ...

  10. VS开发好用的扩展

    VS开发好用的扩展(转) 转自:http://www.haogongju.net/art/1977373 首先为大家介绍一下开发字体,做程序开发,代码可读性,在侧面也能帮助开发提高效率,所以给大家介绍 ...