KACARICH'S BLOG's Archivers

From kaca.rich on 2014-02-25 07:26:19

eclipse插件EGIT使用方法

转载自:http://blog.csdn.net/laizhenhai88/article/details/7234974
一_安装EGIT插件

<img id="aimg_L3Mc1" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344248HjHt.gif" width="332" height="305" border="0" />

<img id="aimg_VN354" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344253yaRI.gif" width="478" height="157" border="0" />

 

http://download.eclipse.org/egit/updates/

或者使用Eclipse Marketplace,搜索EGit

<img id="aimg_RISnl" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283442576Ec3.gif" width="341" height="303" border="0" />

<img id="aimg_hF9g3" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344261vRzT.gif" width="600" height="696" border="0" />

二_使用EGIT前的配置


配置个人信息,最重要的是user.name和user.email

l  Preferences > Team > Git > Configuration

l  New Entry

<img id="aimg_wXQFz" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344607u7A0.gif" width="433" height="462" border="0" />

<img id="aimg_NR5DO" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344609GteE.gif" width="525" height="225" border="0" />

三_新建GIT仓库

新建NC module project

<img id="aimg_eCs7s" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344740rZ6x.gif" width="249" height="322" border="0" />

l  File > Team > Share Project 选择GIT

<img id="aimg_bkgat" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283447436zT0.gif" width="417" height="298" border="0" />

<img id="aimg_Q5u5M" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328344746mW1B.gif" width="600" height="358" border="0" />

创建仓库后,在$workspace\demo目录下的.git文件夹,就是git的仓库地址。和CVS、SVN不同,GIT不会在每一个目录下建立版本控制文件夹,仅在根目录下建立仓库

<img id="aimg_Hy4Cu" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283447519N4x.gif" width="173" height="155" border="0" />

同时,eclipse中的project也建立git版本控制,此时未创建分支,处于NO-HEAD状态

<img id="aimg_F70Ws" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283447532Ch2.gif" width="203" height="105" border="0" />

文件夹中的符号”?”表示此文件夹处于untracked状态,这样就成功创建GIT仓库。

四_配置.gitignore

此时我们尝试做一次提交

l  Team -> Commit…

<img id="aimg_d1P6I" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345023y9I9.gif" width="600" height="556" border="0" />

如上图所示,Author和Committer会默认为Git配置的用户信息。下面的Files窗口中可以看到此次提交的文件,其中有非常多带有NC_HOME的文件,此时可以猜测出,在我们的project中链接的NC_HOME也被GIT默认到版本控制中了,如下图:

<img id="aimg_Qj9vY" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345081Q6Um.gif" width="104" height="71" border="0" />

显然NC_HOME和out是不需要进行版本控制的,我们可以通过配置.gitignore来排除这两个文件夹

打开Navigator窗口,在project根目录中添加.gitignore文件,将需要排除控制的目录写入.gitignore文件中

<img id="aimg_LlUO1" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345029oJez.gif" width="421" height="261" border="0" />

再次尝试commit,需要提交的文件已经被过滤

<img id="aimg_X3okg" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345033V0N7.gif" width="600" height="556" border="0" />

首次提交后,会自动生成master分支

<img id="aimg_Y2yZ4" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345036arNV.gif" width="192" height="90" border="0" />

然后在public中新建一个文件,可以看到图标依然是问号,处于untracked状态,即git没有对此文件进行监控

<img id="aimg_g0NA2" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283450392Ce4.gif" width="170" height="75" border="0" />

通过Team -> Add to index可以将文件加入git索引,进行版本监控

<img id="aimg_vnfun" alt="" src="http://hi.csdn.net/attachment/201202/4/0_132834520400aX.gif" width="600" height="130" border="0" />

可以看到图标显示也有了变化(EGIT中只要Commit就可以默认将untracked的文件添加到索引再提交更新,不需要分开操作)

<img id="aimg_G3BO7" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345219G49D.gif" width="189" height="77" border="0" />

也可以通过Team -> Untrack将文件从索引控制中排除。

