Git鼓励在工作中频繁使用分支与合并。
3.1 何为分支
GIT每次提交会创建一个提交commit对象,这个对象包含指向快照的指针,还有作者及其它附属信息。还包含一个指向直接祖先的指针,直接祖先是上次提交的对象,如果本地提交是由多个分支合并而成,那就有多个直接祖先。
GIT在通过git add添加文件到暂存区时,会创建一个记录目录结构的tree对象。下图描述三个文件在第一次提交后及多次提交后的对象及指针指向关系。
GIT的分支仅仅是指向commit对象的可变指针。默认的分支名是master。若干次提交后,分支指向最后一次提交。说它可变是每次提交它都向前移动指向最新一次的提交。
创建一个新的分支
$ git branch testing #这会在当前commit对象上创建一个分支指针,与原来master分支的指针指向同一个commit对象。
HEAD:特别指针,指向当前工作的分支。
$ git checkout testing #这样会将HEAD指针指向testing分支。
在新分支testing上提交后,再回到master分支提交一次。生成的版本图如下:
创建一个分支,其实就是新创建一个文件记录提交对象的校验后(41个字节,40位SHA-1串,及一个换行)。
3.2 基本的分支与合并
多使用分支与合并的原理场景如下:发一个版本V8.0,拉一个分支V8.0-branch-one,在它上在开发新功能。如果主版本有问题,需要修改。那在 V8.0上拉一个分支V8.0-bug-fix,修改然后打补丁给生产环境。然后把这个修复bug的分支合并到主干上,并删除掉。
3.2.1 基本分支
$ git checkout -b new-branch #新创建分支并切换到这个分支上。
合并分支
$ git merge branch-new
下图是merge一个分支后的图:
注意:由于master分支这时还在要合并的分支的上游,所以当合并的时候,只需要快进到那个分支就OK了。就是master指针指向那个commit对象。
合并后删除无用的分支
$ git branch -d branch-name
两分支合并
修改问题的分支与新功能的分支进行合并。如下图:
GIT负责找到两分支的共同祖先,并决定哪个做为合并基础,它可以自动合并,合并后产生一个新的commit.合并后的分支图:
3.2.3 冲突的合并
两个分支都修改了同一个文件的同一个部分。如果这时尝试去合并,GIT会提示
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
这时可以通过 git status 查看冲突.
unmerged 文件是合并冲突的文件状态,需要我们手工修改。GIT会在文件中加入标准的冲突标记
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
用=======隔开的上下两部分 分别是不同的分支。
手工合并后,使用 git add命令把它们标记为已解决(resolved)。合并也可以使用
git mergetool 来图形工具合并。
3.3 分支管理
$ git branch #查看当前所有分支
$ git branch -v # 查看各分支最后一次提交
$ git branch --merged或--no-merged #查看与当前分支已经合并或者未合并的分支。
$ git branch --merged
iss53
* master
没有星号的表示已经合并过来,即可以删除 $ git branch -d iss53
3.4 分支式工作流程
master保留稳定的代码(已发布或即将发布)。再有一个名为develop的开发版,用于合并新功能,并进行测试。测试完成后,合并到master主干上来。
3.5 远程分支
远程分支-remote branch是对远程仓库状态的索引,它们是一些无法移动的本地分支。远程分支就是远程库的一个本地快照。
远程分支命名:远程仓库名/分支名。
clone一个远程分支到本地。GIT会在本地创建一个origin名称来对应远程库,并且使用master分支名来对应远程库的最新版本。然后它还会自动创建一个本地master分支,来对应这个远程分支。
当远程库有修改后,我们通过git fetch origin,该命令查看origin对应的远程库地址,然后更新本地没有的内容,再然后origin/master远程分支将向前移动,而本地分支在合并前不会对应移动。
添加多个远程分支:
多个远程分支是根据同一个主版本库拉出的多个分支。下面的截图演示通过 git remote add tempone xxxx
后,再通过git fetch tempone命令来拉取这个分支的内容。GIT会同时创建一个远程分支用来标识这个远程库。
3.5.1 推送
$ 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
* [new branch]
serverfix -> serverfix
这会在远程库中创建一个新的同名分支。
过程中GIT将上例中的serverfix串扩展为 refs/heads/serverfix:refs/heads/serverfix
意为“取出我的 serverfix 本地分支,推送它来更新远程仓库的 serverfix 分支”。也可以使用
git push origin serverfix:othername 来自定义远程分支的名称。
推送后,远程库中就多了个分支。
另外用记通过fetch远程库时,就会下到推送的分支,但是同样这只是远程分支。如果希望将它合并到当前分支:git merge origin/serverfix。
如希望在这个分支基础上拉一个新的分支出来:git checkout -b serverfix origin/serverfix。
3.5.2 跟踪分支
从远程分支检出的本地分支称为 跟踪分支。它与远程分支直接关联,在这个分支下执行 git push,会直接将当修改推送到对应的远程分支上支。同样 git pull会拉取所有更新,并自动合并到当前分支。
在clone一个远程库时,GIT基于origin/master远程分支,分化出一个本地分支master。所以,在master分支下,我们可以直接push 或 pull。同样,我们可以不只是基于origin/master分支分化,可以通过这个远程库上的其它远程分支分化:git checkout -b 分支名 远程库名/远程分支名。git 1.6.2后简化命令为:
git checkout -b --track origin/serverfix。如果想自定义本地分支名,代上就是了。
3.5.3 删除远程分支
$ git push 远程名 :远程分支名。这个对应 git push 远程名 本地分支名:远程分支名。
意思就是提取空白然后把它变化为远程分支名。
3.6 衍合
整合分支两人种方式:merge-合并与rebase-衍合
3.6.1 基础
如c2分出c3与c4两分支。通过merge是,提交一个c5,并把c3与c4合并进来。
其实还可以:在c4分支上把c3的变化在c4上再发生一次(重放)。
$ git checkout experiment
$ git rebase master
切换到experiment分支,把当前分支的补丁打到master分支上去。
它的工作原理是GIT回到两人个分支的共同祖先,然后把当前版本发生过的提交再在rebase对象上发生一次。
衍合后,在目标分支上进行一次快进合并,将目标分支的指针指向最新衍合的提交。
衍合产生的提交历史比合并更清晰,能区分哪些是A分支的修改,哪些是B分支的修改。
一种合适的工作方式:开发者基础A库拉一个分支进行修改,完了将分支rebase到origin/master库。然后,A库的维护者只需要一个快进合并就可以把开发者的修改合并进来,而且历史清晰。
衍合将每行改变发生的次序重演,而合并是将最终结果合在一起。
3.6.2 更多有趣的衍合
图3.31表示:基于主分支,先拉一个server分支,又基于server分支拉了client分支,master,server,client三者都有提交。
现在,如果希望只把client提交那部分合并到master分支上来,又不希望把server的合并进来。可以通过:
$ git checkout client
$ git rebase --onto master server client
它的意思是找出client相对server与client共同祖先以后提交的变化内容,并在master分支上衍合进来。
$ git checkout master
$ git merge client #快进
如果要再把server合并进来,
$ git rebase master server #不需要checkout到server分支,使用git rebase [主分支] [特性分支]就自动检出特性分支,然后在主分支上重演。
3.6.3 衍合的风险
永远不要衍合那些已经推送到公共库中的更新。不要在公共库上使用衍合,只在本地分支使用。如果分支已经push到远程库,就不要再将其衍合到其它分支。
相关推荐
《ProGit.pdf--git学习教程》是Scott Chacon和Ben Straub共同编写的关于Git版本控制系统的官方学习指南。本教程涵盖了Git的基本概念、工作流程、配置、分支管理、远程仓库操作、服务器部署、分布式工作模式、GitHub...
Git是一种分布式的版本控制系统,它...整体来看,这本书是学习Git必备的全面指南,涵盖了从基础到高级的各种Git用法,同时特别关注了GitHub这一重要平台,为希望掌握现代版本控制技能的开发者提供了宝贵的知识和技巧。
Git是世界上最流行的分布式版本...总之,Git-2.18.0-64-bit作为Git的最新64位Windows版本,为开发者提供了强大的代码版本管理工具,通过不断的学习和实践,开发者可以充分利用Git提高工作效率,更好地协作开发项目。
- 本章概述了版本控制的基本概念,并介绍了Git的基础知识,为后续章节的学习打下了坚实的基础。 #### 二、Git基础 **2.1 取得项目的Git仓库** - **从当前目录初始化**:使用`git init`命令在一个新的目录中创建一...
Git-2.28.0-64-bit.exe 是适用于Windows 64位操作系统的Git官方安装程序,该版本为2.28.0,意味着它包含了最新的功能和性能改进。 **Git基础概念** 1. **版本控制**:Git的核心功能是版本控制,它能跟踪文件和目录...
Git-2.23.0-64-bit--Windows安装包是一个专门为Windows操作系统设计的64位Git版本,它包含了所有必要的组件,使得用户可以在Windows环境下无缝地使用Git。 Git的核心功能包括: 1. 版本追踪:Git能够记录文件和...
Git-2.41.0-64-bit window版本是针对Windows操作系统的一个特定构建,提供64位架构的支持。这个版本的发布,意味着用户可以在Windows环境下享受到Git的最新功能和性能优化。 Git的核心特性包括: 1. 分布式:每个...
Git-2.34.0-64-bit.rar是一个包含Git的64位安装包,适用于Windows操作系统。这个压缩包中的主要文件是"Git-2.34.0-64-bit.exe",这是Git的可执行安装程序,用于在Windows上部署Git环境。 Git的核心功能包括版本控制...
"git-2.45.0-64bit.exe" 是Git的特定版本,即2.45.0版本的64位Windows安装程序。这个文件是为Windows用户设计的,确保在64位操作系统上顺利运行Git。 Git的核心特性包括: 1. 分布式:每个开发者的本地仓库都包含...
Git-2.21.0-64-bit.zip是一个专为Windows 64位操作系统设计的Git官方客户端工具的压缩包文件。这个版本号(2.21.0)表明这是Git在某个时间点的一个稳定发行版,通常会包含性能优化、新功能和已知问题的修复。 Git的...
Git是世界上最流行的分布式版本控制系统,广泛应用于软件开发...通过Git-2.15.1.2-64-bit和Git-2.15.1.2-32-bit的安装,以及参考git-cheatsheet.PDF,用户可以系统地学习和熟练运用Git进行版本控制,提升团队协作效率。
标题中的"Git-2.19.1-64-bit.exe"表明这是一个Git的64位版本,具体为2.19.1版本的安装程序,适用于Windows操作系统。这个版本的发布可能包含了性能优化、新功能或对已知问题的修复。 Git的核心理念在于它允许开发者...
在这个"Git-2.28.0-64-bit.exe.zip"压缩包中,包含的是Git的最新Windows版安装程序,适用于64位操作系统。这个版本是2.28.0,它在Git的历史中扮演着重要的角色,因为每个新版本都带来了性能优化和新功能。 Git的...
HTML CSS JS 学习、git-笔记HTML CSS JS 学习、git-笔记 HTML CSS JS 学习、git-笔记HTML CSS JS 学习、git-笔记 HTML CSS JS 学习、git-笔记HTML CSS JS 学习、git-笔记 HTML CSS JS 学习、git-笔记HTML CSS JS ...
Git-2.40.0-64-bit.exe Git是一个免费的开源分布式版本控制系统,可以快速高效地处理从小到大的所有项目。Git易于学习,占用空间小,性能却非常快。它超越了像Subversion、CVS、Perforce和ClearCase这样的配置管理...
Git-2.18.0-64-bit是Git的特定版本,适用于64位的Windows操作系统。这个版本的发布旨在提供增强的功能、性能改进以及对之前版本中发现的问题的修复。 Git的2.18版本引入了一些重要的新特性。其中一项关键更新是增强...
64位Git客户端“Git-2.17.0-64-bit”是专为Windows操作系统设计的一个强大工具,它提供了对大型代码库的高效管理和跟踪能力。本文将深入探讨Git的基本概念、主要功能以及如何在Windows上安装和使用Git 2.17.0 64位...
Git-2.25.0-64-bit.zip这个压缩包文件包含的是Git的64位版本,版本号为2.25.0,适用于Windows操作系统。 Git的核心特性包括: 1. 分布式:每个开发者的本地机器都有一个完整的版本库,无需依赖中央服务器进行日常...
Git-2.10.0 是一个较旧但稳定的版本,它提供了基本的版本控制功能,如提交、克隆、拉取、推送、分支和合并等。用户可以通过命令行界面进行操作,但对于不熟悉命令行的用户来说,可能有一定的学习曲线。 TortoiseGit...