Git 命令之 fetch、merge、pull

定义

git fetch

Download objects and refs from another repository.
Fetch branches and/or tags (collectively, "refs") from one or more other repositories, along with the objects necessary to complete their histories.
From git-scm

从另一个仓库下载对象和引用。
从一个或多个仓库获取分支或标签,以及完成提交历史所必须的对象。

# 命令格式

git fetch [<options>] [<repository> [<refspec> <refspec> ...]]
git fetch <repository> <head>:<master>

example

# git config remote.<repository>.fetch
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

# 基于上面的配置,也是默认的配置执行下面命令

# 1. 不指定具体分支名称时,它会获取 origin 存在的所有分支
git fetch
git fetch origin

# 命令格式 fetch <repository>
# 命令可以缺省 <repository>
# fetch 可以缺省 origin,那它默认使用的什么【疑问1】

# 执行日志如下
mac@hgwang2019 ze % git fetch
From https://gitlab.xxx.com/whg/ze
   d17d36e..0ab3813  feat/c     -> origin/feat/c


# 2. 指定具体名称时仅更新名称对应的分支
git fetch origin master
git fetch origin master:
git fetch origin +seen:seen master:main

# 命令格式 <head>:<branch>
# 命令可以缺省符号右边 <head>:
# 命令还可以缺省符号 <head>
# 命令可以指定多个名称 <head1> <head2>
# + 指不使用快进模式更新,默认块进模式更新

# 执行日志如下
% git fetch origin master
From https://gitlab.xxx.com/whg/ze
 * branch            master     -> FETCH_HEAD
 
% git fetch origin master:
From https://gitlab.xxx.com/whg/ze
 * branch            master     -> FETCH_HEAD
 
% git fetch origin master:m1
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 5 (delta 1), reused 1 (delta 1), pack-reused 4
Unpacking objects: 100% (5/5), done.
From https://gitlab.xxx.com/whg/ze
 * [new branch]      master     -> m1
   7700707..3db84ff  master     -> origin/master

# 3. 错误的列子

git fetch xxx

# repository 随便输入会提示 xxx 不是一个仓库

# 执行日志如下
% git fetch ttt
fatal: 'ttt' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.


git merge

Join two or more development histories together.
Incorporates changes from the named commits (since the time their histories diverged from the current branch) into the current branch. This command is used by git pull to incorporate changes from another repository and can be used by hand to merge changes from one branch into another.
From git-scm

合并两个或更多个开发历史记录到一起。
将已经提交的记录(自提交历史记录从当前分支分开的时间开始)合并到当前分支。git pull 使用此命令来合并另一个仓库的更改,也可以手动用来合并一个分支到另一个分支

# 命令格式
git merge [<options>] [<commit> <commit> ...]
git merge <branch> <branch>
      A---B---C topic
     /
D---E---F---G master

     A---B---C topic
    /         \
D---E---F---G---H master

# 假如有上面两个分支的提交记录
# 在 master 分支上执行 git merge topic 后
# 会把 topic 上从 master 分支分出去后的所有改动都重现到 master 分支上
# 并在最后追加一个新的提交记录 H
# 所以执行 merge 命令后通常会多出一条记录

example

# 1. 默认的命令
git merge master

# 执行日志如下
% git merge master
Updating c33c0e4..3db84ff
Fast-forward
 c5.js | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 c5.js


# 2. 无参数命令
git merge

# 日志输出如下
# 当前分支在 master
# 从日志看和命令 git merge origin/master 一致
% git merge
Already up to date.

# 另一个 merge,已经 fetch 
% git merge
Updating ac1a5ba..269f8fd
Fast-forward
 b7.js | 1 +
 1 file changed, 1 insertion(+)

# 3. 不自动追加新的提交记录
git merge --no-commit master


# 执行日志如下
# 如果当前分支有比 master 更早的提交记录
# 当前分支显示需要再次提交合并过来的新文件
% git merge --no-commit master
Automatic merge went well; stopped before committing as requested
% git status
On branch feat_3
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:

    new file:   c7.js

# 如果当前分支没有比 master 更早的提交记录
% git merge --no-commit master
Updating 3db84ff..fefc896
Fast-forward
 c6.js | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 c6.js
% git log
commit fefc8968a648b3da29b3b698a9d0b67f2e2ec429 (HEAD -> feat_3, origin/master, master)
Merge: 3db84ff 8e7a0c7
Author: 莫帆 <whg@xxx.com>
Date:   Fri Sep 18 14:14:58 2020 +0800

    Merge branch 'feat/c' into 'master'
    
    Feat/c
    
    See merge request whg/ze!17

commit 8e7a0c76f6dcd952049995523a68c06593c92758 (origin/feat/c)
Author: 莫帆 <whg@xxx.com>
Date:   Fri Sep 18 14:14:46 2020 +0800

    feat: add c6


# 终止合并,在合并中遇到冲突不想解决或者不想在使用当前合并内容
# 执行后会回滚到 merge 命令之前的状态
git merge --abort

git pull

Fetch from and integrate with another repository or a local branch.
Incorporates changes from a remote repository into the current branch. In its default mode, git pull is shorthand for git fetch followed by git merge FETCH_HEAD.
From git-scm

从另一个仓库或本地分支获取然后在合并。
git pull = git featch + git merge

git pull fetches from origin by default and merges into the current branch.
From "Pro Git book"

# 命令格式

git pull [<options>] [<repository> [<refspec> <refspec> ...]]
git pull <repository> <branch>

example

# 1. 指定分支名称
git pull origin feat_3

在远端分支有新的更新后执行该命令都多一条提交记录(不论本地的提交记录,有更前的、更后面的、还是没有)

# 日志输入如下
# 看日志能分别对应上是分别执行了 git fetch 和 git merge 的
# 且从 log 上看和 merge 行为一致都会多一条提交记录
% git pull origin feat_3
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://gitlab.xxx.com/whg/ze
 * branch            feat_3     -> FETCH_HEAD
   fad7482..901afea  feat_3     -> origin/feat_3
Merge made by the 'recursive' strategy.
 b6.js | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 b6.js
% git log
commit 1cef28fa5d69727bde66934bc8b0811c8ac44a42 (HEAD -> feat_3)
Merge: 5296e52 901afea
Author: 莫帆 <wanghaigang@innotechx.com>
Date:   Fri Sep 18 15:31:58 2020 +0800

    Merge branch 'feat_3' of https://gitlab.xxx.com/whg/ze into feat_3

commit 901afeab4672ccb5f0ebf19ba3a6c378d2e6c81a (origin/feat_3)
Author: 莫帆 <whg@xxx.com>
Date:   Fri Sep 18 15:31:46 2020 +0800

    feat: add b6

commit 5296e52c21cc07b3cf28f2168c2dc4321eea65b1
Author: 莫帆 <whg@xxx.com>
Date:   Fri Sep 18 15:31:25 2020 +0800

    feat: change b1 console

# 2. 无参数命令
git pull
git pull origin


# 日志输出如下
# 看日志结果是分别执行的 git fetch 和 git merge origin/feat_3
% git pull
remote: Enumerating objects: 2, done.
remote: Counting objects: 100% (2/2), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 2 (delta 0), reused 2 (delta 0), pack-reused 0
Unpacking objects: 100% (2/2), done.
From https://gitlab.xxx.com/whg/ze
   a452809..1e68dd0  master     -> origin/master
Already up to date.

# 结合 git fetch 的说明,第一步和执行缺省参数的 git fetch 一致
# 第二步执行 git merge,但它是如何知道 merge origin/feat_3 分支的【疑问2】

branch.<name>.remote 和 branch.<name>.merge

Defines, together with branch.<name>.remote, the upstream branch for the given branch. It tells git fetch/git pull/git rebase which branch to merge and can also affect git push (see push.default). When in branch <name>, it tells git fetch the default refspec to be marked for merging in FETCH_HEAD. The value is handled like the remote part of a refspec, and must match a ref which is fetched from the remote given by "branch.<name>.remote".
The merge information is used by git pull to lookup the default branch for merging \

  • branch.<name>.remote 用于定义 <name> 分支对应远端分支的 repository,这里一般默认为 origin
  • branch.<name>.merge 设置的值定义 fetch、pull 默认合并哪个分支
  • 假如在 <name> 分支执行 git merge,相当于执行 git merge origin/<name>
  • 同样在 <name> 分支执行 git pull,相当于 git pull origin <name>
  • 这里就解释了【疑问1】【疑问2】中的问题

结论

这三个命令都可以缺省参数使用,但如果使用参数 pull、fetch 和 merge 有差异,前者需要指定 repository,后者只需要分支名称即可。

// 这里 repository 就是默认值 origin
git fetch origin master
git pull origin master

// 这里不需要 respository,分支名称指定远端的 master 分支
git merge origin/master

附上命令的定义

git fetch [<options>] [<repository> [<refspec> <refspec> ...]]
git merge [<options>] [<commit> <commit> ...]
git pull [<options>] [<repository> [<refspec> <refspec> ...]]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容