You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
那么,$ git revert -m 1 g 将会保留 master 分支上的修改,撤销 dev 分支上的修改。
撤销成功之后,Git 将会生成一个新的 Commit,提交历史就成了这样:
a -> b -> c -> f -- g -> h -> G (master)
\ /
d -> e (dev)
其中 G 是撤销 g 生成的 commit。通过 $ git show G 之后,我们会发现 G 是一个常规提交,内容就是撤销 merge 时被丢弃的那条线索的所有 commit 的「反操作」的合集。
git rebase
使用 git rebase 命令可以帮助我们的清洁、整理提交记录,方便 代码 review,它可以对某一段线性提交历史进行编辑、删除、复制、粘贴。
注意切勿使用 rebase 对任何已经提交到公共仓库中的commit进行修改
功能一:合并多次提交纪录
# git rebase -i HEAD~4
git rebase -i [startpoint] [endpoint]
1.进入 vi 编辑模式:
pick 9aba15d optaldl Revert "add log"
pick c98d8a3 create http server
pick de9e11b add 调试代码
pick 6333530 print __dirname
# Rebase ec543c9..b75e42a onto 6333530 (4 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
2.异常退出了 vi 窗口
git rebase --edit-todo
git rebase --continue
功能二:变基,减少 master 冲突 commit
通常我们在 master 合入 feature 分支,遇到冲突解决冲突,提交很容易产生污染主干。通过 rebase 可以随时解决冲突,而 merge 必须要到最后合并时才一次性解决。
git revert
Git 的 revert 命令可以用来撤销提交(commit),对于常规的提交来说,revert 命令十分直观易用,相当于做一次被 revert 的提交的「反操作」并形成一个新的 commit,但是当你需要撤销一个合并(merge)的时候,事情就变得稍微复杂了一些。
Merge Commit
在描述 merge commit 之前,先来简短地描述一下常规的 commit。每当你做了一批操作(增加、修改、或删除)之后,你执行
git commit
便会得到一个常规的 Commit。执行git show
将会输出详细的增删情况。Merge commit 则不是这样。每当你使用
git merge
合并两个分支,你将会得到一个新的 merge commit。执行git show
之后,会有类似的输出:其中,Merge 这一行代表的是这个合并 parents,它可以用来表明 merge 操作的线索。
举个例子,通常,我们的稳定代码都在 master 分支,而开发过程使用 dev 分支,当开发完成后,再把 dev 分支 merge 进 master 分支:
上图中,
g
是 merge commit,其他的都是常规 commit。g
的两个 parent 分别是f
和e
。Revert a Merge Commit
当你使用
git revert
撤销一个 merge commit 时,如果除了 commit 号而不加任何其他参数,git 将会提示错误:在你合并两个分支并试图撤销时,Git 并不知道你到底需要保留哪一个分支上所做的修改。从 Git 的角度来看,
master
分支和dev
在地位上是完全平等的,只是在 workflow 中,master
被人为约定成了「主分支」。于是 Git 需要你通过
m
或mainline
参数来指定「主线」。merge commit 的 parents 一定是在两个不同的线索上,因此可以通过 parent 来表示「主线」。m
参数的值可以是 1 或者 2,对应着 parent 在 merge commit 信息中的顺序。以上面那张图为例,我们查看 commit
g
的内容:那么,
$ git revert -m 1 g
将会保留 master 分支上的修改,撤销 dev 分支上的修改。撤销成功之后,Git 将会生成一个新的 Commit,提交历史就成了这样:
其中
G
是撤销g
生成的 commit。通过$ git show G
之后,我们会发现G
是一个常规提交,内容就是撤销 merge 时被丢弃的那条线索的所有 commit 的「反操作」的合集。git rebase
使用
git rebase
命令可以帮助我们的清洁、整理提交记录,方便 代码review
,它可以对某一段线性提交历史进行编辑、删除、复制、粘贴。功能一:合并多次提交纪录
# git rebase -i HEAD~4 git rebase -i [startpoint] [endpoint]
1.进入
vi
编辑模式:2.异常退出了
vi
窗口功能二:变基,减少 master 冲突 commit
通常我们在
master
合入feature
分支,遇到冲突解决冲突,提交很容易产生污染主干。通过rebase
可以随时解决冲突,而merge
必须要到最后合并时才一次性解决。git cherry-pick
cherry-pick可以选择某个分支中的一个或几个
commit
来进行操作。假设我们有个稳定版本的分支,叫v2.0
,另外还有个开发版本的分支feat
,我们不能直接把两个分支合并,这样会导致稳定版本混乱,但是又想增加feat
中的部分功能到v2.0
中,这里就可以使用cherry-pick
了,其实也就是对已存在的commit
进行再次提交。示例, 代码仓库有
master
和feature
两个分支, 现在将提交f
应用到master
分支:git merge 和 git merge --no-ff
通常合并分支时,如果可能,Git会用
Fast forward
模式,但这种模式下,删除分支后,会丢掉分支信息。如果要强制禁用
Fast forward
模式,Git就会在 merge 时生成一个新的 commit,这样从分支历史上就可以看出分支信息。git merge –no-ff 可以保存你之前的分支历史。能够更好的查看 merge历史,以及branch 状态。
git merge 则不会显示 feature,只保留单条分支记录。
Other Resources
Git 撤销合并
The text was updated successfully, but these errors were encountered: