Неоднократное использование git-filter-branch для перезаписи новых коммитов

StackOverflow https://stackoverflow.com/questions/2296047

  •  21-09-2019
  •  | 
  •  

Вопрос

Я хотел бы разделить модули, распространяемые вместе с более крупным приложением, на отдельные подмодули и сохранить возможность извлечения из восходящего потока.

Так что это сложнее, чем Отключить подкаталог в отдельный репозиторий Git..Я не только должен один раз использовать git-filter-branch, но и хочу сохранить возможность извлекать изменения из исходной ветки после того, как я это сделал (а из исходной ветки не было).

Просто перезапустить git-filter-branch для полной истории из исходной версии, включая новые коммиты, не найденные в моей переписанной истории, не вариант, поскольку существуют сотни модулей, для которых мне приходится это делать, а количество коммитов приближается к 100 000. .

Я предполагаю, что это предполагает ограничение истории только новыми коммитами, их переписывание и затем добавление после ранее переписанных коммитов, но я не уверен, как это сделать - и, возможно, есть лучший подход.

Было бы неплохо, если бы ветки и теги также можно было сохранить, но это не является абсолютно необходимым, и если это усложняет ситуацию, я бы предпочел их потерять.

Это было полезно?

Решение

Для первой перебазировки сделайте следующее:

git checkout -b rebased master
git filter-branch --some-filter
git tag rebased-done master

И для «слияния» позже фиксируется:

# Create a tempory branch and rebase it's tail use 'rebase-done~'
# and not 'rebase-done' because some filters (like --index-filter)
# require this, others might not.
git checkout -b rebased-tail master
git filter-branch -f --some-filter -- rebased-done~..HEAD

# Get the commit in branch 'rebased' corresponding to tag 'rebase-done'
# (which tags a commit in 'master' not 'rebased').  Depending on your
# situation you might have to determine this commit differently (in my
# use case I am absolutely sure that there is never a commit with the
# same author date - if that doesn't work you might want to compare
# commit messages).
start_time=$(git show --quiet --pretty=%at rebased-done)
start_hash=$(
git log --reverse --pretty="%H %at" rebased_tail |
while read hash time
do
    [ "$time" = "$start_time" ] && echo $hash && break
done
)

# Finally apply the rebased commits.
git checkout rebased
git format-patch -k --stdout $start_hash..rebased-tail | git am -k
git branch -D rebased-tail
git tag -f rebased-done master
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top