1.git分区
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
工作区() -> 暂存区(stage,index) (.git/index文件)(是版本库的一部分) -> 版本库
2.git初步体验
2.1基本配置
支持三个层级
- –system 系统配置 针对所有用户
- –global 全局配置(用户级)
- –local 项目(本地)配置,针对当前项目
git config --global user.name 'ee' //设置用户名
git config --global user.email 'ee@163.com' //设置用户邮箱
git config --list //查看配置
git config --global alias.lol=log --oneline --decorate --graph --all //别名
2.2本地项目初始化
git init
- 也可```git init --bare(空的) /xxx/xxx.git
2.3添加到暂存区(装车)
git add .
git status //查看添加状态
git statis -s //简洁的
2.4提交到版本库
git commit -m "test" //这里不能用单引号
git status //查看提交状态
###3.git详细命令
git回退
- 取消暂存(unstage)
git reset head
(用版本库的head历史提交还原暂存区) - 撤销修改(discard changes)
git checkout -- <file>
(用暂存区的文件还原工作区) - 回退版本
git reset --hard(硬性回退) 版本号(某个历史提交记录)
(用版本库的历史提交还原工作区和暂存区,重置head) https://www.cnblogs.com/kidsitcn/p/4513297.html git reset --soft(软性回退) 版本号
只重置head,不还原工作区和暂存区,亚型的回退版本git checkout head(版本号) <file>
用版本库的历史提交中的文件还原工作区 ,也是一种亚型撤销修改git reset --mixed(默认) 版本号
亚型取消暂存,重置head,用版本库的历史提交还原暂存区- 其实两个功能,在不同情形下的区分和说法.
一般分三种情况处理
- 修改了,但是没添加到暂存
撤销修改命令
- 修改了也添加到暂存了
先取消暂存,再撤销修改
- 添加到暂存也提交了
凉了
查看文件差异和改动
git diff
查看文件具体修改了哪些内容,尚未缓存的改动git diff --cache
查看已缓存的改动git diff HEAD
查看已缓存与未缓存的所有改动git diff --stat
显示摘要而非整个diff
文件状态,针对于文件所处的不同分区,分以下
- 未追踪,文件第一次出现在工作区
- 已追踪,只要第一次添加到了暂存区,文件就已追踪
- 未修改,文件在工作区未被编辑
- 已修改,文件在工作区被编辑
- 未暂存,文件已修改,但没有添加到暂存区
- 已暂存,文件已修改,也添加到了暂存区
- 未提交,已暂存的文件没有提交到版本库
- 已提交,已暂存的文件提交到版本库
注意有时候git回退的时候,文件状态是可以变回未追踪的,因为第一次添加操作被回退(撤销),相当于没发生过
总之:文件状态之间和文件状态与每个区之间是有联系的,可以推理判断得文件状态
删除跟踪
git rm <file>
这个是工作区和暂存区的文件一起删除,相当于rm后,添加了暂存,没法直接撤销修改,要先取消暂存
.但是它的功能是相当于删除了第一次添加文件,就删除了跟踪,从这也可以看出,git的一些命令,可以就是基本的命令组合操作,可能内部加了点点特色盐
版本号特殊代表
- HEAD^ 前1个版本 HEAD~1
- HEAD^^ 前2个版本 HEAD~2
- HEAD^^^ 前3个版本 HEAD~3
- 以此类推…
查看日志(查看版本号)
-
查看日志
git log
查看关联日志(或简易日志)git reflog
-
过滤查看日志
git log -p //更详细的查看,显示修改内容这些,会分页显示 git log --pretty=online //一行显示,只显示版本号 git log --online 历史记录简洁版本 git log --graph 查看历史中什么时候出现了分支、合并 git log --after '2018-5-20' //显示某天之后的日志 git log --before '2018-5-20' //显示某天之前的日志 git log --author 'ee' //显示某作者(用户)的日志
从远程服务器或github克隆仓库
git clone <http_url>|<ssh_url>|<git@github.com:xxx>
git pull
拉取更新git fetch和git merge的结合
git push
推送远程git remote
查看添加远程仓库,建立虚的连接git remote -v //详细的
git push和git pull和git merge时,git都会检测历史提交的关系逻辑是否相同或者包含
推送版本冲突解决
-
如果有版本冲突时,git有自动合并功能(结果会产生历史提交),如果不能自动合并,协商解决,就是重新修改冲突的地方,然后添加提交,再推送.
-
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用
git log --graph
命令可以看到分支合并图。当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
合并分支
分支不是代表把仓库分成不同空间区域哦,它只是一个引用,指向一个历史提交
在时间线(历史提交关系图)上看,不同分支间是有部分共用的历史提交的.所以不同分支可以理解为最后时间线的走向不同,头不同
这就是git的一大亮点和优势,重点用了分支这个概念和技术
head指针代表着当前操作那个分支,指向着分支引用.
- 其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。但git的分支是与众不同的,无论创建、切换和删除分支,git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。
合并某分支到当前分支:
git merge
git merge带有添加提交操作,所以会产生历史提交记录
通常,合并分支时,如果可能,git会用
Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息
。如果要强制禁用Fast forward
模式,git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。git merge --no-ff -m "merge with no-ff" <name> //--no-ff参数,表示禁用Fast forward
自动合并就是禁用
Fast forward
模式的什么是
Fast forward
模式?
其实就是快速将master分支和head指针要合并的分支的最新历史提交上
<可以是跟自己服务器的分支合并,也可以是跟远程服务器的分支合并(不过这种情况是merge命令内嵌在pull中)>
以下没说的,都是指在只有master一个分支的情况下进行的操作
比如 远程添加了2.txt
本地添加了1.txt
然后git push … ,就会提示
! [rejected] master -> master (fetch first) error: failed to push some refs to 'xxx' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
然后我们执行 git pull … ,就会拉取远程最新的,自动合并到本地,产生一个历史提交(它有两个父).
头) * 27623bc (HEAD -> master) Merge branch 'master' of xxx |\ | * 17a4cdb (blog/master) add 3.txt * | 733d401 add 1.txt |/ * 27e9ee1 create 2.txt * 9f454b3 detele 尾)
<不能自动合并时,就要手工改冲突>
比如:
* branch master -> FETCH_HEAD 27623bc..ca4c24a master -> blog/master Auto-merging 3.txt CONFLICT (content): Merge conflict in 3.txt Automatic merge failed; fix conflicts and then commit the result.
这是版本库关系图上,头部有两个历史提交
头) * 5404d6b (HEAD -> master) add 1 | * ca4c24a (blog/master) add 2 |/ * 27623bc Merge branch 'master' of xxx |\ | * 17a4cdb add 3.txt * | 733d401 add 1.txt |/ * 27e9ee1 create 2.txt 尾)
正确的一个分支关系图头部只能有一个历史提交,这就是版本冲突没解决呢,要手工修改文件冲突的地方(为啥不能自动合并,可能git是根据历史提交是否相同(或者子集)判断,根据历史提交的关系逻辑是否一样,如果有不同的历史提交,就是有冲突,
如果大家同一个文件内容都有修改的话(不会去检查具体内容的,只是记下了是否改变了,就算内容同,也是会冲突,除非历史记录关系图是包含关系或者相同),git没法解决,因为它不知道你们要用谁的代码或者都用,所以要手工)<这里说的有点乱,是第一次凭空理解时候写的,后面修改过,但是还是乱,看后面的顿悟可能好点><<<<<<< HEAD add 1 ======= add 2 >>>>>>> ca4c24ab23f36fab2c89f6d4a8cb8cb3cf48fbdd
修改后
add 1 add 2
然后添加提交
头) * ce1993f (HEAD -> master) change conflict |\ | * ca4c24a (blog/master) add 2 * | 5404d6b add 1 |/ * 27623bc Merge branch 'master' of xxx |\ | * 17a4cdb add 3.txt * | 733d401 add 1.txt |/ * 27e9ee1 create 2.txt 尾)
创建分支,切换分支
创建分支,不是克隆仓库,复制文件哦,是创建一个
新分支名的引用(指针)
,然后指向master
相同的提交,再把HEAD
指向新分支名的引用
所以,git创建一个分支很快,因为除了增加一个
新分支名的
指针,改改HEAD
的指向,工作区的文件都没有任何变化!
git branch //查看分支
git branch <name> //创建分支
git checkout <name> //切换分支
git checkout -b <name> //创建切换分支
git branch -d <name> //删除分支
###突然领悟:
突然意识到:git分布式,而不是svn那种集中的有中央服务器,不能只看github这个基于git的代码托管平台(提供基于git的版本托管服务),这不是git的中央服务器,git是没有中央服务器的,每一个用户都可以是服务器,这就是分布式,如果一个人的服务器崩了,只要有人是最新的或被认可的(这个可以会版本冲突,但是可以解决),就是可以当做服务器,被其他人克隆拉取推送
设置Git 区分文件名大小写
git 默认不区分文件名大小写
当你创建一个文件后,叫 readme.md 写入内容后 提交到线上代码仓库.
然后你在本地修改文件名为 Readme.md 接着你去提交,发现代码没有变化.
控制台输入git status 也不显示任何信息
那么就配置git 使其对文件名大小写敏感
git config core.ignorecase false
顿悟1:github上面的账号不就是git里面说的用户么,只不过是github平台里面的git服务器我们不能命令去操作,但是提供了github这个界面平台,我们电脑上的git和github联系,和与其他服务器的git仓库联系,本质就是一样的,都是分布式,推送最新代码到别的服务器.也就是说github两个不同账号之间的操作和github和我们电脑git之间的操作是一个原理,只不过github在此基础之上,提供了一些评论交流的web功能
顿悟2:fork就是类似我们git pull或者git clone
顿悟3:对比是比较历史提交关系时间线和历史提交节点是否包含,如果存在相同文件发生改变的不包含的,不能自动合并,则会把改变的地方标记出来,让人手工去改,标记是不看具体内容的,就算相同内容也会标记
以上内容在顿悟后,做了修改,可能有些地方没改