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

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

内容简介:将

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

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


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

查看所有标签

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

Spring Into HTML and CSS

Spring Into HTML and CSS

Molly E. Holzschlag / Addison-Wesley Professional / 2005-5-2 / USD 34.99

The fastest route to true HTML/CSS mastery! Need to build a web site? Or update one? Or just create some effective new web content? Maybe you just need to update your skills, do the job better. Welco......一起来看看 《Spring Into HTML and CSS》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具