Переименуйте несколько имен и электронных писем за один проход git -filter-branch

Возможно ли массовое переименование двух или более адресов электронной почты одним проходом git filter-branch?

Я попытался адаптировать код из этого ответа, просто дублируя if..fi clause:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name 1>" ];
        then
                GIT_COMMITTER_NAME="<New Name 1>";
                GIT_AUTHOR_NAME="<New Name 1>";
                GIT_COMMITTER_EMAIL="<New Email 1>";
                GIT_AUTHOR_EMAIL="<New Email 1>";
                git commit-tree "[email protected]";
        else
                git commit-tree "[email protected]";
        fi
        if [ "$GIT_COMMITTER_NAME" = "<Old Name 2>" ];
        then
                GIT_COMMITTER_NAME="<New Name 2>";
                GIT_AUTHOR_NAME="<New Name 2>";
                GIT_COMMITTER_EMAIL="<New Email 2>";
                GIT_AUTHOR_EMAIL="<New Email 2>";
                git commit-tree "[email protected]";
        else
                git commit-tree "[email protected]";
        fi' HEAD

Но это дало мне ошибки во время фильтрации-ветки, которые выглядели так:

error: duplicate parent bc8f9924c33558a275b8f694969529cf56232c80 ignored

И тогда история ветвей была запутана:

введите описание изображения здесь

Ответ 1

Вы хотите получить только одну команду git commit-tree после установки всех переменных среды по желанию. Например, ваш фильтр фиксации может читать что-то вроде этого:

git filter-branch -f --commit-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old Name 1>" ]; then
        GIT_COMMITTER_NAME="<New Name 1>";
        GIT_AUTHOR_NAME="<New Name 1>";
        GIT_COMMITTER_EMAIL="<New Email 1>";
        GIT_AUTHOR_EMAIL="<New Email 1>";
    fi;
    if [ "$GIT_COMMITTER_NAME" = "<Old Name 2>" ]; then
        GIT_COMMITTER_NAME="<New Name 2>";
        GIT_AUTHOR_NAME="<New Name 2>";
        GIT_COMMITTER_EMAIL="<New Email 2>";
        GIT_AUTHOR_EMAIL="<New Email 2>";
    fi;
    git commit-tree "[email protected]"
    '

(хотя, если число изменений имени для создания становится выше, я, скорее всего, пропустил бы файл сопоставления вместо длинной серии easy-to-typo if ... then s, и может возникнуть больше смысла сопоставлять автора и коммиттер отдельно).

Помните, что filter-branch просто копирует все коммиты, которые вы скажете, чтобы скопировать (используя git commit-tree для создания новой копии), при построении карты из файла < old-sha1, new-sha1 > пар. Вот почему создание двух коммитов нехорошо: один существующий (старый) SHA-1 теперь должен отображать две новые копии, что просто не допускается с точки зрения того, что filter-branch делает с графом фиксации. (Несколько старых SHA-1 могут отображать один новый SHA-1, если вы решите опустить некоторые коммиты во время процесса копирования. То есть новый график может быть биективным или сюръективным, но фильтр-ветвь на самом деле не верит в инъективный, поскольку он попытается сопоставить старые ссылки с новым графиком.)