git实操学习 之 git三大特点

关于git的学习,我之前的博客中也有总结:比如Windows下通过图形界面上传代码到git,GitHub学习以及遇到问题的详解这两篇文章,以及看到的文章IDEA版本控制VCS中git的使用也写的很棒。
这里我就简单介绍一下git的常用命令,以及实操时(暂存/合并/拉取)遇到的问题解决。

git实操学习目录

  • 1.git常用命令
  • 2.git工作区域
  • 3.git三大特色之 stage暂存区
  • git 三大特色之 brabch分支
  • git三大特色之 WorkFlow工作流

1.git常用命令

git实操学习 之 git三大特点_第1张图片

2.git工作区域

下图是git的工作区域划分,以及各个区域之间的联系(借鉴图)
git实操学习 之 git三大特点_第2张图片

由上图我们可以看到,git的工作区域分为:工作区,暂存区,本地仓库区,远程仓库区

工作区- workspace:即我们项目的根目录,也是我们存放代码的地方。

暂存区- index/stage:在我们项目的.git目录下有一个index文件,是一个包含文件索引的目录树用于记录文件的变化。当我们代码有改动但不想push时,我们可以选择add到暂存区。我们工作区的代码在提交push/回滚reset时,也会优先选择暂存区的内容进行操作。

本地仓库区- repository:也叫本地版本库是.git目录存在的位置。当我们执行commit命令后,暂存区的目录树会写到版本库中(最终存储在分支branch)。这里安全的存放你提交到所有版本的数据,其中HEAD指向最新放入仓库的版本。

远程仓库区- remote:托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换。

3.git三大特色之 stage暂存区

从工作区域图中,我们可以看到代码add后保存在了暂存区,那么保存在暂存区有什么好处呢?这个stage不知道也罢,理解以后发现真精彩。它能帮助我们很容易的解决以下场景的问题:

  • 1)git第一次执行commit时报错。

因为git提交的内容是暂存区内容,当我们只有工作区改变而未add到暂存区时,版本库与暂存区内容实际是一致的,也就是说我们此次提交操作是无效的。所以git在使用commit将代码提交到版本库时,必须要先add到暂存区,确保此次要提交的操作是有意义的。

  • 2)若当前分支A做出修改代码的操作但并未达到可提交状态,可是此时需要切换分支B做其他事情;若我们直接切换分支B,会提示有修改的代码未提交,那么只能选择提交或者舍弃??

其实还有更好的处理方法。例如这时我们可以先将A分支代码备份(git stash),待B分支事情做完后,再切回A分支并从缓存中取出文件(git stash pop)继续操作。这样我们之前写的代码仍然可以恢复到工作区,避免了将未完成代码提交造成系统报错或者舍弃了代码需要重复编程。

  • 3)我修改到一半的文件,突然不需要修改了,怎么恢复到修改前的代码呢?

这种情况下,我们可以直接切换分支checkout(force)操作或者从暂存区取出上次的内容覆盖当前工作区(git reset --soft)。

  • 4)我修改了4个文件,在不放弃任何修改的情况下,其中一个文件不想提交了,如何操作呢?

没做add的文件先git add,若不提交的文件已经add了就使用git reset --soft恢复到工作区,此时再用push即可正确提交文件。

由以上几种情况的处理方法我们可以看出,通过 add&commit&checkout & stash & reset 命令或与不同参数的搭配,我们可以在工作区,暂存区和版本库之间,轻松的进行数据的来回切换,使得git有更多的灵活性和可操作性。因此我当们理解了介于工作区和版本库之间的一个存储状态-暂存区,就能发现它是一个至关重要的存在。

git add与git stash区别:二者都可以保存工作区修改的内容

git add与git commit一起使用,此时工作区、暂存区和版本库代码都是最新的,并新增了一条commit记录在当前分支上;
git stash与git stash pop搭配使用,git stash 后修改的代码存储在缓存区中,工作区的内容恢复到了修改前,此操作不会新增commit记录,需要取出缓存使用时用git stash pop,可跨分支使用。
注意
新增的文件,直接执行 stash 是不会被存储的,如果要保存这个新增的文件,需要先执行下 git add 把文件加到 git 版本控制中,然后再 git stash 就可以了。
git add 可以选择只添加某个文件到暂存区中,但git stash 会直接缓存所有文件没法选择。
git stash list :查看 stash 了哪些存储
git stash show :显示做了哪些改动,默认 show 第一个存储。如果要显示其他存贮,后面加 stash@{$num},比如第二个 git stash show stash@{1}
git stash clear:删除所有缓存的stash

git stash pop 与git stash apply区别:

git stash pop stash@{n}后,恢复之前缓存的工作目录,将缓存堆栈中的对应 stash 删除。不加@参数时,默认取出第一条;
git stash apply stash@{n}后,应用第n+1 条存储记录,但不会把缓存从存储列表中删除。不加@参数时,默认取出第一条;

放弃本地修改的内容,强制更新代码:

git fetch --all(下载远程仓库最新内容,不用做合并操作)
git reset --hard origin/master (将head指针指向最新的版本)
git pull (当前最新代码远程库中未改变时可以省略)

git 三大特色之 brabch分支

分支存储自己的代码是轻量且易操作的,同时因为有分支的存在,git才构成了多工作流的特色。多分支的存在是必要的,因为在工作中,一个项目往往会有多个人进行操作,如果大家都直接在master分支上操作,那么最后难免会出现两个人写了同一个部分代码导致被互相覆盖或者某一个人的代码本身有问题导致系统无法正确运行,整个系统可能随之挂掉,这问题就很大了。但若我们每个人都单独拉一个分支进行操作,就不会出现上述问题,即使自己分支的代码死循环也不会影响整个项目的运行,这就保证了多人同时工作时的效率。

