首页你好哇,世界马蹄疾
Git专题:remote
马蹄疾
2019-01-16 19:18:37

git是分布式版本管理工具,它没有中央仓库。但多人协作时,我们依然需要一个集散地,让协作成员之间统一往集散地推送和拉取更新。否则,点对点的沟通,效率会很低。

所以就引出了git中远端仓库的概念。

概念

我们之前所有的操作都是在本地仓库完成的,和本地仓库对应的是远端仓库。那么本地有若干分支,远端仓库是不是也有对应的若干分支呢?

当然。

我们探讨一个问题,在离线状态下,git是不是无从知道远端仓库的任何状态?

我让网络下线,查询从github克隆下来的本地仓库的状态,结果它告诉我本地仓库的master分支是up to date with 'origin/master'

$ git status On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean

实际上,git的分支有三种:

  • 本地分支,我们可以通过<branch>写法访问它。
  • 远端分支,我们可以通过<remote branch>写法访问它。
  • 远端分支引用,我们可以通过<remote/branch>写法访问它。实际上它也是本地分支,只不过我们无法操作它,只有git的网络操作才可以更新它。离线状态下,git给的状态就是本地分支和远端分支引用的比较结果。

git官方把我所说的远端分支引用称为远端分支。知道谁是谁就行了,名字不重要🤔

我是马蹄疾

我们看一下本地的远端分支引用。

.git/ .git/refs/ .git/refs/remotes/ .git/refs/remotes/origin/ .git/refs/remotes/origin/HEAD .git/refs/remotes/origin/master

默认的远端仓库名就叫origin。它也有master分支指针,也有HEAD指针。

拉取

如果远端仓库有新的提交或者新的分支,我们需要运行git fetch命令来拉取更新。

$ git fetch remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:veedrin/git 3893459..0f80eeb master -> origin/master

这个命令是git fetch origin的缩写。因为origin是远端仓库的默认名称,所以可以省略。如果有手动添加的远端仓库,那就必须指定远端仓库的名称了。

这个命令做了什么呢?

它会把新的提交和新的分支拉取到本地,然后更新本地的远端分支引用到最新的提交。

git fetch仅仅是将远端的更新拉取下来,同步本地的远端分支引用,不会对本地分支有任何影响。我们需要手动执行合并操作才能更新本地分支。

$ git merge origin/master On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean

当然,有一个更简单的操作。

$ git pull remote: Enumerating objects: 5, done. remote: Counting objects: 100% (5/5), done. Unpacking objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 From github.com:veedrin/git 4fbd1d4..d9785d7 master -> origin/master Updating 4fbd1d4..d9785d7 Fast-forward README.md | 2 ++ 1 file changed, 2 insertions(+)

git pull就是git fetchgit merge的一键操作。

推送

推送到远端的命令是git push <remote-name> <remote-branch-name>

$ git push origin master Counting objects: 3, done. Writing objects: 100% (3/3), 261 bytes | 261.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:veedrin/git.git 3eaa1ae..2bd3c9d master -> master

如果当前分支对远端分支设置了追踪的话,也可以省略分支名。

$ git push Counting objects: 3, done. Writing objects: 100% (3/3), 261 bytes | 261.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:veedrin/git.git 3eaa1ae..2bd3c9d master -> master

有时候本地分支和远端分支同时有新的提交,直接push是不行的。

$ git push To github.com:veedrin/git.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:veedrin/git.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.

有两种方式解决。

第一是先把远端的更新拉下来,有冲突则解决冲突,没冲突则再推送。

第二是强推。有时候我们就是想覆盖远端对吧,也不是不行,但是必须十分谨慎。而且不要在公共分支上强制推送。

$ git push -f Counting objects: 24, done. Delta compression using up to 4 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (24/24), 3.72 KiB | 1.24 MiB/s, done. Total 24 (delta 0), reused 3 (delta 0) To github.com:veedrin/git.git + 54d741b...2db10e0 master -> master (forced update)

实际开发时我们会建很多特性分支,推送到远端,通过测试后再合入主分支。使用git push <remote-name> <remote-branch-name>每次都要指定远端分支名,如果会有多次推送,我们可以在推送时设置本地分支追踪远端分支,这样下次就可以直接推送了。

也可以简写成git push -u <remote-name> <remote-branch-name>

$ git push --set-upstream origin dev Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 255 bytes | 255.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'dev' on GitHub by visiting: remote: https://github.com/veedrin/git/pull/new/dev remote: To github.com:veedrin/git.git * [new branch] dev -> dev Branch 'dev' set up to track remote branch 'dev' from 'origin'.

然后我们在.git/config文件中能看到多了一条配置。

[branch "dev"] remote = origin merge = refs/heads/dev

查看

查看远端仓库的命令是git remote

$ git remote origin

-v参数可以查看更为详细的信息,-v--verbose的缩写。

$ git remote -v origin git@github.com:veedrin/git.git (fetch) origin git@github.com:veedrin/git.git (push)

查看某个远端仓库的信息,可以使用命令git remote show <remote-name>

$ git remote show origin * remote origin Fetch URL: git@github.com:veedrin/git-1.git Push URL: git@github.com:veedrin/git-1.git HEAD branch: master Remote branches: dev tracked master tracked Local branches configured for 'git pull': dev merges with remote dev master merges with remote master Local refs configured for 'git push': master pushes to master (up to date)

添加

添加新的远端仓库,使用git remote add <shortname> <url>命令。

$ git remote add horseshoe https://github.com/veedrin/horseshoe

然后本地就多了一个远端仓库。

$ git remote horseshoe origin

除了添加远端仓库,我们还可以添加本地分支对远端分支的追踪。

$ git checkout -b dev origin/dev Branch 'dev' set up to track remote branch 'dev' from 'origin'. Switched to a new branch 'dev'

创建dev分支的同时,也设置了对远端分支dev的追踪,这样下次推送的时候就不需要指定了。

当然,远端分支引用必须得存在才行。

$ git checkout -b dev origin/dev fatal: 'origin/dev' is not a commit and a branch 'dev' cannot be created from it

git也提供了快捷方式。

$ git checkout --track origin/dev Branch 'dev' set up to track remote branch 'dev' from 'origin'. Switched to a new branch 'dev'

重命名

有时候你想修改远端仓库的简写名。比如你将女朋友的名字命名为远端仓库的简写名,然后你们分手了。这真是一个令人悲伤(欣喜)的故事。

$ git remote rename nvpengyou gaoyuanyuan

查看远端仓库列表。

$ git remote gaoyuanyuan origin

删除

一般来说,一个git项目有一个远端仓库就行了,其余的大多是临时性的。所以总有一天要删除它。

$ git remote rm horseshoe

查看远端仓库列表。

$ git remote origin
#工具
@Git
0comments withand markdown
输入"@+用户名+空格"可以AT某人,AT某人时可以按TAB键补全。
输入"登记过的邮箱"会自动补全剩余信息,可以登记原账号,也可以修改用户名再登记原账号。
先登记后评论,乖
性别: