gitpull fetch 区别和git pull之间的区别

Git教程 - 廖雪峰的官方网站
史上最浅显易懂的Git教程!
为什么要编写这个教程?因为我在学习Git的过程中,买过书,也在网上Google了一堆Git相关的文章和教程,但令人失望的是,这些教程不是难得令人发指,就是简单得一笔带过,或者,只支离破碎地介绍Git的某几个命令,还有直接从Git手册粘贴帮助文档的,总之,初学者很难找到一个由浅入深,学完后能立刻上手的Git教程。
既然号称史上最浅显易懂的Git教程,那这个教程有什么让你怦然心动的特点呢?
首先,本教程绝对面向初学者,没有接触过版本控制概念的读者也可以轻松入门,不必担心起步难度;
其次,本教程实用性超强,边学边练,一点也不觉得枯燥。而且,你所学的Git命令是“充分且必要”的,掌握了这些东西,你就可以通过Git轻松地完成你的工作。
文字+图片还看不明白?有视频!!!
本教程只会让你成为Git用户,不会让你成为Git专家。很多Git命令只有那些专家才明白(事实上我也不明白,因为我不是Git专家),但我保证这些命令可能你一辈子都不会用到。既然Git是一个工具,就没必要把时间浪费在那些“高级”但几乎永远不会用到的命令上。一旦你真的非用不可了,到时候再自行Google或者请教专家也未迟。
如果你是一个开发人员,想用上这个世界上目前最先进的分布式版本控制系统,那么,赶快开始学习吧!
,十年软件开发经验,业余产品经理,精通Java/Python/Ruby/Visual Basic/Objective C等,对开源框架有深入研究,著有《Spring 2.0核心技术与最佳实践》一书,多个业余开源项目托管在,欢迎微博交流:
Make a Comment
Sign In to Make a Comment
You can sign in directly without register:
You need authorize to allow connect to your social passport for the first time.
WARNING: You are using an old browser that does not support HTML5.
Please choose a modern browser ( /
/ ) to get a good experience.Git fetch和git pull的区别_词汇网
Git fetch和git pull的区别
责任编辑:词汇网 发表时间: 11:06:58
原文:/git-fetch-pull/Git中从远程的分支获取最新的版本到本地有这样2个命令:1.git fetch:相当于是从远程获取最新版本到本地,不会自动mergegit fetch origin mastergit log -p master..origin/mastergit merge origin/master 以上命令的含义: 首先从远程的origin的master主分支下载最新的版本到origin/master分支上 然后比较本地的master分支和origin/master分支的差别 最后进行合并 上述过程其实可以用以下更清晰的方式来进行:git fetch origin master:tmpgit diff tmpgit merge tmp从远程获取最新的版本到本地的test分支上 之后再进行比较合并2.git pull:相当于是从远程获取最新版本并merge到本地git pull origin master上述命令其实相当于git fetch 和 git merge在实际使用中,git fetch更安全一些因为在merge前,我们可以查看更新情况,然后再决定是否合并结束
上一集:没有了 下一集:
相关文章:&&&&&&&&&&&&&&
最新添加资讯
24小时热门资讯
附近好友搜索[分享] 真正理解 git fetch, git
pull 以及 FETCH_HEAD · Ruby China
====& 注意:
因为发这个帖子时(2012年) 本人 git 仍处在初级阶段, 纯粹靠臆测写下以下内容, 所以存在不少错误.(已经被证实), 新人同学千万别被误导呀. 有空我会重新改之, 并完善下.
之前使用 git 主要还是限于本地项目使用, 所以接触fetch, pull , push比较少. 最近在github上用到了这些命令, 对其中的一些细节不甚了解, 今天花时间专门研究了下. 整理了一些笔记, 在这里分享给大家.
因为是纯粹靠实践以及系统 man 帮助来 臆测 有关的功能, 可能有不对的地方, 大家一定要指正.
这个很简单, 其实和后面的差不多, 这里就不讲了.
唯一需要注意的地方是:
git push origin :branch2, 表示将一个内容为空的同名分支推送到远程的分支.(说白了, 即删除远程主机的branch2分支), 但是这并不会消除之前的comment内容, 而且你一旦提交了一些大的文件(例如: 图片之类的), 通过这个操作, 是不会将这些文件占用的空间消除的.
如果要真正的删除一个文件, 除了删除整个项目, Github网站也有提供办法, 不过还没看懂.
git fetch, 理解fetch的含义, 是远程协作的关键.
而理解 fetch 的关键, 是理解 FETCH_HEAD.
这里需要解释下什么是FETCH_HEAD??
FETCH_HEAD指的是: 某个branch在服务器上的最新状态'.
每一个执行过fetch操作的项目'都会存在一个FETCH_HEAD列表,
这个列表保存在 .git/FETCH_HEAD 文件中, 其中每一行对应于远程服务器的一个分支.
当前分支指向的FETCH_HEAD, 就是这个文件第一行对应的那个分支.
一般来说, 存在两种情况:
如果没有显式的指定远程分支, 则远程分支的master将作为默认的FETCH_HEAD.
如果指定了远程分支, 就将这个远程分支作为FETCH_HEAD.
常见的git fetch 使用方式包含以下四种:
这一步其实是执行了两个关键操作:
- 创建并更新所有远程分支的本地远程分支.
- 设定当前分支的FETCH_HEAD为远程服务器的master分支 (上面说的第一种情况)
需要注意的是: 和push不同, fetch会自动获取远程`新加入'的分支.
git fetch origin
同上, 只不过手动指定了remote.
git fetch origin branch1
设定当前分支的 FETCH_HEAD' 为远程服务器的branch1分支`.
注意: 在这种情况下, 不会在本地创建本地远程分支, 这是因为:
这个操作是git pull origin branch1的第一步, 而对应的pull操作,并不会在本地创建新的branch.
一个附加效果是:
这个命令可以用来测试远程主机的远程分支branch1是否存在, 如果存在, 返回0, 如果不存在, 返回128, 抛出一个异常.
git fetch origin branch1:branch2
只要明白了上面的含义, 这个就很简单了,
首先执行上面的fetch操作
使用远程branch1分支在本地创建branch2(但不会切换到该分支),
如果本地不存在branch2分支, 则会自动创建一个新的branch2分支,
如果本地存在branch2分支, 并且是`fast forward', 则自动合并两个分支, 否则, 会阻止以上操作.
git fetch origin :branch2
等价于: git fetch origin master:branch2
只要理解了git fetch, git pull就太简单了.
git pull 等价于以下两步:
经命令中的pull换成fetch, 执行之...
git merge FETCH_HEAD
唯一需要提及的一点是:
我认为pull操作, 不应该涉及三方合并 或 衍合 操作 换个说法: pull 应该总是 fast forward 的. 为了达到这样一个效果, 在真正push操作之前, 我倾向于使用衍合, 在本地对代码执行合并操作.
坑爹的 markdown, 我怎么感觉越改越难看呢?
怎么我写的帖子, 除了自己, 一个回复都没有呢?
我觉得可以写成blog啊
下个月打算自己写个博客, 然后上线, 现在还在复习一些 Ruby 的知识...
不过我觉得 Ruby-china 就是一个所有 Rubyist 的 blog...
还有就是, 很多时候, 我并不确定自己讲的对不对, 所以发出来让大家帮我指正.
如果你觉得有问题, 咱们可以讨论下. 可别不说呀.
git我还很浅的,也许
能做一些补充
filter-branch 可以做删除单个文件.
Git 仓库本身也是可以 force push 改变历史的.
好贴,格式很清楚,lz 排版辛苦了。
换个说法: pull 应该总是 fast forward 的.
以前我总是千方百计的保证 pull 是 fast forward,后来发现挺碍手碍脚的,最近钟情于
git pull --rebase
喔~ filter-branch, 那时git里面的核弹级功能, 我除了在网上找的脚本, 删除大文件以外, 貌似其他功能完全用不着. 呵呵
支持一下。
我刚刚看了下 pull --rebase 的 man 帮助,
就是先fetch, 然后和本地当前分支rebase, 我感觉用这个参数会造成混乱.
你平常怎么用这个参数? 先本地rebase, pull 的时候再rebase ?
要不就是你直接在master下工作, 从来不会创建分支, 工作完后,
直接fetch, 然后rebase.
其实你自己完全可以一直保证pull 是 fast forward, 只要保证 不要在master下直接工作,就可以了.
之前就知道git 鼓励多创建分支,
并不明白为什么, 但是等明白了rebase的含义之后, 就理解了.
即使你是在一个单独的分支上来做一个 new feature,也总不免去 master 上去做一些 hotfix 吧。所以本地 master 和远端 master 出现分歧是很正常的事情。这时候就有两个选择:
git pull,也就是 fetch + merge
git pull --rebase,也就是 fetch + rebase
这两种方式都是很自然的,如果这都叫混乱的话,那就干脆不要开新分支了。
假设你首先 pull master 下来,
然后在 master上建立 开发分支 开始工作, 当你确信工作已经完成, 打算要合并到master的时候,
这个时候首先切换到master, 然后再次 pull master, 因为这个时候, 你的本地master 并没有执行任何更改, 当然是 fast-forward,
然后, 下一步在本地
rebase 开发分支 到 最新的master, 解决冲突后, push即可.
我上面这个过程, 你说是不是pull 总是 fast-forwrd 呢?
既然 pull 总是 fast-forward, 干嘛还要加个--rebase, 搞的那么复杂...
你这思路也挺简单清晰的,不过我们如果遇到这样的情况呢:
我们正在我们的 new-feature 分支上写代码,写到一半忽然发现有一个和当前工作不相关的小 bug,那这时你会怎么办呢?
这是普遍情况,你可以用 git-stash 解决。
首先,在这个 new-feature 分之上执行 git stash,这时所有未提交的修改都会被零时保存起来。这个时候你就可以方便的 git checkout master 切换到主干分钟,然后 branch 新的分之并解决bug。等bug解决了以后,你可以回到 new-feature 分之上,用 git stash apply 将之前保存的变更全部还原出来。进一步关于 git-stash 的信息可以看这里:
我是站在作者编写 git 实用的角度, 觉得按照这种方式来使用 git 才是正确的.
事实上我也可以理解为什么提供 pull --rebase, 如果这个项目很大, 例如: linux kernel, 可能在你处理本地rebase的时候, 又有其他人向master push了新的commit, 而且这个commit碰巧就和你要提交的commit发生冲突, 这个时候, 就需要 pull --rebase了. 除非项目很大很大, 否则这样的几率还是很低的.
我的理解, 是rebase应该总是在本地的不同分支间被执行, 这样一步一步才条理,
直接在master 上用 pull --rebase, 我觉得这样是曲解了这个功能的本意(有点滥用). 相比较而言, pull 的时候如果存在冲突, merge反倒更靠谱一些.
讲的很好呀, 受教了, 这的确是使用 stash 很好的场景.~~
不过..., 你是用手机回复的吗? 这不像你的风格呀.
这是普遍情况,你可以用 git-stash 解决。
首先,在这个 new-feature
分之 上执行 git stash,这时所有未提交的修改都会被 零时 保存起来。这个时候你就可以方便的 git checkout master 切换到主干分钟,然后 branch 新的 分之 并解决bug。等bug解决了以后,你可以回到 new-feature 分之 上,用 git stash apply 将之前保存的变更全部还原出来。进一步关于 git-stash 的信息可以看这里.
我补充一点: 好像还有一个git pop, 取出来后, 顺便清空 stash-list.
最近事情有点多,太忙了,所以随手回复之前,忘记好好检查一下了。
我发现zw963 是ruby-china 属一,属二的“建筑开发商“
嘛意思... 褒义还是贬义啊? 呵呵.
我最近恰好做了个screencast关于这个的
顺路推荐一下git flow
的情况,就可以:
git flow hotfix start xxx
git flow就是通过命令将hotfix/feature/release等流程规范化,很适合团队开发。
的 stash 用法我是完全同意的,一个 new-feature 如果代码较少的话,这样就可以了。一般对于较大的 feature, 我会在 new-feature 分支上打十几甚至几十个 commit(碎片无极限),然后往 master 上 merge 的时候用 rebase -i squash 成一个或两个 commit.
这时如果有 hotfix 的话,当然也会用到 stash, 然后切回 master 不过这种小 bug 一般我不会再开新分支了,直接在 master 上 change + commit。只是一两行的小修改,为何要开新分支呢?!
你的意思是:本地 master 和 new-feature 之间 rebase,OK.
远端 master 和 本地 master 之间 rebase,不 OK。
我是100%反对的
因为这两者根本就没有区别。
果断收藏,并学习中。。。
没错,如果只是小修改是不需要开分支的。 如果修bug是不知道要多久,bug修好可可能remote master已经前移了。而remote的新代码又很可能和修bug的代码有冲突。这样的话开分支就比较好,并且在commit back to master之前把当前远程的最新代码抓下来一起integration test.
Nice cast, really enjoyed it.
There are two things I sometimes do a bit differently though:
I always consider my local master branch is just another branch from origin/master.
sometimes if the bugfix is really small(say, a typo), that I do not need to test, then I will just do it on my local master. master shall always be deployable? Yes, but only the public/remote one.
I usually do a lot of &WIP& commits on new-feature branch, then rebase -i master to squash them into logical one or two patches.
I see in the cast you do a &WIP& commit and
laster reset it to continue where you left off, I never do it this way. I will either stash the changes, or in most cases, I will do 20 WIPs on this branch, for features big enough, this brings me the freedom to go back and forth in the history, free as in air.
原理上是这样, 如果把本地的master看成是远程的镜像可以把流程简化很多。也就是说, 这要本地的master测试都通过就立刻push remote master.这样别人可以立刻拿到你的code,可以integration test或者reconcile等等,不至于要一次集成太多代码。还有,你可能有多个remote, 比如一个Github, 一个staging server, 一个production server, 等等, 如果你的deploy用git的workflow, 比如 Heroku。 如果保持本地master deployable, 就可以很方便的选择deploy到哪个上面
如果你的feature需要20个wip, 说明你feature本身太大,应该掰开成更细颗粒的feature. reset -i 是很有用的, 不过我一般最多是五六个commit, 没用过20多个这么多。 有时候我会需要在一个branch上面工作很久,但一般我都会很经常的rebase master, 跟上master。 不然到最后一个大的merge/rebase太头痛
有时只是预期一个小提交,就不想开新分支,直接在主干分支(如 master, dev)上直接提交,但 push 的时候发现远程分支有新 push,这时 pull --rebase 就很适用
是的,我从来不用git pull, 一律git pull --rebase (alias 成 gpr)
With you. Merge often and merge early.
视频翻墙也打不开, 郁闷.
等下找man看看, 我甚至都没有听说过...
这怎么能没有区别呢? 在执行 git pull --rebase 之前, 你甚至都不知道 remote上做了那些更改, 如果你本地master进行了大量更改(例如, 好长时间才push一次), 那绝对是一个噩梦.
在什么时候该使用pull rebase参数, 我和 的想法是一致的. 见 #16
我不反对用 pull---rebase , 事实上, 看了楼上
刚刚我又试了试, 果断的把 pull 的 alias 加上了 --rebase 参数 (反正真要冲突了, 肯定要rebase, 如果不冲突, 直接fast-forword 挺好), 但是关键一点是:
目的和你不一样.
也可能是我误会你了, 你貌似倾向于使用 pull --rebase 直接代替本地的rebase, 好像一步到位那样的.
从更深层次, 多角度 理解 git.
前两天刚好也写了篇 blog 用到 pull --rebase 和 merge --no-ff
讲的很好哇~~ 不过好像那个图画错了...
git pull --rebase 之后, 应该是
D---E---A---B---C--F'--G'
master, remotes/origin/master
&也可能是我误会你了, 你貌似倾向于使用 pull --rebase 直接代替本地的rebase, 好像一步到位那样的.
这个没有误会,我确实经常这么做,但是本地 rebase 用的更多些。这两种方法都没问题啊。
噢……对……马上更正
嗨~ 下午那会儿突然想起了你的这句话:
有时候我会需要在一个branch上面工作很久,但一般我都会很经常的rebase master, 跟上master
因为看不到你的视频, 所以不知道你是如何操作的.
你这个所谓的经常的rebase master,是指的什么意思?
这里面所说的master是remote的master 还是特指本地的master.
你的意思是指你的这个rebase, 是指push之前的rebase, 还是只是在本地rebase, 并不push呢
如果push, 你本地分支的 feature 根本没有完成, 就push到远程的master, 这好像不合理吧?
如果不push,
那你rebase之前, 会不会先pull 呢?
如果每次都pull, 那样会使你当前分支的 commit 呈现一个不连续的状态.
如果一直不pull, 那么等你push之前, 不是还得重新上演一次之前同样的rebase ??
同样的rebase 过程上演两遍, 这不是反而复杂了吗?
所以, 怎么想都觉得这句话不理解, 还望指点一二.
楼上的太高深了,看不懂,还是来学习的好
需要在branch上很久的时候多半是要完成一整块的feature set才能整合在master里面, 比如,凡是涉及到付费的时候就要把很多情形考虑到做完才能一起deploy。可以每做完一小块测试通过后就 git pull -- git checkout my_ git rebase master
这样先把远程master别人的代码拿下来,再rebase到自己的branch上面。再跑测试。 通过了之后git push origin my_branch, 这样就不用担心比如电脑掉到水坑里,或者需要别人接着做这个大feature set. 再继续做下一小块。原因还是每次集成少量代码,有问题早解决。而remote branch伤得的commit message也可以作为一种和同事的交流工具,让别人知道你做到哪里。
等到feature set做完, 还是一样 git pull -- git checkout my_branch, git merge my_branch (fast forward); gi deploy
1) 所有developer的本地master都紧跟remote master,而且都是working code, 随时可以deploy
2) 本地上推前先抓remote master, 整合测试通过后从local master push remote master, no conflict.
3) push/deploy often, push/deploy early
4) remote branches做备份和交流
要是出现了几个long living branch又都不能很快deploy的时候就比较复杂,可以考虑再开一个非master的integration branch. 但这种情况一旦出现更多的是整个项目的筹划出了问题。
我的做法也跟
一样,每次提交前都要 rebase 一次同步过的主干分支,不过我合并时通常会用 merge --no-ff
明白了, 谢谢! 让我收益非浅呀. 大体和我想的差不多, 就是remote多了一个分支, 用来跟踪本地的最新演进,
想了想就像一棵树的分支, 刚分叉不久, 又合并(rebase)', 而开发分支始终保持在最新的master`下游不远的地方. 太酷了!
不过, 我觉得这种方式, 其实根本用不到pull --rebase参数? 感觉就是两个单独的分支, 在不断的向前推进, 因为在你merge 当前开发分支 到master之前,
master始终是remote 的master,
不是应该一直是fast-forword吗?
是fast forward, 因为别人如果按照同样的流程也一定集成了你的所有本地commit,而没有push的commit又都不在master上。
完全明白了, 十分感谢~~
我想问下, 实际应用中, 那样会不会有点乱?
我觉得你的目的是:
希望在将来一眼就可以看出来, 这部分来自于某个分支.
可是分支一旦合并后, 肯定会删除它, 显示之前的某个commit来自于某个分支, 真的很重要么?
像这样,能够很清晰地让其他人看出一系列的提交都是为实现同一目的,方便 code review
很有道理. 谢谢指点呀. 我也添加这个参数试试看效果好了.
说归到底,git是为开发流程服务的, 而开发的流程又跟团队的构成和开放方式密切相关。
比如说,如果团队的程序员都坐在同一个办公室里,并且有对代码交流讨论的习惯,水准都不错而且互相信任;或者经常做结对编程有充分的讨论;这样的话用rebase就很好,可以把小块的代码快速集成而且高频率的deploy, 大部分的branch都是很快就会剔除掉
如果团队不在同一个地方希望能加强交流, 或者水平不一有些新手, 这样象的流程就很好,每一个merge的流程都清晰表现出来,而且要merge的commits也一目了然, 很适合根据这个来进行code review和讨论。 这个流程的代表是Github, 他们的流程包含一个对自己repo的pull request, 并且用pull request来作为讨论代码的一个工具。可以参看
这种方式需要注意的是因为需要等别人的code review, 代码不能立刻deploy会放慢节奏,而且有可能会因此创建大量的branches, 导致可能要多方merge, 而且也可能会让commit history杂乱。 但确实对于团队的交流非常有好处。
所以就是根据团队的情况做选择了。
是啊,通常都会根据团队情况来定一些公共约定
想請問一下...git fetch段落中的一句:
"需要注意的是: 和push不同, fetch会自动获取远程`新加入'的分支."
感覺應該是筆誤, 應該是和 "git pull" 來比較不同吧? 還是您真的指的是"git push"?
我的文章的确有不少错误, 也有很多内容需要补充, 不过你提的那一点是没错的. 我说的是 git fetch,
如果不加分支, git fetch , 会将远程服务器上的所有分支, 拉到本地的 remote 分支.
你一定要明白一点: 真正将数据从远程服务器 pull 到 本机的是 fetch, 而不是 pull. pull 应该只是调用了 fetch. 然后默认 merge 了一下.
根据我的经验, git pull 和 git fetch 不加参数, 行为是完全一致的.
只有加了 branch 参数,
git pull 会帮你自动合并.
后方可回复, 如果你还没有账号请点击这里 。
共收到 51 条回复git的pull和clone有什么区别?
初学git,有些不明白
按时间排序
clone是本地没有repository时,将远程repository整个下载过来。pull是本地有repository时,将远程repository里新的commit数据(如有的话)下载过来,并且与本地代码merge。
git clone是把整个git项目拷贝下来,包括里面的日志信息,git项目里的分支,你也可以直接切换、使用里面的分支等等git pull相当于git fetch和git merge。其意思是先从远程下载git项目里的文件,然后将文件与本地的分支进行merge。
已有帐号?
无法登录?
社交帐号登录

我要回帖

更多关于 git的pull和fetch 的文章

 

随机推荐