1、版本控制器的分类
1.1、本地版本控制
记录文件每次的更新,可以对每个版本做一个快照,或是记录补丁文件,适合个人用,如RCS。
1.2、集中版本控制
所有的版本数据都保存在服务器上,协同开发者从服务器上同步更新或上传自己的修改
所有的版本数据都存在服务器上,用户的本地只有自己以前所同步的版本,如果不连网的话,用户就看不到历史版本,也无法切换版本验证问题,或在不同分支工作。而且,所有数据都保存在单一的服务器上,有很大的风险这个服务器会损坏,这样就会丢失所有的数据,当然可以定期备份。代表产品:SVN、CVS、VSS
1.3、分布式版本控制
所有版本信息仓库全部同步到本地的每个用户,这样就可以在本地查看所有版本历史,可以离线在本地提交,只需在连网时push到相应的服务器或其他用户那里。由于每个用户那里保存的都是所有的版本数据,只要有一个用户的设备没有问题就可以恢复所有的数据,但这增加了本地存储空间的占用。
2、GIT
Git是目前世界上最先进的分布式版本控制系统。
Git是免费、开源的
优点:
- 适合分布式开发,强调个体。
- 公共服务器压力和数据量都不会太大。
- 速度快、灵活。
- 任意两个开发者之间可以很容易的解决冲突。
- 离线工作。
缺点:
- 模式上比SVN更加复杂。
- 不符合常规思维。
- 代码保密性差,一旦开发者把整个库克隆下来就可以完全公开所有代码和版本信息
2、GIT安装与配置
安装:
一直Next默认就好了,如果需要设置就要仔细读一下安装界面上的选项。
配置:
使用git config -l 可以查看现在的git环境详细配置
#(1)查看系统config
#/etc/gitconfig:包含了适用于系统所有用户和所有项目的值。(Win:C:Program FilesGitmingw64etcgitconfig) --system 系统级 git config --system --list #(2)查看当前用户(global)配置
#~/.gitconfig:只适用于当前登录用户的配置。(Win:C:UsersAdministrator.gitconfig) --global 全局 git config --global --list #(3)查看当前仓库配置信息
#位于git项目目录中的.git/config:适用于特定git项目的配置。(Win:C:gitProject) --local当前项目 git config --local --list
注意:对于同一配置项,三个配置文件的优先级是1<2<3
安装Git后首先要做的事情是设置你的用户名称和e-mail地址。这是非常重要的,因为每次Git提交都会使用该信息。它被永远的嵌入到了你的提交中:
$ git config --global user.name "zhoumo" #名称 $ git config --global user.email 838616767@qq.com #邮箱
#传递了--global 选项,--global为全局配置,不加为某个项目的特定配置。
#如果你希望在一个特定的项目中使用不同的名称或e-mail地址,你可以在该项目中运行该命令而不要--global选项。
语句:
添加配置项:
$ git config [--local|--global|--system] section.key value #[--local|--global|--system] #可选的,对应本地,全局,系统不同级别的设置 #section.key #区域下的键 #value #对应的值
删除配置项:
$ git config [--local|--global|--system] --unset section.key
更多配置项:
$ git config --global color.ui true #打开所有的默认终端着色 $ git config --global alias.ci commit #别名 ci 是commit的别名 [alias] co = checkout ci = commit st = status pl = pull ps = push dt = difftool l = log --stat cp = cherry-pick ca = commit -a b = branch user.name #用户名 user.email #邮箱 core.editor #文本编辑器 merge.tool #差异分析工具 color.diff true #diff颜色配置 alias.co checkout #设置别名 git config user.name #获得用户名 git config core.filemode false #忽略修改权限的文件
3、GIT文件操作
3.1、工作区域
Git本地有三个工作区域:工作目录(Working Directory)、暂存区(Stage/Index)、资源库(Repository或Git Directory)。如果在加上远程的git仓库(Remote Directory)就可以分为四个工作区域。文件在这四个区域之间的转换关系如下:
- Workspace:工作区,就是你平时存放项目代码的地方
- Index / Stage:暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
- Repository:仓库区(或本地仓库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
- Remote:远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
3.2、工作流程
git的工作流程一般是这样的:
3.2.1、在工作目录中添加、修改文件;
3.2.2、将需要进行版本管理的文件放入暂存区域;
3.2.3、将暂存区域的文件提交到git仓库。
因此,git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)
3.3、创建仓库
全新仓库
# 在当前目录新建一个Git代码库
$ git init
# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]
克隆远程仓库
由于是将远程服务器上的仓库完全镜像一份至本地,而不是取某一个特定版本,所以用clone而不是checkout,语法格式如下
# 克隆一个项目和它的整个代码历史(版本信息)
$ git clone [url]
3.4、文件操作
文件的四种状态
-
Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制. 通过
git add
状态变为Staged
. -
Unmodify: 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为
Modified
. 如果使用git rm
移出版本库, 则成为Untracked
文件 -
Modified: 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过
git add
可进入暂存staged
状态, 使用git checkout
则丢弃修改过, 返回到unmodify
状态, 这个git checkout
即从库中取出文件, 覆盖当前修改 -
Staged: 暂存状态. 执行
git commit
则将修改同步到库中, 这时库中的文件和本地文件又变为一致, 文件为Unmodify
状态. 执行git reset HEAD filename
取消暂存, 文件状态为Modified
语句:
# 查看指定文件状态
$ git status [filename]
# 查看所有文件状态
$ git status
# 添加指定文件到暂存区
$ git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录的所有文件到暂存区
$ git add .
# 直接从暂存区删除文件,工作区则不做出改变
$ git rm --cached <file>
# 不但从stage中删除,同时删除物理文件
$ git rm readme.txt
# 把a.txt改名为b.txt
$ git mv a.txt b.txt
# 查看文件修改后的差异
$ git diff [files]
$ git reset HEAD <file>... #如果已经用add 命令把文件加入stage了,就先需要从stage中撤销
# 只执行 “git reset HEAD” 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
$ git clean [options] #移除所有未跟踪文件,一般会加上参数-df,-d表示包含目录,-f表示强制清除。
$ git diff HEAD~n #比较工作空间中的文件与仓库中倒数第n+1次提交时的差异
# 只执行git diff HEAD,表示与当前指向的HEAD比较
$ git diff --cached #比较暂存区的文件与之前已经提交过的文件
签出:
$ git checkout
$ git checkout HEAD
# 汇总显示工作区、暂存区与HEAD的差异。
$ git checkout -- filename
$ git checkout filename
#用暂存区中filename文件来覆盖工作区中的filename文件。相当于取消自上次执行git add filename以来(如果执行过)的本地修改。
$ git checkout -- . 或写作 git checkout .
#注意git checkout命令后的参数为一个点(“.”)。这条命令最危险!会取消所有本地的修改(相对于暂存区)。相当于用暂存区的所有文件直接覆盖本地文件,不给用户任何确认的机会!
$ git checkout commit_id -- file_name
#检出指定commit_id的文件到工作区和暂存区的filename。相当于恢复到某一次提交前时的状态。
$ git checkout branch -- filename
#维持HEAD的指向不变。用branch分支所指向的提交中filename替换暂存区和工作区中相应的文件。注意会将暂存区和工作区中的filename文件直接覆盖。
忽略文件:
有些时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等
在主目录下建立".gitignore"文件,此文件有如下规则:
- 忽略文件中的空行或以井号(#)开始的行将会被忽略。
- 可以使用Linux通配符。例如:星号(*)代表任意多个字符,问号(?)代表一个字符,方括号([abc])代表可选字符范围,大括号({string1,string2,...})代表可选的字符串等。
- 如果名称的最前面有一个感叹号(!),表示例外规则,将不被忽略。
- 如果名称的最前面是一个路径分隔符(/),表示要忽略的文件在此目录下,而子目录中的文件不忽略。
- 如果名称的最后面是一个路径分隔符(/),表示要忽略的是此目录下该名称的子目录,而非文件(默认文件或目录都忽略)。
#为注释 *.txt #忽略所有 .txt结尾的文件 !lib.txt #但lib.txt除外 /temp #仅忽略项目根目录下的文件,不包括子目录temp build/ #忽略build/目录下的所有文件 doc/*.txt #会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
提交:
通过add只是将文件或目录添加到了index暂存区,使用commit可以实现将暂存区的文件提交到本地仓库。
# 提交暂存区到仓库区 $ git commit -m [message] # 提交暂存区的指定文件到仓库区 $ git commit [file1] [file2] ... -m [message] # 提交工作区自上次commit之后的变化,直接到仓库区,跳过了add,对新文件无效 $ git commit -a -m [message] # 提交时显示所有diff信息 $ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
撤销提交:
原理就是放弃工作区和index的改动,同时HEAD指针指向前一个commit对象
# 撤销上一次的提交 $ git reset --hard HEAD~1
#另一个用法
$ git reset --hard HEAD^
$ git reset --hard commit-id
#在Git中有一个HEAD指针指向当前分支中最新的提交。当前版本我们使用"HEAD^",那么再前一个版本可以使用"HEAD^^",如果想回退到更早的提交,可以使用"HEAD~n"。(也就是,HEAD^=HEAD~1,HEAD^^=HEAD~2)
撤销提交:(使用这条语句提示冲突,后面再找原因)
git revert <commit-id>
这条命令会把指定的提交的所有修改回滚,并同时生成一个新的提交
恢复被撤销的提交可用"git reflog"查看仓库中所有的分支的所有更新记录,包括已经撤销的更新,撤销方法与前面一样。
$ git reset --hard HEAD@{3}
--hard:撤销并删除相应的更新
--soft:撤销相应的更新,把这些更新的内容放到Stage中
查看日志:
#查看提交日志
git log [<options>] [<revision range>] [[--] <path>…?]
"git log --graph"以图形化的方式显示提交历史的关系,这就可以方便地查看提交历史的分支信息,当然是控制台用字符画出来的图形。
"git log -1"则表示显示1行。
"git reflog"中会记录这个仓库中所有的分支的所有更新记录,包括已经撤销的更新。
查看文件列表:
使用git ls-files指令可以查看指定状态的文件列表,格式如下:
#查看指定状态的文件
git ls-files [-z] [-t] [-v] (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])*
4、GIT分支
基本语句:
# 列出所有本地分支 $ git branch # 列出所有远程分支 $ git branch -r # 列出所有本地分支和远程分支 $ git branch -a # 新建一个分支,但依然停留在当前分支 $ git branch [branch-name] # 新建一个分支,并切换到该分支 $ git checkout -b [branch]
# 切换到指定分支,并更新工作区
$ git checkout [branch-name]
# 合并指定分支到当前分支
$ git merge [branch]
# 删除分支
$ git branch -d [branch-name]
#其他用法 $ git branch [branch] [commit] # 新建一个分支,指向指定commit $ git branch --track [branch] [remote-branch] # 新建一个分支,与指定的远程分支建立追踪关系 $ git checkout [branch-name] # 切换到指定分支,并更新工作区 $ git checkout - # 切换到上一个分支 $ git branch --set-upstream [branch] [remote-branch] # 建立追踪关系,在现有分支与指定的远程分支之间 $ git cherry-pick [commit] # 选择一个commit,合并进当前分支
合并分支
git merge [branch]
先创建一个新的分支,进行修改后提交
回到主分支,查看源文件,此时是没有更新的,合并分支后再查看,新做的修改就更新到主分支
有冲突时合并
masters分支对文件filell.txt进行操作后提交
切换到dev6分支,修改文件filell.txt后进行提交
切换到主分支,进行合并分支。提示存在冲突
查看文件filell.txt在分支master中的状态
Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,其中<<<HEAD是指主分支修改的内容,>>>>>dev6 是指dev6上修改的内容
修改冲突文件后重新提交,请注意当前的状态产master | MERGING:
删除分支
语句:
git branch -d [branch] # -D(大写)是强制删除
创建一个新的分支dev7
切换到其他分支执行删除语句,不能在当前分支执行删除当前分支
删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
5、远程仓库
比较推荐Coding.net、GItHub。
#添加远程主机,主机名为origin 地址为https://git.coding.net/zhangguoGit/project7.git git remote add origin https://git.coding.net/zhangguoGit/project7.git #本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了,-u 参数指定一个默认主机 git push -u origin master
# 下载远程仓库的所有变动 $ git fetch [remote] # 显示所有远程仓库 $ git remote -v # 显示某个远程仓库的信息 $ git remote show [remote] # 增加一个新的远程仓库,并命名 $ git remote add [shortname] [url] # 取回远程仓库的变化,并与本地分支合并 $ git pull [remote] [branch] # 上传本地指定分支到远程仓库 $ git push [remote] [branch] # 强行推送当前分支到远程仓库,即使有冲突 $ git push [remote] --force # 推送所有分支到远程仓库 $ git push [remote] --all #简单查看远程---所有仓库 git remote (只能查看远程仓库的名字) #查看单个仓库 git remote show [remote-branch-name] #新建远程仓库 git remote add [branchname] [url] #修改远程仓库 git remote rename [oldname] [newname] #删除远程仓库 git remote rm [remote-name] #获取远程仓库数据 git fetch [remote-name] (获取仓库所有更新,但不自动合并当前分支) git pull (获取仓库所有更新,并自动合并到当前分支) #上传数据,如git push origin master git push [remote-name] [branch]
克隆:
远程操作的第一步,通常是从远程主机克隆一个版本库,这时就要用到git clone
命令。
#在本地主机生成一个目录,与远程主机的版本库同名 $ git clone <版本库的网址> #要指定不同的目录名,可以将目录名作为git clone命令的第二个参数 $ git clone <版本库的网址> <本地目录名> #克隆版本库的时候,所使用的远程主机自动被Git命名为origin。如果想用其他的主机名,需要用git clone命令的-o选项指定。 $ git clone -o WeUI https://github.com/Tencent/weui.git