目录
分支简介
分支创建
分支切换
分支的新建与合并
新建分支
分支的合并
遇到冲突时的分支合并
分支管理
远程分支
跟踪分支
拉取
删除远程分支
变基
变基的基本操作
更有趣的变基例子
变基的风险
使用分支意味着你可以把你的工作从开发主线上分离开来,以免影响开发主线。
当使用 git commit
进行提交操作时,Git 会先计算每一个子目录(本例中只有项目根目录)的校验和, 然后在 Git 仓库中这些校验和保存为树对象。随后,Git 便会创建一个提交对象, 它除了包含上面提到的那些信息外,还包含指向这个树对象(项目根目录)的指针。 如此一来,Git 就可以在需要的时候重现此次保存的快照。
现在,Git 仓库中有五个对象:三个 blob 对象(保存着文件快照)、一个 树 对象 (记录着目录结构和 blob 对象索引)以及一个 提交 对象(包含着指向前述树对象的指针和所有提交信息)。
Git 是怎么创建新分支的呢? 很简单,它只是为你创建了一个可以移动的新的指针。 比如,创建一个 testing 分支, 你需要使用 git branch
命令:
$ git branch testing
这会在当前所在的提交对象上创建一个指针。
那么,Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD
的特殊指针。 请注意它和许多其它版本控制系统(如 Subversion 或 CVS)里的 HEAD
概念完全不同。 在 Git 中,它是一个指针,指向当前所在的本地分支(译注:将 HEAD
想象为当前分支的别名)。 在本例中,你仍然在 master
分支上。 因为 git branch
命令仅仅 创建 一个新分支,并不会自动切换到新分支中去。
HEAD 指向当前所在的分支
你可以简单地使用 git log
命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate
。
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project
正如你所见,当前 master
和 testing
分支均指向校验和以 f30ab
开头的提交对象。
要切换到一个已存在的分支,你需要使用 git checkout
命令。 我们现在切换到新创建的 testing
分支去:
$ git checkout testing
这样 HEAD
就指向 testing
分支了。
那么,这样的实现方式会给我们带来什么好处呢? 现在不妨再提交一次:
$ vim test.rb
$ git commit -a -m 'made a change'
HEAD 分支随着提交操作自动向前移动
我们不妨再稍微做些修改并提交:
$ vim test.rb
$ git commit -a -m 'made other changes'
现在,这个项目的提交历史已经产生了分叉(参见 项目分叉历史)。 因为刚才你创建了一个新分支,并切换过去进行了一些工作,随后又切换回 master 分支进行了另外一些工作。 上述两次改动针对的是不同分支:你可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来。 而所有这些工作,你需要的命令只有 branch
、checkout
和 commit
。
项目分叉历史
你可以简单地使用 git log
命令查看分叉历史。 运行 git log --oneline --decorate --graph --all
,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
需要拉取某个分支的代码:
git fetch
将本地分支与远程保持同步git checkout -b 本地分支名x origin/远程分支名x
拉取远程分支并同时创建对应的本地分支
让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流。 你将经历如下步骤:
开发某个网站。
为实现某个新的用户需求,创建一个分支。
在这个分支上开展工作。
正在此时,你突然接到一个电话说有个很严重的问题需要紧急修补。 你将按照如下方式来处理:
切换到你的线上分支(production branch)。
为这个紧急任务新建一个分支,并在其中修复它。
在测试通过之后,切换回线上分支,然后合并这个修补分支,最后将改动推送到线上分支。
切换回你最初工作的分支上,继续工作。
假设你正在你的项目上工作,并且在 master
分支上已经有了一些提交。
要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b
参数的 git checkout
命令:
$ git checkout -b iss53
Switched to a new branch "iss53"
它是下面两条命令的简写:
$ git branch iss53
$ git checkout iss53
继续在 #53 问题上工作,并且做了一些提交。 在此过程中,iss53
分支在不断的向前推进,因为你已经检出到该分支 (也就是说,你的 HEAD
指针指向了 iss53
分支)
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
现在你接到那个电话,有个紧急问题等待你来解决。 你所要做的仅仅是切换回 master
分支。
但是,在你这么做之前,要留意你的工作目录和暂存区里那些还没有被提交的修改, 它可能会和你即将检出的分支产生冲突从而阻止 Git 切换到该分支。 最好的方法是,在你切换分支之前,保持好一个干净的状态。 有一些方法可以绕过这个问题(即,暂存(stashing) 和 修补提交(commit amending)), 我们会在 贮藏与清理 中看到关于这两个命令的介绍。 现在,我们假设你已经把你的修改全部提交了,这时你可以切换回 master
分支了:
$ git checkout master
Switched to branch 'master'
接下来,你要修复这个紧急问题。 我们来建立一个 hotfix
分支,在该分支上工作直到问题解决:
这个时候,你的工作目录和你在开始 #53 问题之前一模一样,现在你可以专心修复紧急问题了。 Git 会自动添加、删除、修改文件以确保此时你的工作目录和这个分支最后一次提交时的样子一模一样。
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address1 file changed, 2 insertions(+)
基于 master
分支的紧急问题分支 hotfix branch
你可以运行你的测试,确保你的修改是正确的,然后将 hotfix
分支合并回你的 master
分支来部署到线上。 你可以使用 git merge
命令来达到上述目的:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forwardindex.html | 2 ++1 file changed, 2 insertions(+)
在合并的时候,你应该注意到了“快进(fast-forward)”这个词。 由于你想要合并的分支 hotfix
所指向的提交 C4
是你所在的提交 C2
的直接后继, 因此 Git 会直接将指针向前移动。换句话说,当你试图合并两个分支时, 如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候, 只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
现在,最新的修改已经在 master
分支所指向的提交快照中,你可以着手发布该修复了。
Figure 22. master
被快进到 hotfix
关于这个紧急问题的解决方案发布之后,你准备回到被打断之前时的工作中。 然而,你应该先删除 hotfix
分支,因为你已经不再需要它了 —— master
分支已经指向了同一个位置。 你可以使用带 -d
选项的 git branch
命令来删除分支:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
现在你可以切换回你正在工作的分支继续你的工作,也就是针对 #53 问题的那个分支(iss53 分支)。
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
假设你已经修正了 #53 问题,并且打算将你的工作合并入 master
分支。
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
这和你之前合并 hotfix
分支的时候看起来有一点不一样。 在这种情况下,你的开发历史从一个更早的地方开始分叉开来(diverged)。 因为,master
分支所在提交并不是 iss53
分支所在提交的直接祖先,Git 不得不做一些额外的工作。 出现这种情况的时候,Git 会使用两个分支的末端所指的快照(C4
和 C5
)以及这两个分支的公共祖先(C2
),做一个简单的三方合并。
Figure 24. 一次典型合并中所用到的三个快照
和之前将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。
既然你的修改已经合并进来了,就不再需要 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 the result.
此时 Git 做了合并,但是没有自动地创建一个新的合并提交。 Git 会暂停下来,等待你去解决合并产生的冲突。 你可以在合并冲突后的任意时刻使用 git status
命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件:
$ git status
On branch master
You have unmerged paths.(fix conflicts and run "git commit")Unmerged paths:(use "git add <file>..." to mark resolution)both modified: index.htmlno changes added to commit (use "git add" and/or "git commit -a")
任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。 Git 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。 出现冲突的文件会包含一些特殊区段,看起来像下面这个样子:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github</div>
=======
<div id="footer">please contact us at support@github
</div>
>>>>>>> iss53:index.html
这表示 HEAD
所指示的版本(也就是你的 master
分支所在的位置,因为你在运行 merge 命令的时候已经检出到了这个分支)在这个区段的上半部分(=======
的上半部分),而 iss53
分支所指示的版本在 =======
的下半部分。 为了解决冲突,你必须选择使用由 =======
分割的两部分中的一个,或者你也可以自行合并这些内容。 例如,你可以通过把这段内容换成下面的样子来解决冲突:
<div id="footer">
please contact us at email.support@github
</div>
上述的冲突解决方案仅保留了其中一个分支的修改,并且 <<<<<<<
, =======
, 和 >>>>>>>
这些行被完全删除了。 在你解决了所有文件里的冲突之后,对每个文件使用 git add
命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决。
如果你想使用图形化工具来解决冲突,你可以运行 git mergetool
,该命令会为你启动一个合适的可视化合并工具,并带领你一步一步解决这些冲突:
$ git mergetoolThis message is displayed because l' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.htmlNormal merge conflict for 'index.html':{local}: modified file{remote}: modified file
Hit return to start merge resolution tool (opendiff):
如果你想使用除默认工具(在这里 Git 使用 opendiff
做为默认的合并工具,因为作者在 Mac 上运行该程序) 外的其他合并工具,你可以在 “下列工具中(one of the following tools)” 这句后面看到所有支持的合并工具。 然后输入你喜欢的工具名字就可以了。
Note | 如果你需要更加高级的工具来解决复杂的合并冲突,我们会在 高级合并 介绍更多关于分支合并的内容。 |
等你退出合并工具之后,Git 会询问刚才的合并是否成功。 如果你回答是,Git 会暂存那些文件以表明冲突已解决: 你可以再次运行 git status
来确认所有的合并冲突都已被解决:
$ git status
On branch master
All conflicts fixed but you are still merging.(use "git commit" to conclude merge)Changes to be committed: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.# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
如果你觉得上述的信息不够充分,不能完全体现分支合并的过程,你可以修改上述信息, 添加一些细节给未来检视这个合并的读者一些帮助,告诉他们你是如何解决合并冲突的,以及理由是什么。
现在已经创建、合并、删除了一些分支,让我们看看一些常用的分支管理工具。
git branch
命令不只是可以创建与删除分支。 如果不加任何参数运行它,会得到当前所有分支的一个列表:
$ git branchiss53
* mastertesting
注意 master
分支前的 *
字符:它代表现在检出的那一个分支(也就是说,当前 HEAD
指针所指向的分支)。 这意味着如果在这时候提交,master
分支将会随着新的工作向前移动。 如果需要查看每一个分支的最后一次提交,可以运行 git branch -v
命令:
$ git branch -viss53 93b412c fix javascript issue
* master 7a98805 Merge branch 'iss53'testing 782fd34 add scott to the author list in the readmes
--merged
与 --no-merged
这两个有用的选项可以过滤这个列表中已经合并或尚未合并到当前分支的分支。 如果要查看哪些分支已经合并到当前分支,可以运行 git branch --merged
:
$ git branch --mergediss53
* master
因为之前已经合并了 iss53
分支,所以现在看到它在列表中。 在这个列表中分支名字前没有 *
号的分支通常可以使用 git branch -d
删除掉;你已经将它们的工作整合到了另一个分支,所以并不会失去任何东西。
查看所有包含未合并工作的分支,可以运行 git branch --no-merged
:
$ git branch --no-mergedtesting
这里显示了其他分支。 因为它包含了还未合并的工作,尝试使用 git branch -d
命令删除它时会失败:
$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.
如果真的想要删除分支并丢掉那些工作,如同帮助信息里所指出的,可以使用 -D
选项强制删除它。
Tip | 上面描述的选项 你总是可以提供一个附加的参数来查看其它分支的合并状态而不必检出它们。 例如,尚未合并到 |
$ git checkout testing
$ git branch --no-merged mastertopicAfeatureB
远程引用是对远程仓库的引用(指针),包括分支、标签等等。 你可以通过 git ls-remote <remote>
来显式地获得远程引用的完整列表, 或者通过 git remote show <remote>
获得远程分支的更多信息。 然而,一个更常见的做法是利用远程跟踪分支。
它们以 <remote>/<branch>
的形式命名。 例如,如果你想要看你最后一次与远程仓库 origin
通信时 master
分支的状态,你可以查看 origin/master
分支。 你与同事合作解决一个问题并且他们推送了一个 iss53
分支,你可能有自己的本地 iss53
分支, 然而在服务器上的分支会以 origin/iss53
来表示。
这可能有一点儿难以理解,让我们来看一个例子。 假设你的网络里有一个在 git.ourcompany
的 Git 服务器。 如果你从这里克隆,Git 的 clone
命令会为你自动将其命名为 origin
,拉取它的所有数据, 创建一个指向它的 master
分支的指针,并且在本地将其命名为 origin/master
。 Git 也会给你一个与 origin 的 master
分支在指向同一个地方的本地 master
分支,这样你就有工作的基础。
从一个远程跟踪分支检出一个本地分支会自动创建所谓的“跟踪分支”(它跟踪的分支叫做“上游分支”)。 跟踪分支是与远程分支有直接关系的本地分支。 如果在一个跟踪分支上输入 git pull
,Git 能自动地识别去哪个服务器上抓取、合并到哪个分支。
当克隆一个仓库时,它通常会自动地创建一个跟踪 origin/master
的 master
分支。 然而,如果你愿意的话可以设置其他的跟踪分支,或是一个在其他远程仓库上的跟踪分支,又或者不跟踪 master
分支。 最简单的实例就是像之前看到的那样,运行 git checkout -b <branch> <remote>/<branch>
。 这是一个十分常用的操作所以 Git 提供了 --track
快捷方式:
$ git checkout --track origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
由于这个操作太常用了,该捷径本身还有一个捷径。 如果你尝试检出的分支 (a) 不存在且 (b) 刚好只有一个名字与之匹配的远程分支,那么 Git 就会为你创建一个跟踪分支:
$ git checkout serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'
如果想要将本地分支与远程分支设置为不同的名字,你可以轻松地使用上一个命令增加一个不同名字的本地分支:
$ git checkout -b sf origin/serverfix
Branch sf set up to track remote branch serverfix from origin.
Switched to a new branch 'sf'
现在,本地分支 sf
会自动从 origin/serverfix
拉取。
设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支, 你可以在任意时间使用 -u
或 --set-upstream-to
选项运行 git branch
来显式地设置。
$ git branch -u origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Note | 上游快捷方式 当设置好跟踪分支后,可以通过简写 |
如果想要查看设置的所有跟踪分支,可以使用 git branch
的 -vv
选项。 这会将所有的本地分支列出来并且包含更多的信息,如每一个分支正在跟踪哪个远程分支与本地分支是否是领先、落后或是都有。
$ git branch -vviss53 7e424c3 [origin/iss53: ahead 2] forgot the bracketsmaster 1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do ittesting 5ea463a trying something new
这里可以看到 iss53
分支正在跟踪 origin/iss53
并且 “ahead” 是 2,意味着本地有两个提交还没有推送到服务器上。 也能看到 master
分支正在跟踪 origin/master
分支并且是最新的。 接下来可以看到 serverfix
分支正在跟踪 teamone
服务器上的 server-fix-good
分支并且领先 3 落后 1, 意味着服务器上有一次提交还没有合并入同时本地有三次提交还没有推送。 最后看到 testing
分支并没有跟踪任何远程分支。
当 git fetch
命令从服务器上抓取本地没有的数据时,它并不会修改工作目录中的内容。 它只会获取数据然后让你自己合并。 然而,有一个命令叫作 git pull
在大多数情况下它的含义是一个 git fetch
紧接着一个 git merge
命令。 如果有一个像之前章节中演示的设置好的跟踪分支,不管它是显式地设置还是通过 clone
或 checkout
命令为你创建的,git pull
都会查找当前分支所跟踪的服务器与分支, 从服务器上抓取数据然后尝试合并入那个远程分支。
由于 git pull
的魔法经常令人困惑所以通常单独显式地使用 fetch
与 merge
命令会更好一些。
假设你已经通过远程分支做完所有的工作了——也就是说你和你的协作者已经完成了一个特性, 并且将其合并到了远程仓库的 master
分支(或任何其他稳定代码分支)。 可以运行带有 --delete
选项的 git push
命令来删除一个远程分支。 如果想要从服务器上删除 serverfix
分支,运行下面的命令:
$ git push origin --delete serverfix
To [deleted] serverfix
基本上这个命令做的只是从服务器上移除这个指针。 Git 服务器通常会保留数据一段时间直到垃圾回收运行,所以如果不小心删除掉了,通常是很容易恢复的。
在 Git 中整合来自不同分支的修改主要有两种方法:merge
以及 rebase
。 在本节中我们将学习什么是“变基”,怎样使用“变基”,并将展示该操作的惊艳之处,以及指出在何种情况下你应避免使用它。
请回顾之前在 分支的合并 中的一个例子,你会看到开发任务分叉到两个不同分支,又各自提交了更新。
分叉的提交历史
之前介绍过,整合分支最容易的方法是 merge
命令。 它会把两个分支的最新快照(C3
和 C4
)以及二者最近的共同祖先(C2
)进行三方合并,合并的结果是生成一个新的快照(并提交)。
通过合并操作来整合分叉的历史
其实,还有一种方法:你可以提取在 C4
中引入的补丁和修改,然后在 C3
的基础上应用一次。 在 Git 中,这种操作就叫做 变基(rebase)。 你可以使用 rebase
命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。
在这个例子中,你可以检出 experiment
分支,然后将它变基到 master
分支上:
$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top
Applying: added staged command
它的原理是首先找到这两个分支(即当前分支 experiment
、变基操作的目标基底分支 master
) 的最近共同祖先 C2
,然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件, 然后将当前分支指向目标基底 C3
, 最后以此将之前另存为临时文件的修改依序应用。 (译注:写明了 commit id,以便理解,下同)
将 C4
中的修改变基到 C3
上
现在回到 master
分支,进行一次快进合并。
$ git checkout master
$ git merge experiment
在对两个分支进行变基时,所生成的“重放”并不一定要在目标分支上应用,你也可以指定另外的一个分支进行应用。 就像 从一个主题分支里再分出一个主题分支的提交历史 中的例子那样。 你创建了一个主题分支 server
,为服务端添加了一些功能,提交了 C3
和 C4
。 然后从 C3
上创建了主题分支 client
,为客户端添加了一些功能,提交了 C8
和 C9
。 最后,你回到 server
分支,又提交了 C10
。
从一个主题分支里再分出一个主题分支的提交历史
假设你希望将 client
中的修改合并到主分支并发布,但暂时并不想合并 server
中的修改, 因为它们还需要经过更全面的测试。这时,你就可以使用 git rebase
命令的 --onto
选项, 选中在 client
分支里但不在 server
分支里的修改(即 C8
和 C9
),将它们在 master
分支上重放:
$ git rebase --onto master server client
以上命令的意思是:“取出 client
分支,找出它从 server
分支分歧之后的补丁, 然后把这些补丁在 master
分支上重放一遍,让 client
看起来像直接基于 master
修改一样”。这理解起来有一点复杂,不过效果非常酷。
Figure 40. 截取主题分支上的另一个主题分支,然后变基到其他分支
现在可以快进合并 master
分支了。(如图 快进合并 master
分支,使之包含来自 client
分支的修改):
$ git checkout master
$ git merge client
Figure 41. 快进合并 master
分支,使之包含来自 client
分支的修改
接下来你决定将 server
分支中的修改也整合进来。 使用 git rebase <basebranch> <topicbranch>
命令可以直接将主题分支 (即本例中的 server
)变基到目标分支(即 master
)上。 这样做能省去你先切换到 server
分支,再对其执行变基命令的多个步骤。
$ git rebase master server
如图 将 server
中的修改变基到 master
上 所示,server
中的代码被“续”到了 master
后面。
Figure 42. 将 server
中的修改变基到 master
上
然后就可以快进合并主分支 master
了:
$ git checkout master
$ git merge server
至此,client
和 server
分支中的修改都已经整合到主分支里了, 你可以删除这两个分支,最终提交历史会变成图 最终的提交历史 中的样子:
$ git branch -d client
$ git branch -d server
Figure 43. 最终的提交历史
呃,奇妙的变基也并非完美无缺,要用它得遵守一条准则:
如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
如果你遵循这条金科玉律,就不会出差错。 否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。
变基操作的实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。 如果你已经将提交推送至某个仓库,而其他人也已经从该仓库拉取提交并进行了后续工作,此时,如果你用 git rebase
命令重新整理了提交并再次推送,你的同伴因此将不得不再次将他们手头的工作与你的提交进行整合,如果接下来你还要拉取并整合他们修改过的提交,事情就会变得一团糟。
#bdiag_g
本文发布于:2024-02-02 10:49:10,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170684215143301.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |