版本控制(Version Control System)html
l 记录文件的全部历史变化java
l 错误恢复到某个历史版本git
l 多人协做开发编辑同一个文件github
名称web |
模型数据库 |
并发模式编程 |
历史模式vim |
变动范围安全 |
网络协议bash |
原子提交性 |
CVS |
Client-Server |
Merge |
Changeset |
File |
Pserver,ssh |
No |
SVN |
Client-Server |
3-way merge, recursive merge, octopus merge |
Changeset and Snapshot |
Tree |
custom (svn), custom (svn) over ssh, HTTP and SSL (usingWebDAV) |
Yes |
Git |
Distributed |
Merge or lock |
Snapshot |
Tree |
custom, custom over ssh, rsync, HTTP/HTTPS, email, bundles |
Yes |
* 版本库模型(Repository model):描述了多个源码版本库副本间的关系,有C/S(客户端/服务器)模式和分布式两种模式。在客户端/服务器模式下,每一用户经过客户端访问位于服务器的主版本库,每一客户机只需保存它所关注的文件副本,对当前工做副本(working copy)的更改只有在提交到服务器以后,其它用户才能看到对应文件的修改。而在分布式模式下,这些源码版本库副本间是对等的实体,用户的机器除了保存他们的工做副本外,还拥有本地版本库的历史信息。
* 并发模式(Concurrency model):描述了当同时对同一工做副本/文件进行更改或编辑时,如何管理这种冲突以免产生无心义的数据,有排它锁和合并模式。在排它锁模式下,只有发出请求并得到当前文件排它锁的用户才能对对该文件进行更改。而在合并模式下,用户能够随意编辑或更改文件,但可能随时会被通知存在冲突(两个或多个用户同时编辑同一文件),因而版本控制工具或用户须要合并更改以解决这种冲突。所以,几乎全部的分布式版本控制软件采用合并方式解决并发冲突。
* 历史模式(History model):描述了如何在版本库中存贮文件的更改信息,有快照和改变集两种模式。在快照模式下,版本库会分别存储更改发生先后的工做副本;而在改变集模式下,版本库除了保存更改发生前的工做副本外,只保存更改发生后的改变信息。
* 变动范围(Scope of change):描述了版本编号是针对单个文件仍是整个目录树。
* 网络协议(Network protocols):描述了多个版本库间进行同步时采用的网络协议。
* 原子提交性(Atomic commit):描述了在提交更改时,可否保证全部更改要么所有提交或合并,要么不会发生任何改变。
简而言之,各有优缺点,git要配合hub,能够避免分布式损坏。svn有权限控制,避免全被clone走。git适合纯代码,svn适合综合性文档管理,结合起来就完美。显然最大的不一样在于git是分布式的。
Linus在1991年建立了开源的Linux,今后,Linux系统不断发展,已经成为最大的服务器系统软件了。Linus虽然建立了Linux的核心,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?
事实是,在2002年之前,世界各地的志愿者把源代码文件经过diff的方式发给Linus,而后由Linus本人经过手工方式合并代码!你也许会想,为何Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?由于Linus坚决地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,并且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续经过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,因而Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,受权Linux社区无偿使用这个版本控制系统。
安定团结的大好局面在2005年就被打破了,缘由是Linux社区牛人汇集,难免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不仅他一个),被BitMover公司发现了(监控工做作得不错!),因而BitMover公司怒了,要收回Linux社区的无偿使用权。Linus能够向BitMover公司道个歉,保证之后严格管教弟兄们,嗯,这是不可能的。实际状况是这样的:Linus花了两周时间本身用C写了一个分布式版本控制系统,这就是Git!一个月以内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?你们能够体会一下。
Git迅速成为最流行的分布式版本控制系统,尤为是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。历史就是这么偶然,若是不是当年BitMover公司威胁Linux社区,可能如今咱们就没有免费而超级好用的Git了。
l 工做区:用来保存项目的元数据和对象数据库的地方。 这是 Git 中最重要的部分,从其它计算机克隆仓库时,拷贝的就是这里的数据。
l 暂存区:保存了下次将提交的文件列表信息,通常在 Git 仓库目录中。有时候也被称做“索引”,不过通常说法仍是叫暂存区域。
l 版本库:也叫本地版本库,之因此说git 快,大部分提交都是对本地仓库而言的,不依赖网络,最后一次会推送的到远程仓库。
l 远程仓库:能够看作是github,它是一个远程仓库,它提供web服务供你们方便下载、查看、提交、存储。
新建文件状态为untracked,add命令执行后状态变为staged,已存在的文件状态为unmodified,修改文件内容,文件状态变为modified,commit提交,文件状态编程unmodifed。
l 克隆仓库 clone 克隆
l 对工做目录中文件新增、修改、删除操做
l 暂存文件,将文件的快照放入暂存区 add 新增
l 把暂存区的内容提交到本地仓库 commit 提交
l 把本地仓库的内容提交到远程仓库 push 推送
l 从远程仓库下载最新内容 pull 拉取
每一个人必须有本身的帐号,先官网注册帐号:https://github.com
用户名: nutony,密码:Tony123
Git-2.12.0-64-bit.exe,一路next,安装完桌面右键菜单有下面两项,安装完成。选择Git Bash,进入git客户端。
Windows开始菜单:
提交文件时,就知道这个文件是谁提交的。出了问题,就知道谁干的!
Administrator@tonythink MINGW64 ~/Desktop
$ cd d: #进入d盘
Administrator@tonythink MINGW64 /d
$ cd java
$ cd env
$ mkdir git_repository #建立目录
$ cd git_repository #进入目录
登陆:https://github.com 在git上新建一个仓库
仓库名为stu,拥有者为:nutony。
建立成功
Administrator@tonythink MINGW64 ~/Desktop
$ cd d: #进入d盘
Administrator@tonythink MINGW64 /d
$ cd java
$ cd env
$ cd git_repository #进入目录
首次须要把远程仓库克隆到本地仓库(D:\javaenv\git_repository)
$ git clone https://github.com/nutony/stu.git
本地仓库目录中就多了stu目录
进入子仓库,手动建立文件,文件内容不能为空。
$ cd stu #建立本地仓库
$ git init #建立本地仓库
Administrator@tonythink MINGW64 /d/javaenv/git_repository (master)
当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,不要手动修改这个目录里面的文件,否则改乱了,就把Git仓库给破坏了。若是你没有看到.git目录,是由于默认这个目录是隐藏的,要显示修改其显示隐藏文件便可,通常无需修改。
$ git add . #添加当前目录下文件
$ git commit -m "jttest" #提交,设置备注
能够克隆仓库也能够关联本地仓库
运行 git remote add [shortname] [url]
git remote add stu git://github.com/nutony/stu
$ git push origin master #推送到远程仓库master默认分支,第一次须要登陆,比较慢,弹出登陆框输入用户名和密码。
刷新网页变成目录的页面,能够看到文件也已经上传
点击文件能够查看其内容
每日早上开始工做前拉取最新团队其余人提交的内容,每日下班前提交可用的内容
$ git checkout . #进入某个仓库检出当前仓库全部文件
$ git checkout hello.txt #检出远程仓库最后的版本覆盖本地文件
$ cd stu #进入到要管理的目录中
$ git pull #从服务器拉取最新内容
$ git add . #添加当前目录下文件
$ git commit -m "jttest" #提交,设置备注
$ git push origin master #推送到远程仓库
建立hi.txt
$ git add hi.txt #增长文件到暂存区
$ git add ./* #批量暂存当前目录下全部内容
$ git status #查看文件状态
$ git commit -m "test" #提交,提交文件到本地仓库
[master (root-commit) e522732] test
1 file changed, 1 insertion(+)
create mode 100644 hi.txt
$ git status #查看文件状态
$ git log
commit e522732d94c440fdd750368ce937ac1c40dbd2ed #本次提交惟一标识,对于版本回退很是有用
Author: nutony <52399178@qq.com>
Date: Fri Jun 2 09:39:31 2017 +0800
test
$ rm *.jpg #删除全部jpg结尾,删除本地文件
$ ll
$ git add .
$ git commit -m 'rm'
$ git push origin master
修改hi.txt文件内容,而后和仓库中已经提交的hi.txt比较
$ git diff hi.txt
diff --git a/hi.txt b/hi.txt
index 32f95c0..d7d0f3f 100644
--- a/hi.txt
+++ b/hi.txt
@@ -1 +1 @@
-hi
\ No newline at end of file
+<B1>Ƚϵ<B1>ǰ<CE>ļ<FE><BA>Ͳֿ<E2><CE>ļ<FE> #中文乱码
\ No newline at end of file
Administrator@tonythink MINGW64 /d/javaenv/git_repository (master)
$ git diff hi.txt
diff --git a/hi.txt b/hi.txt
index 32f95c0..2b80830 100644
--- a/hi.txt
+++ b/hi.txt
@@ -1 +1 @@
-hi
\ No newline at end of file
+<U+FEFF>比较当前文件和仓库文件 #文件格式改成UTF-8便可
\ No newline at end of file
Git和其余版本控制系统如SVN的一个不一样之处就是有暂存区的概念。
git的文件状态,文件新建完状态为untracked
点击进入仓库,选择Settings配置,移到页面最下方,点击删除按钮,需确认。输入仓库名称,而后删除便可。
发现提交的内容错了,能够进行回滚操做。
在%HOME%目录中,通常为C:\users\Administrator,也能够是你本身建立的系统用户名目录,反正都在C:\users\中。文件名为.git-credentials,因为在Window中不容许直接建立以"."开头的文件,因此须要借助git bash进行,打开git bash客户端,进行%HOME%目录,而后用touch建立文件 .git-credentials, 用vim编辑此文件。右键打开git bash客户端
这样之后push推送时只只需第一次填写用户名密码,后期就能够直接推送
什么是git?
> git是一款开源的分布式版本控制工具 > 在世界上全部的分布式版本控制工具中,git是最快、最简单、最流行的
git的起源?
> 做者是Linux之父:Linus Benedict Torvalds > 当初开发git仅仅是为了辅助Linux内核的开发(管理源代码)
git的现状?
> 在国外已经很是普及,国内并未普及(在慢慢普及) > 愈来愈多的开源项目已经转移到git
> CVS - 开启版本控制之门 - 1990年诞生,“远古时代”的主流源代码管理工具 > SVN - 全称是Subversion,集中式版本控制之王者 - 是CVS的接班人,速度比CVS快,功能比CVS多且强大 - 在国内软件企业中使用最为广泛(70%-90%) > ClearCase - 收费的集中式版本控制工具,安装比Windows还大,运行比蜗牛还慢 - 能用ClearCase的通常是世界500强,他们有个共同的特色是财大气粗或者人傻钱多 > VSS - 微软的集中式版本控制工具,集成在Visual Studio中
全部的代码都集中在一块, 统一进行管理
在每一个客户端都有一份完整的代码仓库, 能够在每一个客户端自行管理
> 速度 在不少状况下,git的速度远远比SVN快 > 结构 SVN是集中式管理,git是分布式管理 > 其余 SVN使用分支比较笨拙,git能够轻松拥有无限个分支 SVN必须联网才能正常工做,git支持本地版本控制工做 旧版本的SVN会在每个目录置放一个.svn,git只会在根目录拥有一个.git
- svn checkout —— git clone svn 只下载代码, git 会连同代码仓库一块儿下载下来 - svn commit —— git commit svn 是提交到服务器,git 中是提交到本地仓库,须要使用push才能提交到服务器 - svn update - git pull 都是从服务器下载最新被修改的代码
分布式和集中式最大的区别在于:在分布式下,本地有个代码仓库,开发者能够在本地提交; 而集中式版本控制, 只有在服务器才有一个代码仓库, 只能在服务器进行统一管理
概念理解
- 工做区 > 与.git文件夹同级的其余文件夹或者子文件夹 - 版本控制库 > 暂缓区 > 分支(Git不像SVN那样有主干和分支的概念. 仅仅存在分支,其中master分支为默认被建立的分支,相似于SVN中的主干) 切换分支:经过控制HEAD指针指向不一样的分支,就能够切换*
操做原则: 全部新添加/删除/修改的文件 必须先添加到暂缓区,而后才能提交到HEAD指向的当前分支中
单人开发只须要一个本地库
缘由:不须要与他人共享代码,只负责管理本身代码便可;例如提交代码,删除代码,版本控制等等
多人开发时须要一个共享版本库
共享版本库的形式: 本地共享库:文件夹/U盘/硬盘 远程共享库:本身搭建git服务器/ 托管到第三方平台(例如github, oschina)
使用环境 不管是单人开发仍是多人开发,客户端均可以使用命令行或者图形界面使用git
> SourceTree - 下载地址:http://www.sourcetreeapp.com/download/ > GitHub - 下载地址:https://mac.github.com - 不过它是专门为GitHub网站而设计的 > Xcode - 虽然集成较好,可是只能作一些经常使用的简单操做,复杂操做还要使用命令行
> git help [子命令] > 和学习SVN指令是同样的,只不过git是经过使用指南的形式展现给用户看(不能编辑的vim编辑器),使用q退出vim编辑器,按空格进入下一页,ctrl + B 回到上一页; /关键字 进行搜索
> 缘由: 管理本地代码,修改上传,版本回退 > 命令: git init
> 告诉git你是谁? 缘由: 追踪修改记录 命令: git config user.name “shunzi” > 告诉git怎样联系你? 缘由: 多人合做开发时, 沟通交流 命令: git config user.email "shunzi@qq.com" > 查看配置信息(.git -> config打开) 命令: git config -l
> 建立文件并提交 命令: touch main.c git add . git commit -m “注释” > 修改文件并提交 命令: git add . git commit -m “注释” > 删除文件并提交 命令: git rm person.h git commit -m “注释” > 日志查看 命令: git log git reflog > 版本回退 命令: git reset —hard HEAD 重置到当前版本 git reset —hard HEAD^^ 重置到上上个版本 git reset ——hard HEAD2 重置到往上2个版本 git reset —hard 七位版本号 重置到指定版本::
文件状态(git status)
> 颜色含义 红色: 表明被添加或者修改的文件没有被添加到暂缓区 绿色: 表明文件在暂缓区,等待提交 > 版本号的含义 版本号是一个由SHA1生成的40位哈希值 这样作的目的是保证版本号的惟一
vim编辑器的使用
命令模式:等待编辑命令输入;全部输入的内容都被当作命令来执行 插入模式:输入的全部内容都被显示,并被当作文件内容处理 命令行模式:执行待定命令(保存文件并退出vim : wq ; 强制退出不保存: q! )
日志查看配置
命令以下: git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)\<%an\>%Creset' --abbrev-commit"
配置别名
git config alias.st “status” git config alias.ci “commit -m”
--global的做用
能够进行全局配置,全部的版本库共享此配置 查看全局配置(桌面前往->我的->.gitconfig ** 我的电脑上建议使用全局配置**
团队开发必须有一个共享库,这样成员之间才能够进行协做开发
> 本地共享库(只能在本地面对面操做) - 电脑文件夹/U盘/移动硬盘 > 远程共享库(可经过网络远程操做) - 本身搭建Git服务器(**不建议**) - 在Github上托管项目(** 建议**) Github网址(https://github.com); 公开项目免费, 私有项目收费 - 在OSChina上托管项目(** 推荐**) OSChina网址(https://git.oschina.net) 安全免费,在国内访问速度快
缘由: 多人合做开发,代码共享 命令: git init —-bare
命令: git clone 本地代码仓库地址
> 建立文件夹manager, niuda 命令: mkdir manager mkdir niuda > 分别进入到两个文件夹从共享库clone项目到本地 命令: git clone 本地代码仓库地址 git clone 本地代码仓库地址 > 演练新增文件同步 命令: touch person.h git add . git commit -m “建立person.h” git push git pull > 演练修改文件同步 命令: git add . git commit -m “注释” git push git pull > 演练删除文件同步 命令: git rm filename git commit -m “注释” git push git pull > 演练冲突解决 命令: git pull > 演练忽略文件 命令: touch .gitignore open .gitignore 加入忽略文件名 git add . git commit -m “注释” .gitignore文件配置规则 http://www.cnblogs.com/haiq/archive/2012/12/26/2833746.html
> 关于忽略文件 在真实开发中,配置.gitignore文件 , 去github里面搜索gitignore 选择OC版本的,拷贝到本地仓库便可,记得添加到本地版本库 > 常见问题 fetch first 表明当前文件过时,须要从远程共享库更新 git pull
命令: git init —-bare
** 注意: 添加忽略文件, 否则Xcode有可能会把不必的文件提交** ** 必须在使用Xcode以前把忽略文件添加进来, 由于Xcode建立工程时, 默认直接把全部文件添加到暂缓区, 加进去以后忽略文件对其就无效了**
当项目被移到本身代码仓库中,就能够根据地址克隆下来进行操做
** 注意: 你能够针对此框架进行任意修改,可是仅仅做用在你的本地仓库中的副本,对原做者项目没有任何影响. 若是想向原做者提建议,能够直接使用,pull request操做. 提交完成后,原做者能够在pull request中看到你的提交.至因而否采纳,就是原做者的意愿
或者直接只用SSH(如下是生成公钥私钥方法)
> 部署公钥容许以只读的方式访问项目,主要用于项目在生产服务器的部署上,免去HTTP方式每次操做都要输入密码和普通SSH方式担忧不当心修改项目代码的麻烦。 > [https://help.github.com/articles/generating-ssh-keys/]
当项目被移到本身代码仓库中,就能够根据地址克隆下来进行操做
** 注意: 你能够针对此框架进行任意修改,可是仅仅做用在你的本地仓库中的副本,对原做者项目没有任何影响. 若是想向原做者提建议,能够直接使用,pull request操做. 提交完成后,原做者能够在pull request中看到你的提交.至因而否采纳,就是原做者的意愿
新人服务器搭建概念缘由?
概念: 搭建一个临时共享版本库, 供新人专用 缘由: 防止新人刚到时,搞乱服务器上的项目
新建一个文件夹,newBee,做为新人服务器
而后source control ->项目master -> configure 项目
> 选择Remotes 选项 表明当前所连的远程服务器地址 > 点击+号 添加 将newBee文件路径做为另一个远程服务器地址 file:// 协议开头 结尾以/结尾 > Done
经理将最新代码提交到新人远程仓库
图解
在git中不是经过拷贝代码来解决备份和开启分支的 git 直接打标签, 经过控制head指向,来回到任一版本
创建共享库
> 建立文件夹shareWeibo > 进入文件夹后,初始化共享库 git init ——bare
经理克隆项目后开发完1.0版本,打标签后,上传共享库
> 建立manager文件夹 > 进入文件夹后 git clone 共享库绝对路径 > 进入工做区,配置姓名,邮箱 git config user.name “manager” git config user.email “manager@qq.com” > 经理建立文件,并修改部分代码,提交代码,上传到共享库,完成v1.0版本 touch main.c open main.c:: 打开后写入abc git add . git commit -m “完成1.0版本开发” git push > 经理给此版本打标签,并将标签上传到共享库 git tag -a v1.0 -m “标记1.0版本” git push origin v1.0 > 经理继续开发2.0版本......并提交 git add . git commit -m “2.0部分功能” git push
在以上步骤基础上作如下操做
牛大克隆项目,根据1.0版本建立分支,修复bug
> 建立niuda文件夹 > 进入文件夹后 git clone 共享库绝对路径 > 进入工做区,配置姓名,邮箱 git config user.name “niuda” git config user.email “niuda@qq.com” > 根据v1.0版本创建新分支v1.0fixbug并切换到此分支 git checkout v1.0 -b v1.0fixbug:: > 修复bug后提交到本地版本库
注意此处提交到的是HEAD指向的分支-v1.0fixbug
git add . git commit -m “修复bug”
牛大修复bug后,打标签v1.1做版本备份,并上传共享库
git tag -a v1.1 -m “1.1版本备份” git push origin v1.1
牛大上传整个分支到共享版本库
git push origin v1.0fixbug
———至此,分支修复bug结束,下面经理要合并分支———
经理从共享库更新代码到本地库
git pull
经理查看当前服务器都有哪些分支
git branch -r
经理切换到master分支后,将v1.0fixbug分支合并过来
git checkout master git merge origin/v1.0fixbug -m “合并分支”
经理合并完成后提交到共享库
git add . git commit -m “合并分支” git push
合并完成后,能够删除共享库的分支
git branch -r -d origin/v1.0fixbug
查看版本标签,至此结束!!
git tag