全教育培训行业第三方平台平台就业机构
扫码试听
扫码试听
Q:2638333071
首页 > 零基础学习 > Web前端 > > git切换分支的命令
行业动态 行业问答 课程问答 零基础学习 就业前景 技术干货

git切换分支的命令

发布时间:4 周 前 栏目:Web前端 浏览:

1、git切换分支的命令

作为程序员的我们应该都有一个感受,一旦进入某个项目,从开发,到发布生产,到hotfix,到后期维护,那基本都有你的份,正在开发某个feature,老板突然跳出来说让你做生产商的hotfix更是家常便饭,面对这种情况,使用Git的我们通常有两种解决方案:草草提交未完成的feature,然后切换分支到hotfix

gitstash|gitstashpop暂存工作内容,然后再切换到hotfix

第二种方式较第一种还好很多,可是面对下面这些场景,stash依旧不是很好的解决方案

我们面对的场景

正在main分支上跑很长时间的测试,切换到hotfix或feature,测试就会中断

项目非常大,频繁地切换索引,成本非常高

在几年前release的旧版本,设置和当前不一样,IDErestructure适配切换也会带来很大的开销

切换分支,需要重新设置相应的环境变量,比如dev/qa/prod

需要切换到同事的代码,帮助调试代码复现问题

有的同学想到,gitclone多个repo不就可以了吗?这是解决上述问题的一个方法,但背后同样隐藏着很多问题:多个repo的状态是不好同步的,比如没办法快速cherry-pick,一个repocheckout的分支,另外一个repo需要重新checkout

githistory/log是重复的,当项目历史非常长,.git文件夹下的内容是非常占用磁盘空间的

同一个项目,多个repo,不易管理

那如何做才能满足这些特殊场景,又不出现上述这些问题呢?git-worktree

其实,这是Git2015年前就开始支持的功能,却很少有人知道它,git-worktree的使用非常方便,在终端输入:gitworktree--help

就可以快速看到帮助文档说明:

用简单的话来解释git-worktree的作用就是:仅需维护一个repo,又可以同时在多个branch上工作,互不影响上面红色框线命令有很多,我们常用的其实只有下面这四个:gitworktreeaddgitworktreelistgitworktreeremovegitworktreeprune

在展开说明之前,需要和大家普及两个你可能忽视的Git知识点:默认情况下,gitinit或gitclone初始化的repo,只有一个worktree,叫做mainworktree

在某一个目录下使用Git命令,当前目录下要么有.git文件夹;要么有.git文件,如果只有.git文件,里面的内容必须是指向.git文件夹的

第二句话感觉挺绕的,下面用例子说明,就很容易明白了gitworktreeadd

当前项目目录结构是这样的:.└──amend-crash-demo1directory

cdamend-crash-demo运行命令gitworktreeadd../feature/feature2_amend-crash-demogit:gitworktreeadd../feature/feature2PreparingworktreeHEADisnowat82b8711addmainfile

重新看目录结构.├──amend-crash-demo└──feature└──feature23directories

该命令默认会根据HEAD所在的commit-ish创建一个名为feature2的分支,分支磁盘位置如上面结构所示cd../feature/feature2/会发现,这个分支下并不存在.git文件夹,却存在一个.git文件,打开文件,内容如下:gitdir:/Users/rgyb/Documents/projects/amend-crash-demo/.git/worktrees/feature2

到这里,你再理解一下上面的知识点2,是不是就清晰许多了呢?接下来,你就可以在feature2分支上做一切你想做的内容了,和mainworktree互不干扰一般情况下,项目组都有一定的分支命名规范,比如feature/JIRAID-Title,hotfix/JIRAID-Title,如果仅仅按照上面命令新建worktree,分支名称中的/会被当成文件目录来处理gitworktreeadd../hotfix/hotfix/JIRA234-fix-naming

运行完该命令,文件目录结构是这样的.├──amend-crash-demo├──feature│└──feature2└──hotfix└──hotfix└──JIRA234-fix-naming6directories

很显然这不是我们想要的,这时候我们就需要-b参数的支持了,就像gitcheckout-b一样执行命令:gitworktreeadd-bhotfix/JIRA234-fix-naming../hotfix/JIRA234-fix-naming

再来看一下目录结构.├──amend-crash-demo├──feature│└──feature2└──hotfix├──JIRA234-fix-naming└──hotfix└──JIRA234-fix-naming7directories

进入JIRA234-fix-naming目录,默认是在hotfix/JIRA234-fix-naming分支上

worktree建立起来很容易,不加管理,项目目录结构肯定乱糟糟,这是我们不想看到的,所以我们需要清晰地知道某个repo都建立了哪些worktreegitworktreelist

所有的worktree都在共用一个repo,所以在任意一个worktree目前,都可以执行如下命令来查看worktree列表gitworktreelist

