目录
八.修改文件
由文章(一),我们可以清楚地知道,git追踪管理的其实是修改,而不是文件。如何知道这一点呢,接下来我们引入两个命令来查看修改前后的变化。
// 显示暂存区和工作区文件的差异(add前)
git diff [file]
// 查看版本库和工作区文件的区别(commmit前)
git diff HEAD -- [file]
1.我们可以看到,文件名有后缀还是要加上后缀,才能正常访问
2.我们其实可以直接cat README.txt查看文件,为什么还要多次一举呢?因为代码多了,区别就不容易找了。
3.我们可以看到git diff HEAD -- README.txt与git commit -m 'new'都是增加两行减少一行,而不是只是单纯地增加一行
九.版本回退
关于README.txt的两个版本
第一次提交(README)
C++ direction learning log --图片中将缩写为C++
第二次提交(new)
C++ direction learning log --图片中将缩写为C++
new line --图片中将缩写为new
// 本质是回退版本库中的内容
git reset [--soft | --mixed | --hard] [HEAD]
// 当回退版本以后,git log显示的版本也将回到那时
// 当clear后想吃后悔药,git log找不到回退前的哈希值
// 这时就需要如下命令
git reflog
如图介绍了使用不同命令之间的区别,同时应该慎用--hard,因为他会将工作区也一并回退,如果你此时正在开发新内容,new下写了几万字了,那这些也将一并回退,并且无法恢复。下面我将演示如何从new回退到C++,再回退到new。
为什么回退的速度如此只快呢?这就是为什么git被称作版本控制器的原因了,我们只是改变了HEAD指针的指向,回退只需要改其指向,指针指向的哈希值变了而已。
十.撤销修改
// 撤销工作区对指定文件的修改,将文件恢复到 暂存区 或 最新提交版本 的状态。
// 还没有add
git checkout -- [filename]
情况一(还没有add)
情况二(add后还没有commit)
情况三(commit后还没有push)
十一.删除本地仓库中的文件
方法一
先在工作区中删除文件,再add,commit一遍,毕竟删除也是修改
方法二
git rm [file]
先使用git命令删除文件,再commit一遍
由于比较简单,就不做演示,只是要注意删除本地仓库的文件,并非只删除工作区中的文件
十二.理解分支
什么是分支?分支有什么用?一个团队开发代码到一定阶段时,对下一阶段的目标产生了分歧,a有一个思路,b有一个思路,谁的思路最好呢,这时就用得到分支了,他允许开发者在不影响主线代码的情况下,进行独立的开发或试验。Git 的分支本质上是一个指向特定 提交对象(Commit) 的指针。(HEAD)
1.常见的分支工作流程
// 查看当前仓库中的分支
git branch
// 输出示例(*表示当前所在的分支)
// * main
// develop
// feature-xyz
// 创建一个新分支,但不会切换到该分支
git branch <file>
// 切换到指定分支 (注意不要与git checkout -- 混淆)
git checkout <file>
// 使用 -b 参数可以同时创建并切换到新分支
git checkout -b <file>
// 将其他分支的内容合并到当前分支
git merge <file>
// 删除本地分支
git branch -d <file>
// 强制删除(如分支未合并)
git branch -D <file>
下面介绍分支的一般流程,创建分支--在分支上开发--切换回主分支--合并分支--删除分支
1.我们发现当我们切换一个分支对README.txt进行修改,再切换回来后,发现原来的分支上也出现了修改。这与我们隔离开原来的代码,单独开发的目的不符,这是为什么呢?原来,我们在创建一个新的分支进行修改后,必须add,commit,这样切换会原来的分支,就会发现,做出的修改不会作用于原来的分支。
2.为什么合并分支后建议删除分支?合并后删除无用分支的主要目的是为了保持代码库整洁,避免分支冗余、管理混乱和误操作,同时有助于提升团队协作效率。
2.合并冲突
当你在 Git 中合并分支时,如果两个分支修改了同一个文件的同一部分内容,Git 无法自动合并,便会产生合并冲突(Merge Conflict)。你需要手动解决这些冲突,然后完成合并操作。他通常发生在以下场景
- 两个分支修改了同一文件的同一行。
- 一方删除了某个文件,而另一方修改了这个文件。
- 修改的代码在逻辑上存在冲突。
下面演示合并冲突发生的原因及解决办法
我们可以看到当发生合并冲突时会出现如下代码
Auto-merging file.txt
CONFLICT (content): Merge conflict in file.txt
Automatic merge failed; fix conflicts and then commit the result.
解决这种冲突也很朴素,就是直接打开冲突文件,自己选择保留,更改哪些代码。
<<<<<<< HEAD
分支 A 的修改内容
=======
分支 B 的修改内容
>>>>>>> feature-branch
// <<<<<<< HEAD 表示当前分支的修改内容。
// ======= 是分隔线。
// >>>>>>> feature-branch 表示被合并分支(如 feature-branch)的修改内容。
3.合并模式
这里我们只讨论两种合并模式,快进模式和非快进模式。笔者上网查阅这两种的区别时,发现他们的可视化图对于初学者其实不太友好,因为合并前这两种模式的可视化图在我看来并无区别。在这里就用最朴素的方式进行讲解。快进模式就是十二的1.常见的的分支工作流程,非快进模式就是2.合并冲突。区分他们的关键就在于当你切换一个新的分支提交代码后,再切回原来的分支,你有没有提交代码,有就是非快进模式,没有就是快进模式。
// 为了团队协作中便于追踪合并来源,通常推荐使用非快进合并
git merge feature --no-ff
4.分支策略及bug分支
我们创建分支,希望遵循以下原则来确保效率,安全
1.我们希望所有的分支分工明确,master分支是主分支,develop分支负责开发,bug分支负责修bug,因此也希望分支名要能反应分支的功能
2.我们希望分支尤其是主分支保持相对稳定
3.我们希望避免不必要的分支,也包括删除已经完成其使命的分支
在bug分支中,当bug修完后,master分支版本更新了,我们建议先让bug分支合并主分支,然后在bug分支上解决完可能出现的问题,再让master分支合并bug分支,来确保master分支的相对稳定。