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