Git push与pull的默认行为

转载 2016年08月30日 14:33:46

原文看着非常舒服,推荐看原文:

http://blog.angular.in/git-pushmo-ren-fen-zhi/


一直以来对git pushgit pull命令的默认行为感觉混乱,今天抽空总结下。

git push

通常对于一个本地的新建分支,例如git checkout -b develop, 在develop分支commit了代码之后,如果直接执行git push命令,develop分支将不会被push到远程仓库(但此时git push操作有可能会推送一些代码到远程仓库,这取决于我们本地git config配置中的push.default默认行为,下文将会逐一详解)。

因此我们至少需要显式指定将要推送的分支名,例如git push origin develop,才能将本地新分支推送到远程仓库。

当我们通过显式指定分支名进行初次push操作后,本地有了新的commit,此时执行git push命令会有什么效果呢?

如果你未曾改动过git config中的push.default属性,根据我们使用的git不同版本(Git 2.0之前或之后),git push通常会有两种截然不同的行为:

  1. develop分支中本地新增的commit被push到远程仓库
  2. push失败,并收到git如下的警告
fatal: The current branch new has no upstream branch.  
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin develop

为什么git版本不同会有两种不同的push行为?

因为在git的全局配置中,有一个push.default属性,其决定了git push操作的默认行为。在Git 2.0之前,这个属性的默认被设为'matching',2.0之后则被更改为了'simple'。

我们可以通过git version确定当前的git版本(如果小于2.0,更新是个更好的选择),通过git config --global push.default 'option'改变push.default的默认行为(或者也可直接编辑~/.gitconfig文件)。

push.default 有以下几个可选值:
nothing, current, upstream, simple, matching

其用途分别为:

  • nothing - push操作无效,除非显式指定远程分支,例如git push origin develop(我觉得。。。可以给那些不愿学git的同事配上此项)。

  • current - push当前分支到远程同名分支,如果远程同名分支不存在则自动创建同名分支。

  • upstream - push当前分支到它的upstream分支上(这一项其实用于经常从本地分支push/pull到同一远程仓库的情景,这种模式叫做central workflow)。

  • simple - simple和upstream是相似的,只有一点不同,simple必须保证本地分支和它的远程upstream分支同名,否则会拒绝push操作。

  • matching - push所有本地和远程两端都存在的同名分支。

因此如果我们使用了git2.0之前的版本,push.default = matching,git push后则会推送当前分支代码到远程分支,而2.0之后,push.default = simple,如果没有指定当前分支的upstream分支,就会收到上文的fatal提示。

upstream & downstream

说到这里,需要解释一下git中的upstream到底是什么

git中存在upstream和downstream,简言之,当我们把仓库A中某分支x的代码push到仓库B分支y,此时仓库B的这个分支y就叫做A中x分支的upstream,而x则被称作y的downstream,这是一个相对关系,每一个本地分支都相对地可以有一个远程的upstream分支(注意这个upstream分支可以不同名,但通常我们都会使用同名分支作为upstream)。

初次提交本地分支,例如git push origin develop操作,并不会定义当前本地分支的upstream分支,我们可以通过git push --set-upstream origin develop,关联本地develop分支的upstream分支,另一个更为简洁的方式是初次push时,加入-u参数,例如git push -u origin develop,这个操作在push的同时会指定当前分支的upstream。

注意push.default = current可以在远程同名分支不存在的情况下自动创建同名分支,有些时候这也是个极其方便的模式,比如初次push你可以直接输入 git push 而不必显示指定远程分支。

git pull

弄清楚git push的默认行为后,再来看看git pull

当我们未指定当前分支的upstream时,通常git pull操作会得到如下的提示:

There is no tracking information for the current branch.  
Please specify which branch you want to merge with.  
See git-pull(1) for details

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> new1

git pull的默认行为和git push完全不同。当我们执行git pull的时候,实际上是做了git fetch + git merge操作,fetch操作将会更新本地仓库的remote tracking,也就是refs/remotes中的代码,并不会对refs/heads中本地当前的代码造成影响。

当我们进行pull的第二个行为merge时,对git来说,如果我们没有设定当前分支的upstream,它并不知道我们要合并哪个分支到当前分支,所以我们需要通过下面的代码指定当前分支的upstream:

