Git详解之三 Git分支

Git分支

几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。

有人把 Git的分支模型称为必杀技特性,而正是因为它,将 Git从版本控制系统家族里区分出来。Git有何特别之处呢?Git的分支可谓是难以置信的轻量级,它的新建操作几乎可以在瞬间完成,并且在不同分支间切换起来也差不多一样快。和许多其他版本控制系统不同,Git鼓励在工作流程中频繁使用分支与合并,哪怕一天之内进行许多次都没有关系。理解分支的概念并熟练运用后,你才会意识到为什么 Git是一个如此强大而独特的工具,并从此真正改变你的开发方式。

 

3.1 何谓分支

为了理解 Git分支的实现方式,我们需要回顾一下 Git是如何储存数据的。或许你还记得第一章的内容,Git保存的不是文件差异或者变化量,而只是一系列文件快照。

Git中提交时,会保存一个提交(commit)对象,该对象包含一个指向暂存内容快照的指针,包含本次提交的作者等相关附属信息,包含零个或多个指向该提交对象的父对象指针:首次提交是没有直接祖先的,普通提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先。

为直观起见,我们假设在工作目录中有三个文件,准备将它们暂存后提交。暂存操作会对每一个文件计算校验和(即第一章中提到的 SHA-1哈希字串),然后把当前版本的文件快照保存到 Git仓库中(Git 使用 blob 类型的对象存储这些快照),并将校验和加入暂存区域:

$ git add README test.rb LICENSE

$ git commit -m 'initial commit of my project'

当使用 gitcommit 新建一个提交对象前,Git会先计算每一个子目录(本例中就是项目根目录)的校验和,然后在 Git 仓库中将这些目录保存为树(tree)对象。之后 Git创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象(项目根目录)的指针,如此它就可以在将来需要的时候,重现此次快照的内容了。

现在,Git仓库中有五个对象:三个表示文件快照内容的 blob对象;一个记录着目录树内容及其中各个文件对应 blob对象索引的 tree 对象;以及一个包含指向 tree 对象(根目录)的索引和其他提交信息元数据的 commit对象。概念上来说,仓库中的各个对象保存的数据和相互关系看起来如图 3-1所示:


3-1. 单个提交对象在仓库中的数据结构

作些修改后再次提交,那么这次的提交对象会包含一个指向上次提交对象的指针(译注:即下图中的 parent对象)。两次提交后,仓库历史会变成图 3-2的样子:


3-2. 多个提交对象之间的链接关系

现在来谈分支。Git中的分支,其实本质上仅仅是个指向 commit对象的可变指针。Git会使用 master 作为分支的默认名字。在若干次提交后,你其实已经有了一个指向最后一次提交对象的 master分支,它在每次提交的时候都会自动向前移动。


3-3. 分支其实就是从某个提交对象往回看的历史

那么,Git又是如何创建一个新的分支的呢?答案很简单,创建一个新的分支指针。比如新建一个 testing分支,可以使用git branch 命令:

$ git branch testing

这会在当前 commit对象上新建一个分支指针(见图 3-4)。


3-4. 多个分支指向提交数据的历史

那么,Git是如何知道你当前在哪个分支上工作的呢?其实答案也很简单,它保存着一个名为 HEAD的特别指针。请注意它和你熟知的许多其他版本控制系统(比如 Subversion CVS)里的 HEAD概念大不相同。在 Git中,它是一个指向你正在工作中的本地分支的指针(译注:将 HEAD想象为当前分支的别名。)。运行git branch 命令,仅仅是建立了一个新的分支,但不会自动切换到这个分支中去,所以在这个例子中,我们依然还在 master分支里工作(参考图 3-5)。


3-5. HEAD指向当前所在的分支

要切换到其他分支,可以执行 gitcheckout 命令。我们现在转换到新建的testing分支:

$ git checkout testing

这样 HEAD就指向了 testing分支(见图3-6)。


3-6. HEAD在你转换分支时指向新的分支

这样的实现方式会给我们带来什么好处呢?好吧,现在不妨再提交一次:

$ vim test.rb

$ git commit -a -m 'made a change'

3-7展示了提交后的结果。


3-7. 每次提交后HEAD 随着分支一起向前移动

非常有趣,现在 testing分支向前移动了一格,而 master分支仍然指向原先 git checkout 时所在的commit对象。现在我们回到master分支看看:

$ git checkout master

3-8显示了结果。


3-8. HEAD在一次checkout之后移动到了另一个分支

这条命令做了两件事。它把 HEAD指针移回到 master分支,并把工作目录中的文件换成了 master分支所指向的快照内容。也就是说,现在开始所做的改动,将始于本项目中一个较老的版本。它的主要作用是将 testing分支里作出的修改暂时取消,这样你就可以向另一个方向进行开发。

我们作些修改后再次提交:

$ vim test.rb

$ git commit -a -m 'made other changes'

现在我们的项目提交历史产生了分叉(如图 3-9所示),因为刚才我们创建了一个分支,转换到其中进行了一些工作,然后又回到原来的主分支进行了另外一些工作。这些改变分别孤立在不同的分支里:我们可以在不同分支里反复切换,并在时机成熟时把它们合并到一起。而所有这些工作,仅仅需要branch  checkout 这两条命令就可以完成。


3-9. 不同流向的分支历史

由于 Git中的分支实际上仅是一个包含所指对象校验和(40个字符长度 SHA-1字串)的文件,所以创建和销毁一个分支就变得非常廉价。说白了,新建一个分支就是向一个文件写入 41个字节(外加一个换行符)那么简单,当然也就很快了。

这和大多数版本控制系统形成了鲜明对比,它们管理分支大多采取备份所有项目文件到特定目录的方式,所以根据项目文件数量和大小不同,可能花费的时间也会有相当大的差别,快则几秒,慢则数分钟。而 Git的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。同时,因为每次提交时都记录了祖先信息(译注:即parent 对象),将来要合并分支时,寻找恰当的合并基础(译注:即共同祖先)的工作其实已经自然而然地摆在那里了,所以实现起来非常容易。Git鼓励开发者频繁使用分支,正是因为有着这些特性作保障。

接下来看看,我们为什么应该频繁使用分支。

 

3.2 分支的新建与合并

现在让我们来看一个简单的分支与合并的例子,实际工作中大体也会用到这样的工作流程:

1. 开发某个网站。 2.为实现某个新的需求,创建一个分支。 3.在这个分支上开展工作。

假设此时,你突然接到一个电话说有个很严重的问题需要紧急修补,那么可以按照下面的方式处理:

1. 返回到原先已经发布到生产服务器上的分支。 2.为这次紧急修补建立一个新分支,并在其中修复问题。 3.通过测试后,回到生产服务器所在的分支,将修补分支合并进来,然后再推送到生产服务器上。 4.切换到之前实现新需求的分支,继续工作。

分支的新建与切换

首先,我们假设你正在项目中愉快地工作,并且已经提交了几次更新(见图 3-10)。


3-10. 一个简短的提交历史

现在,你决定要修补问题追踪系统上的 #53问题。顺带说明下,Git并不同任何特定的问题追踪系统打交道。这里为了说明要解决的问题,才把新建的分支取名为 iss53。要新建并切换到该分支,运行git checkout 并加上 -b 参数:

$ git checkout -b iss53

Switched to a new branch "iss53"

这相当于执行下面这两条命令:

$ git branch iss53

$ git checkout iss53

3-11示意该命令的执行结果。


3-11. 创建了一个新分支的指针

接着你开始尝试修复问题,在提交了若干次更新后,iss53 分支的指针也会随着向前推进,因为它就是当前分支(换句话说,当前的 HEAD 指针正指向 iss53,见图 3-12):

$ vim index.html

$ git commit -a -m 'added a new footer [issue 53]'


3-12.iss53分支随工作进展向前推进

现在你就接到了那个网站问题的紧急电话,需要马上修补。有了 Git,我们就不需要同时发布这个补丁和 iss53 里作出的修改,也不需要在创建和发布该补丁到服务器之前花费大力气来复原这些修改。唯一需要的仅仅是切换回master 分支。

不过在此之前,留心你的暂存区或者工作目录里,那些还没有提交的修改,它会和你即将检出的分支产生冲突从而阻止 Git为你切换分支。切换分支的时候最好保持一个清洁的工作区域。稍后会介绍几个绕过这种问题的办法(分别叫做 stashing commit amending)。目前已经提交了所有的修改,所以接下来可以正常转换到master 分支:

$ git checkout master

Switched to branch "master"

此时工作目录中的内容和你在解决问题 #53之前一模一样,你可以集中精力进行紧急修补。这一点值得牢记:Git会把工作目录的内容恢复为检出某分支时它所指向的那个提交对象的快照。它会自动添加、删除和修改文件以确保目录的内容和你当时提交时完全一样。

接下来,你得进行紧急修补。我们创建一个紧急修补分支 hotfix 来开展工作,直到搞定(见图3-13):

$ git checkout -b 'hotfix'

Switched to a new branch "hotfix"

$ vim index.html

$ git commit -a -m 'fixed the broken email address'

[hotfix]: created 3a0874c: "fixed the broken emailaddress"

 1 files changed, 0insertions(+), 1 deletions(-)


3-13.hotfix分支是从master 分支所在点分化出来的

有必要作些测试,确保修补是成功的,然后回到 master 分支并把它合并进来,然后发布到生产服务器。用 gitmerge 命令来进行合并:

$ git checkout master

$ git merge hotfix

Updating f42c576..3a0874c

Fast forward

 README |    1 -

 1 files changed, 0insertions(+), 1 deletions(-)

请注意,合并时出现了“Fast forward”的提示。由于当前 master 分支所在的提交对象是要并入的 hotfix 分支的直接上游,Git只需把master 分支指针直接右移。换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。

现在最新的修改已经在当前 master 分支所指向的提交对象中了,可以部署到生产服务器上去了(见图 3-14)。


3-14. 合并之后,master分支和hotfix分支指向同一位置。

在那个超级重要的修补发布以后,你想要回到被打扰之前的工作。由于当前 hotfix 分支和 master 都指向相同的提交对象,所以hotfix 已经完成了历史使命,可以删掉了。使用 git branch  -d 选项执行删除操作:

$ git branch -d hotfix

Deleted branch hotfix (3a0874c).

现在回到之前未完成的 #53问题修复分支上继续工作(图 3-15):

$ git checkout iss53

Switched to branch "iss53"

$ vim index.html

$ git commit -a -m 'finished the new footer [issue 53]'

[iss53]: created ad82d7a: "finished the new footer[issue 53]"

 1 files changed, 1insertions(+), 0 deletions(-)


3-15. iss53分支可以不受影响继续推进。

不用担心之前 hotfix 分支的修改内容尚未包含到 iss53 中来。如果确实需要纳入此次修补,可以用git merge master  master分支合并到 iss53;或者等 iss53 完成之后,再将iss53 分支中的更新并入 master

分支的合并

在问题 #53相关的工作完成之后,可以合并回 master 分支。实际操作同前面合并 hotfix 分支差不多,只需回到master 分支,运行 git merge 命令指定要合并进来的分支:

$ git checkout master

$ git merge iss53

Merge made by recursive.

 README |    1 +

 1 files changed, 1insertions(+), 0 deletions(-)

请注意,这次合并操作的底层实现,并不同于之前 hotfix 的并入方式。因为这次你的开发历史是从更早的地方开始分叉的。由于当前 master 分支所指向的提交对象(C4)并不是 iss53 分支的直接祖先,Git不得不进行一些额外处理。就此例而言,Git会用两个分支的末端(C4 C5)以及它们的共同祖先(C2)进行一次简单的三方合并计算。图 3-16用红框标出了 Git 用于合并的三个提交对象:


3-16. Git为分支合并自动识别出最佳的同源合并点。

这次,Git没有简单地把分支指针右移,而是对三方合并后的结果重新做一个新的快照,并自动创建一个指向它的提交对象(C6)(见图 3-17)。这个提交对象比较特殊,它有两个祖先(C4 C5)。

值得一提的是 Git可以自己裁决哪个共同祖先才是最佳合并基础;这和 CVS Subversion1.5以后的版本)不同,它们需要开发者手工指定合并基础。所以此特性让 Git的合并操作比其他系统都要简单不少。


3-17. Git自动创建了一个包含了合并结果的提交对象。

既然之前的工作成果已经合并到 master 了,那么 iss53 也就没用了。你可以就此删除它,并在问题追踪系统里关闭该问题。

$ git branch -d iss53

遇到冲突时的分支合并

有时候合并操作并不会如此顺利。如果在不同的分支中都修改了同一个文件的同一部分,Git就无法干净地把两者合到一起(译注:逻辑上说,这种问题只能由人来裁决。)。如果你在解决问题 #53的过程中修改了hotfix 中修改的部分,将得到类似下面的结果:

$ git merge iss53

Auto-merging index.html

CONFLICT (content): Merge conflict in index.html

Automatic merge failed; fix conflicts and then commit theresult.

Git 作了合并,但没有提交,它会停下来等你解决冲突。要看看哪些文件在合并时发生冲突,可以用 git status 查阅:

[master*]$ git status

index.html: needs merge

# On branch master

# Changed but not updated:

#   (use "gitadd

   

   

   

   

   

    

    

    

    

     ..." toupdate what will be committed)

#   (use "gitcheckout --

    

    

    

    

    

     

     

     

     

      ..." todiscard changes in working directory)

#

#       unmerged:   index.html

#

    

    

    

    

    

   

   

   

   

   

任何包含未解决冲突的文件都会以未合并(unmerged)的状态列出。Git会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。可以看到此文件包含类似下面这样的部分:

<<<<<<< HEAD:index.html

   

   

   

   

   

 

    

    

    

    

     contact :email.support@github.com

   

   

   

   

   

 

=======

   

   

   

   

   

 

    

    

    

    

    

  please contact usat support@github.com

   

   

   

   

   

 

>>>>>>> iss53:index.html

可以看到 ======= 隔开的上半部分,是 HEAD(即 master 分支,在运行merge 命令时所切换到的分支)中的内容,下半部分是在 iss53 分支中的内容。解决冲突的办法无非是二者选其一或者由你亲自整合到一起。比如你可以通过把这段内容替换为下面这样来解决:

 

   

   

   

   

   

 

    

     

    

    

    

please contact us at email.support@github.com

   

   

   

   

   

 

这个解决方案各采纳了两个分支中的一部分内容,而且我还删除了 <<<<<<<=======  >>>>>>> 这些行。在解决了所有文件里的所有冲突后,运行 git add 将把它们标记为已解决状态(译注:实际上就是来一次快照保存到暂存区域。)。因为一旦暂存,就表示冲突已经解决。如果你想用一个有图形界面的工具来解决这些问题,不妨运行git mergetool,它会调用一个可视化的合并工具并引导你解决所有冲突:

$ git mergetool

merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiffopendiff emerge vimdiff

Merging the files: index.html

 

Normal merge conflict for 'index.html':

  {local}: modified

  {remote}:modified

Hit return to start merge resolution tool (opendiff):

如果不想用默认的合并工具(Git为我默认选择了 opendiff,因为我在 Mac上运行了该命令),你可以在上方”merge tool candidates”里找到可用的合并工具列表,输入你想用的工具名。我们将在第七章讨论怎样改变环境中的默认值。

退出合并工具以后,Git会询问你合并是否成功。如果回答是,它会为你把相关文件暂存起来,以表明状态为已解决。

再运行一次 gitstatus 来确认所有冲突都已解决:

$ git status

# On branch master

# Changes to be committed:

#   (use "gitreset HEAD

   

   

   

   

   

    

    

    

    

     ..." tounstage)

#

#       modified:   index.html

#

   

   

   

   

   

如果觉得满意了,并且确认所有冲突都已解决,也就是进入了暂存区,就可以用 git commit 来完成这次合并提交。提交的记录差不多是这样:

Merge branch 'iss53'

 

Conflicts:

  index.html

#

# It looks like you may be committing a MERGE.

# If this is not correct, please remove the file

# .git/MERGE_HEAD

# and try again.

#

如果想给将来看这次合并的人一些方便,可以修改该信息,提供更多合并细节。比如你都作了哪些改动,以及这么做的原因。有时候裁决冲突的理由并不直接或明显,有必要略加注解。

 

3.3 分支的管理

到目前为止,你已经学会了如何创建、合并和删除分支。除此之外,我们还需要学习如何管理分支,在日后的常规工作中会经常用到下面介绍的管理命令。

gitbranch 命令不仅仅能创建和删除分支,如果不加任何参数,它会给出当前所有分支的清单:

$ git branch

  iss53

* master

  testing

注意看 master 分支前的 * 字符:它表示当前所在的分支。也就是说,如果现在提交更新,master 分支将随着开发进度前移。若要查看各个分支最后一个提交对象的信息,运行git branch -v

$ git branch -v

  iss53   93b412c fix javascript issue

* master  7a98805Merge branch 'iss53'

  testing 782fd34add scott to the author list in the readmes

要从该清单中筛选出你已经(或尚未)与当前分支合并的分支,可以用 --merge  --no-merged 选项(Git 1.5.6 以上版本)。比如用git branch --merge 查看哪些分支已被并入当前分支(译注:也就是说哪些分支是当前分支的直接上游。):

$ git branch --merged

  iss53

* master

之前我们已经合并了 iss53,所以在这里会看到它。一般来说,列表中没有 * 的分支通常都可以用 git branch -d 来删掉。原因很简单,既然已经把它们所包含的工作整合到了其他分支,删掉也不会损失什么。

另外可以用 gitbranch --no-merged 查看尚未合并的工作:

$ git branch --no-merged

  testing

它会显示还未合并进来的分支。由于这些分支中还包含着尚未合并进来的工作成果,所以简单地用 git branch -d 删除该分支会提示错误,因为那样做会丢失数据:

$ git branch -d testing

error: The branch 'testing' is not an ancestor of yourcurrent HEAD.

If you are sure you want to delete it, run 'git branch -Dtesting'.

不过,如果你确实想要删除该分支上的改动,可以用大写的删除选项 -D 强制执行,就像上面提示信息中给出的那样。

3.4 利用分支进行开发的工作流程

现在我们已经学会了新建分支和合并分支,可以(或应该)用它来做点什么呢?在本节,我们会介绍一些利用分支进行开发的工作流程。而正是由于分支管理的便捷,才衍生出了这类典型的工作模式,你可以根据项目的实际情况选择一种用用看。

长期分支

由于 Git使用简单的三方合并,所以就算在较长一段时间内,反复多次把某个分支合并到另一分支,也不是什么难事。也就是说,你可以同时拥有多个开放的分支,每个分支用于完成特定的任务,随着开发的推进,你可以随时把某个特性分支的成果并到其他分支中。

许多使用 Git的开发者都喜欢用这种方式来开展工作,比如仅在 master 分支中保留完全稳定的代码,即已经发布或即将发布的代码。与此同时,他们还有一个名为develop  next 的平行分支,专门用于后续的开发,或仅用于稳定性测试当然并不是说一定要绝对稳定,不过一旦进入某种稳定状态,便可以把它合并到master 里。这样,在确保这些已完成的特性分支(短期分支,比如之前的 iss53 分支)能够通过所有测试,并且不会引入更多错误之后,就可以并到主干分支中,等待下一次的发布。

本质上我们刚才谈论的,是随着提交对象不断右移的指针。稳定分支的指针总是在提交历史中落后一大截,而前沿分支总是比较靠前(见图 3-18)。


3-18. 稳定分支总是比较老旧。

或者把它们想象成工作流水线,或许更好理解一些,经过测试的提交对象集合被遴选到更稳定的流水线(见图 3-19)。


3-19. 想象成流水线可能会容易点。

你可以用这招维护不同层次的稳定性。某些大项目还会有个 proposed(建议)或 puproposed updates,建议更新)分支,它包含着那些可能还没有成熟到进入next  master 的内容。这么做的目的是拥有不同层次的稳定性:当这些分支进入到更稳定的水平时,再把它们合并到更高层分支中去。再次说明下,使用多个长期分支的做法并非必需,不过一般来说,对于特大型项目或特复杂的项目,这么做确实更容易管理。

特性分支

在任何规模的项目中都可以使用特性(Topic)分支。一个特性分支是指一个短期的,用来实现单一特性或与其相关工作的分支。可能你在以前的版本控制系统里从未做过类似这样的事情,因为通常创建与合并分支消耗太大。然而在 Git 中,一天之内建立、使用、合并再删除多个分支是常见的事。

我们在上节的例子里已经见过这种用法了。我们创建了 iss53  hotfix 这两个特性分支,在提交了若干更新后,把它们合并到主干分支,然后删除。该技术允许你迅速且完全的进行语境切换因为你的工作分散在不同的流水线里,每个分支里的改变都和它的目标特性相关,浏览代码之类的事情因而变得更简单了。你可以把作出的改变保持在特性分支中几分钟,几天甚至几个月,等它们成熟以后再合并,而不用在乎它们建立的顺序或者进度。

现在我们来看一个实际的例子。请看图 3-20,由下往上,起先我们在 master 工作到 C1,然后开始一个新分支 iss91 尝试修复 91号缺陷,提交到 C6 的时候,又冒出一个解决该问题的新办法,于是从之前 C4的地方又分出一个分支iss91v2,干到 C8的时候,又回到主干 master 中提交了 C9 C10,再回到 iss91v2 继续工作,提交 C11,接着,又冒出个不太确定的想法,从 master 的最新提交C10处开了个新的分支dumbidea 做些试验。


3-20. 拥有多个特性分支的提交历史。

现在,假定两件事情:我们最终决定使用第二个解决方案,即 iss91v2 中的办法;另外,我们把 dumbidea 分支拿给同事们看了以后,发现它竟然是个天才之作。所以接下来,我们准备抛弃原来的iss91 分支(实际上会丢弃 C5 C6),直接在主干中并入另外两个分支。最终的提交历史将变成图 3-21这样:


3-21. 合并了dumbidea iss91v2 后的分支历史。

请务必牢记这些分支全部都是本地分支,这一点很重要。当你在使用分支及合并的时候,一切都是在你自己的 Git仓库中进行的完全不涉及与服务器的交互。

 

3.5 远程分支

远程分支(remote branch)是对远程仓库中的分支的索引。它们是一些无法移动的本地分支;只有在 Git进行网络交互时才会更新。远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置。

我们用 (远程仓库名)/(分支名) 这样的形式表示远程分支。比如我们想看看上次同 origin 仓库通讯时master 的样子,就应该查看 origin/master 分支。如果你和同伴一起修复某个问题,但他们先推送了一个iss53 分支到远程仓库,虽然你可能也有一个本地的 iss53 分支,但指向服务器上最新更新的却应该是 origin/iss53 分支。

可能有点乱,我们不妨举例说明。假设你们团队有个地址为 git.ourcompany.com  Git 服务器。如果你从这里克隆,Git会自动为你将此远程仓库命名为origin,并下载其中所有的数据,建立一个指向它的 master 分支的指针,在本地命名为origin/master,但你无法在本地更改其数据。接着,Git建立一个属于你自己的本地master 分支,始于 origin  master分支相同的位置,你可以就此开始工作(见图 3-22):


3-22. 一次 Git 克隆会建立你自己的本地分支master和远程分支origin/master,它们都指向 origin/master分支的最后一次提交。

如果你在本地 master 分支做了些改动,与此同时,其他人向 git.ourcompany.com 推送了他们的更新,那么服务器上的master 分支就会向前推进,而于此同时,你在本地的提交历史正朝向不同方向发展。不过只要你不和服务器通讯,你的origin/master 指针仍然保持原位不会移动(见图 3-23)。


3-23. 在本地工作的同时有人向远程仓库推送内容会让提交历史开始分流。

可以运行 gitfetch origin 来同步远程服务器上的数据到本地。该命令首先找到 origin 是哪个服务器(本例为git.ourcompany.com),从上面获取你尚未拥有的数据,更新你本地的数据库,然后把 origin/master 的指针移到它最新的位置上(见图 3-24)。


3-24. gitfetch命令会更新remote索引。

为了演示拥有多个远程分支(在不同的远程服务器上)的项目是如何工作的,我们假设你还有另一个仅供你的敏捷开发小组使用的内部服务器 git.team1.ourcompany.com。可以用第二章中提到的git remote add 命令把它加为当前项目的远程分支之一。我们把它命名为 teamone,以便代替原始的 Git 地址(见图 3-25)。


3-25. 把另一个服务器加为远程仓库

现在你可以用 gitfetch teamone 来获取小组服务器上你还没有的数据了。由于当前该服务器上的内容是你 origin 服务器上的子集,Git不会下载任何数据,而只是简单地创建一个名为teamone/master 的分支,指向 teamone 服务器上 master 分支所在的提交对象31b8e(见图 3-26)。


3-26. 你在本地有了一个指向teamone 服务器上 master 分支的索引。

推送本地分支

要想和其他人分享某个本地分支,你需要把它推送到一个你拥有写权限的远程仓库。你的本地分支不会被自动同步到你引入的远程服务器上,除非你明确执行推送操作。换句话说,对于无意分享的分支,你尽管保留为私人分支好了,而只推送那些协同工作要用到的特性分支。

如果你有个叫 serverfix 的分支需要和他人一起开发,可以运行 git push (远程仓库名) (分支名)

$ git push origin serverfix

Counting objects: 20, done.

Compressing objects: 100% (14/14), done.

Writing objects: 100% (15/15), 1.74 KiB, done.

Total 15 (delta 5), reused 0 (delta 0)

To git@github.com:schacon/simplegit.git

 * [newbranch]      serverfix -> serverfix

这其实有点像条捷径。Git自动把 serverfix 分支名扩展为 refs/heads/serverfix:refs/heads/serverfix,意为取出我在本地的serverfix分支,推送到远程仓库的 serverfix分支中去。我们将在第九章进一步介绍refs/heads/ 部分的细节,不过一般使用的时候都可以省略它。也可以运行 git push origin serverfix:serferfix 来实现相同的效果,它的意思是上传我本地的 serverfix分支到远程仓库中去,仍旧称它为 serverfix分支。通过此语法,你可以把本地分支推送到某个命名不同的远程分支:若想把远程分支叫作awesomebranch,可以用 git push origin serverfix:awesomebranch 来推送数据。

接下来,当你的协作者再次从服务器上获取数据时,他们将得到一个新的远程分支 origin/serverfix

$ git fetch origin

remote: Counting objects: 20, done.

remote: Compressing objects: 100% (14/14), done.

remote: Total 15 (delta 5), reused 0 (delta 0)

Unpacking objects: 100% (15/15), done.

From git@github.com:schacon/simplegit

 * [newbranch]      serverfix    -> origin/serverfix

值得注意的是,在 fetch 操作下载好新的远程分支之后,你仍然无法在本地编辑该远程仓库中的分支。换句话说,在本例中,你不会有一个新的serverfix 分支,有的只是一个你无法移动的 origin/serverfix 指针。

如果要把该内容合并到当前分支,可以运行 git merge origin/serverfix。如果想要一份自己的 serverfix 来开发,可以在远程分支的基础上分化出一个新的分支来:

$ git checkout -b serverfix origin/serverfix

Branch serverfix set up to track remote branchrefs/remotes/origin/serverfix.

Switched to a new branch "serverfix"

这会切换到新建的 serverfix 本地分支,其内容同远程分支 origin/serverfix 一致,这样你就可以在里面继续开发了。

跟踪远程分支

从远程分支 checkout 出来的本地分支,称为_跟踪分支(tracking branch)_。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入git pushGit会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。

在克隆仓库时,Git通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是git push  git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如origin 上除了 master 之外的其它分支。刚才我们已经看到了这样的一个例子:git checkout -b [分支名] [远程名]/[分支名]。如果你有1.6.2以上版本的Git,还可以用--track 选项简化:

$ git checkout --track origin/serverfix

Branch serverfix set up to track remote branchrefs/remotes/origin/serverfix.

Switched to a new branch "serverfix"

要为本地分支设定不同于远程分支的名字,只需在前个版本的命令里换个名字:

$ git checkout -b sf origin/serverfix

Branch sf set up to track remote branchrefs/remotes/origin/serverfix.

Switched to a new branch "sf"

现在你的本地分支 sf 会自动向 origin/serverfix 推送和抓取数据了。

删除远程分支

如果不再需要某个远程分支了,比如搞定了某个特性并把它合并进了远程的 master 分支(或任何其他存放稳定代码的地方),可以用这个非常无厘头的语法来删除它:git push [远程名] :[分支名]。如果想在服务器上删除serverfix 分支,运行下面的命令:

$ git push origin :serverfix

To git@github.com:schacon/simplegit.git

 - [deleted]         serverfix

咚!服务器上的分支没了。你最好特别留心这一页,因为你一定会用到那个命令,而且你很可能会忘掉它的语法。有种方便记忆这条命令的方法:记住我们不久前见过的 git push [远程名] [本地分支]:[远程分支] 语法,如果省略 [本地分支],那就等于是在说在这里提取空白然后把它变成[远程分支]

 

3.6 分支的衍合

