Git是程序员工作中最最常用的分布式版本控制系统,为的就是解决那种多人协作、多次修改的问题,虽说Git可以应用于各行各业,但是实际上还是程序员用的最多了,应该说是程序员的必备技能之一了,如果你还不会Git,赶紧学起来吧,否则可能要out了
可能很多学生党只是平时使用过Git,自己练习过Git命令,但是并未真实在工作中使用过Git,也就是可能没有遇到过各种需要回滚代码、解决冲突这种场景
我这篇文章默认大家对Git是有一定了解的,也就是关于上面这些理论啥的大概应该是懂得,我也就不多啰嗦了,个人操作的是工作区,add之后会提交到一个暂存区stage,commit之后会提交到本地仓库,push是提交到远程仓库
这篇文章大致介绍了下面这些【提交代码几种方式】【撤销add操作】【撤销commit操作】【撤销push操作】【拉取新分支】【解决冲突】,主要是以命令行为主,命令行能帮助大家更容易理解,这样以后操作起可视化工具会更加便捷,比如sourceTree
先说一个需求开发、代码提交的顺利的流程
切换基础分支:先切换到要基于拉取的分支,我们开发中一般可能会基于master拉取的比较多,那就先切换到master(git checkout master)
创建本地分支:git checkout -b new-branch
提交到远程:git push origin new-branch
设置关联:git pull一下拉取远程分支代码会发现并未关联,OK lets do it
git branch --set-upstream-to=origin/new-branch new-branch 来建立关联,第一个new-branch是远程分支名称,第二个是本地名称
再次git pull一下,成功
接下来进行水深火热的开发,假设假设你的开发过程一切顺利,也没有出现和同事提交代码之间的冲突,你可能会有疑问,为什么我单独创建的分支会出现冲突,出现了冲突又该如何解决呢,当然冲突问题下面我会说
OK,下班了,先交下代码
你以为我开发完成了?怎么可能,一天怎么可能开发完成,你这个需求这里这样设计开发起来不简单,那里这样设计开发起来也比较麻烦
总之,一天不可能开发完成(坏笑
但是我想先交一下代码,我怕下班之后别人把我电脑给我偷了,偷了我的劳动成果
把代码放到本地仓库和把大象放到冰箱需要三步相比,也需要三步可完成
第一步:git add命令来把修改的文件放到暂存区
git add file 或者 git add .代表所有
第二步:git commit 命令来把文件提交到仓库
git commit -m ‘提交信息’ 加-m参数后面跟提示信息,强烈建议
这样就可以把代码提交到本地仓库了,这样别人把我电脑偷了,我的代码就不会丢了吗
还没有,现在只是暂时提交到本地仓库了,还没提交到远程,电脑丢了代码还是会丢
接下来我们来做最后一步:
git pull 拉取远程代码,这一步的作用是为了防止代码冲突,如果这个分支只是你个人在操作,这一步可以省略,因为不会有冲突
但是如果多个人在操作同一分支,大家交的代码就可能产生冲突
冲突,顾名思义,就是大家修改的矛盾了,Git服务器无法判断到底哪一版本代码应该保留,需要人工介入
冲突问题可能对于一些初学者来说比较头疼,文章下面单独拎出来说
git push origin new-branch 把本地仓库代码提交到远程
OK,收工!
其实还是可视化工具好用,不过这个还是看个人习惯
当然,这是一切一切都很顺利的情况,但是实际开发中,总有一些不尽人意的情况
再一步步分析其中每一步骤出现问题,如何解决
撤销本地的修改操作
git status查看当前文件状态
git checkout – xxx.java 撤销单个文件的本地修改,当然这里如果已经add到暂存区了,这个命令是无效的,需要先通过下面的git reset HEAD xxx.java进行add操作的撤销,之后才能对撤销文件进行修改
git执行了git checkout – xxx.java之后再次执行git status发现本地没有已经修改的文件了,也就是本地修改已经被撤销了
git checkout branch-name 这个命令可以用来切换本地分支,记得区分
撤销add到暂存区的操作(绿字变红字)
git status查看当前文件状态
git add操作之后添加到本地暂存区,变为绿字
撤销绿字:撤销add操作到暂存区
git reset HEAD xxx.java 这是对某个文件进行add的撤销,如果后面什么文件都不跟,其实就是对刚刚add的所有文件进行撤销了git reset HEAD
我们执行了之后,发现原本变绿(已经add的文件)的文件,又变回红色的文件了,这时候就撤销了刚刚的add操作了
撤销Commit到本地库的操作
执行了add和commit操作之后,这个时候已经提交到本地仓库了
git reset --hard HEAD命令直接将本地文件回退到上一个提交版本,无论是add和commit的操作有没有进行过
其实add的撤回和Commit的撤回都可以直接用git reset命令直接完成,只是这个命令携带不同的参数代表着不同的含义,git reset [–mixed --soft --hard] commitID有三种参数,熟悉这三个参数的含义
–mixed代表撤销git add和git commit的操作,保留编辑器的代码;
–soft代表撤销git commit,不撤销git add操作,同时保留编辑器的代码;
–hard参数很暴力,直接撤销commit和add的操作,撤销所有改动的代码,当你决定用–hard参数的时候,就代表着你应该已经决定了放弃修改过的所有代码咯
撤销push到远程的操作
当我们执行了push操作之后,意味着代码已经推送到远程了,其实这种情况需要回滚的比较少,一般已经提交的代码不需要再次回滚了,如果哪里修改错了,直接再次修改回来,再次提交即可
当然git也是考虑到这方面的,git加入了版本号这一概念,来解决这种问题,也就是每次推送都会生成一个对应的版本号,我们可以利用版本号进行相应的回滚
通过git log查看历史提交记录
将目标版本号保留,也就是你要退回的版本号保留。如果git log无法正常显示中文,执行set LESSCHARSET=utf-8命令
将本地的代码撤销到目标版本号,git reset --hard 547c78001fd2e0eedf83382ef4ee2974e9f445d1,此时本地代码已经切换回该版本号相应代码
强制提交,覆盖远程代码,git push --force执行完了这一步,相应版本号的代码便已经提交了,相应的代码也已经回滚了
慎重提交!reset命令会将你提交的版本号之后的提交版本全部消失掉,谨慎操作。
其实,还有另外一种形式的回滚,叫做git revert,这种回滚是和git reset是不同的回滚方式,git revert其实和git reset操作步骤也是类似的
给大家举个例子吧,这样更容易理解
比如现在依次有版本1、2、3,reset会把修改的版本ID之后的版本都会消失掉,我执行git reset 1,那之后的版本2和3也就全部消失了,revert则是当成一次新的提交版本,执行了git revert 1之后,会保留2和3的代码重新生成一个新的版本4,然后把版本4提交,所以这两个的原理是不同的
reset是回到某次提交,此次提交以及之前的Commit都会被保留,但是此次之后的修改都会被退回到暂存区
revert则是生成一次新的Commit提交来撤销某次提交,此次提交之前的Commit都会被保留,可以理解成把相应版本的代码删除掉,再次提交
reset的作用是修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本,如下图所示,假设我们要回退到版本一
适用场景:如果想恢复到之前某个提交的版本,且那个版本之后提交的版本我们都不要了,就可以用这种方法
revert原理:git revert是用于反做某一个版本,以达到撤销该版本的修改的目的。我们commit了三个版本1、2、3,突然发现版本2不行,想要撤销版本2,但又不想影响版本3的提交,就可以用git revert命令来撤销版本2,生成新的版本4,这个版本4保留了版本3的内容,但撤销了版本2的内容
使用场景:如果我们想要撤销之前的某一个版本,但是又想要保留该目标版本后面的版本,记录下这个版本变动流程,就可以用这种方法
搞清楚这两个的关系之后,其实也就是可以根据相应的业务场景来采用相应的命令,一定要谨慎使用这两个命令,尤其是reset的回退版本,因为git会把相应版本之后的版本删除掉
总之,回退版本需谨慎
命令行式
切换基础分支:先切换到要基于拉取的分支,我们开发中一般可能会基于master拉取的比较多,那就先切换到master(git checkout master)
创建本地分支:git checkout -b new-branch
提交到远程:git push origin new-branch
设置关联:git pull一下拉取远程分支代码会发现并未关联,OK lets do it
git branch --set-upstream-to=origin/new-branch new-branch 来建立关联,第一个new-branch是远程分支名称,第二个是本地名称
再次git pull一下,成功
sourceTress式
解决冲突这种事情在工作中难免会遇到,工作意味着合作,合作意味着你们在同一个分支修改代码,哪怕是在不同分支的代码,最终你们修改的代码上线也会合到相应的上线分支,合到上线分支的时候也可能会出现冲突
比如你需要在idea中合并两个分支dev和master,你需要把dev合并到master,切换到dev分支,执行git pull将本地代码更新为最新
git checkout master切换到master分支,执行git pull更新为最新的代码,执行git merge --no-ff dev(切换到目标分支下执行merge操作)
如果有冲突,直接通过idea来解决就好了,这里会出现一个解决冲突的按钮,点击进行就可以看到哪些文件有冲突
然后点击每个冲突文件,选择你想要保留的文件即可,最后点击右下角的apply来应用
记住,此时你的idea是处于mergeing状态,当你解决完了相应的所有的冲突,你就可以去按照正常修改代码来提交了,也就是上面说的那些add commit push一顿操作
其实啊,解决冲突的工具或者说是方式,有很多种,每个人有自己的代码对比工具来解决,当用命令行或者用sourceTree来merge的时候有冲突,我解决冲突用的最多的就是idea的git工具了,你可以选择自己的代码对比工具来进行代码的解决冲突和merge操作
感谢大家能够做我最初的读者和传播者,请大家相信,只要你给我一
份爱,我终究会还你们一页情的。
欢迎大家关注我的公众号【左耳君】,探索技术,分享生活
哦对了,后续所有的文章都会更新到这里
https://github.com/DayuMM2021/Java