git branch --set-upstream-to=origin/<branch> develop  
// 或者git push --set-upstream origin develop 

实际上,如果我们没有指定upstream,git在merge时会访问git config中当前分支(develop)merge的默认配置,我们可以通过配置下面的内容指定某个分支的默认merge操作

[branch "develop"]
    remote = origin
    merge = refs/heads/develop // [1]为什么不是refs/remotes/develop?

或者通过command-line直接设置:

git config branch.develop.merge refs/heads/develop  

这样当我们在develop分支git pull时,如果没有指定upstream分支,git将根据我们的config文件去merge origin/develop;如果指定了upstream分支,则会忽略config中的merge默认配置。

以上就是git push和git pull操作的全部默认行为,如有错误,欢迎斧正

git push和git pull的默认行为

转自 https://segmentfault.com/a/1190000002783245 一直以来对Git push与git pull命令的默认行为感觉混乱,今天抽空总结下。 ...
  • u010523770
  • u010523770
  • 2017年07月04日 08:59
  • 155

Git push与pull的默认行为

git push 通常对于一个本地的新建分支,例如git checkout -b develop, 在develop分支commit了代码之后,如果直接执行git push命令,develo...
  • sc313121000
  • sc313121000
  • 2016年01月08日 10:45
  • 1328

设置git push和pull的默认分支

例如要把push的默认分支设置为dev,那么:git push --set-upstream origin dev 要把pull的默认分支设置为dev,那么:git branch --set-ups...
  • yuanchao99
  • yuanchao99
  • 2016年05月18日 13:58
  • 4150

Git配置默认pull、push地址

Git配置默认pull、push地址 git remote add -f origin https://github.com/simpleOrg/simpleApp.git git config -e...
  • rrrrrr123rrr
  • rrrrrr123rrr
  • 2016年02月18日 10:16
  • 3304

Git原理杂谈之pull/push命令

这边文章是基于之前三篇文章的后续篇,之前三篇能够帮助小白同学概要性地理解Git的整体原理及快速掌握Git基本技能以进入团队开发,所以建议对Git只了解些浅层内容的看客老爷们先看完前三篇再从本篇开始往后...
  • xiaoxuantengkong
  • xiaoxuantengkong
  • 2015年05月28日 20:48
  • 2238

git pull和git push的区别

Git中从远程的分支获取最新的版本到本地有这样2个命令: 1. git fetch:相当于是从远程获取最新版本到本地,不会自动mergegit fetch origin master git log...
  • CYJ2014go
  • CYJ2014go
  • 2017年10月09日 12:09
  • 143

【git】git基本命令-项目的pull与push

1.查看目前项目状态,是否有修改 git status 2.添加差异文件,相当于开发工具中的git→add git add 3.提交 git commit -m "填写的注释" 4.拉取服务器上的更新...
  • lihuapiao
  • lihuapiao
  • 2016年03月03日 14:34
  • 8037

git fetch, merge, pull, push需要注意的地方

在git操作中,我们经常会用到fetch, merge, pull和push等命令,以下是一些我们需要注意的地方。 给大家准备了参考资料: 1. Whatʼs a Fast Forward Mer...
  • hutaoer06051
  • hutaoer06051
  • 2013年03月14日 17:00
  • 10190

Git的pull、add、commit、push、clone

更新远程项目到本地:直接pull(因为我这个项目已经连接到远程地址了,所以不用再次连接) 上传本地修改到远程地址:先pull,如上所示,然后再进行修改,先add 在commit,最后push git...
  • Jalon2015
  • Jalon2015
  • 2016年08月03日 11:49
  • 1950

Git初步体验(SSH公钥、PUSH、PULL)

今天学习了git的安装与初步体验,本来想更进一步了解下git与github的联合使用,无奈要翻墙,大家都懂的。。。果断结合码云实现对代码项目的版本控制和管理。。。下面主要想记录下今天安装过程的问题: ...
  • DoubleBlack
  • DoubleBlack
  • 2016年07月31日 00:17
  • 523
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Git push与pull的默认行为
举报原因:
原因补充:

(最多只允许输入30个字)