执行完命令后,可以查看到我们上面创建的所有worktree信息,mainworktree也会显示在此处/Users/rgyb/Documents/projects/amend-crash-demo82b8711/Users/rgyb/Documents/projects/chore/chore8782898/Users/rgyb/Documents/projects/feature/feature282b8711/Users/rgyb/Documents/projects/hotfix/hotfix/JIRA234-fix-naming82b8711/Users/rgyb/Documents/projects/hotfix/JIRA234-fix-naming82b8711

worktree工作做完了,也是要及时删除的,否则也会浪费很多磁盘空间gitworktreeremove

这个命令很简单了,worktree的名字叫什么,直接就remove什么就好了gitworktreeremovehotfix/hotfix/JIRA234-fix-naming

此时,分支名弄错的那个hotfix就被删掉了/Users/rgyb/Documents/projects/amend-crash-demo82b8711/Users/rgyb/Documents/projects/chore/chore8782898/Users/rgyb/Documents/projects/feature/feature282b8711/Users/rgyb/Documents/projects/hotfix/JIRA234-fix-naming82b8711

假设你创建一个worktree,并在里面有改动,突然间这个worktree又不需要了,此刻你按照上述命令是不能删掉了,此时就需要-f参数来帮忙了gitworktreeremove-fhotfix/JIRA234-fix-naming

删除了worktree,其实在Git的文件中,还有很多administrative文件是没有用的,为了保持清洁,我们还需要进一步清理gitworktreeprune

这个命令就是清洁的兜底操作,可以让我们的工作始终保持整洁总结

到这里,你应该理解,整个git-worktree使用流程就是下面这四个命令:gitworktreeaddgitworktreelistgitworktreeremovegitworktreeprune

你也应该明白gitworktree和gitclone多个repo的区别了。只维护一个repo,创建多个worktree,操作间行云流水我的实践:通常使用gitworktree,我会统一目录结构,比如feature目录下存放所有feature的worktree,hotfix目录下存放所有hotfix的worktree,这样整个磁盘目录结构不至于因为创建多个worktree而变得混乱在磁盘管理上我有些强迫症,理想情况下,某个repo的worktree最好放在这个repo的文件目录里面,但这就会导致Gittrack新创建的worktree下面的所有文件,为了避免Gittrackworktree的内容,来来回回修改gitignore文件肯定是不合适的,

git切换分支的命令

2、git reset head怎么回去

在git的一般使用中,如果发现错误的将不想提交的文件add进入index之后,想回退取消,则可以使用命令:git reset HEAD ...,同时git add完毕之后,git也会做相应的提示,比如:

引用

git reset [--hard|soft|mixed|merge|keep] [或HEAD]:将当前的分支重设(reset)到指定的或者HEAD(默认,如果不显示指定commit,默认是HEAD,即最新的一次提交),并且根据[mode]有可能更新index和working directory。

下面列出一些git reset的典型的应用场景:

A) 回滚add操纵

引用

(1) 编辑文件frotz.c, filfre.c,做了些更改,并把更改添加到了index

(2) 查看邮件,发现某人要你pull,有一些改变需要你merge下来

(3) 然而,你已经把index搞乱了,因为index同HEAD commit不匹配了,但是你知道,即将pull的东西不会影响已经修改的frotz.c和filfre.c,因此你可以revert这两个文件的改变。revert后,那些改变应该依旧在working directory中,因此执行git reset。

(4) 然后,执行了pull之后,自动merge,frotz.c和filfre.c这些改变依然在working directory中。

B) 回滚最近一次commit

引用

(1) 当提交了之后,你又发现代码没有提交完整,或者你想重新编辑一下提交的comment,执行git reset --soft HEAD^,让working tree还跟reset之前一样,不作任何改变。

HEAD^指向HEAD之前最近的一次commit。

(2) 对working tree下的文件做修改

(3) 然后使用reset之前那次commit的注释、作者、日期等信息重新提交。注意,当执行git reset命令时,git会把老的HEAD拷贝到文件.git/ORIG_HEAD中,在命令中可以使用ORIG_HEAD引用这个commit。commit 命令中 -a 参数的意思是告诉git,自动把所有修改的和删除的文件都放进stage area,未被git跟踪的新建的文件不受影响。commit命令中-c 或者 -C 意思是拿已经提交的commit对象中的信息(作者,提交者,注释,时间戳等)提交,那么这条commit命令的意思就非常清晰了,把所有更改的文件加入stage area,并使用上次的提交信息重新提交。

C) 回滚最近几次commit,并把这几次commit放到叫做topic的branch上去。

引用

(1) 你已经提交了一些commit,但是此时发现这些commit还不够成熟,不能进入master分支,但你希望在新的branch上润色这些commit改动。因此执行了git branch命令在当前的HEAD上建立了新的叫做 topic/wip的分支。

(2) 然后回滚master branch上的最近三次提交。HEAD~3指向当前HEAD-3个commit的commit,git reset --hard HEAD~3即删除最近的三个commit(删除HEAD, HEAD^, HEAD~2),将HEAD指向HEAD~3。

