git 0基础入门—git入门与实践(4)—详细图解git存储操作及超详细的rebase变基操作与原理及远程仓库多人开发详细操作

git入门与实践(4)

1. git 存储

1. 1 问题引入

image-20200701114947081

提交,并创建分支

image-20200701115140212

并添加文件内容:

image-20200701115209619

添加暂存区

image-20200701115332868

  这个时候发现上一个版本开发的过程中有问题,需要修复一下。于是赶紧切换回master分支,其实最好再开一个分支处理这个问题。

image-20200701115556487

  在branch2分支上,首先创建一个文本b。

  log打印暂存区还有a.txta.txt是在branch1时候暂存的,如果仅提交b.txt的话,无意间也会提交a.txt。遇到这种问题怎么办?

image-20200701120220928

1. 1. 1 解决

  当在一个分支中向暂存区添加内容,切换到另一个分支时,提交commit会带上另一分支中的暂存内容。这个时候就需要先保存a.txt(另一分支中的暂存内容),再处理当前需要提交的内容。

切换回branch1

image-20200701121329819

  我们把目前的暂存记录保存起来。

1. 1. 1. 1 git stash

  git stash存储暂存区及工作目录修改文件

image-20200701121502959

1. 1. 1. 2 git stash list

  git stash list 打印所有存储内容

image-20200701121538712

  查看状态:暂存区就没了

image-20200701121716604

  再切换回branch2,去提交b.txt文件。这样问题就解决了。

image-20200701121852703

  我们利用了branch2修复了bug,解决了问题后,现在删除分支。

  发现报错了,原因是我们当前的HEAD指向branch2,得切换回master再删除

image-20200701122036310

  同时因为branch没有进行合并,因此必须用-D强制删除

image-20200701122303838

1. 1. 1. 3 git stash apply

  git stash apply <stashName>

  紧接着,想把之前存的东西恢复。

image-20200701122445968

  我们发现存的时候在暂存区,而取得时候却不在暂存区了。

1. 1. 1. 3. 1 git stash apply --index

  git stash apply --index 将存储内容重新应用(默认不保留已暂存内容)

  将原暂存依旧以暂存进行取出

  因为重复取内容,所以报错,我们可以在工作区将a.txt删除再取

image-20200701122807654

image-20200701122857822

1. 1. 1. 3. 2 git stash apply 标号 --index

  如果存储了多个,恢复时需加上标号

image-20200701123406589

1. 1. 1. 4 git stash drop

  移除存储

  git stash drop

  删除之后,再git stash list打印存储列表页不存在了。

image-20200701123058612

image-20200701123156157

1. 1. 1. 5 git stash 标号 drop

  如果存储了多个,移除时需加上标号

image-20200701123524333

1. 1. 1. 6 git stash -u

  git stash -u 在上面的基础上带上未追踪文件
  我们新建一个文件,不放入暂存直接存储,但是查看状态,记录仍在哦!我们可以存储的时候加上-u告诉它在存储的时候,未追踪的文件也一样存储起来。

image-20200701123735065git stash -u

  大家可能好奇,第一次什么也没存储,怎么还添加上去了。原因是起初对a文件是有修改的,虽然取出来了但并没提交。

image-20200701124006295

  现在看看文件状态

image-20200701124256219

  取出存储

git stash apply 'stash@{0}'

image-20200701124655128

1. 2 小结

  当在一个分支上面,有准备提交或者添加暂存区的内容,又不希望它现在被提交,可以先把它存储起来。再切换分支,去另一个分支做另外的事情,等到那边进行完毕了。再切换回分支,将存储的内容拉取出来,最好再提交或添加暂存区。

2. rebase变基操作

  和merge同样都是进行合并操作的。
  区别在于,将一个分支的内容都移至另一个分支上。

2. 1 回顾merge与rebase对比

  回顾merge,它是以c2、c4、c5为基准创建一个合并,整合到c6提交。合并的时候,切换到master主分支,将branch1合并过来。

image-20200701135314401

  如果是rebase,则c3也参与进来。把想要合并的分支作为当前分支,进行合并。

2. 2 模拟rebase操作

  初始化git,并创建5个文件

image-20200701131438664

进行c1、c2提交

image-20200701131539603

开并切换分支branch1,再提交c3

image-20200701131705208

c4提交

image-20200701131935221

切换回master,c5提交

image-20200701132029782

image-20200701132140746

  rebase把想要合并的分支作为当前分支,进行合并。我们切换到branch1,再合并(master作为基点,将branch1合并过去)。

  形成了一条直线(branch1master处在同一条线上),HEADbranch1上,

image-20200701132713071

2. 1. 1 动态演示

  在c2分支branch1,做了两次提交,在c2后master进行了一次c5提交。我们想要合并的是branch1,所以切换HEAD指向branch1。接下来执行变基操作,然后git会进行rebase分析。

2. 1. 1. 1 rebase分析(工作流程)
  1. 首先找到两个分支的共同祖先
  2. 然后对比当前分支与祖先的历次提交,进行提取相应修改(提取c3、c4),并保存为临时文件(对应c6、c7),将当前分支指向目标基底(master主分支),最后将之前存为临时文件的修改(对应c6、c7)依序应用
  3. HEAD指向目标基底(master主分支)末尾(对应c7
  4. 这就形成了一条直线路径了(c1->c2->c5->c6->c7
  5. rebase只是把分支提交内容放到主分支上,实际上并没有进行合并,因此最终还是需要执行merge命令的。
  6. 先将HEAD指向master分支上,再执行merge命令,然后就进行快速前移了。

image-20200701134804066

2. 1. 1. 2 c3、c4和c6、c7是同一个节点吗?

  我们对比两次c3、c4的哈希是不一样的,因为hash是唯一的,所以证明它们都是不同的节点。可能有人疑问之前的c3、c4去哪了?这其实和reset重置是一样的,重置之后,被遗弃的节点就没有指向了,并且这类节点如果长时间未使用,会被git进行回收(类似编程语言的垃圾回收机制)。

image-20200701134433934

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 为别名

image-20200701141126174

  注意:不是任何东西都可以取别名的,还需要熟悉命名规则,所以不建议改别名。

4. 多人合作开发模式

  以防万一,我们把本地的仓库不小心删除,所以我们需要一个可以备份的地方,这个地方可以是我们的网盘,也可以是u盘,或者是类似于经常用到的github。

  但是u盘或网盘这类的存储方式虽然可以保存备份,却不能适用于多人的开发,如果我们想要多人的开发,就需要有一个中央仓库,可以给团队开发中的每个人下载并且使用。

4. 1 中央仓库

  存储每个成员的提交对象,共享提交对象给每个成员。

  推荐github:https://github.com/(注册与使用自己问度娘吧!或者参考其余小迪的git文章吧。)

image-20200701162319051

4. 2 分布式版本控制系统(git、svn)

  分布在每个成员的电脑上,都有一个本地仓库,任何一个电脑的本地仓库不小心丢失,都可以从成员处找回,或者可以从中央仓库进行下载共享,保存历史纪录的任务分配到了每个开发成员的身上,中央仓库只需要整合共享。

image-20200701162337508

5. 配置忽略文件

  前提:创建并连接仓库与本地管理

  参考github提示:

image-20200701153333570

image-20200701153309391

我们往里添加一个doc文件

image-20200701143340002

  我们会发现,有些时候我就是不希望git管理文件夹中的某个文件,每一次查看状态总是告诉我未追踪,很麻烦~
.gitignore文件,列出忽略文本模式

  注意以.开头的文件我们是无法手动创建的,我们需要用命令行去创建。

image-20200701143432800

5. 1 编写规则

  与正则表达式类似

# 相当于注释

* 匹配零个或多个任意字符

[ ] 匹配任意一个在方括号内的字符,[abc] 匹配这三个字母其中之一即可

只匹配一个任意字符

** 表示匹配任意中间目录

! 忽略指定文件以外的文件或目录(白名单)

[x-x]在这个范围的都可以匹配,如[0-9] 代表0~9的范围

image-20200701143837146

需求:忽略doc文件

image-20200701144652339

看状态,.doc就没了。

image-20200701144744591

如果不想要.gitignore文件

image-20200701144846186

image-20200701144859433

6. tag标签

  我们经常看到下载的软件分为“xx版本”,这个“xx版本”其实就是我们说的标签,该标签指向一个commit对象,虽然我们也可以用这个commit对象进行版本的表述,但是由于哈希太长,并且没有规律,所以我们使用标签的方式,进行版本标注。

6. 1 设置标签

​   git tag v1.0 (默认在最新的commit提交上)

6. 2 查看标签

​   git tag

  这里看到有HEAD、master、branch1、tag四个指针

image-20200701151548796

6. 3 给指定commit添加标签:

​   git tag v0.1 hash

image-20200701151827616

6. 4 添加带有说明的标签

​   光添加版本号,是不靠谱的,很容易忘记这个版本都做了什么事情。

​   git tag -a v0.1 -m "描述信息" hash

image-20200701152119067

6. 5 查看标签版本信息

  git show 标签

  打印tag和commit的描述信息

image-20200701152251475

6. 6 删除标签

git tag -d 版本号

image-20200701152404470

7. 远程仓库命令

  创建远程仓库,仓库的名称默认originorigin中有单独的masterHEAD指针,和本地仓库的HEADmaster并非一致。

7. 1 git push

  提交远程仓库

git push -u origin master

image-20200620171256560

image-20200701153202288

  我们再看github,文件就上传上去了。(忽略文件没上传上来!)

image-20200701153546919

  点击查看commit提交记录。

image-20200701153702950

image-20200701153734721

  也可查看分支

image-20200701153824469

image-20200701153845462

  查看本地分支是有两个的,但是github中却只上传了一个。

image-20200701153920429

7. 1. 1 提交分支

git push -u origin 分支

image-20200701154037299

image-20200701154156404

image-20200701154202891

7. 2 git clone

  克隆项目到本地

  复制地址

image-20200701154410837

git clone 地址

image-20200701154519032

image-20200701154611980

image-20200701154628893

7. 3 git pull

  拉取

  当团队开发的时候,比如你的伙伴提交了本地仓库,而我们自己的仓库没有这些信息,我们自己也提交进本地仓库,就会造成冲突。

  如何解决呢?得先拉去一下,处理完冲突后,再提交代码就没问题了,和之前的冲突合并是一样的解决办法。

7. 4 远程仓库克隆分支

git checkout -b branch1 origin/branch1

拉取下来的分支默认是master

7. 5 删除远程仓库分支

git push origin :branch

如果我们仅仅删除本地分支,git是不会同步到远程仓库的!

image-20200701155552984

image-20200701153824469

image-20200701153845462

7. 6 推送标签到远程仓库

  同理我们在本地设置的标签,也是不会同步到本地仓库的。

image-20200701155845398

image-20200701155945495

7. 6. 1 单独标签上传

git push origin 标签

image-20200701160046608

image-20200701160142478

7. 6. 2 所有标签上传

git push origin --tags 上传所有标签

image-20200701160309318

image-20200701155845398

image-20200701160408554

7. 7 删除远程仓库的标签

git push origin :refs/tags/标签

image-20200701160506157

image-20200701160549535

8. 远程仓库使用SSH密钥

ssh-keygen -t rsa -C "[email protected]"
生成ssh密钥

image-20200701161234079

在电脑上找到钥匙,打开复制给github即可。

image-20200701161805677

② 在github上找到settings,设置SSH

image-20200701160859002

③ 将生成的文件填到对应的位置(生成的信息给到仓库的管理者)

新建锁子,目的是给参与项目的人建立的。

image-20200701161002537

复制进去即可

image-20200701161855976

9. 开发建议

  开发的时候避免在主分支上进行提交代码,在主分支上只记录大的版本。

  如开发在develop分支上进行。

  打补丁在topic分支上进行。

image-20200701162204799



(后续待补充)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章