git merge --squash / git rebase -i / git cherry-pick

栏目: 编程工具 · 发布时间: 4年前

内容简介:将

git merge --squash

git merge --squash {srcBranch} 常用于将 feat 分支合并至 dev 时压缩繁杂的提交日志,让合并变得清晰明了。

srcBranch 上的超前于当前分支的 commits 合并至当前分支,且当前分支不进行 commit ,合并或解决冲突成功后,允许我们手动做一次 commit log ,这样 srcBranch 的多个 commits 合并至当前分支时只产生一个 commit 了。

git checkout dev
echo 1111 >> foo.txt
git add foo.txt
git commit -m "foo.txt 1111"

git checkout -b feat_1
echo 2222 >> foo.txt && git commit -am "foo.txt 2222"
echo 3333 >> foo.txt && git commit -am "foo.txt 3333"
echo 4444 >> foo.txt && git commit -am "foo.txt 4444"
git log

git checkout dev
# 如果我们直接 git merge feat_1 的话 那 feat_1 的所有提交都会记录至 dev
# 但我们想简洁的表征一下
git merge --squash feat_1

# 手动编写 log 提交
git commit -m '
foo.txt 2222
foo.txt 3333
foo.txt 4444
'
# 或者使 diff logs 为模板提交
git commit -v
# 进入 vim 模式 编辑合并的 log
:wq

# 可以看到 feat_1 的 3 log 合并到 dev 上后只有 1 log
git log

--squash 的作用为只合并源分支的内容到当前分支的 stage 区,将 commit 交由我们来决定,这样便可以整合其他分支的提交日志。

git rebase -i

切记不可用于协同开发的分支,只能用于独自使用的分支。

git rebase -i [startPoint] [endPoint]

rebase 可以方便我们编辑本分支的 commit 记录:合并,修改,删除。比如我在 feat 分支上开发测试 ok ,需要合并到 dev 分支,但 feat 上有很多繁杂的 commit logs ,我们可能并不需要在 dev 中体现,可能有人想到可以在 dev 上使用 merge --squash ,但如果 feat 落后 dev 很多,这时我们可能需要使用 git cherry-pick commitLogHash 的方法将 feat 中特定的提交合并至 dev 分支。这时就需要我们在 dev 的基础分支上创建一个 temp 分支, temp merge --squash feat 后获得一次性提交的 temp_commit_log ,然后切换至 dev 执行 git cherry-pick {temp_commit_log} 合并至 dev 分支,或者我们可以使用 rebase -i HEAD~N HEAD 的方式合并本分支的多次提交。

合并多条提交记录至用一条

git checkout dev
echo 1111 >> bar.txt && git add bar.txt
git commit -m "bar.txt 1111"

git checkout -b feat_2 dev
echo 2222 >> bar.txt && git commit -am "bar.txt 2222"
echo 3333 >> bar.txt && git commit -am "bar.txt 3333"
echo 4444 >> bar.txt && git commit -am "bar.txt 4444"

# 开发完成 要讲 feat_2 合并回 dev 但不想要太多 feat-2 的 log
git rebase -i dev

-----------------------------------------------------------------------
pick 0483730 bar.txt 2222
pick adf4d92 bar.txt 3333
pick cd1b421 bar.txt 4444

# Rebase 7ffea48..cd1b421 onto 7ffea48 (3 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
# 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.
-----------------------------------------------------------------------

# 修改至如下
pick 0483730 bar.txt 2222
s adf4d92 bar.txt 3333
s cd1b421 bar.txt 4444
:wq

-----------------------------------------------------------------------
# This is a combination of 3 commits.
# This is the 1st commit message:
# 合并多个日志
bar.txt 2222
bar.txt 3333
bar.txt 4444
# 编辑后 :wq 保存退出
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Apr 26 14:26:09 2019 +0800
#
# interactive rebase in progress; onto 7ffea48
# Last commands done (3 commands done):
#    squash adf4d92 bar.txt 3333
#    squash cd1b421 bar.txt 4444
# No commands remaining.
# You are currently rebasing branch 'feat_2' on '7ffea48'.
-----------------------------------------------------------------------

# 可以看到三个提交合并至 1 个了
git log
# 不过会造成 HEAD detached from fed40ed
git checkout -b temp
# 查看具体的
git log
git checkout feat_2
git cherry-pick 
# 切换至 dev 合并 feat_2 的日志会很简洁 
git checkout dev
git merge feat_2
git log

修改 commit log

git rebase -i [startpoint] [endpoint] 的 startpoint 为开区间,所以如我们想修改提交的日志,需要如下

#重建最近一次的提交
git rebase -i HEAD~1
#重建 HEAD~3 - HEAD~2 的两次提交
git rebase -i HEAD~4 HEAD~2

实例,我们对 feat_4foo4 做了 4 次提交,日志如下

git log --pretty=oneline --abbrev-commit
fed40ed (HEAD -> feat_4) foo4 4444
8455d9a foo4 3333
1548e84 foo4 2222
53e837b foo4 1111

重写最近一次提交的日志

git rebase -i HEAD~1
#进入交互模式
pick fed40ed foo4 4444

# Rebase 8455d9a..fed40ed onto 8455d9a (1 command)
#
# 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
# 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.
------------------------------------------------------------------------------
# 修改 pick 为 reword 即保留本次提交,但要对提交信息做编辑
pick fed40ed foo4 4444
# 保存并退出
:wq
# 会进入日志编辑模式
foo4 4444

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Apr 26 18:40:09 2019 +0800
#
# interactive rebase in progress; onto 8455d9a
# Last command done (1 command done):
#    reword fed40ed foo4 4444
# No commands remaining.
# You are currently editing a commit while rebasing branch 'feat_4' on '8455d9a'.
#
# Changes to be committed:
#       modified:   foo4
--------------------------------------------------------------------------------
# 修改至你想要的日志
foo4 4444 modify by rebase::reword
:wq

# 可以看到日志已经被修改
git log --pretty=oneline --abbrev-commit
7ccdb4c (HEAD -> feat_4) foo4 4444 modify by rebase:reword
8455d9a foo4 3333
1548e84 foo4 2222
53e837b foo4 1111

git rebase -i 合并/修改提交记录的方法如上所示。

git cherry-pick

git cherry-pick 的使用场景主要是用于挑选合并某分支上的提交到当前分支。比如我们将 feat1 合并到了 dev ,产生了 log-dev-feat-1 ,将 feat1 合并到了 dev ,产生了 log-dev-feat-2 ,现在我只想将 feat1 发布到测试分支, git merge dev 已经不能满足了,因为会将 log-dev-feat-2 一起合并过来。

git checkout dev
git merge feat1
git merge feat2
git log --pertty=oneline
git checkout test
# 挑选合并feat1的提交
git cherry-pick feat1-log-hash

这样我们就可以灵活的选择要发布到测试环境的功能项了。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Flash第一步

Flash第一步

陈冰 / 清华大学出版社 / 2006-3 / 45.00元

《Flash第1步:ActionScript编程篇》(珍藏版)为《Flash第一步》的ActionScript编程篇,包含后4部分内容。第3部分为ActionScript篇,你将学会像一个软件设计师那样来思考问题,并掌握在Flash中进行程序开发工作所必须具备的重要知识,还将学会运用Flash完整的编程体系来完成从简单到复杂的各种编程任务。另外,在开发一个Flash应用过程中会涉及的各种其他Web......一起来看看 《Flash第一步》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器