简单版本:
如果我有一个分支“foo-555”,有一堆提交信息如下:
我希望删除所有不以“foo 555:”开头的提交,有没有办法使用git filter-branch(或其他任何工具)?
原始版本(更详细):
在我们的存储库中,我们有一个约定,其中每个提交消息都以某种模式开头:
Redmine#555:SOME_MESSAGE
我们还进行了一些重新定位,以便将潜在的发布分支更改引入特定问题的分支。换句话说,我可能有分支“foo-555”,但在我将它合并到分支“预发布”之前,我需要获得预发布的任何提交,foo-555没有(所以foo- 555可以快进合并到预发布。)
但是,由于预发布有时会发生变化,我们有时会遇到从预发布中引入提交的情况,但之后的提交会从预发布中删除。很容易识别来自预发布的提交,因为提交消息中的数字与分支号码不匹配;例如,如果我在我的foo-555分支中看到“Redmine#123:...”,我知道它不是我分支的提交。
现在问题是:我想删除所有“不属于”分支的提交;换句话说,任何提交:
但当然“555”因分支而异。有没有办法使用filter-branch(或任何其他工具)来实现这一目标?目前我能看到的唯一方法是做一个交互式rebase(“git rebase -i”)并手动删除所有“坏”提交。
答案 0 :(得分:9)
这是一个使用filter-branch
而不是重新定位的快速解决方案。没有交互性或需要解决冲突。
git filter-branch --commit-filter '
if [ `git rev-list --all --grep "<log-pattern>" | grep -c "$GIT_COMMIT"` -gt 0 ]
then
skip_commit "$@";
else
git commit-tree "$@";
fi' HEAD
您可能希望用以下内容进行清理:
git reflog expire --expire=now
git gc --prune=now
答案 1 :(得分:5)
编写脚本以删除Redmine #555
行:
#!/bin/sh
mv $1 $1.$$
grep -v 'Redmine #555' < $1.$$ > $1
rm -f $1.$$
当然你可以随心所欲地做到这一点(例如echo
ed
的命令脚本。
然后启动您的rebase,并将EDITOR
设置为您的脚本:
EDITOR=/path/to/script git rebase -i REVISION
当然,仍然无法保证完成 - 在退出修订期间可能会出现错误。您仍然可以手动修复它们并git rebase --continue
。