Egit使用笔记(个人学习笔记不保证理解是否正确)

在MyEclipse中初次使用Egit所遇到的问题和思考

  1. 什么是分支?分支和仓库有什么关系?
  2. 什么是分支合并?为什么在我的操作中会出现冲突?如何解决?
  3. 为什么要先commit,然后pull,再push?将远程仓库中的项目pull下来不会覆盖我本地修改的代码吗?
  4. egit除了保存修改记录还有其他什么常用操作?

带着疑问的学习总是高效且有针对性的,在解疑的过程中我也收获了很多,通过博客的形式记录学习反思改正过程如下。

Egit使用方法

本地仓库更新至远程仓库

如何将项目加入本地仓库并更新至远程仓库的流程网上很多,在老师讲解后跟着操作两遍便能够记住流程独立完成,非常方便,这里就不再累述流程步骤,可以参考老师分享的资料https://my.oschina.net/songxinqiang/blog/192567?appId=1000 清晰明了。

  • 注意事项:Gitee注册账号之后更改姓名不会自动更改 个人空间地址 ,在本地仓库与远程仓库交互时登录的账号还是初次注册时的用户名,即此时个人空间中的姓名,如果使用修改后的用户名会报错not authorized,血泪教训。

版本回退

  • HEAD:这是当前分支版本顶端的别名,也就是在当前分支你最近的一个提交。
  • Index:也被称为staging area,是指一整套即将被下一个提交的文件集合,也是将成为HEAD的父亲的那个commit。
  • Working Copy:代表你正在工作的那个文件集。

版本回退中Git允许我们在版本的历史之间穿梭,版本历史自动连接成一条时间线,可以使用[History]查看提交历史,以便确定要回退到哪个版本。再回退后也可返回回退前版本,使用Git总是有后悔药吃。版本回退在Egit中是在[reset]中选择,对reset的理解如下:

  • HEAD指向当前分支的最近一个commit,HEAD、INDEX(STAGING)和WORKING COPY都是相同的状态,当修改代码后,Working Copy发生改变,将改变的文件Add To Index后Working Copy和Index一致,Commit后HEAD、INDEX(STAGING)和WORKING COPY三者再次相同。
  • reset命令本身做的事情就是重置HEAD(当前分支的版本顶端)到另外一个commit。git reset HEAD~2,则意味着将HEAD从顶端的commit往下移动两个更早的commit。
  • reset有三个选项soft、mixed、hard,有了上面两点解释,三者区别的理解就更加容易了,如下:
  1. soft参数,Git将停止在那里而什么也不会根本变化,Egit操作也的确是如此,[History]界面不会有任何变化。这表示Index,Working copy都不会做任何变化,所有的在original HEAD和你重置到的那个commit之间的所有变更集都放在Index区域中。
  2. mixed是reset的默认参数,它将重置HEAD到另外一个commit,并且重置Index以便和HEAD相匹配,但Working Copy不会被更改。
  3. hard参数将会重置HEAD返回到另外一个commit,重置Index以便反映HEAD的变化,并且重置Working Copy也使得其完全匹配起来,这时三者又将一致,这是一个比较危险的动作,具有破坏性,数据因此可能会丢失,但是也是可以恢复的。
  4. 总结一下,soft为回退到某个版本,只回退了commit的信息,不会恢复到index,如果还要恢复Original HEAD提交,直接commit即可;mixed为回退到某个版本,只保留源码,回退commit和index信息;hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容。

这里便是此模块内容的很好应用https://www.liaoxuefeng.com/wiki/896043488029600/897889638509536

在理解完三者的区别之后对Git管理修改的方式也有了一定的了解。

标签管理

发布一个版本时,并希望永远记住那个特别的提交快照,我们通常先在版本库中打一个标签(tag),这样就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。就比如PS中的快照,多次提交后,想要恢复快照的那一步,不用逐步撤销,直接使用快照。

Git 支持两种标签:轻量标签(lightweight)与附注标签(annotated)。轻量标签很像一个不会改变的分支——它只是某个特定提交的引用,而附注标签是存储在 Git 数据库中的一个完整对象,它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间等,可根据需要自行创建相应类型标签。

添加方法:

  1. 在[Git Repositories]中的[Tags]文件夹右键[Create Tag],填写标签的说明信息,选择代码版本用于标签。或者在[History]中的某条版本上直接右键[Create Tag],就可以自动输入代码版本Id。
  2. 创建好Tag后,在[Git Repositories]中的[Tags]文件上右键选择[push Tag…],上传Tag至远程仓库。也可在[Team]的[remote]中选择push。
  3. 一般不提倡删除标签这里便不记录具体步骤,可参考文档https://my.oschina.net/songxinqiang/blog/194203

分支管理

在学习上述内容时便多次看到了branch一词,在初次使用Egit时我也遇到了分支冲突,Conflict让人很无奈,当时稍微一查阅又给了我一些新词汇,比如分支合并、Merge、Master、checkout…现在终于到这一步了,在学习完后对这些词汇有了一定的认识。

什么是分支

Git保存的不是文件的变化或者差异,而是一系列不同时刻的快照,在进行提交操作时,Git会保存一个提交对象,该提交对象会包含一个指向暂存内容快照的指针。不仅仅是这样,该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象, 而由多个分支合并产生的提交对象有多个父对象。

分支:其实本质上仅仅是指向提交对象的可变指针。Git的默认分支名字是master。在多次提交操作之后,你其实已经有一个指向最后那个提交对象的master 分支。master分支会在每次提交时自动向前移动。可以看成每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。

可以创建多个分支,Git鼓励使用分支完成某个任务,合并后再删分支,不同的任务组在不同的分支上开发,互相之间不会影响。比如说,需要向项目中添加一个新功能,一般不会直接在主分支上修改,会新建一个分支,在上面更改代码。这样做的好处就是保证主线代码的完整性和可用性,也就是说,主线上都是稳定的代码,可以直接拿来发布的。最后根据需要其他分支与主分支合并即可。

引用廖雪峰老师写的分支策略,真的解释了我的疑惑,之前一直想大家都在一个分支上瞎改,各种可能的意外,这个Git真的能好用吗?现在看了下面这段话觉得流传下来的东西都是有原因的。

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

git-br-policy
Egit分支合并操作参考https://www.cnblogs.com/jtlgb/p/9875491.html

什么是冲突

在分支合并、pull中我都多次遇到冲突,不清楚什么是冲突Git用起来始终是迷迷糊糊。

冲突出现的情景:

  1. 多个分支代码合并到一个分支时;
  2. 多个分支向同一个远端分支推送代码时;

冲突的具体情况是两个分支中修改了同一个文件或两个分支中修改了同一个文件的名称,两个分支中分别修改了不同文件中的部分,不会产生冲突,可以直接将两部分合并。

Egit解决内容冲突的方法参考https://blog.csdn.net/c694421919/article/details/82287626?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

push和pull其实就分别是用本地分支合并到远程分支和将远程分支合并到本地分支,这里也能解释开始提的第三个疑问,如下:

  • 本地和远程的关系相当于两个分支,先commit再pull最后再push的情况就是为了应对多人合并开发的情况,commit是为了告诉git我这次提交改了哪些东西,不然git也不知道我们具体改了些什么,也就无从判断比较。pull是为了本地commit和远程commit的对比记录,git是按照文件的行数操作进行对比的,如果同时操作了某文件的同一行那么就会产生冲突,git 也会把这个冲突给标记出来,你就得去解决这个冲突,这个时候可以协商保留谁的代码,然后如上面链接中介绍的方法,解决掉这种冲突。冲突其实就是给你提个醒,给你一个警告代码版本有更新,让你注意进行选择。只要有改变就要解决冲突大家操作的是同一个库始终要保持代码的同步,所以一旦版本库发生改动同一分支下的所有人都要跟着去同步最新版,反正远程库始终是要为最新的版本。
  • 出现代码覆盖或者丢失的情况:比如A、B两人的代码pull时候的版本都是1,A在本地提交了2、3,并且推送到远程了,B进行修改的时候没有commit操作,他先自己写了东西,然后pull,这个时候B本地版本已经到3了,B在本地版本3的时候改了A写过的代码,再进行了commit和push,那么在远程版本中就是4,而且A的代码被覆盖了,所以说要先commit再pull,不然真的会覆盖代码。
  • commit是不会每次将全部项目代码推送到远程的,是通过对比 commit 的记录,如果本地高于远程就直接把多出来的commit给怼上去,如果本地的这几个 commit和远程的commit有冲突的部分就merge,然后根据提交时间排序再新建一个merge的commit(这里的意思和实操上面分享的Egit解决内容冲突的方法二有解释和展示)记录再怼上去。

引用一个匿名大佬的举例

比如你从一个git log为1,2,3,4,5,6的远程库拉取到了本地;

另一个同事也拉取了同样的代码,而且你的同事先于你提交到远程了;

此时远程的版本是1,2,3,4,5,6,7_new,8_new;

而你当前只是本地的版本1,2,3,4,5,6,7_local,8_local,9_local;

从这里你就能看出你前一部分和远程的一样,后一部分和远程的不一样;

这个时候你不能正常推送上去的,如果你采取git push origin master --force;

那么远程的版本就变成了1,2,3,4,5,6,7_local,8_local,9_local;

之前你同事推送的7_new,8_new这两次推送被覆盖了,这不是大家想要的情况;

因此需要git pull来将本地的版本合并成这样1,2,3,4,5,6,7_new,7_local,8_local,8_new,9_local,10_commit_merge;

远程和本地的排序是按当时 commit 的时间来排的,最后一个10_commit_merge就是你本地和远程合并的标志,最后你推送到远程仓库的应该也是这个。

  • Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容

是的,就是这个强制推送,在小组操作在操作中遇到了,覆盖了仓库所有的内容,当时第二天登陆时发现仓库全部空了,提交动态却还在,当时小组内不明所以,一度以为是灵异事件…好在现在知道是什么原因了,也进行了及时补救。

总结一下就是不要轻易先pull再commit和push,容易覆盖代码,当然如果你是一个人进行项目,并且知道自己的每次push是在干嘛,神志清醒,你这样也完全没关系,但是如果多人参与项目,尽量采用先commit再pull检查是否有冲突,如果有冲突就解决,再pull检验是否有冲突,直到没有冲突,在push的流程。

关于分支冲突其实大同小异,具体解决办法就不累述,见Egit合并操作分享的链接后半段内容。

Egit中常用选项解释

常用文件夹名称
[Egit fetch from upstream]与[pull]的区别

Git中从远程的分支获取最新的版本到本地有这样2个命令:

  1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge
  2. git pull:相当于是从远程获取最新版本并merge到本地

SSH公匙

未完结

猜你喜欢

转载自blog.csdn.net/weixin_44164333/article/details/105806406
今日推荐