一、远程名称(Remote Name)
在 Git 中,其实无论是 origin ,还是 upstream 并没有特殊的含义,但由于被广泛使用,因此它们有了约定俗成、众所周知的含义。
如果我跟你说,以下两条命令是完全等效的,你是不是就差不多猜得出 origin 表示什么了?
$ git push origin master
$ git push https://gitee.com/jsxztshaohaibo/git-usage-test.git master
是的,跟你猜的一样:没有区别。
1.1 Origin
我们用示例来讲...
先在本地随意创建一个 Git 仓库 git-test ,然后新增一个 ReadMe.md 文件,接着 Commit 一下
以上都没问题!接着,我们试着 Push 一下:
可以看到 git push 失败了.
原因很容易理解:我们只是在本地创建一个仓库,并没有将本仓库与远程仓库进行关联,因此 Git 无法理解是将其推送至哪个代码托管平台,然后也不知道是平台上的哪个远程仓库,是 GitHub 平台的,还是 GitLab 平台的?是平台上的 React 仓库,还是 Vue 仓库,还是别的什么仓库?Git 统统都不知道,那么自然是无法替你办事了。
因此,我们需要做的就是把本地的 git-test 仓库与远程仓库关联一下(请注意,一个本地仓库是可以关联多个远程仓库的):
$ git remote add origin <repo_address>
这里用到了?origin ,我们先不管为什么用?origin ,用其他(比如?main、abc )行不行的问题?(答案是可以的)
关联之后,再进行 Push 就能成功了。
?
那么?git remote add ?内部做了什么默默无闻的工作呢,它其实是往?.git/config ?中写入了一个叫?[remote "origin"] ?配置:
[core]
repositoryformatversion = 0
filemode = false
bare = false
logallrefupdates = true
symlinks = false
ignorecase = true
[remote "origin"]
url = https://gitee.com/jsxztshaohaibo/git-usage-test.git
fetch = +refs/heads/*:refs/remotes/origin/*
如果你本地的仓库是通过 git clone 下来的,Git 会默认将远程仓库命名为 origin ,自动帮你关联上远端仓库(可在 .git/config 文件中看到已有 [remote "origin"] 配置项了),因此 Commit 之后就能直接 Push 了。
我们来分析一下,这配置表示什么意思。
[remote "origin"]
url = https://gitee.com/jsxztshaohaibo/git-usage-test.git
fetch = +refs/heads/*:refs/remotes/origin/*
通过 git remote add 命令,添加了一个叫做 origin 的远程名称(Remote Name),
- 其中
url 参数,表示该远程名称对应的远程仓库地址。 - 其中
fetch 参数分为两部分,以冒号 : 进行分割,冒号左边表示本地仓库文件夹,冒号右边表示远程仓库在本地的副本文件夹。里面的加号 + 表示往里面添加数据的意思。
当使用 git fetch origin 时,Git 将远程仓库下的所有分支拉取到本地的 refs/remotes/origin/ 目录下,然后 git merge 时,它会把 refs/remotes/origin/ 目录下的对应分支合并到 refs/heads/ 目录下对应分支上。
那么 origin 究竟是什么呢?
请注意,origin ?只是一个名称(别名),用于指向远程仓库。这个别名是可以自行修改的,比如命名为?foo 、bar ?等。使用别名好处是「简单、方便、好记(就像网址和IP的关系)」。
比起记住一个远程仓库地址,别名实在方便太多了。将?origin ?作为远程仓库的别名是较为普遍的做法,况且所有代码托管平台默认就是?origin 。
回到文章开头的例子
$ git push origin master
# 相当于(其中 origin 指向了 https://gitee.com/jsxztshaohaibo/git-usage-test.git 远程仓库)
$ git push https://gitee.com/jsxztshaohaibo/git-usage-test.git master
以上两种方式是完全等价的,这样就更能体现别名的优势了,简洁很多。
既然是别名,自然是可以修改的,主要有以下命令:
# 新增远程名称(一个本地仓库,可以关联多个远程仓库)
$ git remote add <remote-name> <repo-address>
# 删除已存在远程名称(只会移除本地仓库与远程仓库的管理,不会删除远程仓库的代码哈)
$ git remote rm <remote-name>
# 更新远程名称关联的远程仓库
$ git remote set-url <remote-name> <repo-address>
# 修改远程名称(也可以先删除再添加)
$ git remote rename <old-remote-name> <new-remote-name>
比如使用 git remote set-url 修改关联的远程仓库地址:
然后,我们修改下远程名称为?main ,也是可以的:
?接着,我们随意修改个文件 Push 一下,是这样的?git push main?master :
?到这里,你应彻底明白?origin ?是什么了吧。
前面提到过,一个本地仓库是可以关联多个远程仓库的,举个例子:
我们新建一个远程仓库的地址,给新的仓库地址 起一个别名 origin
$ git remote add origin https://gitee.com/jsxztshaohaibo/git-usage-test.git
?从图中可以看到,别名?foo ?和?bar ?分别指向了两个不同的远程仓库,然后使用方法与?origin ?是相同的,比如:
# 将本地的 master 分支推送至 main 对应的远程仓库(git-usage-test-02.gt)
$ git push main master
# 将本地的 master分支推送至 origin 对应的远程仓库(git-usage-test.git)
$ git push origin master
?二、远程分支(Remote Branch)
常说的「远程分支」是远程仓库对应分支在本地的一个副本。比如常见的 origin/master 、origin/main 、origin/develop 等都是远程分支,可以在 .git/refs/remotes/ 目录下看到。
# 查看所有本地分支
$ git branch
# 查看所有远程分支(-r 是 --remotes 的简写)
$ git branch -r
# 查看所有本地分支和远程分支(-a 是 --all 的简写)
$ git branch -a
?可以通过?git branch -r ?命令查看所有的远程分支:
?
上一节,我们介绍了远程名称只是一个代号、别名,是可以修改的。那么我们将 Remote Name 由 origin 修改为 foo ,那么远程分支,会不会由 origin/main 变为 foo/main 呢?
?将远程名称修改之后,远程分支名称也会跟着改变的。
三、拉取最新代码
通常,拉取最新代码的过程是这样的:?
-
通过 git fetch 拉取代码的过程:先读取 .git/config 文件里面的配置 [remote <remote-name>] ,将里面的所有(因为 fetch 并没有指定其中一个或多个远程仓库)远程名称对应仓库的分支下载到本地,并放在 .git/refs/remotes/<remote-name>/ 目录下。 比如 git fetch origin main 会创建或更新 .git/refs/remotes/origin/main 的文件,此时通过 git branch -r 就能看到一个 origin/main 的分支。但注意,我们使用的时候还是用 origin/main 而不是 remotes/origin/main 哦。 -
有时候,我们可能会通过 git diff 命令来对比本地分支与远程分支的一些信息,才决定要不要合并。比如,git diff main origin/main 。 -
通过 git merge 或 git rebase 来进行分支合并。比如 git merge origin/main ,表示将远程分支 origin/main 合并至本地分支 main 中。
也可以直接使用 git pull 命令,其实包括了 git fetch 和 git merge 两个过程。请注意 git fetch 并不会修改「本地分支」的代码。
细心的同学可能会发现,refs/remotes/origin/ 目录下,相应的分支文件记录的只是一个 Commit-ID (SHA-1),比较特殊的是 HEAD 文件(即 origin/HEAD 分支)记录的是 ref: refs/remotes/origin/main 的东西,它始终指向默认远程分支。
四、git 根据tag创建分支
现在主分支上有一个tag为v1.0.0,主分支的名字为master.
?1.执行:git origin fetch ?获得最新.
?2.通过:?git branch newbranch tagName 创建新分支
git branch newbranch v1.0.0.
?会以tag v1.0.0创建新的分支newbranch;
?3.再通过??git checkout newbranch?切换到新的分支.?
git checkout newbranch
4.通过 git push origin newbranch 把本地创建的分支提交到远程仓库。
git push origin newbranch
执行完以后,远程仓库也会有新创建的分支了。
|