前言
Git 是开发过程中非常重要的一个工具,几乎是所有开发工作必须的,在本科阶段一知半解的,即使有 Git 的使用场景也没有深入去学习过。
看了许多 Git 教程和资料之后,在这里做个整理,提炼出最核心的原理,帮助你快速入门 Git。
但 Git 总归是个工具,需要动手实践才能快速掌握,建议所有学 Git 的都自己做个小实验,走一遍流程。
本系列文章的案例都是在 Windows 环境下运行的,需要安装 Git
目录
远程仓库
此前我们所有的操作都是在本地的,而 Git 真正的用途是在远程仓库中体现的,在网络中才能实现多人协作,例如大家在 Github 上面共同维护一个项目。
关于远程仓库的配置,本文就不赘述了,网络上有非常多的资料(Git 教程廖雪峰)。
远程仓库本文以 Github 举例,在实际情况中,对于不想公开的项目,也可以运行在自己搭建的 Git 服务器中。
在开始进入实例之前,先理解两个新概念:push
和 pull
顾名思义,push
是推,即把本地的修改推送到远程服务器中,而 pull
是拉,即把远程的仓库拉取到本地。这样一推一拉,就实现了服务器仓库和本地仓库的同步。
在这样的场景中,远程仓库实际上担任了主分支的角色,我们拉取到本地的是一个克隆的仓库,本质上就是一个分支,我们进行了修改之后,push
到远程仓库,就是对远程仓库的主分支进行合并。
有了这样的直观理解,我们就可以继续往下,从创建一个远程仓库开始吧!
下面的实例较为简略,在远程仓库操作这方面,已经存在很多现成的集成工具或 GUI 工具,不需要我们进行详细的命令操作,对于入门,只需要理解其命令的作用即可。
初始化远程仓库
命令 | 功能 |
---|---|
git clone | 克隆仓库至本地 |
git remote | 远程仓库相关操作 |
git push | 向远程仓库推送修改 |
初始化远程仓库有两种方式:远程拉取和本地创建
- 远程拉取就是在 Github 网页中,进行初始化仓库的操作,或是它已经是一个现成的仓库了,我们要拉取到本地进行后续的开发
- 而本地创建就是先在本地创建仓库,然后推送到远程服务器,即让服务器拷贝一份仓库,后续的开发就和远程拉取的仓库没什么区别了
在第一种情况下,假设远程已经完成了仓库的创建(关于如何在 Github 上创建仓库,本文不涉及),那么我们本地就需要克隆下来,命令如下:
git clone git@github.com:<username>/<reponame>.git
:这里 git@github.com
代表远程服务器是 Github,如果是其他服务器,内容会不一样。<username>
则是自己的用户名,reponame
是仓库名,这样就可以指向一个具体的仓库了。
在第二种情况下,Github 仍然要求我们先在网页上创建一个空仓库,然后再将本地的仓库克隆到空仓库中,命令如下:
git remote add origin git@github.com:<username>/<reponame>.git
:add
的意思是在本地添加一个远程的版本库,将本地的仓库与远程的仓库链接起来,后续的 push
才知道要 push
到哪。origin
实际上是个名字,可以任意修改,但约定俗成将远程仓库名设置为 origin
(这个名字只在本地有意义,看到 origin
就知道他是远程仓库)
完成了本地和远程仓库的绑定,我们就需要把本地仓库直接克隆到远程仓库中:
git push -u origin master
:-u
是一个选项,一般用于第一次推送,他将本地的 master
分支和远程的 master
分支关联起来,以后推送就不用指定要推送到哪个分支了(默认是 master
)
向远程仓库提交修改
关于本地仓库的修改,本文不再赘述,在本地仓库完成了 Commit 操作之后,就可以 Push 到远程仓库了,命令如下:
git push origin master
:由于此前已经进行分支的关联,所以现在不需要 -u
这个选项了,如果是克隆下来的仓库,会自动进行关联,也不需要这个选项。
origin
就是我们此前所关联的远程仓库,而 master
代表我们所要推送的本地分支,又因为我们此前进行了默认关联,所以本地的 master
推送上去是默认和远程的 master
分支进行合并的,如果需要和指定的远程分支进行合并,可以通过 git push origin master:<branchname>
的方式进行指定。当然,本地的分支也是可以更改的,可以提交任意我们想提交的分支,不一定是提交 master
。
从远程仓库拉取最新版本
命令 | 功能 |
---|---|
git fetch | 将更新下载到本地 |
git merge | 将修改同步到本地仓库 |
git pull | 下载并将修改同步到本地仓库 |
在多人协作的场景下,远程仓库被其他人更新了,此时我们需要从远程仓库拉取最新版本,同步到我们的本地仓库中,此时就需要用到拉取操作。
当远程仓库更新时,我们可以通过 git fetch orgin
命令,将远程仓库的更新都下载到本地(可以只下载某一个分支的更新),但此时修改还未真正同步到本地仓库,只是下载了更新。所以还需要对修改进行 merge
操作,将本地的分支和远程的分支进行合并。
此时
merge
操作的命令:git merge origin/master
,合并origin
中的master
分支到当前分支。
不过还存在一个更简单的命令,兼并了下载和合并的操作,那就是 pull
,他可以直接拉取更新并进行合并,将两个命令结合在一起。
此时
pull
操作的命令:git pull orgin master
,拉取origin
中的master
分支,并合并到当前分支。
解决冲突
不论是拉取还是推送,本质上都是将修改合并到仓库中,涉及到合并操作,那就不可避免会出现冲突的情况。
例如,我们想要从远程仓库更新代码,但此时我们已经对某个代码做了修改,且远程仓库也修改了这个代码,Git 不知道需要保存哪一个版本,只能向我们报出冲突信息。此时我们只能手动解决与远程仓库冲突的文件(暂存修改或其他手段),然后再去拉取远程仓库的更新。
又或者,两个人同时进行开发,另一个人已经将修改 Push 到远程仓库了,但你的本地仓库并没有拉取他的更新,此时我们进行 Push 就会被阻止,系统会要求我们先同步本地仓库,再进行 Push。
上述两种场景说明,在解决远程与本地版本库的问题时,无非都是先同步仓库,然后再提交修改。如果允许不同步版本库就提交修改,在多人协作中,就很容易覆盖其他人的修改。
从一个极端的情形来理解,本地的是一个很久远的原始仓库,我们想要提交一个修改,但远程仓库中 90% 的代码都和原来不一样了,我们没有拉取更新就推送,导致远程仓库的这个文件被我们覆盖,其中许多更新都丢失了,显然就不符合我们的需要。
所以 Git 必须要求我们,本地和远程的仓库版本是一致的才能进行推送,强制杜绝了发生这种事的可能性(经常是无意的)
结语
到这里,我们的 Git 之路就告一段落了,可以说掌握了这么多,已经跨入了 Git 的大门,但是说到底 Git 只是一个工具,具体如何使用,还是得靠我们自己。
这让我想起了前段时间了解到的一个哲学概念,「异化」,他说的是把手段当成目的,而使目的处于永远无法达到的状态。就比如学习 Git 只是为了更好进行团队开发的一个手段,学习 Git 并不是目的,我们不能将学习 Git 这件事异化,让学习 Git 这件事成为目的,而忽略了其实他是为了更好进行团队开发的这一根本初衷。
当然我相信学 Git 的人,大部分都不可能不去应用,一定是有这样的使用场景和需求才会去学,所以这个例子可能不太贴切,主要是为了告诉大家,Git 中的命令和操作选项有非常多,一开始没必要全学个遍,基础的学会了,复杂的需要的时候再学是完全可以的。
最后,本系列中的案例基本都是最简单的,但也最常用的,但具体如何在团队协作中使用 Git,这就是另一门学问了。
🎉🎉🎉完结撒花!🎉🎉🎉