Git push与pull的默认行为

本文详细解析了Git推送与拉取操作的默认行为,包括如何配置push.default属性,以及在不同Git版本中如何影响推送行为。同时,阐述了如何在未指定分支上游时,Git拉取操作的工作流程及如何设置分支上游。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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操作的全部默认行为,如有错误,欢迎斧正


[1] 为什么merge = refs/heads/develop 而不是refs/remotes/develop?
因为这里merge指代的是我们想要merge的远程分支,是remote上的refs/heads/develop,文中即是origin上的refs/heads/develop,这和我们在本地直接执行git merge是不同的(本地执行git merge origin/develop则是直接merge refs/remotes/develop)。

<think>好的,用户现在问的是git pushgit pullgit remote如何配合使用。之前他们已经了解了git remote的作用,现在需要进一步解释这三个命令如何协同工作。 首先,我需要确定用户的需求。他们可能已经知道每个命令的基本用法,但想了解这些命令如何在实际工作流中一起使用。比如,如何配置远程仓,然后进行推送或拉取。 接下来,我需要回顾之前回答的结构,确保一致性。之前的回答详细列举了git remote的不同用法,并给出了应用场景。现在需要将git pushgit pull整合进去,说明它们如何依赖远程仓的配置。 用户可能的疑问点在于:为什么需要配置remote才能使用pushpull?不同远程仓名称如何影响这些命令?例如,origin和upstream的区别。此外,他们可能想知道如何同时推送到多个远程仓,或者如何处理权限问题。 我需要分步骤解释:首先配置remote,然后使用pushpull时指定远程名称和分支。需要强调默认情况下,如果不指定远程,git会使用origin。还要提到如何设置上游分支,简化命令。 应用场景部分,可以举协作开发和开源项目维护的例子,说明如何使用不同的remote名称进行同步和协作。注意事项中要提到权限、上游分支设置和多远程仓的管理。 最后,总结这三个命令如何形成一个工作流,帮助用户高效管理代码。需要保持语言清晰,结构分明,使用示例代码和表格来增强可读性。</think>### `git push`、`git pull` `git remote` 的协同工作流程 `git push` 和 `git pull` 是远程仓交互的核心命令,而 `git remote` 负责管理本地仓远程仓的关联关系。它们的配合使用形成了 Git 多人协作的基础。以下是具体协作逻辑和典型场景: --- #### **1. 核心关系** - **`git remote`**:定义远程仓的名称(如 `origin`)和 URL,建立本地远程的映射。 - **`git push`**:将本地代码推送到远程仓。 - **`git pull`**:从远程仓拉取最新代码并合并到本地。 三者关系可简化为: **`git remote` 配置连接 → `git pull` 同步代码 → `git push` 提交代码** --- #### **2. 基础协作流程** ##### **步骤 1:关联远程仓(`git remote`)** - 克隆仓时自动关联远程: ```bash git clone https://github.com/user/repo.git # 默认远程仓名为 origin ``` - 手动添加远程仓: ```bash git remote add upstream https://github.com/other/repo.git # 添加第二个远程仓 ``` ##### **步骤 2:拉取代码(`git pull`)** - 从默认远程仓(`origin`)拉取代码: ```bash git pull origin main # 拉取 origin 的 main 分支并合并到本地 ``` - 从其他远程仓(如 `upstream`)同步代码: ```bash git pull upstream main # 同步开源项目的主仓更新 ``` ##### **步骤 3:推送代码(`git push`)** - 推送到默认远程仓: ```bash git push origin main # 将本地 main 分支推送到 origin ``` - 推送到其他远程仓: ```bash git push backup main # 推送到名为 backup 的远程仓 ``` --- #### **3. 典型场景示例** ##### **场景 1:日常开发协作** 1. **配置远程仓**: ```bash git remote add origin https://github.com/your-username/project.git ``` 2. **拉取最新代码**: ```bash git pull origin main # 同步团队最新代码 ``` 3. **提交并推送修改**: ```bash git add . git commit -m "feat: 添加新功能" git push origin main # 推送代码到自己的远程仓 ``` ##### **场景 2:参开源项目(多远程仓)** 1. **关联原始仓(`upstream`)和自己的仓(`origin`)**: ```bash git remote add upstream https://github.com/opensource/project.git git remote add origin https://github.com/your-username/project.git ``` 2. **同步原作者代码**: ```bash git pull upstream main # 拉取原始仓更新 ``` 3. **推送自己的修改**: ```bash git push origin main # 推送到自己的仓 ``` ##### **场景 3:推送到多个远程仓** ```bash # 添加两个远程仓 git remote add github https://github.com/user/repo.git git remote add gitee https://gitee.com/user/repo.git # 同时推送到 GitHub 和 Gitee git push github main git push gitee main ``` --- #### **4. 关键参数简化操作** ##### **设置上游分支(简化 `git push/pull`)** - **绑定本地分支远程分支**: ```bash git push -u origin main # -u 参数设置上游分支 ``` - **后续操作无需指定远程和分支**: ```bash git pull # 自动从 origin/main 拉取 git push # 自动推送到 origin/main ``` ##### **强制推送(谨慎使用)** ```bash git push --force origin main # 覆盖远程分支(可能破坏协作历史) ``` --- #### **5. 注意事项** | 问题类型 | 解决方案 | |----------------|--------------------------------------------------------------------------| | **权限错误** | 检查远程 URL 协议(HTTPS/SSH),确认密钥或账号权限 | | **冲突处理** | 先 `git pull` 解决冲突,再 `git push` | | **分支对应** | 确保 `git push/pull` 时本地分支远程分支名称匹配(或通过 `-u` 设置关联) | | **多远程仓** | 明确不同远程仓用途(如 `origin` 为自己仓,`upstream` 为原始仓) | --- ### **总结** - **`git remote`**:定义远程仓的入口(名称和 URL)。 - **`git pull`**:从已配置的远程仓拉取代码(`fetch + merge`)。 - **`git push`**:向已配置的远程仓推送代码。 **协作本质**:通过 `git remote` 建立连接,用 `pull` 保持代码同步,用 `push` 共享修改,三者共同实现分布式版本控制的高效协作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值