问题
我们按照如下步骤pull代码是会出现错误的
1-在一个文件夹git init创建本地仓库
2-git remote 连接名字 连接地址url,如git remote origin xxx
3-git pull
提示:
tips:git branch可以查看当前本地所在分支
原因:我们虽然建立了一个仓库连接,但是这个仓库可能有多个分支,我们必须指定远程仓库的分支才可以进行代码合并。(如果我现有的项目就是从远程仓库clone下来的,就自动指定了)
git pull origin master
或者git pull origin head:master(这行和下面一行一样,因为默认head就是本地仓库的master)
获取git pull origin master:master(这是把本地仓库origin的master分支与远程仓库master绑定 )
两个是一个效果,其实底层分支的切换都是通过head来进行的
如果你不想每次都写远程仓库的分支,可以给本地分支绑定一个上游分支。绑定追踪后,pull和push都可以对应上了
上面就是总是将origin仓库提交到远程仓库的master分支上。(在github一般是main分支)
设置一次,以后每次只需要git pull即可,就不需要再指定分支了。
问题二
1-在git2.9版本后,当我们添加了远程仓库,在拉取的时候也指定了是拉取远程仓库的master,还是会提示一个refusing to merge,也就是拒绝合并代码。
2-因为git pull等于git fetch和git merge,这个时候其实代码已经从远程仓库拿到本地了,但是没有合并
3-为什么要这样,就是防止一些小白,乱pull一些东西下来,然后自己项目的代码和远程仓库代码一合并,结构完全看不明白了,多了很多对自己毫无用处的东西(git根据它的本地仓库和此远程仓库项目有无联系来判断,比如有无从本地提交一次东西到远程仓库,或者这个项目就是远程仓库clone的,当然也就有历史联系)。
4-如果我们就是要合并,可以加一行 –allow-unrelated-histories,也就是允许无关联历史
git pull –allow-unrelated-histories
仓库的交互公司开发流程
常见的开源协议
是否闭源:比如我的项目用了vue3的框架,我的项目是否可以不公开源码。
修改的文档放置版权说明:比如我用了vue3的框架,我每修改一处原先是vue的源码的页面,都要说一下这里的版权归属于vue开发团队。
广告用你的名字促销:如我的用vue3的项目,能不能宣传我的运行速度很快,是因为我用了vue框架。
问题
在github中,本地的分支需要和远程仓库的分支最好名称一样,不然尽管你用命令追踪 指定了匹配哪个分支,在push中还是可能有问题
为什么呢?
因为如果我们只git push,如上图默认为git push simple,也就是push当前本地仓库的分支,给和当前本地仓库分支相同的远程仓库分支,如果找不到直接报错。
我们虽然配置了上游为master,但是这个默认是simple
方法一:我们需要在git的config中再设置
git config push.default upstream (这里加–global可以全局,所有本地仓库都生效,不加的话只在当前本地仓库生效)
方法二:我们把命令写全即可
git push origin master:main
前面的master代表本地仓库的master分支,后面的main代表远程仓库的分支,github中默认就是main,如果我们写成master,github就会再生成一个master分支。
方法三:git config push.default current
把当前分支上传到远程服务器,远程服务器有相同名字分支就加上去,没有就自动创建一个。
git-tag-tag的使用过程
提示:我们必须先git tag v1.0给要提交的东西环境打了标签,(标签记录的是当前在本地仓库也就是被commit过的代码版本)才能git push origin v1.0
一次可以打多个tag,如git tag v1.0,git tag v1.1,git tag v1.2,推送的时候如果只加了tag如v1.0,如git push origin v1.0就会把tag1.0内的commit的内容提交;打的1.1和1.2标签不会生效,内容也不会被push;如果是git push origin –tags就会所有标签全部被打上,所有内容全部push
不加的话就正常上传全部本地仓库代码,远程仓库不会生成新的tag,但是本地tag的版本也会被保存,下次push可以带上此标签push。
当然你也可以删除掉这个不需要被远程仓库显示的本地tag,如下图命令
git的提交对象object
git master分支
master指向最新的最后一次提交,head默认指向master
创造一个分支的话,就是新添加了一个指针指向最后一次提交对象。
从master分支切换到另一个分支testing,也就是head指针从指向master变成指向testing
如上图在最后一次提交commit为333的时候创建一个testing,那么testing就会指向333
tag指向333是打了一个标签,是不会动的
这个时候我们又把分支切换会master,并又提交了两次分别为444,555,那么master会指向最后一次提交555,testing还是指向333,所以testing分支内是没有444和555的内容的
如果又转换到testing,然后提交了xxx和yyy就会如下图
变成了两条开发流程,master仓库是拿不到xxx和yyy的,testing仓库也拿不到444和555
切换分支或者tag的命令
git chekout master(分支名字)
git chekout v1.0.0(tag名字)
注意你tag切回去版本,只是为了出现bug创建新分支,是无法切换了tag继续开发代码并push的,会被拒绝。(因为如果给你push,那么此远程仓库tab这条分支的后续代码都会被覆盖丢失)
创造分支命令
git branch testing(新分支名)
查看当前拥有分支
git branch
创建分支同时切换分支
git checkout -b testing(新分支名)
为什么使用分支
如上图,当我们项目已经开发到了555,突然发现333出现了bug,那么我们就需要reset回到333的代码版本,然后创建新的分支hotfix,在新的分支修复bug,为什么不直接在原分支修改bug呢?
因为原分支的项目功能还在继续被其他同事开发,我们提交的东西不能扰乱它。还有bug需要反复修改的,你不可能同分支提交上去别人拿到的还是有bug,我们最好把自己的东西完全改好了,再合并分支。
最后当bug修复完成,然后再拉取切换到当前最新的项目分支,再合并分支。
合并分支
git merge hotfix
合并后会冲突,111和222和333是共同的,如上图
current change:只保留当前分支代码,也就是444,555
incoming change:保留被合并进来的分支的代码,那么原分支333以后的代码都会被删除
both change:两个分支代码都保留,就相当于相同的不变,不同的加起来
compare change:就是比较两个分支代码,让我们人为决定
如上图合并后,合并的commit同时指向555和fix_02
查看和删除分支
当我们一个分支已经被合并到了主分支上,那么就可以删除了
注意:移除的只是一个指针,比如原先的图,移除hotfix,只是让红色框的hotfix指针清除了,fix_01_02是照样存在的。
Git的工作流
日常开发都是在develop分支中,当develop中的一个版本非常稳定了,再合并到master分支
在日常开发中,如果有一个非常新颖的功能开发,但是不确定最终能不能实现或者使用,就再创造分支到topic中开发,最终如果实现和使用再合并到develop分支中。
下图工作流也很常用,feature就是topic,但是多了一个release发布版本测试。
git远程分支操作
1-git init创建仓库
2-git remote add origin xxx建立并命名远程仓库origin的连接
3-建立上游,让本地分支绑定远程仓库分支,git branch –set-upstream-to=origin/main
这个origin/main其实就是下载的远程仓库的main分支到了本地
我们直接建立上游是会有警告的,因为本地根本不知道,远程仓库的分支有origin/main
所以我们需要先执行git fetch把远程仓库分支下载到本地变成origin/main
4-git config push.default upstream 设置默认push使用上游绑定,而不是simple
其实了解了原理,我们怎么操作都可以,最简单的是直接clone项目,连接什么的都自动搞好了,不需要以上这些繁琐操作。但是不了解原理万一遇到问题了,我们自己就没法解决。
tips
如果远程仓库有多个分支,如master和feature,我们clone下来,默认会在master主分支上,进行命令git checkout feature即可进入feature分支。
分支合并merge和rebase的区别
第一个图
是merge合并experient和master,其中c5是合并的commit记录
第二个图
1-是先在分支experient中执行git rebase master就可以把新代码c4和老代码合并同一条线上(rebase会把用此命令的分支这里是experient,的最后一次commit这里就是c4的指向,指向 master的最后一次提交c3)
2-然后回到主分支master执行git merge experient,就可以让master也拥有c4实现合并。
永远不要在主分支中或者develop分支(经常被提交的分支)中用rebase,为什么如下图
如果我们在主分支这个经常被很多人提交拉取的分支用rebase,那么就会改变主分支dev的最后一次提交到feature,那么所有组员的提交记录指向就全部被改变了。