我正在尝试将许多提交压缩成一个,问题是我需要通过作者(名称或电子邮件)来做。
案例:
假设我有一个名为feature-a的分支,在这个分支中我有很多作者的提交。如何将作者(例如电子邮件)的所有提交压缩到一个提交中。我希望这样做能够将所有作者提交合并到master。
这里有任何帮助吗?
提前致谢
答案 0 :(得分:1)
如果为每个作者创建分支,cherry-pick从每个作者提交到正确的分支,然后压缩这些更改,则可能会出现所需的最终结果。但是,如果这些提交有意义地相互依赖,我认为这不会起作用。
如果您有一系列提交:
Author1 Author2 Author1
version1 ---commit---> version2 ---commit---> version3 ---commit--->...
如果您尝试从Author2中提取更改并将其应用于版本1,则很可能没有意义(例如,如果Author2修改了Author1创建的代码)。
答案 1 :(得分:1)
SORTED_GIT_LOGS=$(git log --pretty="format:%an %H" master..feature_a | sort -g | cut -d' ' -f2); \
IFS=$(echo -en "\n\b"); for LOG in $SORTED_GIT_LOGS; do \
git cherry-pick $LOG; \
done | less
git log --pretty="format:%an %H" master..feature_a | sort -g
会对feature_a
提交的日志进行排序(而不是master
提交的日志,因为master..feature_a
语法)
你仍然需要做一个交互式的rebase来压缩master
上的(现在按作者排序)提交。
答案 2 :(得分:1)
我需要在repo离线时对不必要的大型存储库进行类似的重写。我采用的方法是使用GIT_SEQUENCE_EDITOR
尝试自动化的“交互式”变基,this answer涵盖@ james-foucar& @pfalcon。
为了使其运行良好,我发现最好首先从正在重写的历史记录部分中删除合并。对于我自己的情况,这是使用大量的git rebase --onto
来完成的,这在StackOverflow的其他问题中有很多内容。
我创建了一个small script generate-similiar-commit-squashes.sh
来生成pick
& squash
命令,以便连续的类似提交被压扁。我使用author-date-and-shortlog来匹配类似的提交,但你只需要作者(我的要点有关于如何使其仅与作者匹配的评论)。
$ generate-similiar-commit-squashes.sh > /tmp/git-rebase-todo-list
输出看起来像
...
pick aaff1c556004539a54a7a33ce2fb859af0c4238c foo@example.com-2015-01-01-Update-head.html
squash aa190ea2323ece42f1cd212041bf61b94d751d5c foo@example.com-2015-01-01-Update-head.html
pick aab8c98981a8d824d2bc0d5278d59bc1a22cc7b0 foo2@example.com-2015-01-28-Update-_config.yml
存储库也充满了自我还原,具有相同样式的“更新xyz”提交消息。当被压扁时,它们会导致空提交。
我合并的提交有相同的提交消息。 git rebase -i
提供修改后的提交消息,其中附加了所有压缩的提交消息,这些消息本来是重复的。为了解决这个问题,我使用this answer中的一个小的perl脚本从git rebase
提供的提交消息中删除重复的行。它在文件中更好,因为它将在shell变量中使用。
$ echo 'print if ! $x{$_}++' > /tmp/strip-seen-lines.pl
现在进行最后一步:
$ GIT_EDITOR='perl -i -n -f /tmp/strip-seen-lines.pl ' \
GIT_SEQUENCE_EDITOR='cat /tmp/git-rebase-todo-list >' \
git rebase --keep-empty -i $(git rev-list --max-parents=0 HEAD)
尽管使用--keep-empty
,但git
在此过程中多次抱怨空提交。它会把我带到一个不完整的git rebase
的控制台。要跳过空提交和恢复处理,需要以下两个命令(在我的情况下经常使用)。
$ git reset HEAD^
$ GIT_EDITOR='perl -i -n -f /tmp/strip-seen-lines.pl ' git rebase --continue
尽管--keep-empty
,我在最后的git历史记录中找到了had no empty commits,所以上面的重置已将它们全部删除了。我认为我的git版本2.14.1有问题。处理~10000这样的提交在一台糟糕的笔记本电脑上花了10多分钟。