在复习SC的讲git指令的知识点时,对Git 上有关远程仓库与本地仓库交换数据的一些指令有了新的理解,之前无论是上课还是做实验对像git fetch,git pull,git push,git clone这样对远程仓库与本地仓库交换数据的指令一直不太懂,今天提交了实验,又恰巧复习到这,那么我就分享一下我对这几条指令的理解。
git clone:
git clone这条指令可以说是我们做实验时的第一步,从老师指定的github上的远程仓库克隆到本地,创建一个新的本地仓库。
克隆仓库是一种获取本地git仓库的方法。
克隆仓库的命令是 git clone <url>
。 比如,要克隆 Git 的链接库 libgit2
,可以用下面的命令:
$ git clone https://github.com/libgit2/libgit2
这条指令在本地当前目录下创建一个与这个远程仓库同名的本地仓库,上例就会创建一个名为libgit2
的本地仓库。这条指令会为你关联一个远程仓库,也就是我们克隆的这个远程仓库。Git 的 clone
命令会为你自动将其命名为 origin
, origin
就是我们关联的仓库的一个代号(可有git remove指令查看,详细的信息到Git - 远程仓库的使用 (git-scm.com)去查看),拉取(fetch)它的所有数据, 创建一个指向它的 master
分支的指针,并且在本地将其命名为 origin/master
。 Git 也会创建一个与 origin 的 master
分支在指向同一个地方的本地 master
分支,并将这个本地分支与origin/master
这样的远程分支进行关联,称为追踪远程分支,这样我们就有了在本地工作的分支基础。
git fetch:
在讲git fetch之前需要了解一下什么是远程分支。
远程引用是对远程仓库的引用(指针),包括分支、标签等等。 你可以通过 git ls-remote <remote>
来显式地获得远程引用的完整列表, 或者通过 git remote show <remote>
获得远程分支的更多信息。 然而,一个更常见的做法是利用远程跟踪分支。
远程跟踪分支是远程分支状态的引用。它们是你无法移动的本地引用。一旦你进行了网络通信, Git 就会为你移动它们以精确反映远程仓库的状态。请将它们看做书签, 这样可以提醒你该分支在远程仓库中的位置就是你最后一次连接到它们的位置。
它们以 <remote>/<branch>
的形式命名。 例如,如果你想要看你最后一次与远程仓库 origin
通信时 master
分支的状态,你可以查看 origin/master
分支。 你与同事合作解决一个问题并且他们推送了一个 iss53
分支,你可能有自己的本地 iss53
分支, 然而在服务器上的分支会以 origin/iss53
来表示。
以上是git指令使用手册中的对于远程分支的解释,其中较为重要的是这句话:远程跟踪分支是你无法更改和移动的本地引用,我对这句话的理解是:像使用fetch指令抓取远程仓库的数据信息到本地,这样算是做了一次网络通信,相当于小山村里来了一个邮递员带来了新的信息,这次通讯后像
origin/master
分支就会更新一次信息,相当于村里的新闻栏里更新了信息,但你不能动它,你若要用到这些文件,则必须自己手动将他们merge到自己要用的分支下(git merge origin/master
),或者创建一个跟踪这个远程分支的本地分支(git checkout -b <branch>
<remote>/<branch>
),相当于你拿个小本子,把村里的新闻栏里的信息抄到小本子上。
了解了远程分支后继续回到fetch。
如果要与给定的远程仓库同步数据,运行 git fetch <remote>
命令(例如使用 git fetch origin来从代号origin的远程仓库进行数据的抓取
)。 这个命令查找 “origin” 是哪一个服务器, 从中抓取本地没有的数据,并且更新本地数据库,移动 origin/master
指针到更新之后的位置。更新一次远程分支的数据信息。
但需要注意,git fetch并不会创建一个可编辑的副本(拷贝),这个已经在上面提到。fetch指令的本质我认为就是做一次网络通信,获得指定的远程仓库的信息。
git push:
在讲git push前同样要了解一下跟踪远程分支。
跟踪远程分支就是将一个远程跟踪分支与一个本地分支相关联起来,而远程跟踪分支又与一个真正的远程分支对应,这样就形成了一个本地分支可以与一个真正的远程分支相对应。
从一个远程跟踪分支检出一个本地分支会自动创建所谓的“跟踪分支”(它跟踪的分支叫做“上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支。
另一种建立这种联系的方法就是 git checkout -b <branch>
<remote>/<branch>
这条指令,它会自动将本地分支与远程分支相对应。这条指令还有很多更便捷的版本,可以在我在本文结尾处的链接中查看。
设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支, 你可以在任意时间使用 -u
或 --set-upstream-to
选项运行 git branch
来显式地设置。
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
我们继续回到git push。
git push <remote> <branch>
指令将我们的本地分支branch推送到远程仓库的与该本地分支相连的远程分支,更新他们。但是还有另一种git push的格式,可以让我们这个本地分支不关联远程分支就可以推送到某个远程分支上(并没有验证,只是个人理解。),如git push origin serverfix:awesomebranch
来将本地的 serverfix
分支推送到远程仓库上的 awesomebranch
分支。
git pull:
当 git fetch
命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。 然而,有一个命令叫作 git pull
在大多数情况下它的含义是一个 git fetch
紧接着一个 git merge
命令。 如果有一个像之前讲的那样设置好的跟踪分支,不管它是显式地设置还是通过 clone
或 checkout
命令为你创建的,git pull
都会查找当前分支所跟踪的服务器与远程分支, 从服务器上抓取数据然后尝试合并入那个远程分支。由于 git pull
的魔法经常令人困惑所以通常单独显式地使用 fetch
与 merge
命令会更好一些。
这里仅仅是我个人的理解,看git指令指导手册真的了解到了很多东西,但无法很好的表达出来,很有可能有错,希望大家批评指正。如果大家不明白的话,我建议大家去下方链接的网址亲自读一下git指令的指导书,真的很不错,认真读完会有很大收获!