把一个分支整合到另一个分支的办法有两种:merge  rebase(译注:rebase 的翻译暂定为衍合,大家知道就可以了。)。在本章我们会学习什么是衍合,如何使用衍合,为什么衍合操作如此富有魅力,以及我们应该在什么情况下使用衍合。

基本的衍合操作

请回顾之前有关合并的一节(见图 3-27),你会看到开发进程分叉到两个不同分支,又各自提交了更新。


3-27. 最初分叉的提交历史。

之前介绍过,最容易的整合分支的方法是 merge 命令,它会把两个分支最新的快照(C3 C4)以及二者最新的共同祖先(C2)进行三方合并,合并的结果是产生一个新的提交对象(C5)。如图 3-28 所示:


3-28. 通过合并一个分支来整合分叉了的历史。

其实,还有另外一个选择:你可以把在 C3里产生的变化补丁在 C4的基础上重新打一遍。在 Git里,这种操作叫做_衍合(rebase_。有了 rebase 命令,就可以把在一个分支里提交的改变移到另一个分支里重放一遍。

在上面这个例子中,运行:

$ git checkout experiment

$ git rebase master

First, rewinding head to replay your work on top of it...

Applying: added staged command

它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支 experiment)后续的历次提交对象(这里只有一个 C3),生成一系列文件补丁,然后以基底分支(也就是主干分支master)最后一个提交对象(C4)为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象(C3’),从而改写 experiment 的提交历史,使它成为 master 分支的直接下游,如图 3-29 所示:


3-29. C3 里产生的改变到 C4上重演一遍。

现在回到 master 分支,进行一次快进合并(见图 3-30):


3-30.master分支的快进。

现在的 C3’对应的快照,其实和普通的三方合并,即上个例子中的 C5对应的快照内容一模一样了。虽然最后整合得到的结果没有任何区别,但衍合能产生一个更为整洁的提交历史。如果视察一个衍合过的分支的历史记录,看起来会更清楚:仿佛所有修改都是在一根线上先后进行的,尽管实际上它们原本是同时并行发生的。

一般我们使用衍合的目的,是想要得到一个能在远程分支上干净应用的补丁比如某些项目你不是维护者,但想帮点忙的话,最好用衍合:先在自己的一个分支里进行开发,当准备向主项目提交补丁的时候,根据最新的origin/master 进行一次衍合操作然后再提交,这样维护者就不需要做任何整合工作(译注:实际上是把解决分支补丁同最新主干代码之间冲突的责任,化转为由提交补丁的人来解决。),只需根据你提供的仓库地址作一次快进合并,或者直接采纳你提交的补丁。

请注意,合并结果中最后一次提交所指向的快照,无论是通过衍合,还是三方合并,都会得到相同的快照内容,只不过提交历史不同罢了。衍合是按照每行的修改次序重演一遍修改,而合并是把最终结果合在一起。

有趣的衍合

衍合也可以放到其他分支进行,并不一定非得根据分化之前的分支。以图 3-31的历史为例,我们为了给服务器端代码添加一些功能而创建了特性分支 server,然后提交 C3 C4。然后又从 C3的地方再增加一个client 分支来对客户端代码进行一些相应修改,所以提交了 C8 C9。最后,又回到 server 分支提交了C10


3-31. 从一个特性分支里再分出一个特性分支的历史。

假设在接下来的一次软件发布中,我们决定先把客户端的修改并到主线中,而暂缓并入服务端软件的修改(因为还需要进一步测试)。这个时候,我们就可以把基于 server 分支而非 master 分支的改变(即 C8 C9),跳过 server 直接放到master 分支中重演一遍,但这需要用 git rebase  --onto 选项指定新的基底分支master

$ git rebase --onto master server client

这好比在说:取出 client 分支,找出 client 分支和 server 分支的共同祖先之后的变化,然后把它们在master 上重演一遍。是不是有点复杂?不过它的结果如图 3-32 所示,非常酷(译注:虽然 client 里的 C8, C9 C3 之后,但这仅表明时间上的先后,而非在 C3修改的基础上进一步改动,因为server  client 这两个分支对应的代码应该是两套文件,虽然这么说不是很严格,但应理解为在 C3 时间点之后,对另外的文件所做的 C8C9修改,放到主干重演。):


3-32. 将特性分支上的另一个特性分支衍合到其他分支。

现在可以快进 master 分支了(见图 3-33):

$ git checkout master

$ git merge client


3-33. 快进 master 分支,使之包含client分支的变化。

现在我们决定把 server 分支的变化也包含进来。我们可以直接把 server 分支衍合到 master,而不用手工切换到 server 分支后再执行衍合操作— git rebase [主分支] [特性分支] 命令会先取出特性分支server,然后在主分支 master 上重演:

$ git rebase master server

于是,server 的进度应用到 master 的基础上,如图 3-34 所示:


3-34. master 分支上衍合server分支。

然后就可以快进主干分支 master 了:

$ git checkout master

$ git merge server

现在 client  server 分支的变化都已经集成到主干分支来了,可以删掉它们了。最终我们的提交历史会变成图 3-35 的样子:

$ git branch -d client

$ git branch -d server


3-35. 最终的提交历史

衍合的风险

呃,奇妙的衍合也并非完美无缺,要用它得遵守一条准则:

一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。

如果你遵循这条金科玉律,就不会出差错。否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。

在进行衍合的时候,实际上抛弃了一些现存的提交对象而创造了一些类似但不同的新的提交对象。如果你把原来分支中的提交对象发布出去,并且其他人更新下载后在其基础上开展工作,而稍后你又用git rebase 抛弃这些提交对象,把新的重演后的提交对象发布出去的话,你的合作者就不得不重新合并他们的工作,这样当你再次从他们那里获取内容时,提交历史就会变得一团糟。

下面我们用一个实际例子来说明为什么公开的衍合会带来问题。假设你从一个中央服务器克隆然后在它的基础上搞了一些开发,提交历史类似图 3-36所示:


3-36. 克隆一个仓库,在其基础上工作一番。

