Git使用

  最近在使用github来管理一个项目,但是多地开发的时候,发现pull不好使。原来是要在preference中的Team-git-configuration中添加一个core.remote.url选项,value值为你的github地址

  但是这是网上的解决方案,还是没有解决。

  但是在调查过程中发现了一个Git的view很重要:Git Repositories;Branches-Remote Tracking,下面可以看到master分支,然后右键-Synchronize workspace(或者切换到Team Synchronizing),然后点击Merge-All小按钮;就可以同步了。

  这个时候其实还是有问题,因为下载的东西在本地的库中并没有的,所以还需要提交一下。

git概念

  git,尤其是远程服务器git有几种状态:

  首先本地工作区(workspace)

  其次,add to stage(index),这一步是将内容放置到缓冲区中,但是并没有放置到当前的版本分支中

  然后,commit,提交,这个时候才会把内容放置到版本库中,当然可以从workspace中直接放到版本库分支中

  之后,remote/push,将代码提交到远程的版本库分支中。

  最后,可以通过pull来获得最新版本。pull的时候可能会有异常信息:nothing to fetch,这是因为需要在git中配置一下origin的fetch属性:Windows->Preference->Team->Git->Config->repository Setting(tab)->remote.origin.fetch=+refs/heads/brook:refs/remotes/origin/brook(你的分支的名称)即可。

  我使用的是eclipse下面的git,所以在创建分支的时候,会友情提示:如果是pull,是无条件覆盖还是尝试合并,看情况选择吧。我突然明白了为什么git建议留着master不要直接使用,而是创建一个分支出来,其中一个原因是可以在新创建的分支上面做更多的配置;另外一个原因是,留着一个可用的分支版本,不断合并更加健康;因为交付过程中可能需要在开发新的分支的同时来对老版本进行一些调整。

  总之你会觉得git强调本地化开发,自成体系,不再受远程版本库的约束。

  关于head,origin,master以及branch

  head是一个指针,指向当前的工作分支(branch),当你"checkout master",指针指向master;当你"check out branch_name",指针指向branch_name。

  origin就是远程库(原始库)根目录的意思。

  merge之后要add来标记合并完成,否则一直处于merge状态,无法进行后续操作。

关于Index,Repository

  当把修改的文件内容放入到了index之后,再修改文件,就仍然还是在工作空间;修改的内容并不会波及到index,在index域的文件内容是独立于工作空间的;工作空间的内容放入到了Index中,如果同文件,直接覆盖(不会merge)
  放入stage的好处在于可以避免一次次的提交,因为每次提交(commit),就意味着需要提交到远程库,如果是太过于琐碎的尝试,可能被推翻,那就向服务器提交次数太多了;所以,stage库称之为缓存区,就是你的一个临时版本库,如果OK在提交到版本库(local repository)。
 
  文件放入到了index,就意味着版本被跟踪了;并且可以提交到本地库(local repository);
  文件通过commit放入了本地仓库(local repository),就意味着版本可以提交到远程仓库(remote repository);
  文件提交到了远程仓库(remote repository),意味着可以让其他人拉去,共享。

关于revert

  习惯于svn的revert,但是在git中没有revert的概念,只有reset,而且是整个工程的reset到指定的版本,不过其实这样想来和revert的内涵也是一致的,只不过revert默认回退到最近的一个版本,git可以指定,另外一个区别就是svn指定文件进行revert,git只能是整个工程进行reset。

  reset有三种模式:

  Hard,工作空间,Index域,版本库全部回滚到指定版本。这种模式和svn的revert是最相像的。

  Soft,版本库回滚到指定版本,a->b->c,reset --soft A,Index域将会是c;这个策略更多的用于打patch,可以少生成一个路径节点的变更,直接生成a->c即可。

  Mixed,版本库以及Index域将会回滚到指定版本,但是工作区内容保持,但是状态修改为未添加(add)。

 

  如果是对于单个文件的revert,可以单独选择这个文件,然后replace with...,可以选择本地仓库历史版本,branch,远程库的历史版本等

