@byee
--版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统
优点:
缺点:
优点:
Git 直接纪录快照
工作流程:
1.在工作目录修改文件
2.对修改后的文件进行快照,保存在暂存区
3.提交更新,将保存在暂存区的文件快照永久转储到Git仓库中
SHA:
所有的项目历史文件都是通过一个40个字符的(40-digit)“对象名”来索引的,类似:
6ff87c4664981e4397625791c8ea3bbb5f2279a3
该字符是通过对“对象”内容做SHA1哈希计算得来的(SHA1是密码学的哈希算法)。这就意味这不同内容的对象就不可能有相同的“对象名”
好处:
对象:
每个对象(Object)包括三个部分:类型、大小和内容
类型:"blob","tree","commit"和"tag"
1.blob对象:通常用来存储文件的内容
git show 6ff87c4664 //使用git show命令来查看内容
Note that the only valid version of the GPL as far as this project
is concerned is _this_ particular version of the license (ie v2, not
v2.2 or v3.x or whatever), unless explicitly otherwise stated.
...
//一个"blob"对象就是一块二进制数据,它没有指向任何东西或有任何其他属性,甚至连文件名都没有
因为blob对象内容全部都是数据,如两个文件在一个目录树(或是一个版本仓库)中有同样的数据内容,那么它们将会共享同一个blob对象。
Blob对象和其所对应的文件所在路径、文件名是否改被更改都完全没有关系。
2.tree对象:
git show 6ff87c4664 //使用git show命令来查看内容 或者使用git ls-tree 让你看到更多细节
$ git ls-tree fb3a8bdd0ce
100644 blob 63c918c667fa005ff12ad89437f2fdc80926e21c .gitignore
100644 blob 5529b198e8d14decbe4ad99db3f7fb632de0439d .mailmap
100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 COPYING
040000 tree 2fb783e477100ce076f6bf57e4a6f026013dc745 Documentation
100755 blob 3c0032cec592a765692234f1cba47dfdcc3a9200 GIT-VERSION-GEN
100644 blob 289b046a443c0647624607d471289b2c7dcd470b INSTALL
100644 blob 4eb463797adc693dc168b926b6932ff53f17d0b1 Makefile
100644 blob 548142c327a6790ff8821d67c2ee1eff7a656b52 README
...
3.Commit对象:
$ git show -s --pretty=raw 2be7fcb476
commit 2be7fcb4764f2dbcee52635b91fedb1b3dcf7ab4
tree fb3a8bdd0ceddd019615af4d57a53f43d8cee2bf
parent 257a84d9d02e90447b149af58b271c19405edb6a
author Dave Watson <dwatson@mimvista.com> 1187576872 -0400
committer Junio C Hamano <gitster@pobox.com> 1187591163 -0700
Fix misspelling of 'suppress' in docs
Signed-off-by: Junio C Hamano <gitster@pobox.com>
// 你可以看到一个提交(commit)由以下部分组成:
1.一个tree
2.父对象
3.作者
4.提交者
5.注视
4.tag对象:
$ git cat-file tag v1.5.0
object 437b1b20df4b356c9342dac8d38849f24ef44f27
type commit
tag v1.5.0
tagger Junio C Hamano <junkio@cox.net> 1171411200 +0000
GIT 1.5.0
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQBF0lGqwMbZpPMRm5oRAuRiAJ9ohBLd7s2kqjkKlq1qqC57SbnmzQCdG4ui
nLE/L9aUXdWeTFPron96DLA=
=2E+0
-----END PGP SIGNATURE-----
commit流程
$>tree
.
|-- README
`-- lib
|-- inc
| `-- tricks.rb
`-- mylib.rb
2 directories, 3 files
git目录
$>tree -L 1
.
|-- HEAD # 这个git项目当前处在哪个分支里
|-- config # 项目的配置信息,git config命令会改动它
|-- description # 项目的描述信息
|-- hooks/ # 系统默认钩子脚本目录
|-- index # 索引文件
|-- logs/ # 各个refs的历史信息
|-- objects/ # Git本地仓库的所有对象 (commits, trees, blobs, tags)
`-- refs/ # 标识你项目里的每个分支指向了哪个提交(commit)。
工作目录:
Git"工作目录"存储着你现在检出(checkout)的文件.当你在项目不同分支切换时,工作目录里的文件经常会被替换和删除。所有历史信息都保存在'git目录'中。
//获得一个Git仓库,由两种方法:
1.从已有的Git仓库中,clone
2.新建一个仓库
//1.clone仓库
// git://协议较为快速和有效
git clone git://git.kernel.org/pub/scm/git/git.git
//或者
git clone http://www.kernel.org/pub/scm/git/git.git
//该命令执行结果:会在本目录下生成一个文件夹,
例如. git clone http://git.kernel.org/linux/kernel/git/torvalds/linux-2.6.git
会建立一个目录叫'linux-2.6')
//2. 初始化一个新的仓库
mkdir demo
cd demo
git init
//Git 会输出Initialized empty Git repository in .git/ 这样就代表着 仓库被新建成功
git add files 把当前文件放入暂存区域。
git commit 给暂存区域生成快照并提交。
git reset -- files 用来撤销最后一次git add files,你也可以用git reset 撤销所有暂存区域文件。
git checkout -- files 把文件从暂存区域复制到工作目录,用来丢弃本地修改。
git status //显示当前项目的一个状态
//一个仓库可以维护很多开发分支,现在我们来创建一个叫dev的分支
//新建一个dev分支 新建文件demo1.txt 编辑 并提交
git branch dev //git branch -----list, create, or delete branches
touch
//切换到dev分支 查看demo1.txt 修改再提交
git checkout dev // git checkout --Checkout a branch or paths to the working tree
//回到master 分支 并执行 合并 (无冲突和有冲突)
git checkout master
//git merge ---dev Join two or more development histories together
冲突:同一个文件在不同分支或者远程和本地分支按不同的方式修改了
如何解决冲突:
发生冲突,则需要你手动解决完冲突后,将该文件添加到索引区/暂存区(index),然后进行一次提交
//撤销分支:
如果你觉得合并之后的状态是一团乱麻,想把当前的修改都放弃,
你可以使用git reset命令回到之前的状态
如:git reset //Reset current HEAD to the specified state
若加上--hard 参数 reset HEAD, index and working tree
$ git reset --hard HEAD
//你已经把合并之后的代码提交,但是还是想把他们撤销
$ git reset --hard ORIG_HEAD //执行某些情况下,会比较危险。如:如果你把一个已经被另一个分支合并的分支给删了,那么 以后在合并相关的分支时会出错。
快速向前合并:
通常,一个合并会产生一个合并提交(commit),把两个父分支里的每一行都合并起来
但是,如果当前分支和另一个分支没有内容上的差异(即冲突),git就会执行一个"快速向前(fast-forward)"操作,git不会创建新的提交,只是将当前分支指向合并进来的分支
//日志操作
git log //Show commit logs
git log [<options>]
options :
-p //显示patchs
--stat //显示每个提交(commit)中哪些文件被修改了
--pretty= online //你可以按你的要求来格式化日志输出。‘--pretty'参数可以使用若干表现格式,如‘oneline short',
//例如:$ git log --pretty=format:'%h was %an, %ar, message: %s'
$ git log --pretty=format:'%h : %s' --graph
$ git log --pretty=format:'%h : %s' --topo-order --graph
//Diff 操作 git diff 是一个难以置信的有用的工具,可以找出你项目上任意两点间 的改动,
或是用来查看别人提交进来的新分支。
git --Show changes between commits, commit and working tree, etc
$ git diff master..test
//上面这条命令只显示两个分支间的差异
$ git diff
//上面命令,回显示在当前的工作目录和上次提交与本地索引间的差异
//显示你当前的索引和上次提交间的差异:
$ git diff --cached
$ git diff HEAD //显示你工作目录与上次提交时之间的所有差别
//更多的比较选项
$ git diff dev //查看当前的工作目录与另外一个分支的差别
$ git diff dev -- ./lib 你也以加上路径限定符,来只 比较某一个文件或目录
源仓库:
1.汇总参与该项目的各个开发者的代码
2.存放趋于稳定和可发布的代码
开发者仓库:
fork源仓库,每个开发者仓库是完全独立的,互不干扰。
开发流程:
开发功能-> 提交到自己的仓库->开发完成->向源仓库发送pull request (pr)------分布式开放工作
1.永久性分支:
- master branch :主分支
- develop branch : 开发分支
2. 临时性分支
- feature branch :功能分支
- release branch :预发布分支
- hotfix branch : bug修复分支
//功能开发
step 1: 切换到develop分支
>>> git checkout develop
step 2: 分出一个功能性分支
>>> git checkout -b feature-discuss
step 3: 在功能性分支上进行开发工作,多次commit,测试以后...
step 4: 把做好的功能合并到develop中
>>> git checkout develop
# 回到develop分支
>>> git merge --no-ff feature-discuss
# 把做好的功能合并到develop中
>>> git branch -d feature-discuss
# 删除功能性分支
>>> git push origin develop
# 把develop提交到自己的远程仓库中
这样,就完成一次功能的开发和提交。
release:
预发布分支,当产品即将发布的时候,要进行最后的调整和测试,这时候就可以分出该分支,测试完成之后,就可以将该分支卡发布,并删除。
hotfix:
表示产品已经发布,但是出现重大bug,需要修复,就可以分该分支,bug修复之后,将该分支合并到master分支上
1.源仓库的构建
2.开发者fork源仓库
3.将开发者自己的仓库clone到本地
4.构建功能分支进行开发
5.向管理员提交pr
6.管理员测试、合并
4.构建功能分支进行开发
>>> git checkout develop
# 切换到`develop`分支
>>> git checkout -b feature-discuss
# 分出一个功能性分支
>> touch discuss.js
# 假装discuss.js就是我们要开发的功能
>> git add .
>> git commit -m 'finish discuss feature'
# 提交更改
>>> git checkout develop
# 回到develop分支
>>> git merge --no-ff feature-discuss
# 把做好的功能合并到develop中
>>> git branch -d feature-discuss
# 删除功能性分支
>>> git push origin develop
# 把develop提交到自己的远程仓库中
6.管理员测试、合并
//管理员的一般测试、合并流程
1.对代码进行review
2.在它的本地测试新建一个测试分支,测试某人pr的代码
如:
>> git checkout develop
# 进入他本地的develop分支
>> git checkout -b livoras-develop
# 从develop分支中分出一个叫livoras-develop的测试分支测试我的代码
>> git pull https://github.com/livoras/git-demo.git develop
# 把我的代码pull到测试分支中,进行测试
2.1 如果测试成功
>> git checkout develop
>> git merge --no-ff livoras-develop
>> git push origin develop