在GIT中,git 查看分支提交记录是如何存储和记录的?

{"debug":false,"apiRoot":"","paySDK":"/api/js","wechatConfigAPI":"/api/wechat/jssdkconfig","name":"production","instance":"column","tokens":{"X-XSRF-TOKEN":null,"X-UDID":null,"Authorization":"oauth c3cef7c66aa9e6a1e3160e20"}}
{"database":{"Post":{"":{"contributes":[{"sourceColumn":{"lastUpdated":,"description":"一个专注互联网相关技术的专栏","permission":"COLUMN_PUBLIC","memberId":,"contributePermission":"COLUMN_PUBLIC","translatedCommentPermission":"all","canManage":true,"intro":"高效的中文IT技术平台","urlToken":"dreawer","id":21254,"imagePath":"v2-def9c21d9ca33ad157f4208.jpg","slug":"dreawer","applyReason":"0","name":"极乐科技","title":"极乐科技","url":"/dreawer","commentPermission":"COLUMN_ALL_CAN_COMMENT","canPost":true,"created":,"state":"COLUMN_NORMAL","followers":22034,"avatar":{"id":"v2-def9c21d9ca33ad157f4208","template":"/{id}_{size}.jpg"},"activateAuthorRequested":false,"following":false,"imageUrl":"/v2-def9c21d9ca33ad157f4208_l.jpg","articlesCount":472},"state":"accepted","targetPost":{"titleImage":"","lastUpdated":,"imagePath":"","permission":"ARTICLE_PUBLIC","topics":[,64816],"summary":"作者:惊鸿三世 链接: 版权归作者所有,转载请注明出处
几乎所有的版本控制系统都以分支的方式进行操作,分支是独立于项目主线的一条支线,我们可以在不影响主线代码的情况下,在分支下进行工作。对于传统的一些版本控制工具来说,…","copyPermission":"ARTICLE_COPYABLE","translatedCommentPermission":"all","likes":0,"origAuthorId":0,"publishedTime":"T14:43:46+08:00","sourceUrl":"","urlToken":,"id":2677978,"withContent":false,"slug":,"bigTitleImage":false,"title":"Git由浅入深之分支管理","url":"/p/","commentPermission":"ARTICLE_ALL_CAN_COMMENT","snapshotUrl":"","created":,"comments":0,"columnId":21254,"content":"","parentId":0,"state":"ARTICLE_PUBLISHED","imageUrl":"","author":{"bio":"极乐小程序商店(/)","isFollowing":false,"hash":"4b43cf6f3d97f480b3ca2c13e5b12752","uid":563500,"isOrg":false,"slug":"Dreawer","isFollowed":false,"description":"知乎专栏 && /dreawer \n极乐小程序商店 && /\n极乐科技
&& /","name":"极乐君","profileUrl":"/people/Dreawer","avatar":{"id":"v2-8cb80f97b7d5f74c7a8997cbc4089e1f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"memberId":,"excerptTitle":"","voteType":"ARTICLE_VOTE_CLEAR"},"id":605544}],"title":"Git由浅入深之分支管理","author":"Dreawer","content":"作者:惊鸿三世链接:版权归作者所有,转载请注明出处 几乎所有的版本控制系统都以分支的方式进行操作,分支是独立于项目主线的一条支线,我们可以在不影响主线代码的情况下,在分支下进行工作。对于传统的一些版本控制工具来说,我们通常需要花费比较多的时间拷贝主线代码,创建一个分支,并且对分支的管理效率也越来越不令人满意,而如今备受推崇的Git确实名副其实,Git中的分支非常轻量,我们可以随时随意创建任意数量的新分支,几乎感觉不到什么延时,而且对分支的操作也很高效,如,切换分支,暂存内容,分支合并,分支提交等。Git分支的与众不同上一节我们提到相对于其他大多数版本控制系统,Git分支是轻量且高效的,为什么呢?答案在前几篇已经有提到:传统的版本控制系统存储的数据是文件的变更,而Git则是存储一系列的文件快照(snapshot)。Git分支的这些特性,使得分支对我们几乎没有什么限制,一般针对每一个功能或需求都可以随意创建分支,而在传统的版本控制系统,这样几乎是不现实的。当我们向服务器提交数据时,Git会存储一个提交对象(commit object),这个存储对象包括一系列有用信息,。Git主干分支(master)master,有主人,大师的意思,在Git是通常作为主干分支,Git初始化仓库时,默认创建的分支名就是master,就像默认的远端主机别名是origin一样,大多数人不会修改它,这并不说明它与别的分支有什么区别,你可以随意修改名称。分支类型 在Git中,除了默认的master主干分支,我们创建的每一个分支,一般可分为两种:长运行分支(Long-Running branch):与master并行,长期存在使用的分支,如用以测试项目稳定性或作为主分支;主题分支(topic branch):针对每一个需求或功能或bug而暂时创建的分支,一旦任务完成,即可能回收。分支指针(HEAD)Git中有一个HEAD指针,始终指向当前分支,如图可见,项目当前处在master分支,之前一共有三次提交:上图可见,第一行显示了当前项目所有分支,HEAD -& master表明当前所处分支为master,我们可以总结如下图:上图可见,第一行显示了当前项目所有分支,HEAD -& master表明当前所处分支为master,我们可以总结如下图: 我们可以在项目根目录.git文件下找到一个HEAD文件:vi .git/HEAD,其内保存了指向当前分支最新提交的指针: 我们可以在项目根目录.git文件下找到一个HEAD文件:vi .git/HEAD,其内保存了指向当前分支最新提交的指针:该指针指向refs/heads/分支名文件,我们进入.git/refs/heads/目录,其下以分支名为文件名列出了所有分支:我们查看当前分支文件,执行vi master:我们查看当前分支文件,执行vi master:可以看到,其内存储的就是当前分支的最新一次提交对象ID。创建分支(git branch, git checkout -b)接下来,假设有一个需求A,我们创建一个分支work-a: git checkout -b 分支名\n-b参数声明为创建新分支等价于以下两条指令: 等价于以下两条指令: git branch 分支名\ngit checkout 分支名\n切换分支(git checkout)git checkout 分支名表示切换到该分支,上文提到指定-b配置即说明创建新分支。注:在切换分支前,一定确保当前分支的修改已经提交或者缓存。多分支并行我们经常会遇到同时需要开发多个功能和需求,或者突然发现线上bug需要紧急处理,我们只需要提交当前分支修改,然后切换到主干分支,从其基础上再切出一个新分支fix-bug1:可以看到,在work-a分支上我们新增了一次提交:b287b8eeb4cc6989。可以看到,在work-a分支上我们新增了一次提交:b287b8eeb4cc6989。现在我们在fix-bug1分支上修复bug后,进行提交:现在我们在fix-bug1分支上修复bug后,进行提交:可以看到,在fix-bug1分支上多了一个提交:ca270e6,现在整个结构就变成如下图:可以看到,在fix-bug1分支上多了一个提交:ca270e6,现在整个结构就变成如下图:合并分支(git merge)我们已经修复了某bug或完成了功能开发,这时要做的是把代码并入主干,,当然一般公司或团队都需要经过代码审查,才能并入主干,在此略过不谈,分支合并相关指令:git merge 分支名\n该指令告诉Git将指定分支合并到当前分支,当然是可能出现冲突的,我们按照指示解决冲突,即可。现在我们先切换到master分支,然后把fix-bug1分支并入主干:可以看到执行git merge指令后,状态信息显示:第一行Updating,告诉我们提交记录更新至ca270e6;第二行Fast-forward,即快速推进,说明Git直接将当前分支推进到指向新提交对象;后面是merge的内容信息非快速推进合并(NO FAST-FORWARD)现在,我们再次创建一个分支fix-bug2,并进行几次修改提交:多次提交后,状态如下:多次提交后,状态如下:我们通过非快速推进方式合并分支进主干分支:我们通过非快速推进方式合并分支进主干分支:如上图,指定--no-ff即声明进行非快速推进合并,第二行的Merge made by the 'recursive' strategy表明通过非快速推进方式合并,我们发现除了分支上进行的提交记录外,Git创建了一个新的提交对象:7a657a,使用如上图,指定--no-ff即声明进行非快速推进合并,第二行的Merge made by the 'recursive' strategy表明通过非快速推进方式合并,我们发现除了分支上进行的提交记录外,Git创建了一个新的提交对象:7a657a,使用git log --graph指令查看其信息:如图,快速推进方式合并入主干的fix-bug1分支的提交记录直接并入主线,且不会创建新的提交对象;而对于非快速推进方式合并的fix-bug2分支,其提交历史也都保存,但是并未进入主线,而是保存了一条支线,同时,在主线上创建一个新的提交对象。最后描述其结构如图:非快速推进与快速推进合并(FAST-FORWARD & NO FAST-FORWARD)从上例,对比一下两种方式合并分支的异同:提交对象都会保存;报存提交对象方式不同:快速推进方式是直接在主线(合并主分支)上,添加这些提交对象,即直接移动HEAD指针;而非快速推进方式是将提交对象保存在支线,然后在主线新建一个提交对象,修改HEAD指针及新建提交对象的指针,而且此新建提交对象有两个父提交对象(即有两个parent指针)。合并后分支指向不同:快速推进合并后,两个分支将同时指向最新提交对象,而非快速推进合并后,合并主分支指向新建的提交对象,另一分支指向不变。我们查看一下新创建提交对象:可以看到该提交对象中有两个指针指向父提交对象,一个指向主线中的父提交对象,一个指向fix-bug2分支合并而来的支线父提交对象。 三路合并(THREE-WAY MERGE)除了之前提到的两种合并的情况,其实还存在这样一种情况,就是现在假如我完成了work-a分支的开发,需要将其并入主干,我们能看到当前master主干分支已经推进到7a6576了,而work-a分支指向b287b8,两者有共同祖先提交对象6d50f6,我们将其合并:
上图第二行表明此次是通过非快速推进方式合并,我们查看提交对象记录图:结构如图:结构如图:我们发现,三路合并结构是在需要合并的两个分支的最新提交对象的基础上,创建一个新提交对象(4ae14b),将合并主分支(即执行合并指令时,当前所处分支)的HEAD指针前移指向该提交对象,该提交对象有两个父提交对象,分别为合并前待合并分支的最新提交对象(即b287b8和7a657a)。我们发现,三路合并结构是在需要合并的两个分支的最新提交对象的基础上,创建一个新提交对象(4ae14b),将合并主分支(即执行合并指令时,当前所处分支)的HEAD指针前移指向该提交对象,该提交对象有两个父提交对象,分别为合并前待合并分支的最新提交对象(即b287b8和7a657a)。关于三路合并需要明确:三路合并其实是一种非快速推进合并方式;三路合并的前提是两个分支有共同祖先提交对象;分支冲突(conflict)在合并分支,不可避免会发生冲突,当我们在两个分支对同一文件同一部分进行不同修改后,发起合并时就会提示有冲突,假设我们有work-b分支,在其基础上切出新分支work-b-1,然后在两分支上分别对README.md文件同一部分进行不同修改并提交,然后将work-b-1分支合并到work-b分支:
发现README.md文件有冲突,查看该文件:发现README.md文件有冲突,查看该文件:如上图,列出了两个分支的不同修改,HEAD表明当前分支的修改内容,下面是work-b-1分支的修改,我们选择需要保留的内容,删除其他无关信息和内容,然后保存该文件,查看当前状态:如上图,列出了两个分支的不同修改,HEAD表明当前分支的修改内容,下面是work-b-1分支的修改,我们选择需要保留的内容,删除其他无关信息和内容,然后保存该文件,查看当前状态:根据提示,解决冲突后提交:根据提示,解决冲突后提交:查看分支对于创建过但并未删除的分支,我们可以查看分支列表,依然使用git branch指令,不传入任何参数:
图中列出了所有分支,前面带星号的表示当前分支,当然我们还可以查看指明最新提交信息的分支列表,可以添加-v参数:筛选分支除了可以查看所有分支列表,Git还支持筛选已合并或未合并至当前分支的所有分支:--merged参数指明筛选已合并分支;--no-merged参数指明筛选未合并分支。删除分支(git branch -d)当分支合并入主干后,也许我们不再需要那个分支了,我们需要将其删除,使用指令: git branch -d 分支名\n之前介绍到使用git branch是创建新分支,而指定-d参数,说明需要删除该分支:远程分支(remote branch)我们注意到,前文所讲述的分支都是存在本地的,即本地分支,还需要了解远程分支,如[remote]/[branch]这种形式,表示是远端主机的某分支,,其实远程分支和本地分支基本理论概念还是相同的,区别是有些指令不同而已: git checkout -b test origin/develop\n以上指令即从远程分支(远端主机origin上的develop分支)切出新的本地分支test分支。跟踪分支(TRACKING BRANCH)前文已经介绍了本地分支和远程分支的概念及操作,那么这两类分支之间应该有某种关系将他们关联起来,本地项目都需要与远端主机仓库同步(pull\n & push),当我们从一个远程分支切出(创建)一个本地分支时,这个分支就叫跟踪分支(tracking \nbranch),而远程分支叫上游分支(upstream branch)。当我们克隆一个远端仓库时,会默认创建一个跟踪分支master,其上游分支就是远端主机别名/master。创建跟踪分支创建跟踪分支指令如下: git checkout -b 本地分支名 远端主机别名/远程分支名\n当然也可以不指定分支名,使用远程分支同名:git checkout --track 远端主机别名/远程分支名\n修改跟踪关系有时候,可能需要为本地分支设置其上游分支,添加-u参数:git branch -u 远端主机别名/远程分支名\n以上指令就指明当前分支跟踪某远端主机的远程分支。查看跟踪分支(git branch -vv)使用以下指令查看分支的上游分支:git branch -vv\n上图输出信息第二行表明master分支跟踪远程origin/master分支,ahead 7表明本地有7个提交未推到服务器,其他分支不是跟踪分支,没有上游分支。上图输出信息第二行表明master分支跟踪远程origin/master分支,ahead 7表明本地有7个提交未推到服务器,其他分支不是跟踪分支,没有上游分支。删除远程分支对于不再需要的远程分支,是可以删除的:git push origin --delete test\n以上指令删除远端主机origin的test分支,但是在垃圾回收之前,Git服务器仍然会保留分支数据,我们可以很方便的恢复数据,之后会详细介绍。变基(rebase)Git中有两种方式整合不同分支的修改:第一种是前文介绍的合并(merge),另一种就是本节的主题变基(rebase)。变基其实与前文提到的三路合并(three-way merge)颇有渊源:如图work-a分支与主干master分支合并后,创建一个新提交对象,我们还可以通过变基完成两个分支的修改整合,由于work-a分支已合并到master分支,我们在work-a分支再提交一次修改e0ae7dc,然后我们将work-a分支对master分支进行变基:如图work-a分支与主干master分支合并后,创建一个新提交对象,我们还可以通过变基完成两个分支的修改整合,由于work-a分支已合并到master分支,我们在work-a分支再提交一次修改e0ae7dc,然后我们将work-a分支对master分支进行变基:执行变基时,由于两个分支对同一文件同一部分进行了不同修改,会提示冲突,需要解决冲突,我们修改文件解决冲突,然后查看状态:上图,第一行 onto 4ae14b3说明当前分支针对4ae14b3快照进行变基,第三到第五行分别说明:第三行:解决冲突然后执行git rebase --continue指令继续变基;第四行:执行git rebase --skip指令,跳过解决冲突;第五行:执行git rebase --abort指令,终止变基,回到分支变基前状态。下面第6到第八行说明:第七行:使用git reset HEAD &file&指令撤销某文件变更;第八行:使用git add &file&指令标记冲突为已解决状态。最后一行no changes added to commit (use \"git add\" and/or \"git commit -a\"),说明尚未标记冲突,需要使用指令标记变更,在继续执行变基: 如上图,变基后,在主线上创建新提交对象640b83,并修改work-a分支指针指向该提交对象:如上图,变基后,在主线上创建新提交对象640b83,并修改work-a分支指针指向该提交对象:之后我们可以正常的合并:之后我们可以正常的合并:之后我们可以正常的合并:如图,主线分支更新提交对象到640b83a,第二行Fast-forward说明此次合并属于快速推进合并方式,结构如下:如图,主线分支更新提交对象到640b83a,第二行Fast-forward说明此次合并属于快速推进合并方式,结构如下:三路合并与变基基于上例,三路合并,整合修改变更后会保留分支的原始提交记录,新创建提交对象有两个父提交对象,一个在主线上,一个在待合并分支上;而变基则不能保留待合并分支的原始提交记录,主线上新建的提交对象只有一个位于主线上的父提交对象。更多变基相关内容计划单独出文介绍。至于到底选用哪种方式整合变更,变基还是合并,这个一直有争论,没有哪一种方式绝对合理,我们只需要把握一个原则:无论变基还是合并,你应该只操作本地历史记录,任何已经推到服务器并入主干的内容和提交历史不应该更改。作者:惊鸿三世链接:版权归作者所有,转载请注明出处 ","updated":"T06:43:46.000Z","canComment":false,"commentPermission":"anyone","commentCount":0,"collapsedCount":0,"likeCount":39,"state":"published","isLiked":false,"slug":"","isTitleImageFullScreen":false,"rating":"none","titleImage":"","links":{"comments":"/api/posts//comments"},"reviewers":[],"topics":[{"url":"/topic/","id":"","name":"Git"},{"url":"/topic/","id":"","name":"版本控制"},{"url":"/topic/","id":"","name":"Branch"}],"adminClosedComment":false,"titleImageSize":{"width":0,"height":0},"href":"/api/posts/","excerptTitle":"","column":{"slug":"dreawer","name":"极乐科技"},"tipjarState":"inactivated","annotationAction":[],"sourceUrl":"","pageCommentsCount":0,"hasPublishingDraft":false,"snapshotUrl":"","publishedTime":"T14:43:46+08:00","url":"/p/","lastestLikers":[{"bio":"如有异议,你是对的。","isFollowing":false,"hash":"b0effbcc44410bbdfe07e50a","uid":08,"isOrg":false,"slug":"shandian","isFollowed":false,"description":"VR虚拟现实从业者","name":"王又贝","profileUrl":"/people/shandian","avatar":{"id":"c","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"8f74a4ef47c2df070df80c0","uid":48,"isOrg":false,"slug":"yu-hu-29","isFollowed":false,"description":"","name":"yu hu","profileUrl":"/people/yu-hu-29","avatar":{"id":"70af92d82","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"想成为程序员的本科生。","isFollowing":false,"hash":"eee8d0c8f","uid":692200,"isOrg":false,"slug":"bu-lai-ke-44-36","isFollowed":false,"description":"","name":"布莱克","profileUrl":"/people/bu-lai-ke-44-36","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":null,"isFollowing":false,"hash":"edb0bf37f4c84e2a3d44f","uid":80,"isOrg":false,"slug":"kw-zhou-77","isFollowed":false,"description":"","name":"kw zhou","profileUrl":"/people/kw-zhou-77","avatar":{"id":"da8e974dc","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},{"bio":"按图索骥","isFollowing":false,"hash":"d6d254e1f77c5d1c3b39cef","uid":80,"isOrg":false,"slug":"mageer","isFollowed":false,"description":"","name":"Balian","profileUrl":"/people/mageer","avatar":{"id":"d2c52d250b32b9ef6a373b525db7cfd0","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false}],"summary":"作者:惊鸿三世 链接: 版权归作者所有,转载请注明出处
几乎所有的版本控制系统都以分支的方式进行操作,分支是独立于项目主线的一条支线,我们可以在不影响主线代码的情况下,在分支下进行工作。对于传统的一些版本控制工具来说,…","reviewingCommentsCount":0,"meta":{"previous":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"/v2-ad5a3e2ac_r.jpg","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"JavaScript"},{"url":"/topic/","id":"","name":"freeCodeCamp"},{"url":"/topic/","id":"","name":"算法"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"singsing.io/blog","isFollowing":false,"hash":"79ab1b418e814d01f479b15c","uid":12,"isOrg":false,"slug":"liuxing0514","isFollowed":false,"description":"","name":"柳星","profileUrl":"/people/liuxing0514","avatar":{"id":"cd36c5675e9","template":"/{id}_{size}.png"},"isOrgWhiteList":false},"column":{"slug":"dreawer","name":"极乐科技"},"content":"原文链接:题目链接\n级别:初级 (Basic Algorithm Scripting)问题解释\n这个 function 接收一个字符串参数,返回翻转后的字符串比如接收的是 \"hello\",那么输出就是 \"olleh\"基本解法\n思路提示\n先把字符串分割成为数组翻转数组把翻转后的数组合并为字符串参考链接\n代码function reverseString(str) {\n
var strArr = str.split('');\n
var reversedArr = strArr.reverse();\n\n
return reversedArr.join('');\n}\n\n解释\n第一步就是把传入的 str 分割,并赋值给 strArr第二步是把数组翻转,并赋值给 reversedArr第三步是返回合并之后的字符需要注意的是,以上的 split 和 join 都不会改变原来的字符串或数组,但 reverse 会改变原来的数组优化\n代码function reverseString(str) {\n
return str.split('').reverse().join('');\n}\n\n解释\nsplit 返回分割后的数组,因此可以直接调用 reversereverse 方法返回的是翻转后的数组,因此可以直接调用 joinjoin 之后就是我们想要的字符串,直接返回即可这里用到了 Method Chaining,也就是方法的链式调用。只要你熟悉方法的返回值,就可以这么做,好处在于可以不用创建这么多变量中级解法\n思路提示\n直接利用字符串方法,而不需要转换成数组多说一句,获取字符串中 str 的某一个字符有两种方式,分别是 str.charAt(i) 和 str[i]。两种方式都只是读取,均不可以通过赋值修改原字符串代码function reverseString(str) {\n
var result = \"\";\n\n
for (var i = str.length - 1; i &= 0; i--) {\n
result += str[i];\n
return result;\n}\n\n解释\n首先我们先创建一个变量,叫 result,用于保存输出结果然后,从右边开始遍历字符串。值得注意的是,就像数组一样,字符串一样可以通过所以来获取某一个字符。比如,str[0] 就是获取第一个字符。再比如,str[-1] 就是获取最后一个字符因为是从右边开始遍历,那我们把每次遍历到的字符直接加到 result 就可以了需要注意的是边界条件的确定,因为字符串的索引同样是从 0 开始的,因此遍历的初始值要设置为 str.length - 1,结束值为 0高级解法\n思路提示\n通过字符串方法以及递归来翻转代码function reverseString(str) {\n
// 设置递归终点(弹出条件)\n
if (str.length === 1) {\\n
} else {\n
// 递归调用\n
return reverseString(str.substr(1)) + str[0];\n
}\n}\n\n解释\n这种方法,一开始不能理解没关系。等做到高级算法题,再回来看看应该就可以理解了递归涉及到两个因素,递归调用以及弹出过程。reverseString(str.substr(1)) 就是递归调用,+ str[0] 就是弹出过程代码在执行到 reverseString(str.substr(1)) 的时候,会重新调用 reverseString,并传入 str.substr(1) 作为参数。后面的 + str[0] 暂时不会执行直到传入的字符串长度为 1,就不会再去调用 reverseString 了,而是会执行 if 里面的部分,返回当前传入的 str。然后就会一步一步地执行之前的 + str[0],也就是弹出过程举个例子:var str = \"abc\";\n\nreverseString(str)\n\n执行过程如下:首先执行 reverseString(\"abc\"),这时候传入的 str 长度不为 1,所以执行 else 部分,也就是 reverseString(str.substr(1))。这就是递归调用,执行这段代码,其中 str.substr(1) 为 \"bc\"reverseString(\"bc\"),这时候传入的 str 长度依旧不为 1,所以执行 reverseString(str.substr(1)),其中 str.substr(1) 为 \"c\"reverseString(\"c\"),这时候传入的 str 长度为 1,所以执行 if 中的部分,返回传入的 str,也就是返回 \"c\"回到 reverseString(\"bc\") 这一步,此时的 str[0] 为 \"b\"。由于上一步的返回值是 \"c\",那么这一步的返回值是 \"cb\"回到 reverseString(\"abc\"),此时的 str[0] 为 \"a\"。由于上一步的返回值是 \"cb\",那么这一步的返回值是 \"cba\"至此,我们得到了最终结果,\"cba\"性能测试根据测试结果来看,第三种方法是最快的,第四种方法是最慢的","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T12:09:49+08:00","url":"/p/","title":"翻转字符串 (Reverse a String)","summary":"原文链接:题目链接\n
级别:初级 (Basic Algorithm Scripting) 问题解释\n这个 function 接收一个字符串参数,返回翻转后的字符串 比如接收的是 \"hello\",那么输出就是 \"olleh\" 基本解法\n思路提示\n先…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":15,"likesCount":18},"next":{"isTitleImageFullScreen":false,"rating":"none","titleImage":"","links":{"comments":"/api/posts//comments"},"topics":[{"url":"/topic/","id":"","name":"前端开发"},{"url":"/topic/","id":"","name":"前端性能优化"},{"url":"/topic/","id":"","name":"JavaScript"}],"adminClosedComment":false,"href":"/api/posts/","excerptTitle":"","author":{"bio":"程序员","isFollowing":false,"hash":"086d2ffcb95d","uid":353200,"isOrg":false,"slug":"li-yin-cheng-24","isFollowed":false,"description":"","name":"李银城","profileUrl":"/people/li-yin-cheng-24","avatar":{"id":"3c1a4bab55","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false},"column":{"slug":"dreawer","name":"极乐科技"},"content":"由于上一篇《从Chrome源码看JS Object的实现》有些地方表述不对,最后的结论是Object不太适合拿来当map,然而很遗憾,这个结论不太对,感觉有点误导大众,特此对原文做了更新,详细查看:文章目录:1. V8的代码结构2. JS Object类图3. 创建JSObject4. 字符串哈希查找5. 字符串哈希表查找6. 数字索引哈希查找7. ES6 Map的实现8. Object和ES 6 Map的速度比较(此文章将过段时间删除)","state":"published","sourceUrl":"","pageCommentsCount":0,"canComment":false,"snapshotUrl":"","slug":,"publishedTime":"T22:30:57+08:00","url":"/p/","title":"从Chrome源码看JS Object的实现(更新)","summary":"由于上一篇《从Chrome源码看JS Object的实现》有些地方表述不对,最后的结论是Object不太适合拿来当map,然而很遗憾,这个结论不太对,感觉有点误导大众,特此对原文做了更新,详细查看: 文章目录:1. V8的代码结构2…","reviewingCommentsCount":0,"meta":{"previous":null,"next":null},"commentPermission":"anyone","commentsCount":0,"likesCount":22}},"annotationDetail":null,"commentsCount":0,"likesCount":39,"FULLINFO":true}},"User":{"Dreawer":{"isFollowed":false,"name":"极乐君","headline":"知乎专栏 && /dreawer \n极乐小程序商店 && /\n极乐科技
&& /","avatarUrl":"/v2-8cb80f97b7d5f74c7a8997cbc4089e1f_s.jpg","isFollowing":false,"type":"people","slug":"Dreawer","bio":"极乐小程序商店(/)","hash":"4b43cf6f3d97f480b3ca2c13e5b12752","uid":563500,"isOrg":false,"description":"知乎专栏 && /dreawer \n极乐小程序商店 && /\n极乐科技
&& /","profileUrl":"/people/Dreawer","avatar":{"id":"v2-8cb80f97b7d5f74c7a8997cbc4089e1f","template":"/{id}_{size}.jpg"},"isOrgWhiteList":false,"badge":{"identity":null,"bestAnswerer":null}}},"Comment":{},"favlists":{}},"me":{},"global":{},"columns":{"next":{},"dreawer":{"following":false,"canManage":false,"href":"/api/columns/dreawer","name":"极乐科技","creator":{"slug":"Dreawer"},"url":"/dreawer","slug":"dreawer","avatar":{"id":"v2-def9c21d9ca33ad157f4208","template":"/{id}_{size}.jpg"}}},"columnPosts":{},"columnSettings":{"colomnAuthor":[],"uploadAvatarDetails":"","contributeRequests":[],"contributeRequestsTotalCount":0,"inviteAuthor":""},"postComments":{},"postReviewComments":{"comments":[],"newComments":[],"hasMore":true},"favlistsByUser":{},"favlistRelations":{},"promotions":{},"switches":{"couldAddVideo":false},"draft":{"titleImage":"","titleImageSize":{},"isTitleImageFullScreen":false,"canTitleImageFullScreen":false,"title":"","titleImageUploading":false,"error":"","content":"","draftLoading":false,"globalLoading":false,"pendingVideo":{"resource":null,"error":null}},"drafts":{"draftsList":[],"next":{}},"config":{"userNotBindPhoneTipString":{}},"recommendPosts":{"articleRecommendations":[],"columnRecommendations":[]},"env":{"isAppView":false,"appViewConfig":{"content_padding_top":128,"content_padding_bottom":56,"content_padding_left":16,"content_padding_right":16,"title_font_size":22,"body_font_size":16,"is_dark_theme":false,"can_auto_load_image":true,"app_info":"OS=iOS"},"isApp":false},"sys":{}}

我要回帖

更多关于 git查看远程分支记录 的文章

 

随机推荐