远程仓库(remote)
前面两章我们对于git的所有操作都是在本地进行的。这时我们需要一个远程的git仓库,它本质和本地仓库没有区别。
不同点在于远程仓库可以被多人同时访问使用,方便我们协同开发。在实际工作中,git服务器通常由公司搭建由内部
使用,或者是购买一些公共的私有git服务器。学习阶段,我们通常使用开放的公共git仓库。
目前常用的有两个:GitHub和Gitee(码云)
Github
右上角➕号 ----> New repository ----> Repository name* (库名) ---->选择public(公开)或者private(私有)
这样就创建好了一个仓库
怎么把仓库里的东西传进来
创建好了后它会提示你怎么做
这段文字就是教程(create a new repository on the command line)创建一个新仓库通过命令行
下面还有一段
( push an existing repository from the command line)push一个已经存在的仓库通过命令行
我们这里通过第二个演示
git remote add origin https://xxxxxxxx
# git remote add <remote name> <url>
git branch -M main
# 修改分支的名字为main(无关紧要的政治问题)
git push -u origin main
# git push 将代码上传到服务器上,这里的 origin 和第一条代码名字一样, main 和第二条代码名字一样
其中 remote 就是远程库的意思
origin 就是我们远程库的名字,名字可以随便起,一般来讲,主远程库的地址就叫origin,再后面就是我们远程库的地址
成功后就可以在github上看见自己的仓库内容了
远程库的操作
远程库的操作的命令
git remote
# 列出当前关联的所有远程库
git remote add <远程库名> <url地址>
# 关联远程仓库,但是主要的远程库一般叫origin
git remote remove <远程库名>
# 删除远程库
git remote -v
#origin origin (fetch)
#origin origin (push)
#上传和下载的地址,大功率是一个地址
git push -u <远程库名> <你的本地分支名>
# 向远程仓库推送代码并和当前分支关联
# -u 给本地分支绑定一个远程分支,只有第一次推送一个全新的本地分支到远程时才用
# 完整写法
git push <远程库名> <本地分支>:<远程分支>
# 如果你想推送给别的分支,只需改后面的远程分支
如果推送的时候很卡,这是正常的,我建议用SSH,可以不受代理影响,因为https基于账户认证,容易被网络、代理干扰
git remote set-url <远程仓库名> <新的仓库地址>
怎么判断成功了呢
git remote -v
##当显示由https://改变为@github.com:xxxx时就是成功了
做这一切的前提是你在GitHub已经有SSH密钥对
当你已经关联仓库后,并进行第一次上述完整操作,下一次你再想往仓库push,只需要git push就好了
模拟多人开发
创建一个文件夹,在终端打开,模拟其他人想克隆我的项目,从远程库下载代码
git clone <url>
在GitHub上,这个克隆地址就在进去仓库里面的绿色按钮(代码)里面
克隆下来后,文件的名字和库的名字一样,如果想换名字只需要在后面加名字就好了
git clone <url> <name>
注意
此时已经有三个库
github库,原来本地库,克隆库
此时我们可以进入克隆库,然后编写代码进行提交,这一切操作都是在克隆的本地库操作的,和远程库并没有关联
也就是说,在我们push之前,所以的操作都是在本地进行的,跟别的库没有任何关系
当你使用git push之后,你的代码就会与远程库产生关联,也就成功推送了
注意
如果你像上述我说的那样使用了SSH密钥,你需要检查git remote -v检查你是HTTPS推送还是SSH推送
如果是SSH推送,请看上面如何进行SSH推送,也很简单,步骤就一步。
在这个克隆库代码提交到远程后,就会有个问题,原来本地库代码是最新的代码吗?
如果,我们的原来本地库继续维护代码,创建文件,push代码。此时,你会发现出现以下问题
这是vscode的图形化提交
如果你使用的是命令行,会出现以下效果
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to '<url>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
这是因为我们本地库的版本低于我们远程库的版本,push默认推不上去。
如何解决
要想推送成功,必须先确保本地库和远程库版本一致
git fetch <指定库名>
如果不指定,就是向自动关联的库加载代码
Fetch,ajax里是发送请求的,在这可以理解成加载代码
完成这步之后,还不能push成功,这是因为fetch会从远程库下载所有更新到你的本地仓库,但是他不会将
代码和当前分支自动合并,也就是不会修改你当前使用的本地
使用fetch拉取代码后,必须要手动合并
合并是当前的本地分支去和远程的分支进行合并
远程分支和本地分支写法不同,本地分支直接写分支;远程分支我们必须先写 远程库的名字/远程分支
例如 git merge origin/main(这里的main是远程的main分支)
完成前面两步后,你就可以顺利进行push了
如果在合并过程中遇见冲突怎么解决
请看第二章处理方式,这就是普通处理冲突的方式
除了上述的fetch,还有一个pull
git pull
他会自动完成前面两步,从服务器上拉取代码,并自动合并,fetch + merge
当分支少的时候用pull,分支多的时候fetch更灵活
注意
push代码之前,一定要先从远程库拉取最新的代码
tag标签
你可以通过 git log查看提交日志,其中commit 有一串id,用来标识出每一次提交。
需求:当你写代码,提交了几次,并生成节点,如果你有需求想把代码回到原来状态,也就是旧的代码
这时就可以使用 git switch + ?
分支有名字,但是节点呢
commit e7cf348d1e9b81258fca9ffb65f88154738292c5
这一串就是他的节点名
但是也不用全写,写前几位就好,保持不重复就行
c此时他会报出
hint: If you want to detach HEAD at the commit, try again with the --detach option.
也就是你需要在节点名后面写
--detach
此时你的位置也就切换回你想要在的节点的那个位置
问题
在git当中除了有向分支那样的指针以外,还有一个HEAD头指针,这个头指针表示我们现在所处的位置
如果你此时 git log
此时: commit 7b1a9196a3f9f43e4c0e19f21ea43c6c08211573 (HEAD)
头指向在哪,我们的代码就会看到哪
但是
头指针应该在哪?头指针应该在某一个分支的位置
比如,我们现在有个main分支,我们的头指针就应该指向main,总之,头指针应该在分支上,而不是在某一个节点(commit)上
并且HEAD不是指向这个分支的名字,而是指向这个分支的引用,分支引用再指向最新的commit节点
所以
如果出现 commit 7b1a9196a3f9f43e4c0e19f21ea43c6c08211573 (HEAD)
说明我们处于分离头指针状态,那会出现什么问题呢
1.如果头在某一个节点上,我们无法判断它是在哪一个分支上
2.如果我们修改代码后,该放哪
虽然我们在分离头指针的情况下也能操作代码,但是这些操作不会出现在任何的分支上,所以注意不要在分离头指针的状态下操作仓库
解决
把头指针切换到正常的位置
git switch <分支名>
当你用 git status 出现 On branch main 说明正常了
但但是
我们的问题没有解决,我的需求是想把代码回到原来状态,怎么办呢?
如果我们非得回到后面的节点对代码进行操作,则可以选择创建分支后再操作
解读
上文我们说头指针应该在分支上,如果我们非得会到某一个节点,我们可以在那个节点上创建分支,我们再把头指针放上去即可
具体实现
git switch -c <分支名> <提交id>
表示,我们创建一个新分支,这个新分支指向 <提交id> 这个节点,然后切换过去。
刚才我们切换节点的时候,切换到了 <提交id>这个节点上,此时又会带来问题。我们切换节点是通过 commit id 切换的
假如我们的日志非常多,此时你会发现,你会发现找起来特别麻烦,此时我们就会迫切希望给我们提交日志打上标签
这样我们就能可以通过标签快速的切换到某个节点
git tag
如果你没有打标签,它什么都不会显示
如何打标签
git tag 版本
这个 版本是随便起的,你可以叫 v1.0 等等等等。这个命令意思是给我当前所在的节点打上标签名字叫 v1.0
此时再用 git log 就会显示:
commit 9b9fcac338cda395afe447dc9c09d6acf1fe5413 (HEAD -> main, tag: v1.0, origin/main)
如果我们想给别的节点打标签呢
git tag v2.0 <commit id>
打完标签后 ,以后我们想切换的时候可以直接写 版本,标签没有特殊效果,依旧需要解决分离指针头的问题
把标签推送到远程服务器
git push origin v2.0
或者
git push <远程仓库> --tags
# 推送所有标签
git tag -d 标签名
# 删除标签(本地)
git push <远程仓库> -- delete 标签名
# 删除远程标签