GIT和SVN有什么区别:
GIT把内容按元数据方式存储类似k/v数据库,而SVN是按文件(新版svn已改成元数据存储)
git hash-object -w 文件
将文件夹写入到数据库中(本地数据库.git/object
)
git cat-file -p Hash值
在数据库(hashmap)中根据hash值查找文件内容
保存到数据库但是还没有保存到暂存区中(类似C语言中的指针)
git add 文件
只是让本地指针跟踪到到了该文件,但是还没有写入到版本中
一旦git commit 文件 -m message
就会在文件中的refs/heads
中写入该此提交(保存的是key(hash值))
SVN没用过,不清楚,听说是cp readme.md readme.md.version1
的保存方式
从本地把文件推送远程服务,SVN只需要commint 而GIT需要 add、commint、push 三个步骤
git add 文件是添加到暂存区
git rm --cached 文件
是从暂存区删除
//待考证 只要不push,代码都可以找回,并修改,一旦push到远程仓库就可能控制不了远程的文件了(没有权限)
git 是一个分布式的版本管理系统,而要SVN是一个远程集中式的管理系统
分布式
官方客户端
其它客户端
$ git
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
或者
sudo apt-get install git-core
因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。
注意git config
命令的--global
参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
完整模拟从项目添加到push 过程
本地初始化GIT 仓库:
基于远程仓库克隆至本地
git clone
当前目录初始化为git 本地仓库
git init
基于mvn 模板创建项目
mvn archetype:generate
将本地仓库和yuanchengck进行关联
git remote add origin https://XX
本地添加
添加指定文件至暂存区
git add
添加指定目录至暂存区
git add
添加所有
git add -A
或
git add .
将指定目录及子目录移除出暂存区
git rm --cached 文件/-r
git rm --cached
文件或者git rm --cache -r
移除还没有提交所有的文件
添加勿略配置文件.gitignore
本地提交
提交至本地仓库
git commit file -m '提交评论'
快捷提交至本地仓库, 提交所有 -am或者.(.代表本目录下的所有内容)
git commit -am '快添加与提交'
设置远程分支并推送
git push --set-upstream origin master
命令解释git push
推送命令,第一次推送需要设置推送的远程分支,后面不改远程分支就不需要了。--set-upstream
设置远程分支,master
远程分支名称
推送不成功,说明本仓库的内容和远程仓库中的内容不一致。需要git pull
还不如直接git clone 项目地址
不用初始化,直接。
另外:
我们提交代码,有时有编译时生成的修改项并不想提交,因为每次编译都会生成不一样的东西,我们可以进行过滤,步骤如下:
在工程根目录下新建 .gitignore文件
vim .gitignore
此处默认使用linux指令新建,需要会vim编辑器的基本用发(我也是不久前刚系统的学习了一下 )
当然如果是其他的文本编辑器也行,如notepad++
在生成的.gitignore文件中输入你不想上传的文件,我的如下:
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/build
设置完之后,下次上传之后这些目录的修改就不在版本控制范围之内了
git branch 查看分支
:-a
所有分支 -av
详细信息 -avv
远程仓库和本地仓库的关系
基于当前分支 创建一个新分支
基于远程分支 创建一个新分支
基于一个提交 创建一个新分支
基于Tag 创建一个新分支
当前分支一样,证明没有冲突。
本地分支修改:不push
远程修改:
文件冲突:
本地提交:本地分支改变,远程分支远程修改,导致不一致。
不能push
能pull
查看状态:
提示两边都修改了,需要merge。
修改为:
#基于当前分支新建分支
git branch
#基于提交新建分支
git branch
$ git branch -d {dev}
#切换分支
git checkout
#合并分支
git merge
#解决冲突,如果因冲突导致自动合并失败,此时 status 为mergeing 状态.
#需要手动修改后重新提交(commit)
将本地分支与远程建立关联
git branch --track --set-upstream-to=origin/test test
跟分支类似,不过tag是只读的。
比较两个分支的区别
git log master..experiment
后一个有多少提交没有提交到前一个
git log master..test
: test有多少提交没有提交到master
git log test..master
: master有多少提交没有提交到test
合并分支:合并以后无差别
查看文件:显示本地文件和本地仓库内部的不同
git status
命令可以让我们时刻掌握仓库当前的状态,上面的命令输出告诉我们,README.MF
被修改过了,但还没有准备提交的修改。
虽然Git告诉我们readme.txt被修改了,但如果能看看具体修改了什么内容,自然是很好的。比如你休假两周从国外回来,第一天上班时,已经记不清上次怎么修改的readme.txt,所以,需要用git diff这个命令看看:
第一次修改 -> git add -> 第二次修改 -> git commit
Git管理的是修改,当你用git add
命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit
只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。
提交后,用git diff HEAD -- 文件
命令可以查看工作区和版本库里面最新版本的区别
那怎么提交第二次修改呢?你可以继续git add
再git commit
,也可以别着急提交第一次修改,先git add
第二次修改,再git commit
,就相当于把两次修改合并后一块提交了:
步骤:第一次修改 -> git add -> 第二次修改 -> git add -> git commit
总结:每次提交都要先git add
然后在git commit
git checkout -- file
git checkout -- file
可以丢弃工作区的修改:$ git checkout -- README.MF
git add
命令。此时恢复的是上一次提交的暂存区的文件内容。git reset HEAD 文件
:撤回git add
操作git reset HEAD
: 回退到暂存区git add
,就使用该命令,作用撤销git add
git checkout -- file
git add
即可git reset --hard hash值
结合git reflog
可去任何地方:回退commit
版本git relog
记录每一次命令
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:
git diff HEAD file
查看文件修改情况
解释:绿色代表加入到暂存区还没有提交,红色代表还没有添加到暂存区
简单说就是没有执行git add
是红色,执行git add
是绿色
+:号代表添加的内容
-:代表删除的内容
黑白色的内容就是代表此时本地仓库(最后一次提交)里面的内容
Git 是一个内容寻址文件系统,其核心部分是一个简单的键值对数据库(key-value data store),你可以向数据库中插入任意内容,它会返回一个用于取回该值的hash 键。
git 键值库中插入数据
根据内容生成hash值,内容一样hash值一样。同一个操作系统的值一样的,window和Ubuntu不一样,亲自测试。
echo 'luban is good man' | git hash-object -w --stdin
79362d07cf264f8078b489a47132afbc73f87b9a
基于键获取指定内容
git cat-file -p 79362d07cf264f8078b489a47132afbc73f87b9a
Git基于该功能 把每个文件的版本中内容都保存在数据库中,当要进行版本回滚的时候就通过其中一个键将期取回并替换。
写入版本1
echo 'version1' > README.MF; git hash-object -w README.MF
;
5bdcfc19f119febc749eef9a9551bc335cb965e2
写入版本2
echo 'version2' > README.MF; git hash-object -w README.MF;
df7af2c382e49245443687973ceb711b2b74cb4a
写入版本3
echo 'version3' > README.MF; git hash-object -w README.MF;
777d3c2b51e73cc9177c34d14d9b6079b7c3ae7d
回滚指定版本
git cat-file -p df7af2c382e49245443687973ceb711b2b74cb4a> README.MF
只是查了该hash值的内容,没有写入文件,顾问兼内容不败你
所以我们平常用的 git add
其实就是把修改之后的内容 插入到键值库中。当我们执行 git add README.MF
等同于执行了 git hash-object -w README.MF
把文件写到数据库中。
我们解决了存储的问题,但其只能存储内容同并没有存储文件名,如果要进行回滚 怎么知道哪个内容对应哪个文件呢?接下要讲的就是树对象,它解决了文件名存储的问题 。
树对像解决了文件名的问题,它的目的将多个文件名组织在一起,其内包含多个文件名称与其对应的Key和其它树对像的用引用,可以理解成操作系统当中的文件夹,一个文件夹包含多个文件和多个其它文件夹。
git hash-object -w hello.txt
git hash-object -w hello.txt
git hash-object -w hello.txt
git hash-object -w hello.txt
git hash-object -w hello.txt
git hash-object -w hello.txt
git hash-object -w hello.txt
git hash-object -w hello.txt
已经写入了数据库中,不会重复写入数据库。
增加两个对象,一个提交对象,一个树对像。
一次提交即为当前版本的一个快照,该快照就是通过提交对像保存,其存储的内容为:一个顶级树对象、上一次提交的对像啥希、提交者用户名及邮箱、提交时间戳、提交评论。
git cat-file -p master^{tree}
git cat-file -p hash值
当我们执行 git branch {branchName}
时创建了一个分支,其本质就是在git 基于指定提交创建了一个引用文件,保存在 .git\refs\heads\
下。
演示分支的创建
git branch dev
cat.git\refs\heads\dev
git 总共 有三种类型的引用:
GC清理无用的引用并打包后删除