Подтвердить что ты не робот

Запуск фильтра-ветки по целому ряду коммитов

git filter-branch --env-filter '
export GIT_AUTHOR_EMAIL="[email protected]"
export GIT_AUTHOR_NAME="foo"' -- commita..commitb

Результаты в Which ref do you want to rewrite?

Итак, кажется, что filter-branch не позволяет использовать использование нотации диапазона в диапазоне между двумя произвольными ссылками.

Каков самый прямой способ запуска фильтра по целому ряду последовательных коммитов (где-то в истории ветки), если этот подход невозможен.

4b9b3361

Ответ 1

Самое чистое решение, которое я нашел, это сделать следующее:

  • Создайте временную ветвь в refb.
  • Примените фильтр ветвления к refa..temp.
  • Восстановите временную ветку и удалите ее.

е.

git branch temp refb

git filter-branch --env-filter '
export GIT_AUTHOR_EMAIL="[email protected]"' refa..temp

git rebase temp
git branch --delete temp

Ответ 2

Вы не можете применить ответвление фильтра в середине истории, как говорит @kan. Вы должны подать заявку от вашего известного коммита до конца истории

git filter-branch --env-filter '...' SHA1..HEAD

Фильтр-ветвь может проверять автора коммита или другую информацию, выбирать, менять или нет коммит, поэтому есть способы выполнить то, что вы хотите, см. https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History, поищите "Изменение адресов электронной почты глобально"

Помните: если вы отправили коммиты в публичный репозиторий, вы не должны использовать filter-branch пользователя

Ответ 3

git filter-branch выполняет принятие нотации диапазона, но конец диапазона должен быть ссылкой, а не идентификатором фиксации.

git checkout -b tofilter commitb
git filter-branch .... commita..tofilter

Если заданы только коммиты, он не будет знать, что нужно обновить с фильтрованной веткой.

Ответ 4

Включите команды фильтрации в if-statement, который проверяет этот диапазон. Вы можете проверить, находится ли коммит в заданном диапазоне с помощью этой команды:

git rev-list start..end | grep **fullsha**

Текущая фиксация будет сохранена в $GIT_COMMIT в вашем фильтре. Таким образом, ваш фильтр будет выглядеть следующим образом:

git filter-branch --env-filter '
  if git rev-list commita..commitb | grep $GIT_COMMIT; then
    export GIT_AUTHOR_EMAIL="[email protected]"
    export GIT_AUTHOR_NAME="foo"
  fi' -- ^commita --all

Если вы хотите переписать только текущую ветвь, замените --all на HEAD

Ответ 5

Вы не можете просто переопределить фиксации в середине истории, потому что sha1 фиксации зависит от родительского. Таким образом, git не знает, где вы хотите указать ссылку HEAD после фильтрации. Итак, вы должны переписать все до HEAD.

Пример:

A---B---C---D---E---F   master
            \
             \--G---H   branch

если вы хотите, чтобы фильтр комментирует B и C, вы также должны фильтровать все фиксации после: D, E, F, G, H. Итак, почему git говорит вам использовать ref в конце диапазона, чтобы он просто не заканчивался отсоединенной головкой.

После того, как вы измените фиксации B и C и остановитесь, это будет выглядеть так:

A---B---C---D---E---F   master
\           \
 \           \--G---H   branch
  \-B'--C'      (HEAD or a temporary TAG?..)      

Итак, master и branch будут не затронуты. Я не думаю, что это то, чего ты хочешь. Это означает, что вы должны переопределить все фиксации. История будет следующей:

A---B---C---D---E---F   (loose end, will be garbage collected one day)
\           \
 \           \--G---H   (loose end, will be garbage collected one day)
  \-B'--C'--D'--E'--F'  master
            \
             \--G'--H'  branch

Ответ 6

Я делаю это так.

Предположим, вы хотите отфильтровать содержимое ветки с именем branch-you-are-filtering.

Предположим, что в этой ветке есть предок, с ref ref-for-commit-to-stop-at.

git filter-branch --commit-filter 'YOUR_FILTER_COMMANDS' branch-you-are-filtering...ref-for-commit-to-stop-at

После выполнения, фиксация в ref-for-commit-to-stop-at не будет изменена. Все отфильтрованные\измененные фиксации в ветки ветки - вы-фильтрация будут основаны на ref-for-commit-to-stop-at.

Независимо от того, используете ли вы -commit-filter или что-то еще, вы не можете.

Ответ 7

Решение от @Acron мне кажется неправильным. Я бы предложил следующее для переключения между refa и refb, включая оба хэша:

  1. git tag master.bak
  2. git reset --hard refa
  3. git filter-branch --env-filter ' export GIT_AUTHOR_EMAIL="[email protected]"' refa^..master
  4. git cherry-pick refb..master.bak
  5. git tag -d master.bak

Ответ 8

Используйте фильтр-ветвь --setup parm и немного мощности оболочки:

git filter-branch --setup '
for id in 'git rev-list commitA..commitB'; do
         eval filterfor_$id=rewrite
done
rewrite() {
        GIT_AUTHOR_NAME="Frederick. O. Oosball"
        [email protected]
}
' --env-filter 'eval \$filterfor_$GIT_COMMIT'