丨玩转git五种提高代码提交原子性的基本操作_第1页
丨玩转git五种提高代码提交原子性的基本操作_第2页
丨玩转git五种提高代码提交原子性的基本操作_第3页
丨玩转git五种提高代码提交原子性的基本操作_第4页
丨玩转git五种提高代码提交原子性的基本操作_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

帮你学习到Git我在第21篇文章中提到,代码提交的原子性指的是,一个提交包含一个不可分割的特性、修复或者优化。如果用一个提交完成一个功能,这个提交还是会比较大的话,我们需要把这个功能再拆分为子功能。为什么要强调代码提交的原子性呢?这是因为它有以下3大好处:origin/master而GitGit下面,我就来与你Git支持原子性的5种基础操作,具体包括于Git的一些基础概念和使用方法,推荐你参考“图解Git”这篇文章。如果是把整个文件添加到提交中,操作很简单:先用gitadd<文件名>把需要的文件添加到Git暂存区,然后使用gitcommit命令提交即可。这个操作比较常见,我们应该都比里的一部分改动添加到提交中,剩下的部分暂时不产生提交。针对这个需求,Git提供了gitadd-p命令。##>gitdiff--gita/index.jsindex63b6300..986fcd8---6+++7@@-1,8+1,14+varport=3000varexpress=varapp=##vvv添加+app.get('/timestamp',function(req,res)14+res.send(''+1516app.get('/',function(req,res)res.send('o 21-22+//Startthe23+app.listen(port)##<--这时,运行gitadd-pindex.js命令,Git会把文件改动分块儿显示,并提供操作选项,比如我可以通过y和n指令来选择是否把当前改动添加到Gits的改动添加到Git的暂存区中。>gitadd-pdiff--gita/index.jsindex63b6300..986fcd8---5+++6@@-1,8+1,147port=8express=9app=+app.get('/timestamp',function(req,res)12+res.send(''+1314app.get('/',function(req,res)res.send('o -+//StarttheStagethishunk[y,n,q,a,d,s,e,?]?Splitinto3@@-1,3+1,4+varport=varexpress=varapp=Stagethishunk[y,n,q,a,d,j,J,g,/,e,?]?@@-1,7+2,11varexpress=varapp=+app.get('/timestamp',function(req,{+res.send(''++app.get('/',function(req,res)res.send('o42Stagethishunk[y,n,q,a,d,K,j,J,g,/,e,?]?43@@-4,5+9,6 app.get('/',function(req,res) res.send('o 48-49+//Startthe5051Stagethishunk[y,n,q,a,d,K,g,/,e,?]?gitdiffcached>gitdiff--diff--gita/index.jsindex63b6300..7b82693---5+++6@@-1,3+1,47port=8express=9app=11@@-5,4+6,5@@app.get('/',function(req,res)res.send('o 15-16+//Startthe17通过gitdiffendpoint>gitdiff--gita/index.jsindex7b82693..986fcd8---5+++6@@-2,6+2,10@@varport=varexpress=varapp=910+app.get('/timestamp',function(req,res)11+res.send(''+1213app.get('/',function(req,res)res.send('o gitcommit如果你想深入了解gitadd-p通过gitadd-p,我们可以把工作区中的代码拆分成多个提交。但是,如果需要拆分的代码已经被放到了一个提交中,怎么办?如果这个提交已经推送到了代码仓共享分支,那就所谓当前提交,指的是当前分支的HEADendpoint用gitadd-p的方法重新产生提交。这里的取消是带引号的,因为在Git里所有的提交都gitloggitshowendpoint##>gitlog--graph--oneline--*7db082a(HEAD->master)ChangemagicportANDadda*352cc92Addgitignorefilefor*e2dacbc(origin/master)Addedthesimplewebserver78##>gitcommit (HEAD->diff--gita/index.jsindex63b6300..986fcd8---17+++18@@-1,8+1,1419+varport= varexpress= varapp=23+app.get('/timestamp',function(req,res)24+res.send(''+2526 app.get('/',function(req,res) res.send('o 31-32+//Startthe33gitbranchtemptempHEAD。temp作用是,预防代码丢失。如果后续工作出现问题的话,我可以使用gitreset--hardtemp1>gitbranch2>gitlog--graph--oneline--*7db082a(HEAD->master,temp)ChangemagicportANDadda*352cc92Addgitignorefilefor*e2dacbc(origin/master)Addedthesimplewebserver接下来,运行gitresetHEAD^命令,把当前分支指向目标提交HEAD^,也就是当前提交的父提交。同时,在没有接–hard或者–soft参数时,gitreset会把目标提交的内容同时endpoint相关改动和端口相关改动。也就是说,这个命令的效果,就是让我回到了对这两>gitresetUnstagedchangesafterM4>gitOnbranchYourbranchisaheadof'origin/master'by1(use"gitpush"topublishyourlocal9Changesnotstagedfor(use"gitadd<file>..."toupdatewhatwillbe(use"gitcheckout--<file>..."todiscardchangesinworking nochangesaddedtocommit(use"gitadd"and/or"gitcommit-15:06:58(master)jasonge@Juns-MacBook-Pro-2.local:~/jksj-repo/git-atomic-##>gitdiff--gita/index.jsindex63b6300..986fcd8---25+++26@@-1,8+1,1427+varport= varexpress= varapp=31+app.get('/timestamp',function(req,res)32+res.send(''+3334 app.get('/',function(req,res) res.send('o 39-40+//Startthe41##>gitdiff--gitaddpCommitMessagegitcommitamendGitgitcommitamendCommitMessage有些时候,我们需要把多个提交交换顺序。比如,masterAB,BAorigin/master这时,我先完成了提交B,想把它先单独推送到origin/master上去,就需要交换A和B的位置,使得A在B之上。我可以使用gitrebase--inctive(选项–inctive可以简写为-i)来实现这个功能。首先,还是使用gitbranchtemp产生一个临时分支,确保代码不会丢失。然后,使用gitlog--oneline--graph来确认当前提交历史:>gitlog--oneline--*7b6ea30(HEAD->master,temp)Addanewendpointtoreturn*b517154Changemagicportnumberto*352cc92(origin/master)Addgitignorefilefor*e2dacbcAddedthesimplewebserver*2f65a89Initcommitcreatedbyinstallingexpress>gitrebase-iGitrebasepickb517154Changemagicportnumbertopick7b6ea30Addanewendpointtoreturn3#Rebase352cc92..7b6ea30onto352cc92(2###p,pick<commit>=use#r,reword<commit>=usecommit,buteditthecommit#e,edit<commit>=usecommit,butstopfor#s,squash<commit>=usecommit,butmeldintoprevious#f,fixup<commit>=like"squash",butdiscardthiscommit'slog#x,exec<command>=runcommand(therestoftheline)using#b,break=stophere(continuerebaselaterwith'gitrebase--#d,drop<commit>=remove#l,label<label>=labelcurrentHEADwitha#t,reset<label>=resetHEADtoa#m,merge[-C<commit>|-c<commit>]<label>[## createamergecommitusingtheoriginalmerge# message(ortheoneline,ifnooriginalmergecommit# specified).Use-c<commit>torewordthecommit##Theselinescanbere-ordered;theyareexecutedfromtopto##IfyouremovealinehereTHATCOMMITWILLBE##However,ifyouremoveeverything,therebasewillbe##Notethatemptycommitsarecommentedrebase命令一般翻译为变基,意思是改变分支的参考基准。具体到gitrebase-iorigin/master命令,就是把从origin/master之后到当前HEAD的所有提交,也就是A和B,重新有选择地放到origin/master上面。你可以选择放或者不放某一个提交,也可指的就是在HEAD之上应用一个提交的意思。Gitrebasei参考基准上去,具体到这个例子,是用两个pick命令把A和B先后重新放到origin/master之上,如果我直接保存退出的话,结果跟rebase之前没有任何改变。ABpick可。Gitrebase就会先后把B和A放到origin/master上。pick7b6ea30Addanewendpointtoreturnpickb517154Changemagicportnumberto3#Rebase352cc92..7b6ea30onto352cc92(2#B##以下是gitrebase-iorigin/masterSuccessfullyrebasedandupdated34##>gitlog--oneline--graph--*65c41e6(HEAD->master)Changemagicportnumberto*40e2824Addanewendpointtoreturn|*7b6ea30(temp)Addanewendpointtoreturn|*b517154Changemagicportnumberto*352cc92(origin/master)Addgitignorefilefor*e2dacbcAddedthesimplewebserver*2f65a89Initcommitcreatedbyinstallingexpress值得注意的是,ABcommitSHA1AB的拷贝,原来的两个提交仍然存在(图中的阴影部分),我们还可以用分支temp找到它们,但不再需要它们了。如果temp分支被删除,A和B也会自动被Git的收集过程gc清除掉。其实,gitrebasei的功能非常强大,除了交换提交的顺序外,还可以删除提交、和并多在上面的基本操作二、三、四中,我与你介绍的都是对当前分支头部的一个提交或者多个提交进行操作。但在工作中,为了方便实现原子性,我们常常需要修改历史提交,也就是修改非头部提交。对历史提交操作,最方便的方式依然是使用强大的itrease-i。接下来,我继续用上面修改A和B两个提交的顺序的例子来做说明。在还没有交换提交BBAAgitrebaseiorigin/master;然后,在弹出的编辑窗口中把原来的“pickb517154”的一行改为“editb517154”。其中,b517154是提交A的SHA1。editb517154Changemagicportnumbertopick7b6ea30Addanewendpointtoreturn3#Rebase352cc92..7b6ea30onto352cc92(2#而“editb517154”,是告知Gitrebase命令,在应用了b517154之后,暂停后续的rebasegitrebasecontinue辑器中保存修改并退出之后,gitrebase就会暂停。>gitrebase-iStoppedatb517154...ChangemagicportnumbertoYoucanamendthecommitnow,4 gitcommit--67Onceyouaresatisfiedwithyourchanges,8 gitrebase--1122:29:35(master|REBASE-i)~/jksj-repo/git-atomic-demo这时,我可以运行gitlog--oneline--graph--all,确认当前HEAD已经指向了要修改的提交A。>gitlog--oneline--graph--*7b6ea30(master)Addanewendpointtoreturn*b517154(HEAD)Changemagicportnumberto*352cc92(origin/master)Addgitignorefilefor*e2dacbcAddedthesimplewebserver*2f65a89Initcommitcreatedbyinstallingexpress接下来,我就可以使用基本操作二中提到的方法对当前提交(A)进行修改了。具体来说,就是修改文件,之后用gitadd<文件名>,然后再运行gitcommit--amend。##检查当前HEAD>gitcommit c8a872e9e9b9118ebAuthor:JasonGe MonOct1412:50:366 Changemagicportnumberto8It'snotgoodtohaveamagicnumber.ThiscommitchangesittoRunnodeindex.jsandverifiedtherootendpointstilldiff--gita/index.jsindex63b6300..7b82693---19+++20@@-1,3+1,4+varport=varexpress=varapp=25@@-5,4+6,5@@app.get('/',function(req,res) res.send('o -30+//Startthe31##用VIM"atapredefined>vim38##39>git40diff--gita/index.js41index7b82693..eb53f5f42---43+++44@@-6,5+6,5@@app.get('/',function(req,res) res.send('o 48-//Startthe49+//Starttheserveratapredefined22:40:10(master|REBASE-i)jasonge@Juns-MacBook-Pro-2.local:~/jksj-repo/git-atomic->gitadd##对修改添加到提交A>gitcommit--[detachedHEADf544b12]Changemagicportnumberto Date:MonOct1412:50:361filechanged,3insertions(+),1deletion(-22:41:18(master|REBASE-i)jasonge@Juns-MacBook-Pro-2.local:~/jksj-repo/git-atomic-##查看修改过后的A。确认其包含了新修改的内容"atapredefined>gitcommit c7dd08a32c0d59b032Author:JasonGe MonOct1412:50:36 ChangemagicportnumbertoIt'snotgoodtohaveamagicnumber.ThiscommitchangesittoRunnodeindex.jsandverifiedtherootendpointstilldiff--gita/index.jsindex63b6300..eb53f5f---81+++82@@-1,3+1,483+varport=varexpress=varapp=87@@-5,4+6,5@@app.get('/',function(req,res)

res.send('o91-92+//Starttheserveratapredefined93执行完成之后,我就可以运行gitrebase--continue,完成gitrebase-i的后续操作,也就是在A之上再应用提交B,并把HEAD重新指向了B,从而完成了对历史提交A的修##继续运行rebase>gitrebase--Successfullyrebasedandupdated45##>gitlog--oneline--graph--*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论