git 0基础入门—git入门与实践(4)—详细图解git存储操作及超详细的rebase变基操作与原理及远程仓库多人开发详细操作
文章目录
git入门与实践(4)
1. git 存储
1. 1 问题引入
提交,并创建分支
并添加文件内容:
添加暂存区
这个时候发现上一个版本开发的过程中有问题,需要修复一下。于是赶紧切换回master
分支,其实最好再开一个分支处理这个问题。
在branch2
分支上,首先创建一个文本b。
log
打印暂存区还有a.txt
,a.txt
是在branch1
时候暂存的,如果仅提交b.txt
的话,无意间也会提交a.txt
。遇到这种问题怎么办?
1. 1. 1 解决
当在一个分支中向暂存区添加内容,切换到另一个分支时,提交commit
会带上另一分支中的暂存内容。这个时候就需要先保存a.txt
(另一分支中的暂存内容),再处理当前需要提交的内容。
切换回branch1
我们把目前的暂存记录保存起来。
1. 1. 1. 1 git stash
git stash
存储暂存区及工作目录修改文件
1. 1. 1. 2 git stash list
git stash list
打印所有存储内容
查看状态:暂存区就没了
再切换回branch2
,去提交b.txt
文件。这样问题就解决了。
我们利用了branch2
修复了bug,解决了问题后,现在删除分支。
发现报错了,原因是我们当前的HEAD
指向branch2
,得切换回master
再删除
同时因为branch
没有进行合并,因此必须用-D
强制删除
1. 1. 1. 3 git stash apply
git stash apply <stashName>
紧接着,想把之前存的东西恢复。
我们发现存的时候在暂存区,而取得时候却不在暂存区了。
1. 1. 1. 3. 1 git stash apply --index
git stash apply --index
将存储内容重新应用(默认不保留已暂存内容)
将原暂存依旧以暂存进行取出
因为重复取内容,所以报错,我们可以在工作区将a.txt
删除再取
1. 1. 1. 3. 2 git stash apply 标号 --index
如果存储了多个,恢复时需加上标号
1. 1. 1. 4 git stash drop
移除存储
git stash drop
删除之后,再git stash list
打印存储列表页不存在了。
1. 1. 1. 5 git stash 标号 drop
如果存储了多个,移除时需加上标号
1. 1. 1. 6 git stash -u
git stash -u
在上面的基础上带上未追踪文件
我们新建一个文件,不放入暂存直接存储,但是查看状态,记录仍在哦!我们可以存储的时候加上-u
告诉它在存储的时候,未追踪的文件也一样存储起来。
git stash -u
大家可能好奇,第一次什么也没存储,怎么还添加上去了。原因是起初对a文件是有修改的,虽然取出来了但并没提交。
现在看看文件状态
取出存储
git stash apply '[email protected]{0}'
1. 2 小结
当在一个分支上面,有准备提交或者添加暂存区的内容,又不希望它现在被提交,可以先把它存储起来。再切换分支,去另一个分支做另外的事情,等到那边进行完毕了。再切换回分支,将存储的内容拉取出来,最好再提交或添加暂存区。
2. rebase变基操作
和merge
同样都是进行合并操作的。
区别在于,将一个分支的内容都移至另一个分支上。
2. 1 回顾merge与rebase对比
回顾merge
,它是以c2、c4、c5为基准创建一个合并,整合到c6提交。合并的时候,切换到master
主分支,将branch1
合并过来。
如果是rebase
,则c3
也参与进来。把想要合并的分支作为当前分支,进行合并。
2. 2 模拟rebase操作
初始化git,并创建5个文件
进行c1、c2提交
开并切换分支branch1
,再提交c3
c4提交
切换回master
,c5提交
rebase
把想要合并的分支作为当前分支,进行合并。我们切换到branch1
,再合并(master
作为基点,将branch1
合并过去)。
形成了一条直线(branch1
和master
处在同一条线上),HEAD
在branch1
上,
2. 1. 1 动态演示
在c2分支branch1
,做了两次提交,在c2后master
进行了一次c5提交。我们想要合并的是branch1
,所以切换HEAD
指向branch1
。接下来执行变基操作,然后git会进行rebase
分析。
2. 1. 1. 1 rebase分析(工作流程)
- 首先找到两个分支的共同祖先
- 然后对比当前分支与祖先的历次提交,进行提取相应修改(提取
c3、c4
),并保存为临时文件(对应c6、c7
),将当前分支指向目标基底(master
主分支),最后将之前存为临时文件的修改(对应c6、c7
)依序应用 - 将
HEAD
指向目标基底(master
主分支)末尾(对应c7
) - 这就形成了一条直线路径了(
c1->c2->c5->c6->c7
) -
rebase
只是把分支提交内容放到主分支上,实际上并没有进行合并,因此最终还是需要执行merge
命令的。 - 先将
HEAD
指向master
分支上,再执行merge
命令,然后就进行快速前移了。
2. 1. 1. 2 c3、c4和c6、c7是同一个节点吗?
我们对比两次c3、c4的哈希是不一样的,因为hash是唯一的,所以证明它们都是不同的节点。可能有人疑问之前的c3、c4去哪了?这其实和reset
重置是一样的,重置之后,被遗弃的节点就没有指向了,并且这类节点如果长时间未使用,会被git进行回收(类似编程语言的垃圾回收机制)。
2. 1. 2 rebase好处
经过上述操作,我们实际上发现,c3和c4依然保留在记录中。不会像merge
操作,直接合并成了c7,但是c3、c4在路线上却不存在了。这样既保留了原始记录,又不会妨碍版本迭代开发,造成主线的冗余。
2. 1. 3 rebase和merge应用场景
如注重每次提交要有详细过程,可选用rebase
,而注重结果精简过程的话,就选用merge
。
3. 别名
有时候觉得常用的命令字母多了点,例如:git checkout
我们输入的时候,会花费很长的时间,那不如给它取个别名吧~
git config --global alias.co checkout
不想配成全局,而是本地则:
git config --local alias.co checkout
.
后面 co
为别名
注意:不是任何东西都可以取别名的,还需要熟悉命名规则,所以不建议改别名。
4. 多人合作开发模式
以防万一,我们把本地的仓库不小心删除,所以我们需要一个可以备份的地方,这个地方可以是我们的网盘,也可以是u盘,或者是类似于经常用到的github。
但是u盘或网盘这类的存储方式虽然可以保存备份,却不能适用于多人的开发,如果我们想要多人的开发,就需要有一个中央仓库,可以给团队开发中的每个人下载并且使用。
4. 1 中央仓库
存储每个成员的提交对象,共享提交对象给每个成员。
推荐github:https://github.com/(注册与使用自己问度娘吧!或者参考其余小迪的git文章吧。)
4. 2 分布式版本控制系统(git、svn)
分布在每个成员的电脑上,都有一个本地仓库,任何一个电脑的本地仓库不小心丢失,都可以从成员处找回,或者可以从中央仓库进行下载共享,保存历史纪录的任务分配到了每个开发成员的身上,中央仓库只需要整合共享。
5. 配置忽略文件
前提:创建并连接仓库与本地管理
参考github提示:
我们往里添加一个doc文件
我们会发现,有些时候我就是不希望git管理文件夹中的某个文件,每一次查看状态总是告诉我未追踪,很麻烦~.gitignore
文件,列出忽略文本模式
注意以.
开头的文件我们是无法手动创建的,我们需要用命令行去创建。
5. 1 编写规则
与正则表达式类似
#
相当于注释
*
匹配零个或多个任意字符
[ ]
匹配任意一个在方括号内的字符,[abc]
匹配这三个字母其中之一即可
?
只匹配一个任意字符
**
表示匹配任意中间目录
!
忽略指定文件以外的文件或目录(白名单)
[x-x]
在这个范围的都可以匹配,如[0-9]
代表0~9的范围
需求:忽略doc
文件
看状态,.doc
就没了。
如果不想要.gitignore
文件
6. tag标签
我们经常看到下载的软件分为“xx版本”,这个“xx版本”其实就是我们说的标签,该标签指向一个commit
对象,虽然我们也可以用这个commit
对象进行版本的表述,但是由于哈希太长,并且没有规律,所以我们使用标签的方式,进行版本标注。
6. 1 设置标签
git tag v1.0
(默认在最新的commit
提交上)
6. 2 查看标签
git tag
这里看到有HEAD、master、branch1、tag
四个指针
6. 3 给指定commit添加标签:
git tag v0.1 hash
6. 4 添加带有说明的标签
光添加版本号,是不靠谱的,很容易忘记这个版本都做了什么事情。
git tag -a v0.1 -m "描述信息" hash
6. 5 查看标签版本信息
git show 标签
打印tag
和commit
的描述信息
6. 6 删除标签
git tag -d 版本号
7. 远程仓库命令
创建远程仓库,仓库的名称默认origin
,origin
中有单独的master
和HEAD
指针,和本地仓库的HEAD
或master
并非一致。
7. 1 git push
提交远程仓库
git push -u origin master
我们再看github,文件就上传上去了。(忽略文件没上传上来!)
点击查看commit提交记录。
也可查看分支
查看本地分支是有两个的,但是github中却只上传了一个。
7. 1. 1 提交分支
git push -u origin 分支
7. 2 git clone
克隆项目到本地
复制地址
git clone 地址
7. 3 git pull
拉取
当团队开发的时候,比如你的伙伴提交了本地仓库,而我们自己的仓库没有这些信息,我们自己也提交进本地仓库,就会造成冲突。
如何解决呢?得先拉去一下,处理完冲突后,再提交代码就没问题了,和之前的冲突合并是一样的解决办法。
7. 4 远程仓库克隆分支
git checkout -b branch1 origin/branch1
拉取下来的分支默认是master
7. 5 删除远程仓库分支
git push origin :branch
如果我们仅仅删除本地分支,git是不会同步到远程仓库的!
7. 6 推送标签到远程仓库
同理我们在本地设置的标签,也是不会同步到本地仓库的。
7. 6. 1 单独标签上传
git push origin 标签
7. 6. 2 所有标签上传
git push origin --tags
上传所有标签
7. 7 删除远程仓库的标签
git push origin :refs/tags/标签
8. 远程仓库使用SSH**
① ssh-****** -t rsa -C "[email protected]"
生成ssh**
在电脑上找到钥匙,打开复制给github即可。
② 在github上找到settings
,设置SSH
③ 将生成的文件填到对应的位置(生成的信息给到仓库的管理者)
新建锁子,目的是给参与项目的人建立的。
复制进去即可
9. 开发建议
开发的时候避免在主分支上进行提交代码,在主分支上只记录大的版本。
如开发在develop
分支上进行。
打补丁在topic
分支上进行。
(后续待补充)