20210113关于本地git与远程仓库关联的创建与取消(4)结合一个本地只能关联一个远程的特性思考旧mylib的情况 - ziyouzy/2021blog GitHub Wiki
其实也只是原则上的一个本地只能关联一个远程,也可以通过一些配置来实现一个本地关联两个远程,如同时关联github和gitee
我先试让一个新本地仓库去关联[email protected]:ziyouzy/test1.git从而确认这种一对一关系是单向的还是双向的
经测试,本机两个不同的git仓库只要ssh密钥一致,给同一个远程仓库添加关联是可以的
git remote -v后所显示的也完全一样
接下来尝试push操作
遇到了被github拒绝ssh登录的情况,这是因为id_rsa和id_rsa.pub这两个文件必须都在~/.ssh目录下,而不能是~/.ssh/github这样的子目录
修改后顺利解决了问题
到这一步,其实可以看出,虽然肯定会存在让~/.ssh目录下并存两个sshkey的方法,但是这并不符合配置逻辑
因此要明确一点,除非特殊情况一台宿主机/主机只拥有一个sshkey并存在于~/.ssh目录中
但是这个sshkey可以分别和github以及gitee绑定
但是生成sshkey的时候我用的是github@xxx或gitee@xxx这样的名字,所以似乎这里存在着逻辑问题而是应该这样:
zqy@oldThinkPadE480_20210113.com
同时也隐式表明了不能通过创造多个ssh-key的方式实现github与gitee这样的多远程仓库同步更新
不过通过配置ssh的config文件似乎也可以实现多个key对应多个远程仓库,但是似乎是把简单的问题复杂了,还是优先尝试一个key对应一个宿主机/主机的模式吧
之后,这篇文章解决了最为核心的问题:
https://blog.csdn.net/xiecheng1995/article/details/106570059
我们先来看两条语句:
git remote add origin [email protected]:ziyouzy/test1.git
git remote add origin [email protected]:ziyouzy/giteetest1.git
以及:
git push origin master
这些都是我之前执行过的
重点在于git remote add origin的“origin”
翻译成中文应该是"给xxx远程仓库添加一个名为origin的分支并将本地仓库与其关联"
因此我先做了个特殊的测试:
git remote add origin2 [email protected]:ziyouzy/test1.git
成功后,git push origin2 master和git push origin master都能成功的同步远程仓库
因此总结如下:首先,push和pull的操作都是分支对分支的操作,同时在语句内部已经明确表达了哪个本地分支与哪个远程分支关联
接下来我在具体说明下核心的两句话分别代表了什么
1.git remote add origin [email protected]:ziyouzy/test1.git
2.git push origin master
首先,第一句的origin其实只是给远程仓库[email protected]:ziyouzy/test1.git起了个简写名称,同时将本地仓库与[email protected]:ziyouzy/test1.git仓库相关联
origin这个名称是保存在本地仓库的配置文档中的,有些类似指针:origin->(指向了)[email protected]:ziyouzy/test1.git
第二句则可以翻译成:git push [email protected]:ziyouzy/test1.git local.master
也就是将本地的master分支推送到远程仓库账户的test1.git仓库中
而我之前所进行的git remote add origin2 [email protected]:ziyouzy/test1.git其实相当于又创建了一个指针并且同样指向了[email protected]:ziyouzy/test1.git
于是乎git push origin master翻译后为git push [email protected]:ziyouzy/test1.git local.master是没有区别的。
可以看出git的设计方式确实十分灵活,之前本以为是死板规则的各个语句,其实都是有健壮的逻辑思路的
继续聊:
在远程test1.git仓库的创建时默认创建了main分支,而我之后在本地执行的git push origin master操作,由于远程仓库没有master分支,只有main分支,于是单独创建了master分支
现在我执行git push origin2 main 从而验证我所说的话,不过这样似乎是不行的,因为本地并不存在名为main的分支,只存在名为master的分支
验证结果存在如下错误:
error: src refspec main does not match any.
error: failed to push some refs to '[email protected]:ziyouzy/test1.git'
于是在本地创建名为main的分支(git branch main)并重复该操作:
验证结果如下:
之后直接执行git push origin2 main报错:
To [email protected]:ziyouzy/test1.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to '[email protected]:ziyouzy/test1.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
可以看到系统尝试了将本地main分支与远程main分支进行同步操作,但是却失败了,提示建议现在commit一个版本在同步看看效果如何:
git checkout main(先切换)
git add -A
git commit -m "for new branch of main"
git push origin2 main
报了同样的错误:
To [email protected]:ziyouzy/test1.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to '[email protected]:ziyouzy/test1.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
这次确实是遇到了git使用方式的硬性规定了:
1.本地创建一个分支有两种方式:本地创建和拉取远程已实现关联仓库的某个分支
2.本地创建一个仓库只有一种方式:本地创建一个本地仓库(git init)
3.本地创建一个分支要先创建一个本地仓库,不过这个本地仓库不必需去做好与某个远程仓库的关联操作,如果需要拉去分支或上传分支(同步相关操作)则必须做好关联
如果想同步远程的某个分支,必须在本地先拉去该分支(pull),才能同步(push)
而不能之间在做好关联的本地仓库创建个只是名称一样的分支,强行push
再来思考一下关联的本质:
当执行了
git remote add origin [email protected]:ziyouzy/test1.git
git push origin master
后,远程才存在了master分支
因此得出结论,远程仓库里已有的分支不能被直接同步,但是如果push了一个远程不存在的分支,则远程会自动创建该分支,同时这个远程分支和本地分支的关系是可以实现同步操作的,或者说,创建后隐式打通了本地与远程的同步通道
再或者说,一个分支只能有一个“创造节点”,比如main,实在github上被创造的,而你在本地git init了一个仓库的同时隐式创造了master分支后所创建的子分支main,这两个main的创造节点显然是不同的,因此会同步失败
而第一句git push origin2 main之所以报错其实是因为在本地找不到main分支
第二句git push origin2 main报错则更为严重,我在尝试用一个虚假的main同步远程上真实的main,这两个的“创造节点”是不同的