Eclipse快速创建git库

  1. 工程->右键share->Git->将会弹出一个Config Git Repository界面,其中有一个复选框:User or create repository parent foler of project。恩,勾选,这样就会在工程本地创建git文件,这样当前工程就被纳入到git管理了。灰常方便;

  2. 如果是多个工程,可以选择Top Level Elements为Working Sets模式,然后在顶级文件夹执行第一步,可以一次性将多个工程纳入到git中;或者直接多选项目,然后执行步骤1,等效;

  3.如果你不选择复选框,那么就意味着你需要手动指定一个git目录,指定好之后,git将会把当前项目进行剪切,剪切到指定目录下。对于Web工程,这个样的操作就是灾难,因为lib下面的jar还没来得及进行处理,便被生硬的进行了处理,将会导致“WEB App Libraries”下面爆出jar包找不到的异常。

分支

  0.创建分支并提交后(客户端创建了一个分支后,需要push一次);

  1.要在另外一个客户端中(Eclipse)中的Git repository视图中选中项目,右键->remote->fetch,此时就会在source ref中感知到新的版本,然后选择,Destination ref自动会选择;然后finish;

  2.然后继续右键项目->switch to->选择新的分支即可。

  作为本地仓库,一定要首先Fetch到这些新的分支信息,然后才能够切换;

pull/Fetch

  fetch只是将提交信息同步到本地仓库,并不进行代码合并;

  pull则是首先获取代码提交信息,然后是下载代码自动和本地代码进行合并。

  关于提交冲突:non-fast-forward

  这说明本地的版本和服务器版本不一致,commitId已经过期;这个时候,你最好切换到synchronized试图

  1. 首先fetch或者pull,从服务器上面获取最新的文件信息;fetch比较友好一些,见上面的说明;
  2. 对于冲突需要进行解决,这里包括overwrite,服务器覆盖本地,以及可以通过选择“Merge”来进行手工合并;eclipse中的merge工具支持手工动态修改以及可以通过界面操作进行将冲突某个部分修改为服务器版本等操作,十分友好;
  3. 在视图中右键根节点或者操作对象,add to index,然后提交即可。

git冲突

  git提交的时候,发生异常:rejected –non-fast-forward - Freeman的...
  这是因为本地版本和数据有冲突,就是本地有的文件,版本库中没有。
  如果是已经识别出来了冲突,需要解决冲突,然后make as merge,然后pull,再提交才能够成功;
  如果两地文件,旧版本还没有提交到index,且冲突,覆盖本地后,还需要将文件add to index之后,才能够通过pull来解决冲突;
  如果通过synchronized windows发现不了冲突,那么冲突时因为本地文件需要更新本地文件需要更新(其实并没有冲突,只是版本低),pull之后,问题可以解决。
 
  non-fast-forward问题本质原因是版本问题;pull的本质是拉取最新版本,然后和本地文件做合并;所以解决的根本方式是将本地的版本提升到最高改版;所以如果是冲突,则解决冲突(marke as merge就是将本地版本提高到高于Remote Repository);如果没有冲突,则说明本地版本比较旧(但是本地的旧版本并没有修改),则需要解决的是本地是最新版本。总之都是要通过pull的方式获取最新的版本;但是对于冲突需要首先手动merge,对于非冲突,自动merge即可。
 
  git解决冲突的正确姿势:解决冲突之后,需要提交commit到本地,然后观察下行箭头,如果减少说明提交是OK的减少了需要pull的对象;如果没有修改完全部的冲突,PUSH是还是报冲突异常,只有全部的冲突都解决了,提交才顺利。
 
  .class文件的冲突后,override之后,提交后仍然是冲突,但是pull一下之后,就OK了。这类(Override)冲突不是提交能够解决的,而是要通过pull来进行处理,因为其实你的提交并没有新的东西,依然无法获取最新;只能够是pull获取服务器代码,进行比对搞定。
 
  开发分支错误,在first_stage开发了半天,怎么办?开始尝试将transfer_stage分支reset为first_stage,但是提交的时候发生异常,工程结构全乱了;后来发现可以采用relace With的方式,指定为替换为first_stage的内容,如此获取到了first_stage分支内容,同时还是在transfer分支最新的代码中修改;
注意完全替换和merge不一样;前者是完全拿来用,后者还会做比对冲突处理,看情况使用。

git管理eclipse工程

  工程的资源库应该建立在工程目录的上一级,这样,只需要一个git就可以管理多个工程,而且,如果git放置到了工程目录下,将会导致eclipse提交的时候,连带着把git文件也一并提交,导致隐患。多个工程推荐使用一个git来进行管理。
  如果你在.git同级建立项目,会自动被git管理。git会自动管理其同级目录的文件。
  文件夹/资源文件/包下只有添加文件了,才会标记为工作空间有值;
  ignore文件可以通过Git Repository视图看到(在eclipse 工程将会自动忽略.*文件);也可以到文件目录下找到,可以进行编辑,来屏蔽无关文件夹/文件上传,比如日志文件,/logs/,一行一个即可,但是只能屏蔽未放入到index的文件。
  碰到了一个问题:开始没有定义gitignor文件,在push的时候,发现了no-fast-forward,应该是冲突了;结果呢mark as merge之后,我执行了一个动作:add to index,结果把一大堆.class文件放入到了index域中;这样在commit的时候发现了一堆的.class文件;此时我添加了gitignore文件,指定bin下的文件忽略;但是却依然可见这些class文件的提交,这是怎么回事?后来想明白了,是因为这些.class文件都已经放入到了index域了,gitignore只是能够忽略在工作空间的文件。于是在工程中邮件,remove from index,问题解决。
  使用Eclipse的git发现了一个很奇怪的现象;就是开始把infrastrution的bin目录提交了;然后在提交的时候,发现大批的.class的冲突;本地库版本上次Push和这次Push之间和远程服务器有了新版本提交;但是其实我是要忽略的这些.class文件的;而且已经在.gitignore文件中增加了屏蔽;尽管已经屏蔽,但是因为远程服务器已经有了bin/*.class文件,于是我提交了.gitignore文件,然后删除了本地的bin文件夹;问题解决了。

找到删除的工程

  误删除了taskAccess工程,在git Repository视图的远程分支中”check out“出当前分支,然后误删除工程内容将会在工作空间中出现,标记为删除,然后将这些文件放入到stage中,此时会有一些新的文件在工作空间生成,将其迁移到Staged,此时因为文件齐全,于是项目自动还原。在Eclipse中再次import即可。
可见checkout默认是在当前的工作空间;至于为什么文件放置到staged空间之后,项目就自动回复了,这个还是未解。

删除分支

  在Push的页面,通过选择Remove ref to delete的分支,记得点击“add Spec"按钮,即可实现提交
  点击Add Spec
  Next/Finish即可实现远程分支删除;
  删除之后,需要手动将本地的分支删掉(远程分支在本地的Git Repositories视图中将会自动消失)。

删除已经提交的class文件

  发现.class文件在工作空间中,而且标志指示该文件曾经提交过(已经入index文件了);此时即使使用.gitignore文件进行指定屏蔽,也无济于事。于是删除掉bin下面所有的文件,此时文件删除被版本控制识别出来,加入stage中然后提交。
  再clean工程重新生成class文件,不再识别为待提交文件。
  
  对于已经提交的文件,如果想要屏蔽,一定需要首先删除,然后才能屏蔽;也就是说屏蔽的文件一定是没有放入到index或者已经从index库中删除掉的。
  还有一个情况就是一个class文件曾经被别的同学提交过,但是本地已经将其屏蔽了,这个时候就可能会发生纠结,这个冲突怎么也解决不了;解决方案:将屏蔽去掉,然后,生成该class文件;冲突消失,再设置屏蔽,问题解决。

merge禁忌

  今天给我的项目组成员搞版本;但是他开始是在笔记本开发,后来打算改到台式机,但是台式机因为代码问题有冲突,我解决了冲突,之后,就手进行了Merge,将台式机版本和develop分支进行了合并;这导致了一个严重的后果:就是笔记本再取最新的时候,导致了一堆的冲突。
  尽管来费了很多劲儿才解决冲突,其实没有完全解决冲突,只是冲突不再影响提交。merge一定要在开发人员所在机器上面。
  CryInfo.class文件曾经被提交过;.gitignore后来已经屏蔽过了bin文件;解决流程:
  1.将被识别为修改了的CryInfo.class文件放入到index区域;
  2.物理上删除CryInfo.class文件;
  3.再将CryInfo.class文件移除index区域,此时文件呈现为删除状态;再将其放入到index域并提交即可。
 
 
 

posted on 2016-12-11 16:50  下士闻道  阅读(576)  评论(0编辑  收藏  举报

导航