将此次新增的文件commit到仓库中,文件将处于unmodified状态,或者说,这就是一种staged状态

<img id="aimg_UPRzm" alt="" src="http://hi.csdn.net/attachment/201202/4/0_132834523653s5.gif" width="192" height="71" border="0" />

然后修改文件的内容,文件将处于modified状态

<img id="aimg_NPEH3" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345291m6W7.gif" height="26" border="0" />


五_查看历史记录Team -> Show in history可以查看版本历史提交记录

<img id="aimg_ByGgm" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345425WsGl.gif" width="592" height="90" border="0" />

 

<img id="aimg_N8HvX" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345430z69s.gif" width="600" height="215" border="0" />

可以选择对比模式

<img id="aimg_gIFss" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345433N8y8.gif" width="364" height="62" border="0" />

 

<img id="aimg_euUW3" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345466MXXm.gif" width="600" height="276" border="0" />


六_远程GIT仓库此小结的前提是已经搭建GIT服务器,并通过SSH协议连接,可参看文档《RHEL下搭建GIT服务器》《WindowsXP下搭建GIT服务器》《GIT服务器使用基础》。本文使用RHEL5.5系统下的GIT-2012-01-11,用户root/password,GIT仓库统一存放在/app/gitspace目录下。

首先通过shell工具连接到服务器,建立空仓库gitdemo,此时的ssh访问地址如下,分别由协议名称、用户名、IP、端口、git仓库目录组成。

ssh://root@192.168.1.101:22/app/gitspace/gitdemo

打开GIT资源库窗口,选择克隆资源库

<img id="aimg_ZJ0ad" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345738oZG2.gif" width="449" height="101" border="0" />

<img id="aimg_E39uD" alt="" src="http://hi.csdn.net/attachment/201202/4/0_132834574166VH.gif" width="525" height="478" border="0" />

<img id="aimg_UoxWf" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345743Am6m.gif" width="525" height="478" border="0" />

<img id="aimg_Wql9q" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345746zgGL.gif" width="525" height="478" border="0" />

<img id="aimg_VIpL9" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345753jstN.gif" width="471" height="330" border="0" />

现在已经把远程的GIT仓库克隆到本地,接下来需要将仓库检出为NC模块项目。

<img id="aimg_m3pFQ" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345757hzNO.gif" width="420" height="325" border="0" />

<img id="aimg_KlcZZ" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345760JTc4.gif" width="592" height="516" border="0" />

最后得到gitdemo模块项目,分支是mirror

<img id="aimg_cURcZ" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328345767S3tK.gif" width="281" height="340" border="0" />

七_推送远程仓库

克隆服务器端仓库后,会在本地建立一个一样的仓库,称本地仓库。在本地进行commit操作将把更新提交到本地仓库,然后可以将服务器端的更新pull到本地仓库进行合并,最后将合并好的本地仓库push到服务器端,这样就进行了一次远程提交。

<img id="aimg_gccsY" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283463456NBm.gif" width="354" height="250" border="0" />

先提交一次到本地仓库

<img id="aimg_PIRSx" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283463843Sj2.gif" width="600" height="556" border="0" />

然后push到服务器端的mirror分支,Team -> remote -> Push

<img id="aimg_ANPCe" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346386xH9s.gif" width="600" height="626" border="0" />

完成推送后,可以在服务器端mirror镜像的log中查看到此次记录

<img id="aimg_PsXn6" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346393Y2zN.gif" width="366" height="211" border="0" />


八_解决推送冲突

多人协作开发的情况下,往服务器推送更新时难免出现冲突,所以推送之前需要解决服务器端的最新版本和本地仓库的冲突。Pull操作就是把服务器端的更新拉拢到本地仓库进行合并,解决好合并冲突后,就可以顺利push到服务器分支了。

假设现在Mairo兄弟在用GIT协作开发NewSuperMairoBro游戏,目前服务器端的mushroom.java文件的内容如下:

<img id="aimg_S1o1l" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346684zy27.gif" width="261" height="120" border="0" />

MairoBro克隆出代码后,Mairo哥哥做了如下修改

