需求:将本地一个非Git项目同远程的空仓库关联起来
*************************************************************************************************************************************************
① git init
将一个本地项目变为一个本地Git仓库,到本地项目目录下
git init:
git branch: 看一下本地有哪些分支:
竟然什么都没有,但是目录名明明后面有个(master)标记,先不管,进IDEA看:
也是显示有master的,那就先不管,这个问题后面再讨论,当作当前是再master分支下的。
接下来再远程仓库new 一个repository,将本地Git的SSH公钥添加进远程仓库,执行关联本地仓库和远程仓库的指令:
类似于:
试试:
什么反应也没有,并且远程分支好像没有什么变化。因为远程库的唯一分支叫master,而git remote add
是在远程仓库上新建一个分支,并且将本地此仓库同此分支关联起来,为了避免混淆,再试试在远程新建一个dev 分支,并将不本地分支(master)同其关联起来:
还是没反应,看看远程库:
远程库也还是一个分支,没有任何变化,奇了怪了!!
git branch -r
也看不见远程分支,也不报错,奇怪。
先不管了,默认此时已经同远程maste分支关联上,也同dev分支关联上了,去IDEA中操作:
有趣,看不见远程分支,先pull试试:
全是灰色的,无法pull,但是点击刷新试试:
出现了!!
勾选,pull一下:
push一下:
其实实测中,如果有时没有想起来先pull,直接进来就push,这里的push按钮根本就是灰色的,所以才回头去pull再push。先不管,这里先push,看一下远程库:
是25分钟之前的,远程库没有任何变化!
回看项目目录:
得,这时才想起来本地目录git init之后一直没有任何add commit操作,即本地面向远程仓库的repository一直是空的!!
所以去add commit就行了,这里为了批量add ,在项目目录下右击:
再批量commit:
此时可以更改不想提交得内容:
此时还没结束哦,再去push一下:
???(黑人问号脸)
到网上查了一下大概是因为当时git remote add master 和 git remote add dev了两下,得,此时本地和远程分支结构是这样的:(不要问我git branch是什么时候好的。。。)
看见了吧,远程有两个master分支,此时你push到master分支就会产生错误,无法识别是哪个master(自己挖的坑啊,哎)
当然,这也说明了当时git remote add master git@XXX命令是初始化本地“仓库”和远程“仓库”,不是在远程新建一个分支,然后让本地“仓库”关联它(这也不匹配啊),所以还是按照教程上来,git remote add origin git@XXX,这样就唯一了,以后只创建“分支”,而不是关联仓库,PS:关联仓库时会将远程库上的所有分支都放进仓库中,也就是加一层目录,添加分支的命令是:
git push origin master:dev
即在远程仓库origin中的master分支下创建dev分支,所以git remote add master git@XXX是初始化的!!!
这个问题搞明白了就好了,从头再来一遍:
项目目录下,git init —— git remote add git@xxx 进行关联
进IDEA,先add commit 在push,发现:
要先pull,再push:
嘤嘤嘤,又不行呢~
网上搜,得,知道了,因为git remote add git@xxx 只是将两个仓库进行了关联,对于本地master分支远程和origin/master分支仍然是认为没有关系的,所以用普通的pull命令会报错,可以使用:
git pull origin master --allow-unrelated-histories
参考:https://blog.youkuaiyun.com/u012145252/article/details/80628451评论区
命令行执行,竟然还要填一下为什么merge。。。填吧,可以了。
远程:
成功了!!,当然还有一点挺有趣的,更新时间为17分钟前,并不是本地库向远程库push的时间,貌似是本地commit的时间,经验证,正确。
另外,有个很有趣的问题,在本地新建分支并转向此分支后,用Git push时,Git会默认提交到远程同名分支,若没有的话会创建一个新分支,看例子:
远程库:
bash新建分支:
当然也可以使用IDEA右下角New Branch新建,一个原理:
这个checkout就是转向这个新分支:相当于git checkout -b shishikan
此时看IDEA果然已经转向了shishikan分支:
此时修改任意文件后add commit:
push:
上方竟然多出了一个shishkan (提示)New!
提交试试,看远程:
果然多了一个hsishikan分支,显然,IDEA“自作主张”地使用了:git push origin IDEA建的远程新分支:本地新分支 命令,所以要小心,特别是本地新建了一个分支时,push时要选择想要merge的分支名(第一次关联后之后是不会自动变的)
还记得之前git init之后git branch 不见本地分支的问题吗,现在再看这个问题。
其实git init是初始化一个仓库,并不是初始化一个分支,而系统的确默认当前工作在master分支上,故路径后方有个(master),
可以看到,创建本地另一分支localdev后,转向此分支,可以看到括号内的分支名改变了。(图只作验证,与本处要讨论的问题(看不见分支)无关)
为了追踪原问题(看不见分支),创建空的仓库实验一下:
一样的,git branch什么都没有,那么再去看看仓库里面什么情况:
git status还是可以看到当前 on branch master上的,但是git branch又没有,提示信息是个线索: No commits yet,
好,添加一个文件试试:
touch 1.txt:
看下status,加入:
此时再看下git branch:
有了,同样道理,可以想见,将之前testgit项目add commit新的文件就可以看到分支了,即这个分支只有第一次commit后才有。
远程分支什么时候才可见,有待探究
1.原理一样,fetch
git init //初始化本地仓库,但是本地分支没有初始化
git remote add git@xxx // 将本地仓库和远程仓库关联起来,但是对于本地分支来说,远程分支还未知
只有pull或者fetch之后本地才知道-r的结果。
理解: git branch 指令只是查本地数据(可以断开网络和远程新建分支但是不pull或fetch试试),而且查本地只看 repository接口(不看工作区)。
原理图:
git fetch origin --prune // 本地更新远程分支信息
评论区
经验证,理解正确
动手试试看:写一个todolist.txt
① 写一个"3",保存
git add todolist.txt
git commit todolist.txt -m "the first commit"
② 写一个"2",保存
git add todolist.txt
③ 写一个"1",保存
不操作
根据之前知识,知道:
看三个 git diff指令的区别:
git diff:
很明显:区别是-2,+1,即Working区和Stage区的difference
git diff Head:
很明显:区别是-3,+1,即Working区和本地Branch区的difference
git diff --cached(注意有两个杠):
很明显:区别是-3,+2,即Stage区和本地Branch区的difference
所以,那张图是正确的:
顺便说一句:
① 上面提到git diff Head是显示Working区和本地Branch区的difference,其实由git版本回退命令
git reset -hard HEAD/HEAD^/HEAD^^/HEAD~100
得到启发,那么git diff HEAD^是显示Working区和本地Branch区上一个版本的difference,经的确如此。那么由此可以比较之前任意版本(Branch区)和当前版本(Working区)的区别。(不难想到IDE继承的Git插件应该调用此API实现的功能)
② Working区可以看作面向用户的接口,版本库(即上面称为”本地Branch区“的东东)是面向远程仓库的接口。
官网给的图示:多了一个checkout:
Git SSH公钥生成方法:
① 运行Git GUI Here:
Help —— Show SSH Key(如果没有往下操作生成)
② Git Bash Here 命令行产生:
$ ssh-keygen -t rsa -C "youremail@example.com"
接下来到用户主目录里找到.ssh
目录,里面有id_rsa
和id_rsa.pub
两个文件,这两个就是SSH Key的秘钥对,id_rsa
是私钥,不能泄露出去,id_rsa.pub
是公钥,可以放心地告诉任何人。