说我介绍了< feature.c>前一段时间,现在注意到它不应该是我的main
分支的一部分,而是分支feature
。有可能使用例如git-filter-branch
自动将所有< feature.c>的历史记录从main
分支移出到feature
分支?
答案 0 :(得分:6)
听起来你正在做一些相当疯狂的事情! :)
那就是说,我看到了一些选项,其中没有一个是特别自动化的。
如果您对该文件提交了大量提交,只需承认错误,从HEAD创建一个新分支,并将该功能的进一步提交放入该分支,直到它们稳定为止。如果你是repo的共享,这将成为唯一真正的选择。没有人想要有不同的历史,特别是如果这个特征在历史深处都有。
如果您只是在谈论实际触及该文件的大约10个提交,并且它们最近提交而没有交错的许多其他提交,您可以在HEAD上检出新分支,并还原在添加功能之前,您不希望使用此功能,然后在功能分支中提取您需要的提交,直到您准备好以后再提交它们为止。
如果你正在处理大量的历史记录,大量的交错提交,而你真的不想让这个功能出现,你可以写一点获取git log
输出的shell脚本,并将其选入新分支。有点像:
$ cd git-repo
$ git checkout -b feature-x
$ the-perfect-shell-script `git log --pretty=format:"%H" path/to/feature.c`
一旦你拥有了所有提交的功能分支,你可以使用git filter-branch
过滤掉引用该文件的所有提交。 man page有一个简单的例子,就是这样。
一旦你有了这个,你就可以git rebase feature-x --onto <filtered-branch>
,你应该好好去。
当然应该非常气馁,特别是如果发布任何的话。
答案 1 :(得分:1)
好的,这是我的去处:
如果我没有提交操作&lt; feature.c&gt;,我可以从&lt; feature.c&gt;的第一次提交中分支,然后在循环中使用git cherry-pick
和git log
, suggested Tim Visher。从大师开始,我想这应该有效:
#!/bin/bash
# create the feature branch starting from feature.c's first commit
FIRSTCOMMIT=$(git log --pretty=format:"%H" feature.c | tail -n1)
git checkout -b feature $FIRSTCOMMIT
# find all commits concerning feature.c...
for i in $(git log feature..master --reverse --pretty=format:"%H" feature.c)
do
# ... cherry-pick them ...
git cherry-pick $i
# ... and copy ONE modified tag of it if existing
git describe --tags --exact-match $i && xargs taghelperscript
done
# now eliminate feature.c from master
git filter-branch --prune-empty --tag-name-filter "cat" --index-filter 'git rm --cached --ignore-unmatch feature.c' $FIRSTCOMMIT..master
taghelperscript
类似于git tag prefix.$1
(也许这可以做得更好?)。标记部分可能仅适用于我使用的轻量级标签。另请注意,如果&lt; feature.c&gt;已经在某个时候被重命名,如果它已经存在于初始提交中,这可能会导致两个单独的历史记录,或者(我的猜测)master
中的提交,其中包含删除&lt; feature.c&gt;这可能会导致合并冲突或混乱。
问题是,我的一些提交会修改其他文件,从而导致git cherry-pick
触发未解析的合并,或者引入这些其他文件。相反,我会尝试一些git filter-branch
魔法。 <子>后来。请继续关注...