<img id="aimg_h4UCK" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346687u0mm.gif" width="232" height="90" border="0" />

Mairo弟弟做了如下修改

<img id="aimg_T46jD" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346689MxZZ.gif" width="228" height="86" border="0" />

然后Mairo弟弟先push代码,Mairo哥哥使用pull来合并本地仓库和远程仓库,将发行文件出现冲突,此时GIT会自动合并冲突的文件,如下图所示:

<img id="aimg_vGuGu" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346692XCnN.gif" width="276" height="72" border="0" />

<img id="aimg_Y9SgW" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346695vKlr.gif" width="573" height="397" border="0" />

<img id="aimg_ycFSb" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346699BBna.gif" width="600" height="169" border="0" />

很明显自动合并的冲突文件不能直接使用,我们可以手动调整,右键发生冲突的文件,选择Team -> Merge Tool

<img id="aimg_jygN3" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346702761R.gif" width="433" height="137" border="0" />

第一项是将GIT自动合并过的文件和服务器端文件进行对比

第二项是用本地最新版本的文件和服务器端文件进行对比,建议用此项

接下来就是熟悉的对比界面

<img id="aimg_C8358" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346705MmV1.gif" width="600" height="294" border="0" />

Mairo哥哥将冲突文件修改如下

<img id="aimg_eYT3b" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346708rY2R.gif" width="271" height="97" border="0" />

然后右键点击此冲突文件,选择Team -> Add to index再次将文件加入索引控制,此时文件已经不是冲突状态,并且可以进行提交并push到服务器端

<img id="aimg_yv8zJ" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346711cX96.gif" width="269" height="70" border="0" />

解决合并冲突后,Mairo弟弟只需要将服务器中合并后的版本pull到本地,就完成了一次协作开发的代码合并。从历史记录中可以看到,从mushroom开始历史进入分支,先是mushroomA的记录,然后是mushroomB的记录,最后历史分支合并。

<img id="aimg_AG58r" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328346871dn4e.gif" width="342" height="153" border="0" />


九_Rebase和Merge的区别

Rebase和Merge操作最终的结果是一样的,但是实现原理不一样。

从上面的MairoBro例子可以知道pull大概对历史记录进行了怎样的合并操作,其实默认pull的操作就是一个分支的merge操作,如下图重现一下:

Mairo弟弟的提交记录如下:

<img id="aimg_FU44Z" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347200wAN9.gif" width="307" height="42" border="0" />

Mairo哥哥的提交记录如下:

<img id="aimg_xpSph" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347229mZIA.gif" width="307" height="42" border="0" />

首先是Mairo弟弟把更新push到服务器,这样服务器端的记录就和Mairo弟弟本地的记录是一样的,接着Mairo哥哥执行pull操作,现在分析下pull是如何操作的。

l  pull默认就是先把服务器端的最新记录更新到本地的Remote Tracking中对应的mirror分支

l  接着对Local的mirror分支和Remote Tracking的mirror分支进行merge操作

<img id="aimg_tbNbN" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347244tBs2.gif" width="205" height="140" border="0" />

Merge操作后的结果就是会新增加一个merge记录节点,如下所示:

<img id="aimg_FtExS" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347282wDpE.gif" width="493" height="152" border="0" />

从上图可以看出,mushroomA是在mushroomB之前的,这个时间关系不取决于谁先执行push,而取决于本地仓库中谁先执行commit。所以merge会按照时间顺序严格的记录每一次commit。

接下来看看rebase,其实rebase也是把两个分支进行合并的操作,当Mairo弟弟push更新后,服务器端的mirror分支的历史如下:

<img id="aimg_zYb5e" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347200wAN9.gif" width="307" height="42" border="0" />

Mairo哥哥本地的历史如下:

<img id="aimg_NqYbj" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347229mZIA.gif" width="307" height="42" border="0" />

现在Mairo哥哥不是执行merge操作,而是执行rebase操作,最后结果如下:

<img id="aimg_WZk6d" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347473ffN2.gif" width="455" height="76" border="0" />

