• 欢迎访问 winrains 的个人网站!
  • 本网站主要从互联网整理和收集了与Java、网络安全、Linux等技术相关的文章,供学习和研究使用。如有侵权,请留言告知,谢谢!

git操作(13):remote

Git winrains 来源:veedrin 1年前 (2019-08-30) 77次浏览

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

作者:veedrin

来源:https://github.com/veedrin/horseshoe/blob/master/git/remote.md


版权声明:文末如注明作者和来源,则表示本文系转载,版权为原作者所有 | 本文如有侵权,请及时联系,承诺在收到消息后第一时间删除 | 如转载本文,请注明原文链接。
喜欢 (1)