第二次学习GIT,整体按照书中的顺序来,插入我自己的理解
安装GIT
略
设置GIT
配置git环境:git config --global
- 参数config:用来配置git环境
- –global:长命令表示设置整个git环境
初次使用
配置基础
git config --global user.name "你的用户名"
git config --global user.email “你的邮箱”
起步
创建本地版本库
命令 git init
- init:初始化当前目录为仓库,初始化后会自动将当前仓库设置为master
添加文件到本地仓库
git add:将文件添加到暂存区
看着书学到这个地方,我在想暂存区是什么以及为什么要有暂存区这个东西,他能干啥?
查了一些资料,我明白了。
将文件提交到本地仓库是必要的两部也是重要的两部,第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区,第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。可以的简单的理解成将需要提交的文件(未暂存的or未跟踪的)统统放到暂存区,然后再一次性的提交,不用一个文件一次提交,显得特别的混乱。
问问自己,使用git时候是否都是所有的修改全部提交了,根本没有考虑到多个修改文件,是和多个功能有关,而每一个功能应该单独做成一次提交,这样可以保证提交历史的清晰。否则,当你想要回滚历史的时候,你会无所适从,根本分不清每个版本包含了哪些功能,修复了哪些bug.而暂存区的作用就是为了,可以选择提交,比如你在开发B功能的时候,发现A功能还存在Bug,这时候就需要先修复A中的Bug,然后先提交修复的A中的Bug,然后再提交B功能开发的文件。这样就可以提高提交版本历史记录的清晰,方便回滚。而提交是“原子性”的操作,文件的选择就放在暂存区去做,每一次提交都是一个功能的完整开发,保证了提交的干净。
git commit:将缓存区内的文件提交到本地仓库中
- 参数-m : 在提交的时候可以使用git commit -m “描述信息” 来为这次的提交填写描述信息。
- 如果单独的使用git commit ,会调用终端的注释编辑器让你输入描述信息。
- –amend : 重写上一次的提交信息
在项目中工作
- git status : 显示工作目录树的状态,即当前的视图状态
- git log : 查看日志
- -p 可以显示版本之间的代码差异
- –all 显示所有分支
- –pretty=oneline 将提交信息显示为一行
- –abbrev-commit 使得输出的 commitid更简短
- –graph 以图的形式显示
- 指定查找范围:假如只想查看最近五小时内的提交可以git log 后加–since=“5 hours” 也可以通过加–since=“5 hours” -1 来查看五小时之前的最后一个提交,也可以使用"最老版本…最新版本"这种格式作为查找范围(不包括起点,包括终点)。查看两个标签之间的历史都是有用的(git log --pretty=format:"%h %s" 1.0…HEAD),这次在git log 命令后添加了参数–pretty=format:"%h %s"告诉git显示提交提交名称的缩写,即标题。
- ^:一个脱字号作用相当于回溯一个版本。18f922e是指18f922e之前的那个版本,即父节点。
- ~N:波浪字符加数字的操作符是指回溯N个版本
回滚代码仓库:git reset --hard
reset参数是重置命令
–hard是重置代码仓库版本
有三种模式
–soft 、–mixed以及–hard是三个恢复等级。
使用–soft就仅仅将头指针恢复,已经add的暂存区以及工作空间的所有东西都不变。
如果使用–mixed,就将头恢复掉,已经add的暂存区也会丢失掉,工作空间的代码什么的是不变的。
如果使用–hard,那么一切就全都恢复了,头变,aad的暂存区消失,代码什么的也恢复到以前状态。
About 分支
创建分支
bit branch 新分支名称 父分支名称 (例如:git branch RB_1.0 master)
- -d 删除分支
- -b(创建并切换到该分支)
- -m 修改分支名称
- -r 显示远程分支
- -vv 查看关联关系
切换分支是
git checkout
- 这里如果在git checkout 后加上-b,变成git checkout -b [新分支名称],即创建新分支并切换到新的分支上
分支改名
git branch -m <原分支名称> <新分支名称>
_注意:在用参数-d的git branch命令删除旧分支,是要将代码合并回当前分支之后删除分支的操作才会成功。_如果确定无须合并,但必须要删除分支,则运行git bracnh -D <分支名称>,git就无须再检查要删除的分支上的内容是否都已经合并过来了。
克隆远程版本库
git clone [远程版本库的位置][存放该版本库的本地目录]
此命令带了两个参数,远程版本库的位置和存放该版本库的本地目录,第二个参数是可选的。
基础
添加文件到暂存区
通常我们用的是git add [文件名]这样的用法来添加文件到暂存区。这个方法比较慢,如果文件太多了怎怎么办?
- git add *.扩展名 ,这条命令可以添加所有同种类型的文件到暂存区。如果我们要添加不同类型的文件进去怎么办?
- git add . ,这条命令可以检测到新增、修改、删除。
- git add -u ,这条命令可以更新你已经跟踪过的文件,即提交后更改过的文件。如果添加了新文件,git是探测不到新的文件的。
- git add -i ,启动交互命令提示符,通过交互式的方式,提供查看当前状态、更新索引、revert索引、追踪未索引文件、打补丁、显示差异等功能。该命令主要用在索引前有很多文件,且各文件需要添加到不同提交中的情况。
提交修改
三种提交方法
第一种提交方法
先对要提交的文件或修改调用命令git add添加到暂存区,再调用git commit 命令完成提交。
第二种提交方法
给命令git commit 传递-a参数。
注意:此方法git只会把工作目录树中当前所有的修改提交到版本库中,不会添加尚未被跟踪的文件。
第三种提交方法
指定要提交的文件或者文件列表,把要提交的文件列在其他参数后面
例如:git commit -m “描述” [file1] [file2] […]
查看修改内容
如果添加新的文件或修改文件等工作刚完成,通常应该还记得动了哪些文件但有时就没有那么幸运了。
使用git status 和 git diff可以找出工作目录树中做出了哪些修改,以及如何修改的。
下面是使用git status的情况
查看文件改动
git diff
- 比较暂存区和版本库中的区别,在命令git diff后添加参数--cached 在
- 在git diff 后添加参数HEAD可以比较工作目录树和版本库中的差别
管理文件
文件重命名与移动
命令git mv <原文件命名称> <新文件名称>来移动文件(此命令告诉git使用原文加源文件内容来创建新文件,新文件保留源文件的历史修改记录,并删除源文件)
查看文件中每一行的历史记录
git blame 命令来查看文件中每一行的历史记录
- -M 参数,该参数告诉命令git blame 检测在同一个文件内移动或复制的代码行
- -C -C 参数 ,该参数告诉git blame 来查看文件之间的复制,给git log命令传递-C -C参数,也能显示文件复制信息, 当用git log命令检测文件的复制的时候,还得i传递参数-p,这样git除了显示常规日志信息之外,还会显示代码的具体变动
**反转提交 **
- 命令: git revert (此命令通过在版本库中创建一个“反向的”新提交来抵消原来提交的改动)
- -n 参数,通常GIT回立即提交反转结果,但是也可以通过 -n 参数告诉git先不要提交,这对于需要反转多个提交非常有用。运行多个git revert -n命令,git会暂存所有的变更,然后进行一次性提交
查看所有分支的所有操作记录
Git reflog 可以查看所有分支的所有操作记录(包括提交、回退、已删除的提交操作记录等 )。
- 每行记录都由版本号(commit id SHA),HEAD值和操作描述三部分组成。 版本号在第一列,HEAD值在第二列,操作描述信息在第三列。
- 版本号:在之前都有提到,标识着每一次提交、合并等操作时的版本,相当于唯一标识
- HEAD值:同样用来标识版本,但是不同于版本号的是,Head值是相对的。
- 当HEAD值为HEAD时,表示为提交的最新版本;HEAD表示为最新版本的上一个版本;HEAD^表示为最新版本的上上个版本;
- HEAD~100表示为最新版本的往上第100个版本。
- HEAD值越小,表示版本越新,越大表示版本生成时间越久。
- 在上面图中,我们发现HEAD值的展示形式为HEAD@{0}、 HEAD@{1}、HEAD@{2}…同样HEAD值的数字越小,表示版本越新,数字越大表示版本越旧。
- 操作描述:记录了本次是哪种操作,以及操作时编写的描述信息。
分支
分支改名
分支改名 git branch -m <原分支名称> <新分支名称>
直接合并分支
直接合并分支,只需要指定乡合并到当前分支的缘分支名称 git merge <源分支名称>(例如现在是master分支,要将alternate分支合并到master分支,则git merge alternate
压合合并
功能分支,在已有分支上创建新的分支,用于新功能开发或者BUG修复,然后通过一个压合提交将新分支上的修改合并回来。调用git merge 并给他传送参数–squash告诉git merge命令,将另一条分支上的全部提交压合成当前分支的一个提交。
拣选合并
有时候分之间只需要合并一个提交,并不需要要合并一条分支上的全部改动,因为该分支上可能含有尚未完成过的新功能忙活着包换一些尚不能合并的改动。使用git cherry-pick命令可以合并单个提交。参数-n的功能是,完成辩词拣选操作后git停了下来,,不是立即提交,而是暂存下来,可以进行下一个拣选操作,拣选完后一起提交,以免有多个拣选多个提交。
变基(什么是变基)
在看书的过程中,有很多疑惑,什么是变基?
提取子分支引入的补丁和修改,然后在稳定的主分支的基础上应用一次。 这种操作就叫做 变基(rebase)。
- rebase操作可以把本地未push的分叉提交历史整理成直线;
- rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。
- rebase(变基):改变当前分支的基础分支版本(父版本)(理解这句话就豁然开朗了)
基础分支的意思是当前从哪一个分支的哪一个版本创建出来。 - 比如说 :你可以提取在 C4 中引入的补丁和修改,然后在 C3 的基础上应用一次。 在 Git 中,这种操作就叫做 变基(rebase)。 也就是说git自动的将你基于C2上的修改,在C3上进行合并,C2也是test分支和master分支的分叉处,基于这一点,这一个版本进行比较差异,然后自动的完成修改,当然,如果有冲突的话,需要手动的处理冲突,然后使用git rebase --continue继续完成变基。
- 可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。
变基和合并这两种方法的最终结果没有任何区别,但是变基使得提交历史更加整洁。 使得你的头发没有了分叉,看上去就更加漂亮了。变基和合并最终的结果都是一样的,只不过是提交的历史不同。
GIT冲突和解决冲突
产生冲突原因
多个开发者同时使用或者操作git中的同一个文件,最后在依次提交和push的时候,第一个操作的是可以正常提交的,而之后的开发者想要执行pull(拉)和pull(push)操作的时候,就会报冲突异常conflict。
冲突的解决
- 直接修改文件
- 用git mergetool解决冲突,解决完后git会自动暂存修改等待提交
拉取or推送到远程仓库
生成公钥和获取公钥
- 生成SSH公钥 ssh-keygen -t rsa
- 获取公钥 cat -/.ssh/id_rsa.pub
连接远程仓库
git remote add <远端名称> <远程仓库地址>
- 远端名称,默认是orgin
- 仓库路径,从远端服务器获取此URL
- 查看远程仓库 git remote
推送版本到远程仓库
git push [-f] [-set-upstream][远端名称[本地分支名][:远端分支名]]
- 如果远端分支名和本地分支名称相同,则可以只写本地分支
- -f 表示强制覆盖(如果本地的代码和云端的代码有冲突,他会不让你推,-f就是强制覆盖)
- -set-upstream 推送到远端的同时并且建立起和远端分支的关联关系
- 例:git push --set-upstream orgin master:matser orgin(远端名称) master:master(将本地master分支与远端master分支绑定起来)
查看关联关系
git branch -vv
从远程仓库中抓取和拉取
- 抓取:git fetch [remote name][branch name]
- 如果不指定远端名称和分支名,则抓取所有分支。
- 拉取:git pull [remote name][branch name]
- 拉取指令就是将远端仓库的修改拉到本地并自动进行合并,等同于fetch+merge
- 如果不指定远端名称和分支名,则拉取所有分支。