很明显的区别是没有出现分支的记录,而且注意到mushroomA*,请注意这个记录和mushroomA不是同一个记录,我们先分析下rebase操作下,Mairo哥哥的历史记录都做了哪些变化:

l  先将当前分支的更新部分保存到临时区域,而当前分支重置到上一次pull的记录

<img id="aimg_tlQ7Z" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347508mYnn.gif" width="175" height="99" border="0" />

l  然后将服务器端的更新添加到当前分支,此时当前分支和服务器端分支是一样的

<img id="aimg_zFWa0" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347536tbiO.gif" width="307" height="99" border="0" />

l  最后将原分支的更新部分mushroomA提交到当前分支的后面,就是要在mushroomB的后面添加mushroomA的更新,当然此时更新记录已经不是之前的mushroomA了,如果出现冲突则使用对比工具解决冲突,最后记录变成mushroomA*。

<img id="aimg_tAOz1" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347473ffN2.gif" width="455" height="76" border="0" />

如果Mairo哥哥提交过mushroomA1、mushroomA2、mushroomA3,那么执行rebase后会对mushroomA1、mushroomA2、mushroomA3分别顺序执行上图所示的合并,最后记录为mushroomA1*、mushroomA2*、mushroomA3*。很显然rebase操作更复杂,冲突的概率也更高,并且不是按照时间顺序记录。


十_Rebase和Merge如何选择的简单解析

此小结为什么说是简单解析呢,因为rebase和merge的选择问题讨论比较激烈,笔者也没有一个定论,而且git也处于研究发展阶段,很多理论还没有完全的纯熟。

对于一个多人开发团队频繁提交更新的情况,如果使用merge会使得历史线图非常复杂,并且merge一次就会新增一个记录点,如果使用rebase就是完全的线性开发。

<img id="aimg_KK447" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347857efEw.gif" width="422" height="552" border="0" />

上图所示是Merge和Rebase的两个结果,显然你不想要merge的混乱结果吧,你能告诉我merge图中那条线是master分支吗?

所以给出如下建议,如果同一文件反复修改或提交次数比较多,预期会出现很多的conflict,那么可以使用merge合并,仅需要解决一次冲突即可(不过,大范围主题式的修改,是不是应该事先就新开一个分支呢?);如果修改范围小,预期conflict少,则建议使用rebase。

EGIT中默认的pull操作是Fetch+Merge,如果要用rebase,可以分开操作。先执行Fetch更新remote tracking,再执行rebase进行合并(下一小节将介绍rebase操作)。或者修改pull的默认操作,在.git/config文件中配置:

<img id="aimg_szNN8" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347889tV99.gif" width="358" height="84" border="0" />

上述配置只对mirror分支有效,也可做全局配置,在$HOME/.gitconfig中配置,windows系统如果没有配置HOME变量的话就默认在$documents and settings/ USER目录下:

<img id="aimg_ZI9jj" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328347928l3Lf.gif" height="26" border="0" />


十一_Fetch和Rebase

MairoBro来做fetch和rebase的测试,首先Mairo弟弟在client中添加文件OPQ分别提交,并push到服务器,如图:

<img id="aimg_hbXgM" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348110dNdd.gif" width="210" height="141" border="0" /><img id="aimg_ClFm2" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348113edl4.gif" width="199" height="102" border="0" />

此时服务器端的历史已经被更新,但是Mairo哥哥的remote tracking中mirror分支并没有更新到最新的记录,如图:

<img id="aimg_LM0I7" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348146FPEJ.gif" width="540" height="234" border="0" />

所以需要更新remote tracking中的分支,使得它与服务器端的分支同步,右键点击资源库选择Fetch

<img id="aimg_g5Fgj" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283481777q4z.gif" width="238" height="167" border="0" />

<img id="aimg_KD04l" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348180baAS.gif" width="600" height="433" border="0" />

这样就更新了本地的remote tracking中的分支,使得它和服务器端分支同步。

<img id="aimg_MqZ9k" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348227l3Ko.gif" width="433" height="202" border="0" />