现在,某人在 C1的基础上做了些改变,并合并他自己的分支得到结果 C6,推送到中央服务器。当你抓取并合并这些数据到你本地的开发分支中后,会得到合并结果 C7,历史提交会变成图 3-37 这样:


3-37. 抓取他人提交,并入自己主干。

接下来,那个推送 C6上来的人决定用衍合取代之前的合并操作;继而又用 git push --force 覆盖了服务器上的历史,得到C4’。而之后当你再从服务器上下载最新提交后,会得到:


3-38. 有人推送了衍合后得到的C4’,丢弃了你作为开发基础的 C4 C6

下载更新后需要合并,但此时衍合产生的提交对象 C4’ SHA-1 校验值和之前 C4 完全不同,所以 Git会把它们当作新的提交对象处理,而实际上此刻你的提交历史 C7中早已经包含了 C4 的修改内容,于是合并操作会把 C7 C4’ 合并为 C8(见图 3-39:


3-39. 你把相同的内容又合并了一遍,生成一个新的提交 C8

C8 这一步的合并是迟早会发生的,因为只有这样你才能和其他协作者提交的内容保持同步。而在 C8之后,你的提交历史里就会同时包含 C4 C4’,两者有着不同的 SHA-1校验值,如果用git log 查看历史,会看到两个提交拥有相同的作者日期与说明,令人费解。而更糟的是,当你把这样的历史推送到服务器后,会再次把这些衍合后的提交引入到中央服务器,进一步困扰其他人(译注:这个例子中,出问题的责任方是那个发布了 C6 后又用衍合发布 C4’的人,其他人会因此反馈双重历史到共享主干,从而混淆大家的视听。)。

如果把衍合当成一种在推送之前清理提交历史的手段,而且仅仅衍合那些尚未公开的提交对象,就没问题。如果衍合那些已经公开的提交对象,并且已经有人基于这些提交对象开展了后续开发工作的话,就会出现叫人沮丧的麻烦。

3.7 小结

读到这里,你应该已经学会了如何创建分支并切换到新分支,在不同分支间转换,合并本地分支,把分支推送到共享服务器上,使用共享分支与他人协作,以及在分享之前进行衍合。

 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 使用wangEditor轻量级的富文本编辑器,来批量上传图片

    1.wangEditor编辑器wangEditor官网 相对其他几个编辑器来说, wangEditor还是比较功能齐全的, 而且用起来上手也快.缺点就是表情不多, 就内置了几个新浪表情和emoji, 不过可以自己拓展 , 然后菜单的图标也不太好看2. 初始化点击 https://github.com/wangfupeng1988/wangEditor/…...

    2024/4/20 23:35:14
  2. 负载均衡(lvs+keepalive 比较详细的安装配置文档)

    转载http://5iwww.blog.51cto.com/856039/267278lvs说明:目前有三种IP负载均衡技术(VS/NAT、VS/TUN和VS/DR);八种调度算法(rr,wrr,lc,wlc,lblc,lblcr,dh,sh)。在调度器的实现技术中,IP负载均衡技术是效率最高的。在已有的IP负载均衡技术中有通过网络地址转换(Network Ad…...

    2024/4/20 23:35:13
  3. 编程入门教程

    一 Basic入门 一个基本Basic程序 某班32人,电脑成绩如下:A等(5分)13人,B等(4分)12人,C等(3分)5人,D等(2分)2人,求全班该科目平均成绩 10 LET A=13 20 LET B=12 30 LET C=5 40 LET D=2 50 LET U=A+B+C+D 60 LET G=(5*A+4*B+3*C+2*D)/U 70 PRINT G 80 END …...

    2024/4/20 6:58:42
  4. CSS和JavaScript在线代码压缩工具推荐

    网页前端的JavaScript代码编写好之后,不像C语言会编译成机器码,作为脚本语言,JavaScript是直接从源码文件执行的。通常为了节省空间,可以把代码进行压缩,去掉多余的空格和换行等(代码可以全部写到一行,这个有点像C语言)。同样HTML,CSS等代码也可以进行这样的压缩操作。…...

    2024/5/5 7:43:51
  5. 富文本编辑器ueditor 自定义工具栏配置

    UEditor定制工具栏图标UEditor 工具栏上的按钮列表可以自定义配置,只需要通过修改配置项就可以实现需求配置项修改说明修改配置项的方法: 1. 方法一:修改 ueditor.config.js 里面的 toolbars 2. 方法二:实例化编辑器的时候传入 toolbars 参数var ue = UE.getEditor(containe…...

    2024/5/5 8:00:05
  6. asp.net利用RAR实现文件压缩解压缩【月儿原创】

    asp.net利用RAR实现文件压缩解压缩 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/ 时间:2007.6.13 如果服务器上安装了RAR程序,那么asp.net可以调用RAR实现文件压缩与解压缩。 不过要注意的是,由于Web程序不能直接调用客户端的程序(除非用ActiveX,Acti…...

    2024/4/20 23:35:10
  7. 总结apache2.2和2.4和tomcat负载均衡配置和总结。

    apache负载均衡有3种方式,本人只搭配了两种方式 一.mok_jk方式(目前这个方式只配置成功2.2版本,2.4未配置。) 1.apache2.2配置准备工作 1.1下载安装包httpd-2.2.22-win32-x86-no_ssl.msi 1.11下载后安装到指定文件夹。如:F:\apache22 1.2下载mod_jk-1.2.31-httpd-2.2.3.so 1…...

    2024/4/29 3:46:04
  8. tomcat启用gzip压缩提高浏览网站的速度

    一、场景HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网 页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解 压缩并浏览 对于Tomcat5.0以后的版本是支持对输出内容进行压缩的。使用的是gzip压缩格式 。 gzip压缩是非常流行的一种数据…...

    2024/4/20 23:35:09
  9. 为什么我们要使用ssh框架技术,及感想

    前言: 在公司从C++转向Java Web方向大概有3个月(11月初-1月底)了。三个月前对Java和Web还几乎是零基础。然后从安装Eclipse,MySQL,tomcat开始,到学习HTML/CSS/Javascript,JQuery,JSP,SQL,在项目已有的架构Spring-Struts-Hibernate上,开始加入新的功能页等。这三个月,…...

    2024/4/23 2:28:10
  10. 浙江大学公开课《王阳明心学》

    浙江大学公开课:王阳明心学第一课 导论:王阳明与阳明心学王阳明达到了真三不朽,立言,立德,立功,然而在他年轻的时候,其实是走过很多“弯路”的。兴趣广泛的他骑马射箭,吟诗作对。12岁的时候再私塾里对老师的一番对话说要读书做圣人,这就是年少立志,人永远在成为他期盼…...

    2024/4/20 23:35:06
  11. 22种web内嵌编辑器

    1 简单介绍富-文本编辑器,内联内容编辑器,10 个基于 JavaScript 的 WYSIWYG(所见即所得) 编辑器-或任何一种都可以使用,作为web应用,在网站中允许用户输入,编辑和操纵字母数字字符。可能只是个<textarea>标签,使用富文本编辑器也可以使其可用性改善。 总之, We…...

    2024/4/20 23:35:05
  12. Nginx+Sticky实现负载均衡(1)

    Nginx拓展Sticky块根据cookie实现负载均衡1. 下载nginx-1.4.7.tar.gz 下载sticky扩展模块 2配置服务器 Nginx:192.168.100.10 Tomcat1:192.168.100.12:8080 Tomcat2:192.168.100.13:80803测试网页 动态网页:ip:8080/index.jsp #Tomcat1显示:this is the first serser …...

    2024/4/20 23:35:03
  13. CentOS 7 SSH配置免密码登录

    目的在搭建Linux集群服务的时候,主服务器需要启动从服务器的服务,如果通过手动启动,集群内服务器几台还好,要是像阿里1000台的云梯hadoop集群的话,轨迹启动一次集群就得几个工程师一两天时间,是不是很恐怖。如果使用免密登录,主服务器就能通过程序执行启动脚步,自动帮我…...

    2024/4/25 14:24:38
  14. tomcat7 开启gzip压缩

    原因 原理 操作步骤原因同事反应网页打开速度慢。 zabbix检测到tomcat没有开启gizp压缩报警,开启gzip压缩功能。原理HTTP 压缩可以大大提高浏览网站的速度,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏…...

    2024/4/20 14:54:17
  15. 开源负载均衡通讯分发器(LB dispatcher) - G5

    from:http://bbs.csdn.net/topics/3907530431.开发背景今天和系统运维的老大聊天,谈到一直在用的F5,行里对其评价为价格过高、功能复杂难懂,反正印象不是很好,使用前景不明。因为以前我曾经给行里开发过一个通讯中间件,附带软实现了负载均衡,几年使用下来一直效果不错,…...

    2024/4/20 16:44:08
  16. 企业的地基与承重墙

    很多大企业的员工,对自己企业内部的问题吐槽都是很多的,我知道有腾讯的前任中层,对腾讯发展很绝望。我也知道有阿里的元老,对阿里的内部问题忧心忡忡。至于百度,我就不用说了,已经被群众判了十几年死刑了。说来也有意思,大家都觉得百度必然会掉队,从十年前说到现在,但…...

    2024/4/26 3:31:20
  17. 最适合Java开发者的一本书与一编辑器

    转载:https://mp.weixin.qq.com/s/NSObxmf598qjmc_t4e4Dkg一书-《Java编程思想》一软件-IntelliJ IDEAJava自学是否可以成功,答案显而易见,可以。自学Java关键看自己是否有毅力、是否有恒心。自学Java自学Java不是把自己封闭在屋子里闭门造车,自学Java包括一个核心的部分就是…...

    2024/4/20 21:17:50
  18. 简单谈谈自己对SSH框架的理解

    J2EE开发框架其实也是jar类库,大部分是对原生方法的封装。目的是为了简化开发人员的工作,规范开发过程。学习框架即学习其核心原理和配置。 但java世界的框架五花八门,但万变不离其宗,只有真正掌握了SSH框架的核心机制和设计理念才能轻松的学好其他框架。 下面谈谈我对SSH框…...

    2024/4/20 21:17:49
  19. htaccess添加gzip压缩

    在.htaccess中添加如下代码<ifmodule mod_deflate.c>AddOutputFilter DEFLATE html xml php jpg png js css </ifmodule>之所以发现这个,是因为用了YSLOW,提示 Grade F on Compress components with gzip 获得了F等级,添加gzip后,立马变成了A。gzip还是很有用的…...

    2024/4/20 23:35:00
  20. 傲慢与偏见之 - 因果倒置的锦上添花

    傲慢与偏见之 - 谷歌中国逆袭史傲慢与偏见之 - 防火墙与竞争力 前言: 本系列的由来,第一篇就说了,是基于这边一个师姐的咨询和调研,这个咨询和调研的问题,基本上是基于一些西方的评论,和部分中国评论家的言论。 我将当时的一些回答内容和观点,二次整理,…...

    2024/4/27 12:42:56

最新文章

  1. 【数据结构】链表专题2

    前言 本篇博客继续探讨有关链表的专题&#xff0c;这片博客的题&#xff0c;提前打个预防针&#xff0c;有点意思哦&#xff0c;哈哈哈&#xff0c;话不多说&#xff0c;进入正文 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论…...

    2024/5/5 8:38:30
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. k8s_入门_kubelet安装

    安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…...

    2024/5/4 14:33:56
  4. npm常用命令技巧

    NPM (Node Package Manager) 是 JavaScript 的包管理工具&#xff0c;广泛用于管理项目中的依赖。无论是前端项目还是Node.js后端项目&#xff0c;NPM 都扮演着重要的角色。本文将介绍 NPM 中常用的几个命令&#xff0c;并提供相应的代码示例。 1. 初始化项目&#xff1a;npm …...

    2024/4/30 9:33:01
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/4 23:55:17
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/4 18:20:48
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57