一、 引言:从单机游戏到网络游戏
在前面的章节中,我们所有的Git操作都是在本地完成的,这就像玩一个精彩的单机游戏。但Git真正的威力在于其分布式特性,它让代码协作从"单机模式"升级到了"网络游戏模式"。
想象一下,一个项目需要由分布在不同地点的多位开发者共同完成。如果只靠本地版本库,大家如何同步代码?如何知道队友做了什么修改?这时,我们就需要一个远程仓库作为中央枢纽,让所有开发者都能推送自己的更新,并拉取他人的更新。
本章我们将学习如何将本地仓库与远程仓库连接,实现最基本的推送和拉取操作,为后续的多人协作打下基础。
二、 理解分布式版本控制系统
2.1 分布式 vs 集中式
在深入远程操作之前,我们需要理解Git作为分布式版本控制系统 与传统的集中式版本控制系统(如SVN)的根本区别:
集中式版本控制系统(如SVN):
-
有一个单一的中央服务器,保存所有文件的版本历史。
-
开发者从中央服务器 checkout 代码到本地工作副本。
-
所有提交(commit)都必须连接到中央服务器才能完成。
-
缺点:单点故障。如果服务器宕机,所有人都无法工作;如果服务器磁盘损坏,且备份不及时,项目历史可能丢失。
分布式版本控制系统(如Git):
-
没有严格的中央服务器概念。每个开发者的本地仓库都是一个完整的镜像,包含完整的版本历史。
-
开发者可以在本地进行提交、创建分支等所有操作,无需网络连接。
-
远程仓库(如Gitee、GitHub上的仓库)只是多个仓库中的一个,通常被约定为"官方"版本库,用于交换大家的修改。
-
优势:
-
更强壮:任何一个人的仓库损坏,都可以从其他人那里复制恢复。
-
更灵活:可以离线工作,可以在多个远程仓库间协作。
-
2.2 远程仓库的角色
尽管Git是分布式的,但在实际团队协作中,一个公认的远程仓库(通常托管在Gitee、GitHub、GitLab等平台上)仍然至关重要,它的作用是:
-
备份:防止本地电脑故障导致代码丢失。
-
同步:作为团队成员间交换代码修改的中心节点。
-
发布:作为正式版本的发布源。
-
代码审查:通过Pull Request/Merge Request机制进行代码审核。
-
持续集成:与CI/CD工具集成,实现自动化测试和部署。
三、 使用Gitee管理远程仓库
我们将以国内的Gitee(码云)为例,演示远程仓库的基本操作。GitHub的操作逻辑基本一致。
3.1 新建远程仓库
-
登录Gitee:访问 https://gitee.com并登录你的账号。
-
创建新仓库 :点击页面右上角的
+号,选择"新建仓库"。 -
填写仓库信息:
-
仓库名称 :
git_teaching(可以自定义) -
路径:会自动生成,通常与仓库名一致。
-
仓库介绍:可选,填写"Git教学测试仓库"。
-
开源选择:选择"公开"或"私有"。公开仓库所有人都能看到,私有仓库需要授权才能访问。对于练习,可以选择"公开"。
-
初始化设置:可以选择"不选择",我们将手动推送本地代码。
-
-
点击创建:完成仓库创建。
创建成功后,你会看到一个空的仓库页面,并获得了这个仓库的访问地址,通常有两种协议:
-
HTTPS :
https://gitee.com/liu/git_teaching.git -
SSH :
git@gitee.com:liu/git_teaching.git
3.2 克隆远程仓库(Clone)
克隆是将远程仓库完整地下载到本地的操作。这是参与一个已有项目最常用的起点。
方法一:使用HTTPS协议克隆(最简单)
liu@139-159-150-152:~$ git clone https://gitee.com/liu/git_teaching.git
Cloning into 'git_teaching'...
Username for 'https://gitee.com': liu # 输入Gitee用户名
Password for 'https://liu@gitee.com': # 输入Gitee密码(或Token)
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
使用HTTPS方式每次推送(push)时都需要输入密码,稍显麻烦。为了方便,可以配置凭据缓存。
方法二:使用SSH协议克隆(推荐,更安全方便)
SSH协议使用密钥对进行认证,配置一次后即可免密操作。但需要先配置SSH公钥。
步骤1:检查并生成SSH Key
# 检查是否已有SSH密钥
liu@139-159-150-152:~$ ls -al ~/.ssh
id_rsa id_rsa.pub known_hosts # 如果看到类似文件,说明已存在
# 如果没有,则生成新的SSH Key
liu@139-159-150-152:~$ ssh-keygen -t rsa -C "your_email@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/liu/.ssh/id_rsa): # 直接回车用默认路径
Enter passphrase (empty for no passphrase): # 设置一个密码短语(可选,增加安全性)
Enter same passphrase again: # 再次输入密码短语
Your identification has been saved in /home/liu/.ssh/id_rsa.
Your public key has been saved in /home/liu/.ssh/id_rsa.pub.
生成成功后,id_rsa是私钥(绝不能泄露),id_rsa.pub是公钥。
步骤2:添加公钥到Gitee
-
查看并复制公钥内容:
liu@139-159-150-152:~$ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6...(很长一串)...liu@example.com -
登录Gitee,进入设置 -> SSH公钥。
-
在"添加公钥"页面,标题栏可自定义(如"My Laptop"),将复制的公钥内容粘贴到"公钥"栏中。
-
点击"确定"完成添加。可能需要输入密码验证。
步骤3:使用SSH克隆
liu@139-159-150-152:~$ git clone git@gitee.com:liu/git_teaching.git
Cloning into 'git_teaching'...
The authenticity of host 'gitee.com (212.64.63.215)' can't be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0wc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes # 输入yes确认
Warning: Permanently added 'gitee.com,212.64.63.215' (ECDSA) to the list of known hosts.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
克隆成功!现在你本地有了一个与远程仓库关联的本地仓库。
3.3 查看远程仓库信息
进入克隆下来的本地仓库,并查看远程信息:
liu@139-159-150-152:~$ cd git_teaching
liu@139-159-150-152:~/git_teaching$ git remote # 查看远程仓库别名
origin # 默认的远程仓库别名,指向你克隆的来源
liu@139-159-150-152:~/git_teaching$ git remote -v # 查看详细信息(verbose)
origin git@gitee.com:liu/git_teaching.git (fetch) # 抓取地址
origin git@gitee.com:liu/git_teaching.git (push) # 推送地址
origin是Git给远程仓库起的默认别名。
四、 远程仓库的基本操作
4.1 向远程仓库推送(Push)
现在,我们在本地仓库做一些修改,然后推送到远程仓库。
-
在本地进行修改并提交:
liu@139-159-150-152:~/git_teaching$ echo "My first remote push" > file.txt liu@139-159-150-152:~/git_teaching$ git add file.txt liu@139-159-150-152:~/git_teaching$ git commit -m "add file.txt via local" [master 7ce3183] add file.txt via local 1 file changed, 1 insertion(+) create mode 100644 file.txt -
推送到远程仓库:
git push命令用于将本地的分支更新推送到远程仓库。liu@139-159-150-152:~/git_teaching$ git push origin master Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) remote: Powered by GITEE.COM [GNK-6.4] To gitee.com:liu/git_teaching.git c6ce3f0..7ce3183 master -> master # 推送成功!命令格式:
git push <远程主机名> <本地分支名>:<远程分支名>-
如果本地分支名与远程分支名相同,可以省略冒号,简写为
git push origin master。 -
如果当前分支与远程分支存在追踪关系(通常克隆后自动建立),可以进一步简写为
git push。
-
现在刷新你的Gitee仓库页面,会发现 file.txt文件已经出现在远程仓库中!
4.2 从远程仓库拉取(Pull)
当你的队友向远程仓库推送了新的提交,你需要将这些更新拉取到本地,以保持同步。
模拟场景 :在Gitee网页上直接修改 README.md文件。
-
在仓库页面点击
README.md文件。 -
点击"编辑"按钮。
-
在文件末尾添加一行:"第一次在线修改内容"。
-
点击"提交"按钮,填写提交信息"online modify"。
在本地拉取远程更新:
git pull命令用于从远程仓库获取更新并合并到当前分支。
# 确保在本地git_teaching目录中
liu@139-159-150-152:~/git_teaching$ git pull origin master
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 1.02 KiB | 1.02 MiB/s, done.
From gitee.com:liu/git_teaching
* branch master -> FETCH_HEAD
7ce3183..60e6b0a master -> origin/master
Updating 7ce3183..60e6b0a
Fast-forward
README.md | 2 ++
1 file changed, 2 insertions(+)
# 验证本地文件已更新
liu@139-159-150-152:~/git_teaching$ cat README.md
...(原有内容)...
第一次在线修改内容 # 新增的内容!
拉取成功!git pull实际上是两个操作的结合:git fetch(获取远程更新) + git merge(合并到当前分支)。
五、 配置Git以便更好地工作
5.1 忽略特殊文件(.gitignore)
项目中总有一些文件不希望被提交到Git仓库,比如:
-
编译生成的二进制文件(如
.o,.exe,.class) -
依赖的库文件(如
node_modules/,__pycache__/) -
IDE配置文件(如
.vscode/,.idea/) -
包含敏感信息的配置文件(如数据库密码)
我们可以创建一个名为 .gitignore的文件,在其中列出要忽略的文件模式。
创建.gitignore文件:
liu@139-159-150-152:~/git_teaching$ vim .gitignore
示例内容:
# 忽略所有 .a 文件
*.a
# 但跟踪所有的 lib.a,即使你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 .doc 文件,但不包括 doc/ 目录下的 .doc 文件
*.doc
!doc/*.doc
# 忽略特定的文件
secret_password.txt
# 忽略操作系统自动生成的文件
.DS_Store
Thumbs.db
验证忽略效果:
liu@139-159-150-152:~/git_teaching$ touch secret_password.txt
liu@139-159-150-152:~/git_teaching$ touch lib.a
liu@139-159-150-152:~/git_teaching$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean # 被忽略的文件不会显示!
Git确实忽略了我们在 .gitignore中指定的文件。
5.2 给命令配置别名(Alias)
有些Git命令较长,我们可以为它们设置简短的别名,提高效率。
# 设置全局别名
liu@139-159-150-152:~/git_teaching$ git config --global alias.st status
liu@139-159-150-152:~/git_teaching$ git config --global alias.ci commit
liu@139-159-150-152:~/git_teaching$ git config --global alias.br branch
liu@139-159-150-152:~/git_teaching$ git config --global alias.co checkout
# 设置一个查看最后一次提交的别名
liu@139-159-150-152:~/git_teaching$ git config --global alias.last 'log -1'
# 现在可以使用别名了
liu@139-159-150-152:~/git_teaching$ git st # 等同于 git status
liu@139-159-150-152:~/git_teaching$ git last # 查看最后一次提交
commit 60e6b0a26f3853d4ec6dde904415b0e6c1dabcc6 (HEAD -> master, origin/master)
Author: liu <2689241679@qq.com>
Date: Fri May 12 17:27:06 2023 +0800
online modify
注意:对于初学者,建议先熟练使用原生命令,再考虑使用别名,以免混淆。
六、 总结
本章我们迈出了从本地开发到团队协作的关键一步:
-
理解分布式概念:明确了远程仓库在分布式系统中的角色和重要性。
-
掌握Gitee基本操作:学会了如何创建远程仓库、配置SSH密钥。
-
核心远程操作:
-
git clone:获取远程仓库的完整副本。 -
git push:将本地提交推送到远程仓库。 -
git pull:从远程仓库拉取更新并合并到本地。
-
-
实用配置技巧:
-
.gitignore文件:管理需要忽略的文件,保持仓库清洁。 -
命令别名:提高命令行操作效率。
-
现在你已经具备了基本的远程仓库操作能力。在下一篇中,我们将进入真正的多人协作开发场景,学习如何在团队中高效地使用分支、处理冲突、进行代码集成,这是Git在企业级开发中最核心的应用。