Я хотел бы работать git filter-branch
на всех детях данной фиксации. Это, кажется, не легкая задача, так как, кажется, нет способа сказать git rev-list
только возвратить детей конкретной фиксации. Используя.. синтаксис не будет работать, потому что он будет также включать родительские фиксации любого слияния в том диапазоне. Я пропускаю что-то здесь?
Разъясниться: мне назвали ответвление base
который был объединен в derivative
многократно. Я хотел бы перечислить, и в конечном счете работать filter-branch
на, просто фиксации, которые убывают от его новой фиксации. Я также хотел бы перечислить подобные фиксации на других ответвлениях.
(Упрощенная) ситуация (derivative
ответвление слева):
$ git rev-list --graph --oneline base derivative
* f16fd151b374b2aeec8b9247489c518a6347d001 merged in the latest from the base branch
|\
| * 564d795afb63eab4ffe758dbcd726ca8b790f9f6 spelling correction
* | 2f2ed5f1d429492e1491740e30be5a58ec20af21 snogg before flarg
|\ \
| |/
| * 0c520ea33ef57b30846b122781d41fcef5e62f9b now with added flarg
* | 5068c34c3862856f511b6b4d48f2adb766e1bde4 now with added snogg
|/
* b51f227e931f830cbda042bc372087398ae7e50d initial commit
Предложение @araqnid, кажется, не работает, если я не испортил чтение его:
$ git rev-list --oneline derivative --not base
f16fd151b374b2aeec8b9247489c518a6347d001 merged in the latest from the base branch
2f2ed5f1d429492e1491740e30be5a58ec20af21 snogg before flarg
5068c34c3862856f511b6b4d48f2adb766e1bde4 now with added snogg
поскольку это подает все фиксации derivative
за исключением фиксаций в base
. Это отчасти имеет смысл, начиная со всего, что он делает, удаляет предков отрицаемой фиксации. То, что я хочу, чтобы это показало, является просто первой строкой.
ну, «--branches» или «--all» будут включать все концы веток, а затем «--not A» исключит A и все его предки. Однако "--branches --not A" будет включать ветки, в которых нет A, что, я думаю, вам не нужно.
Нет простого способа получить все, что вы хотите, хотя вы можете решить это. Это перечислит все ветки, содержащие фиксацию A:
git for-each-ref refs/heads/* | while read rev type name; do
git rev-list $rev | grep $(git rev-parse A) >/dev/null && echo $rev
done
, тогда вам нужно будет перечислить все ревизии, доступные из любой из них, но не сам A и любые предыдущие ревизии
git rev-list $(git for-each-ref refs/heads/* | while read rev type name; do
git rev-list $rev | grep $(git rev-parse A) >/dev/null && echo $rev
done) --not A
Обратите внимание, что я провел только очень краткий тест : p Но я думаю, что основы хороши.
Кажется, это сработает:
$ for rev in $(git rev-list --branches); do
git rev-list $rev \
| grep $(git rev-parse base) &>/dev/null \
&& echo $rev;
done \
| xargs -L 1 git rev-list -n 1 --oneline
f16fd151b374b2aeec8b9247489c518a6347d001 merged in the latest from the base branch
564d795afb63eab4ffe758dbcd726ca8b790f9f6 spelling correction
Последняя секция канала с xargs
предназначена только для отображения сообщений фиксации для каждого из этих совершает.
Здесь перечислен целевой коммит в дополнение к его дочерним элементам, чего я и хотел. Хотя это чертовски медленно: на выполнение репо с 40 фиксациями требовалось более 3 секунд. Это неудивительно, поскольку это такая же грубая сила, как Андре Великан. Я предполагаю, что более элегантный метод прошел бы через список изменений для каждой ссылки и построил бы дерево хэшей каждого коммита, связанного с его дочерними элементами, а затем перешел бы его, начиная с целевого коммита. Но это довольно сложно, поэтому я надеялся, что для этого есть команда git :)
. Мне все еще нужно выяснить, как поместить этот набор коммитов в filter-branch
. Думаю, я могу просто выполнить команду rev-list
из $ GIT_COMMIT
из моей команды - tree-filter
.