D) 永久删除最后几个commit

引用

(1) 最后三个commit(即HEAD, HEAD^和HEAD~2)提交有问题,你想永久删除这三个commit。

E) 回滚merge和pull操作

引用

(1) 从origin拉下来一些更新,但是产生了很多冲突,你暂时没有这么多时间去解决这些冲突,因此你决定稍候有空的时候再重新pull。

(2) 由于pull操作产生了冲突,因此所有pull下来的改变尚未提交,仍然再stage area中,这种情况下git reset --hard与 git reset --hard HEAD意思相同,即都是清除index和working tree中被搞乱的东西。

(3) 将topic/branch合并到当前的branch,这次没有产生冲突,并且合并后的更改自动提交。

(4) 但是此时你又发现将topic/branch合并过来为时尚早,因此决定退滚merge,执行git reset --hard ORIG_HEAD回滚刚才的pull/merge操作。说明:前面讲过,执行git reset时,git会把reset之前的HEAD放入.git/ORIG_HEAD文件中,命令行中使用ORIG_HEAD引用这个commit。同样的,执行pull和merge操作时,git都会把执行操作前的HEAD放入ORIG_HEAD中,以防回滚操作。

F) 在被污染的working tree中回滚merge或者pull

引用

(1) 即便你已经在本地更改了一些你的working tree,你也可安全的git pull,前提是你知道将要pull的内容不会覆盖你的working tree中的内容。

(2) git pull完后,你发现这次pull下来的修改不满意,想要回滚到pull之前的状态,从前面的介绍知道,我们可以执行git reset --hard ORIG_HEAD,但是这个命令有个副作用就是清空你的working tree,即丢弃你的本地未add的那些改变。为了避免丢弃working tree中的内容,可以使用git reset --merge ORIG_HEAD,注意其中的--hard 换成了--merge,这样就可以避免在回滚时清除working tree。

G) 被中断的工作流程

在实际开发中经常出现这样的情形:你正在开发一个大的feature,此时来了一个紧急的bug需要修复,但是目前在working tree中的内容还没有成型,还不足以commit,但是你又必须切换的另外的branch去fix bug。请看下面的例子

引用

(1) 这次属于临时提交,因此随便添加一个临时注释即可。

(2) 这次reset删除了WIP commit,并且把working tree设置成提交WIP快照之前的状态。

(3) 此时,在index中依然遗留着“snapshot WIP”提交时所做的uncommit changes,git reset将会清理index成为尚未提交"snapshot WIP"时的状态便于接下来继续工作。

(H) Reset单独的一个文件

假设你已经添加了一个文件进入index,但是而后又不打算把这个文件提交,此时可以使用git reset把这个文件从index中去除。

引用

(1) 把文件frotz.c从index中去除,

(2) 把index中的文件提交

(3) 再次把frotz.c加入index

(I) 保留working tree并丢弃一些之前的commit

假设你正在编辑一些文件,并且已经提交,接着继续工作,但是现在你发现当前在working tree中的内容应该属于另一个branch,与这之前的commit没有什么关系。此时,你可以开启一个新的branch,并且保留着working tree中的内容。

引用

(1) 这次是把在branch1中的改变提交了。

(2) 此时发现,之前的提交不属于这个branch,此时你新建了branch2,并切换到了branch2上。

(3) 此时你可以用reset --keep把在start之后的commit清除掉,但是保持working tree不变。

git切换分支的命令

3、程序员每周打包文件需要多久完成

30到40分钟。程序员每周打包文件时需要切换分支开发调试和bugfix,切换分支之后,整个IOS工程打包时间在30到40分钟。程序员是从事程序开发、程序维护的基层工作人员。

4、【重新问】很少有机会和喜欢的女孩见面,该怎样和她沟通?

我和自己喜欢的女孩不能经常见面,近2个月她也基本不上Q

所以上来求教大家,恳请各位给我些在这种情况下和女孩的沟通技巧(如果发短信和她自然联系的话,我不知道该说些什么好。主要不想让她感受到我追她的压力,让她觉得自然、轻松)

PS:我和她是属于比较好的朋友,一年前我向她表白过,被拒绝了,不过我们还是保持着朋友关系

还有就是:如果在女方把我当朋友的前提下,我如果一段时间没有和她联系(大概20天左右),那她会以为我把她忘了吗?这种情况下女方会有这种心态吗?

求教 谢谢

上一篇:没有了
技术干货
零基础学习
行业多年深耕,从这报名,学费立减800
  • 岳同学180****1241刚刚成功领取
  • 胡同学134****6431刚刚成功领取
  • 李同学150****6122刚刚成功领取
  • 张同学136****2231刚刚成功领取
  • 孙同学178****5521刚刚成功领取
  • 齐同学156****7788刚刚成功领取
猜你喜欢
查看更多
相关推荐
查看更多
现在学习,我的薪资能达到多少?
立即报名

联系我们:

Q:2638333071

鄂ICP备2023015464号