第 7 篇:Git 远程仓库:clone、push、pull、ignore 和 tag

第 7 篇:Git 远程仓库:clone、push、pull、ignore 和 tag

文章目录

  • Git 远程仓库:clone、push、pull、ignore 和 tag
    • 一、本地仓库和远程仓库的关系
    • 二、创建远程仓库与克隆到本地
    • 三、HTTPS、SSH 和 SSH 公钥配置
    • 四、查看远程仓库信息
    • 五、push:把本地提交推送到远程
    • 六、pull:拉取远程更新
    • 七、.gitignore:忽略不该提交的文件
    • 八、给 Git 命令配置别名
    • 九、tag 标签管理:创建、查看、推送和删除
      • 1. 创建和查看标签
      • 2. 删除本地标签
      • 3. 推送标签到远程
      • 4. 删除远程标签
    • 十、本文总结

Git 远程仓库:clone、push、pull、ignore 和 tag

前面几篇主要围绕本地仓库展开:本地提交、版本回退、分支创建、分支合并、冲突解决等。这些内容解决的是“我自己电脑上的代码如何管理”的问题。

但真实开发里,代码通常不会只待在一台机器上。我们需要把代码同步到远程仓库,方便备份、换电脑继续开发,以及多人协作。于是就有了这一篇要整理的内容:远程仓库、克隆、推送、拉取、忽略规则、命令别名和标签管理

这一篇涉及的命令不少,但主线其实很简单:

  • git clone:把远程仓库下载到本地。
  • git remote:查看本地仓库关联了哪些远程仓库。
  • git push:把本地提交推送到远程。
  • git pull:把远程更新拉取到本地。
  • .gitignore:让 Git 忽略不需要管理的文件。
  • git tag:给重要提交打标签,常用于版本发布。

一、本地仓库和远程仓库的关系

本地仓库解决的是个人机器上的版本管理问题,远程仓库解决的是代码同步、备份和协作问题。

如果只有本地仓库,那么代码提交都在自己的电脑上。优点是速度快、离线也能工作;缺点也很明显:电脑坏了,代码可能丢;换电脑开发不方便;多人协作时也没有统一的代码交换位置。

远程仓库就是为了解决这些问题的。可以把它理解成一个放在服务器上的公共仓库,本地仓库和远程仓库之间通过网络同步提交:

  • 从远程仓库下载代码到本地,叫克隆
  • 把本地提交上传到远程仓库,叫推送
  • 把远程仓库的新提交同步到本地,叫拉取

Git 是分布式版本控制系统。分布式的意思是:每个人本地都有一份完整的仓库历史,而不是只保存当前文件快照

这和集中式版本控制有很大区别。集中式模式下,很多操作强依赖中央服务器;而 Git 本地就有完整历史,所以提交、查看日志、切换分支、回退版本等操作都可以在本地完成。远程仓库更多承担的是“交换代码”和“集中备份”的职责。

实际开发中常见流程是:

  1. 远程平台上先创建一个仓库。
  2. 开发者用git clone克隆到本地。
  3. 本地修改、addcommit
  4. git push把提交推送到远程。
  5. 别人推送了新代码后,用git pull拉取到本地。

二、创建远程仓库与克隆到本地

远程仓库可以放在 GitHub、Gitee、GitLab,或者公司内部自建平台上。创建仓库的流程大同小异:填写仓库名、仓库描述、可见性,然后创建即可。

新建远程项目仓库:

填写仓库基本信息:

创建成功后会进入仓库主页:

远程仓库通常还可以设置开源或私有:

创建好的仓库里也会有默认分支。很多平台现在默认叫main,有些仓库仍然叫master。下面示例沿用master

远程仓库创建好后,就可以复制仓库地址进行克隆:

克隆命令格式很简单:

git clone<远程仓库地址>

使用 HTTPS 地址克隆:

hyb@139-159-150-152:~$ git clone https://gitee.com/hyb91/git_teaching.gitCloning into'git_teaching'...Usernamefor'https://gitee.com':hyb91 Passwordfor'https://hyb91@gitee.com':remote:Enumerating objects:4,done.remote:Counting objects:100%(4/4),done.remote:Compressing objects:100%(4/4),done.remote:Total4(delta0),reused0(delta0),pack-reused0Unpacking objects:100%(4/4),1.80KiB|1.80MiB/s,done.hyb@139-159-150-152:~$ ls gitcode git_teaching hyb@139-159-150-152:~$ ls git_teaching/README.en.md README.md

克隆完成后,本地会多出一个仓库目录,例如这里的git_teaching

三、HTTPS、SSH 和 SSH 公钥配置

Git 常见的远程访问方式有两种:HTTPS 和 SSH。

HTTPS 的优点是上手简单,拿到仓库地址后通常就能克隆。缺点是推送时可能需要输入账号、密码或访问令牌,长期开发时不够方便。

SSH 的优点是配置好公钥后,日常推送和拉取更顺手,也更适合长期开发。缺点是第一次使用前需要生成 SSH Key,并把公钥配置到远程平台。

如果没有配置 SSH 公钥,直接使用 SSH 地址克隆,可能会失败:

hyb@139-159-150-152:~$ git clone git@gitee.com:hyb91/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 tocontinueconnecting(yes/no/[fingerprint])?yes Warning:Permanently added'gitee.com,212.64.63.215'(ECDSA)to the list of known hosts.git@gitee.com:Permissiondenied(publickey).fatal:Couldnotread from remote repository.Please make sure you have the correct access rightsandthe repository exists.

这个错误的核心是Permission denied (publickey),也就是远程平台没有识别到本机的 SSH 公钥。

生成 SSH Key 之前,可以先检查用户目录下是否已经有.ssh目录,以及是否存在id_rsaid_rsa.pub这类文件。如果没有,可以执行:

hyb@139-159-150-152:~$ ssh-keygen-t rsa-C"your_email@example.com"Generatingpublic/privatersa key pair.Enter file in which to save thekey(/home/hyb/.ssh/id_rsa):Enterpassphrase(emptyforno passphrase):Enter same passphrase again:Your identification has been saved in/home/hyb/.ssh/id_rsa Yourpublickey has been saved in/home/hyb/.ssh/id_rsa.pub The key fingerprint is:SHA256:sepKZUwKIXjJxYcot49tvOW+Aa+pEhdsRqVDFSmgQZo your_email@example.com

生成后查看.ssh目录:

hyb@139-159-150-152:~$ ls-a.ssh/...id_rsa id_rsa.pub known_hosts

这里要分清楚:

  • id_rsa是私钥,不能泄露
  • id_rsa.pub是公钥,可以配置到远程平台。

接着在远程平台里找到 SSH 公钥配置入口:

id_rsa.pub的内容添加进去:

配置完成后,再使用 SSH 地址克隆就可以正常进行:

hyb@139-159-150-152:~$ git clone git@gitee.com:hyb91/git_teaching.git Cloning into'git_teaching'...Warning:Permanently added the ECDSA host keyforIP address'212.64.63.190'to the list of known hosts.remote:Enumerating objects:4,done.remote:Counting objects:100%(4/4),done.remote:Compressing objects:100%(4/4),done.remote:Total4(delta0),reused0(delta0),pack-reused0Receiving objects:100%(4/4),done.hyb@139-159-150-152:~$ ls gitcode git_teaching hyb@139-159-150-152:~$ ls git_teaching/README.en.md README.md

如果是多人协作,每个人都需要把自己电脑上的公钥添加到远程平台账号里,这样每个人才能在自己的机器上正常推送代码。

四、查看远程仓库信息

当我们从远程仓库clone下来后,Git 会自动建立本地分支和远程分支的关联,并把远程仓库默认命名为origin

进入克隆后的仓库,使用git remote可以查看远程仓库名称:

hyb@139-159-150-152:~/git_teaching$ git remote origin