然后Mairo哥哥在本地的private中添加文件ABC,并分别提交到本地仓库中。

<img id="aimg_bwZzR" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348246iu76.gif" width="234" height="123" border="0" /><img id="aimg_N9494" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348259x81C.gif" width="232" height="98" border="0" />

然后将本地mirror分支和remote tracking中的mirror分支进行rebase,先checkout本地mirror分支 ,然后右键点击选择Rebase

<img id="aimg_PIpSE" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348295Y7x7.gif" width="357" height="204" border="0" />

<img id="aimg_ItIf3" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283483169XQS.gif" width="530" height="461" border="0" />

<img id="aimg_GQ58A" alt="" src="http://hi.csdn.net/attachment/201202/4/0_132834831814IS.gif" width="524" height="148" border="0" />

<img id="aimg_E4337" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328348321Tzcz.gif" width="368" height="221" border="0" />

如上图可以看到历史记录的顺序是OPQABC,已经rebase成功,接着push到服务器即可。
十二_重置功能


GIT中有三种重置功能,分别是soft、mixed、hard,区别如下:

l  Soft - 当前分支重置到指定commit记录位置,索引和工作树不变;

l  Mixed - 当前分支重置到指定commit记录位置,索引被更新,工作树不变;

l  Hard - 当前分支重置到指定commit记录位置,索引和工作树都更新。

貌似不好理解,首先要理解GIT的三个区域(工作树、索引区、仓库),可以参考文档《GIT简介》。

先做soft的测试,新建Soft.java文件,可以看到此文件未添加到索引控制

<img id="aimg_unstn" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353367e252.gif" width="227" height="103" border="0" />

先进行一次提交,提交后在History窗口中重置此次提交,如图:

<img id="aimg_DDDMD" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353373LRmv.gif" width="478" height="353" border="0" />

重置后查看工作树,如图

<img id="aimg_b4d13" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353376daF8.gif" width="258" height="107" border="0" />

从上图可以看出,soft文件还存在,说明重置没有改变工作树,而且soft文件不是“问号”图标,说明已经添加到索引,说明索引也没有变。唯一重置的是历史记录。

然后新建Mixed.java文件,此时Mixed.java也没有添加到索引控制,然后提交。

<img id="aimg_S6Fi8" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353379ku86.gif" width="239" height="123" border="0" />

在History窗口中重置

<img id="aimg_tyhy9" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353382A6PP.gif" width="484" height="341" border="0" />

重置后查看工作树结果如下:

<img id="aimg_PgRS6" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353385ZAM5.gif" width="240" height="121" border="0" />

从上图可以看出,Mixed.java文件还存在,说明工作树没有改变,但是文件状态是untracked,说明索引被更新,此时文件没有添加索引控制。

最后来看hard重置,新建Hard.java文件,此时文件没有添加索引,然后提交。

<img id="aimg_yKOhf" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283533909Xou.gif" width="260" height="139" border="0" />

在History界面重置此次提交,如图:

<img id="aimg_VW59X" alt="" src="http://hi.csdn.net/attachment/201202/4/0_1328353392So7T.gif" width="459" height="343" border="0" />

重置后再查看工作树,结果如下:

<img id="aimg_YZ508" alt="" src="http://hi.csdn.net/attachment/201202/4/0_13283533956366.gif" width="248" height="123" border="0" />

可以看到Hard.java文件已经不存在了,说明索引和工作树都被更新。

PS:这里对第六点远程GIT仓库稍微做个补充,我们一般情况下从github官网上clone代码的时候,这个远程仓库就是github了,首先我们在github上找到自己想要的源代码,这里以eoe客户端的源代码为例,如图:

在网页的顶部我们可以找到地址,有https,ssh,和git only三个,我一般都是选的ssh,然后把这个地址copy出来,再回到eclipse中,点击打开clone a git repository,在URI中把刚才复制的地址粘贴进去,然后在protocol中选择ssh就行了,其它信息会自动补全

查看完整版本: eclipse插件EGIT使用方法

Tags: eclipse, egit


©KACARICH'S BLOG