关于分支操作的命令并不多,基础的命令如下即增删改查

  • 1)创建分支(先选择基础分支再执行命令):git branch

  • 2)查看分支:git branch – 查看本地分支 ; git branch -r - 查看远程分支 ; git branch -a - 查看本地+远程所有分支 ;

  • 3)删除分支:git branch -d

  • 4)重命名分支:根本不存在!!回到基础分支再用新名字重新创建分支(git branch

  • 5)签出分支:git checkout

  • 6)合并分支:git merge

关于分支的操作,更重要的操作就是分支代码的合并与回滚
branch分支合并:

Fast-Forward(快进式):当A分支与B分支存在上下游关系时,即顺着一个分支走下去能够到达另一个分支,那么Git 在合并两者的时候,合并操作没有需要解决的分歧,git只要简单的将指针向前推进(指针右移)指向最新的版本即可完成合并。
Recursive Strategy Merge(三方合并式):在项目开发中,可以使用快进式合并的情况并不多。因为我们大家同时修改,提交历史也存在交叉,此时A分支、B分支、AB原始分支就是所指的三方,git会将这三个分支简单合并形成新的分支并用head指针指向它。
注意:前两个git的自动合并虽然很省事,但有人在的地方就有江湖,对于在同一个文件的同一个部分进行了不同的修改操作,git就无法继续帮助我们解决这里的冲突,也就无法自动合并了。因此我们仍需要手动解决冲突的文件。
另外git的自动合并操作不完全可靠,所幸在工作中,我们研发人员有技术方案以及对别人方法的改造评审,并且也会有其他人进行code review,可以更有效的保证git在自动合并代码时的可靠性(这里其实与工作流管理有关,下面细讲)。

idea中,在代码合并时不同的颜色代表了什么?
灰色:删除 ;
蓝色:改变 ;
绿色:新增 ;
红色:冲突 ;
最终提交的内容是中间展示的合并结果。

分支回滚很重要:

当我们代码操作错误后,git给我们提供了一条后退路,就是回滚操作。因为有reset和revert命令存在,所以git有很好的容错性。但是前提是,我们在做每一步操作前,都要养成良好的备份习惯,这非常重要,相信你吃过很多未备份/保存的亏,所以有备无患啊~
本地分支回滚:git reset --hard commit id
远程分支回滚:只是个伪命题。我们删除之前的远程分支(git push origin :),将本地分支进行回滚(git reset --hard commit id),再将最新的本地分支push到远程分支(git push),"远程回滚"就达到了。

reset和revert的区别:代码回滚的命令

git reset 在push命令前使用,可直接删除掉指定的commit操作。若在push后使用git reset --hard 看似代码恢复到了上个版本,实则线上代码并没有变,这时本地代码修改完再次提交时会出现很多冲突,所以在push命令后,最好使用revert命令。使用示例如下:
git reset - -soft – 回到add前;git reset --mixed --回到commit前;git reset --hard --版本库和暂存区都回到add前
git revert 在push命令后使用,用一个新提交来消除一个历史提交所做的任何修改,也就是用新的commit(旧版本)覆盖了原来commit(旧版本+1)的操作。使用示例如下:
git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61 或者只输入前几位也可以达到回滚效果 git revert c011eb3
注意:reset是在正常的commit历史中,删除了指定的commit,这时HEAD在之前提交的地方并没有变。而revert是在正常的commit历史中再commit一次,只不过是反向提交,它的HEAD是向前的;
另外如果在日后现有分支和历史分支需要合并的时候,reset回滚部分之前的代码依然会出现在历史分支里,但是revert方向提交的commit并不会出现在历史分支里。

git三大特色之 WorkFlow工作流

工作流顾名思义就是工作流程,也叫分支管理策略。这里不涉及任何命令,因为它只是一个规则,项目开发者默认遵循使得git使用更高效。比如前面讲到分支合并时说的问题,若开发者没有一个好的规范习惯,那么git管理等同虚设。目前使用最多的工作流有三种:

  • 1)git flow:主要分支(master + develop),协助分支(feature branch + release branch + hotfix branch)
    主要分支 – origin/master 分支上的最新代码永远是版本发布状态;origin/develop 分支则是最新的开发进度,待代码成功发布后合并到master分支上。
    协助分支 – feature 分支用来做分模块功能开发,模块开发完后合并到dev分支并删除自己分支;release 分支用来做版本发布的预发布分支,dev与master合并的分支;hotfix 分支是用来做线上的紧急 bug 修复的分支,问题修复后,合并 master 和 dev然后删除自己(建议仍然带上fix标签)。

  • 2)github flow:只有一个长期分支 master ,而且 master 分支上的代码,永远是可发布状态,一般 master 会设置 protected 分支保护,只有有权限的人才能推送pull代码到 master 分支。
    特点:Pull Request -可以很好的控制pull权限,可选其他人进行参与,代码review时可添加意见;issue tracking - 问题追踪,实时关注问题修复状态。

  • 3)GitLab flow:GitLab 既支持 Git Flow 的分支策略,也有 GitHub Flow 的 Pull Request 和 issue tracking功能,是非常有优势的工作流。
    特点:支持版本的延迟发布–Prodution Branch:专门用来发布版本的分支 ; 支持不同环境的部署–Environment Branches & Upstream First:上游优先,即上游分支测试通过后才能被合并到下游分支。

我们现在工作中用的就是gitLab工作流。

你可能感兴趣的:(JAVA专栏,实训心得,git,java)