使用git remote -v可以查看更详细的远程地址:

hyb@139-159-150-152:~/git_teaching$ git remote-v origin git@gitee.com:hyb91/git_teaching.git(fetch)origin git@gitee.com:hyb91/git_teaching.git(push)

这里的fetch表示拉取地址,push表示推送地址。一般情况下它们相同,但也可以配置成不同地址。

origin不是固定魔法词,只是 Git clone 后默认给远程仓库起的名字。你也可以添加其他远程仓库,例如:

git remote add backup git@gitee.com:xxx/backup.git

不过初学阶段先记住:默认远程仓库通常叫origin

五、push:把本地提交推送到远程

克隆远程仓库后,本地就可以正常修改文件、提交文件。比如新增一个file.txt

hyb@139-159-150-152:~/git_teaching$ ls README.en.md README.md hyb@139-159-150-152:~/git_teaching$ vim file.txt hyb@139-159-150-152:~/git_teaching$ cat file.txt hello git

提交到本地仓库:

hyb@139-159-150-152:~/git_teaching$ git add.hyb@139-159-150-152:~/git_teaching$ git commit-m"create file.txt"[master7ce3183]create file.txt create mode100644file.txt

注意:commit只是提交到了本地仓库,远程仓库还不知道这个提交。要把本地提交同步到远程,需要使用git push

git push的完整格式是:

git push<远程主机名><本地分支名>:<远程分支名>

如果本地分支名和远程分支名相同,可以省略冒号后面的部分:

git push<远程主机名><本地分支名>

把本地master推送到远程origin/master

hyb@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),308bytes|308.00KiB/s,done.Total3(delta0),reused0(delta0)remote:Powered by GITEE.COM[GNK-6.4]To gitee.com:hyb91/git_teaching.git c6ce3f0..7ce3183 master->master

推送成功后,远程仓库里就能看到这次提交:

文件也已经出现在远程仓库中:

这里可以顺手记住一个常见错误:如果远程分支已经有了别人提交的新内容,而本地没有先拉取,直接推送可能会被拒绝。解决思路通常是先git pull,处理完冲突后再git push

六、pull:拉取远程更新

远程仓库可能会出现本地没有的新提交。比如有人在远程平台上直接修改了README.md

提交远程修改后:

此时远程仓库比本地仓库多一个提交。为了让本地保持最新,需要使用git pull

git pull的完整格式是:

git pull<远程主机名><远程分支名>:<本地分支名>

如果远程分支就是要合并到当前分支,可以省略冒号后面的本地分支:

git pull<远程主机名><远程分支名>

例如拉取远程master并合并到当前分支:

hyb@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%(3/3),done.remote:Total3(delta1),reused0(delta0),pack-reused0Unpacking objects:100%(3/3),1.02KiB|1.02MiB/s,done.From gitee.com:hyb91/git_teaching*branch master->FETCH_HEAD7ce3183..60e6b0a master->origin/master Updating7ce3183..60e6b0a Fast-forward README.md|2++hyb@139-159-150-152:~/git_teaching$ cat README.md...第一次修改内容

pull可以理解成两个动作的组合:

git fetch git merge

也就是说,它先从远程拿到最新提交,再把远程提交合并到当前分支。后面多人协作时,pull会非常常用,尤其是在推送前先拉一下,可以减少很多非快进推送和冲突问题。

七、.gitignore:忽略不该提交的文件

日常开发中,有些文件不应该交给 Git 管理,比如:

  • 编译生成的二进制文件。
  • IDE 自动生成的临时配置。
  • 日志文件。
  • 本地环境配置。
  • 含有密码、密钥、访问令牌的敏感文件。

这类文件可以写到.gitignore里,让 Git 自动忽略。

很多远程平台在创建仓库时可以帮我们生成.gitignore

如果创建仓库时没有生成,也可以在工作区根目录手动创建。

例如忽略所有.ini.so文件:

#My configurations:*.ini*.so

修改.gitignore后,也应该把它提交到仓库里:

hyb@139-159-150-152:~/git_teaching$ vim.gitignore hyb@139-159-150-152:~/git_teaching$ git add.hyb@139-159-150-152:~/git_teaching$ git commit-m"add .gitignore"[master97811ab]add.gitignore create mode100644.gitignore hyb@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),362bytes|362.00KiB/s,done.Total3(delta0),reused0(delta0)remote:Powered by GITEE.COM[GNK-6.4]To gitee.com:hyb91/git_teaching.git60e6b0a..97811ab master->master

验证忽略规则是否生效:

hyb@139-159-150-152:~/git_teaching$ touch a.so b.ini hyb@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 status没有提示新增a.sob.ini,说明.gitignore生效了。

如果某个文件被.gitignore忽略了,但你确实想强制添加,可以使用-f

git add-f<filename>

如果不确定某个文件为什么被忽略,可以使用git check-ignore检查:

hyb@139-159-150-152:~/git_teaching$ git check-ignore-v a.so.gitignore:3:*.so a.so

这个输出表示:.gitignore第 3 行的*.so规则忽略了a.so

再看一个常见规则:忽略所有以.开头的隐藏文件。

# 排除所有.开头的隐藏文件.*

但这样会把.gitignore自己也忽略掉。如果希望例外保留.gitignore,可以加上!

# 排除所有.开头的隐藏文件.*# 不排除.gitignore!.gitignore

.gitignore!文件名表示反向规则,也就是不要忽略这个文件。

还有一个很重要的细节:.gitignore只对尚未被 Git 跟踪的文件生效。如果某个文件已经被提交过,后来再写进.gitignore,Git 仍然会继续跟踪它。需要先把它从索引里移除:

git rm--cached<filename>

然后再提交.gitignore和索引变化。

八、给 Git 命令配置别名

有些 Git 命令比较长,Git 支持给命令配置别名。

比如把git status简化为git st

git config--global alias.st status

--global表示全局配置,这台电脑上的所有 Git 仓库都能使用。如果不加--global,就只对当前仓库生效。

配置后执行:

hyb@139-159-150-152:~/git_teaching$ git st On branch master Your branch is up to date with'origin/master'.nothing to commit,working tree clean

再比如配置一个git last,查看最后一次提交:

git config--global alias.last"log -1"

执行效果:

hyb@139-159-150-152:~/git_teaching$ git last commit97811abd1d43774aeb54fee32bf4fc76b2b08170(HEAD->master,origin/master,origin/HEAD)Author:hyb91<your_email@example.com>Date:Fri May1217:27:062023+0800add.gitignore

别名可以提高效率,但刚开始学 Git 时,我更建议先把完整命令多敲几遍。等命令含义真正熟悉后,再按自己的习惯配置别名。

九、tag 标签管理:创建、查看、推送和删除

标签tag可以理解为给某次提交起一个稳定、好记的名字。比如项目发布v1.0时,可以给对应提交打上v1.0标签。以后想查看或回到这个版本,就不用记一长串 commit id。

1. 创建和查看标签

先切换到需要打标签的分支:

hyb@139-159-150-152:~/git_teaching$ git branch*master

给当前最新提交打标签:

hyb@139-159-150-152:~/git_teaching$ git tag v1.0

查看所有标签:

hyb@139-159-150-152:~/git_teaching$ git tag v1.0

默认情况下,git tag v1.0会把标签打在当前最新提交上。如果想给历史提交打标签,需要先找到对应 commit id:

hyb@139-159-150-152:~/git_teaching$ git log--pretty=oneline--abbrev-commit97811ab(HEAD->master,tag:v1.0,origin/master,origin/HEAD)add.gitignore60e6b0a update README.md.7ce3183 create file.txt c6ce3f0 Initial commit

Initial commit对应的提交打标签:

hyb@139-159-150-152:~/git_teaching$ git tag v0.9c6ce3f0 hyb@139-159-150-152:~/git_teaching$ git tag v0.9v1.0

注意,git tag默认按字母顺序列出标签,不一定按创建时间排序。

查看某个标签的详细信息:

hyb@139-159-150-152:~/git_teaching$ git show v1.0commit97811abd1d43774aeb54fee32bf4fc76b2b08170(HEAD->master,tag:v1.0,origin/master,origin/HEAD)Author:hyb91<your_email@example.com>Date:Fri May1217:27:062023+0800add.gitignore diff--git a/.gitignore b/.gitignore...

还可以创建带说明的标签:

git tag-a<tagname>-m"说明文字"<commit_id>

例如:

git tag-a v1.0-m"release version 1.0"97811ab

2. 删除本地标签

如果标签打错了,可以删除本地标签:

hyb@139-159-150-152:~/git_teaching$ git tag v0.9v1.0hyb@139-159-150-152:~/git_teaching$ git tag-d v0.9Deleted tag'v0.9'(was c6ce3f0)hyb@139-159-150-152:~/git_teaching$ git tag v1.0

没有推送到远程的标签只存在本地,删除起来比较简单。

3. 推送标签到远程

标签默认不会随着普通git push origin master自动推送到远程。要推送某个标签,需要显式执行:

git push origin<tagname>

例如推送v1.0

hyb@139-159-150-152:~/git_teaching$ git tag v1.0hyb@139-159-150-152:~/git_teaching$ git push origin v1.0Total0(delta0),reused0(delta0)remote:Powered by GITEE.COM[GNK-6.4]To gitee.com:hyb91/git_teaching.git*[newtag]v1.0->v1.0

远程平台上也能看到这个标签:

如果要一次性推送所有本地标签:

git push origin--tags

4. 删除远程标签

如果标签已经推送到远程,删除时通常分两步。

先删除本地标签:

hyb@139-159-150-152:~/git_teaching$ git tag v1.0hyb@139-159-150-152:~/git_teaching$ git tag-d v1.0Deleted tag'v1.0'(was97811ab)

再删除远程标签:

hyb@139-159-150-152:~/git_teaching$ git push origin:refs/tags/v1.0remote:Powered by GITEE.COM[GNK-6.4]To gitee.com:hyb91/git_teaching.git-[deleted]v1.0

这个写法看起来有点奇怪,可以先直接记住:删除远程标签使用git push origin :refs/tags/<tagname>

标签常用于版本发布。例如发布一个稳定版本时,可以给对应提交打v1.0.0v1.1.0这样的标签,后续排查问题、回滚版本、生成发布记录都会方便很多。

十、本文总结

  • 远程仓库用于代码同步、备份和多人协作,本地仓库通过clonepushpull与远程仓库交互。
  • Git 是分布式版本控制系统,本地仓库也保存完整历史,远程仓库主要负责交换代码和集中备份。
  • git clone <url>可以把远程仓库克隆到本地。
  • HTTPS 上手简单,SSH 更适合长期开发;使用 SSH 前需要生成 Key,并把公钥添加到远程平台。
  • git remote查看远程仓库名称,git remote -v查看远程仓库地址。
  • git push origin master可以把本地master分支推送到远程。
  • git pull origin master可以拉取远程master并合并到当前分支。
  • .gitignore用来忽略不需要纳入版本管理的文件,git check-ignore -v可以检查某个文件被哪条规则忽略。
  • git config --global alias.xxx可以给 Git 命令配置别名。
  • tag适合标记重要版本节点,比如v1.0v2.0.0
  • 标签默认只在本地,推送标签需要使用git push origin <tagname>git push origin --tags

到这里,Git 已经从“个人本地版本管理”推进到了“本地和远程之间同步代码”。下一篇继续往下,就可以进入多人协作和企业级分支模型:远程分支怎么协作、同一个分支多人修改怎么办、feature 分支如何流转,以及实际项目里常见的master/release/develop/feature/hotfix模型。