git filter-ветки, не закрывающие удаленные ветки - PullRequest
0 голосов
/ 01 декабря 2018

Я пытаюсь отфильтровать ветки в этом уроке https://help.github.com/articles/removing-sensitive-data-from-a-repository/.

git filter-branch --force --index-filter "git rm -r --cached --ignore-unmatch $1" --prune-empty --tag-name-filter cat -- --all
git push --force --all

фильтрует только главную ветвь, а не orgin / ветки.Вместо этого мне пришлось написать этот сценарий:

for branch in $(git for-each-ref --format='%(refname)' refs/)
do
    git checkout $branch
    git filter-branch --force --index-filter "git rm -r --cached --ignore-unmatch $1" --prune-empty --tag-name-filter cat -- --all
    git push --force --all
done

Есть идеи, как получить первую команду, которая перебирает все ссылки, чтобы мне не пришлось делать цикл самому?

1 Ответ

0 голосов
/ 01 декабря 2018

[git filter-branch ... --all] фильтрует только главную ветвь, а не orgin / branch ...

Это нормально и желательно, поскольку имена origin/ не являютсяна самом деле ветвь имен вообще.(Git называет их названиями веток для удаленного отслеживания , что, мне кажется, звучит слишком похоже на "имена веток" - в конце концов, там есть фраза "имя ветки"! - поэтому я решил их назвать«имена для удаленного отслеживания», помогающие их различать.)

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

Ваш последующий git push --force --all просит ваш Git отправить в Git все имена ваших веток и соответствующий им коммитхэш-идентификаторы, а также любые ваши коммиты, которых нет у origin, которые необходимы для того, чтобы все это работало.Затем ваши команды Git (--force) их Git устанавливают свои имена ветвей так же, как ваши, то есть указывают на скопированные, новые и улучшенные коммиты.Если они примут эту команду, ваш Git обновит ваши имена для удаленного отслеживания.

В общем, вы хотите найти все ваши имена для удаленного отслеживания, соответствующие их именам ветвей:

git for-each-ref refs/remotes/origin  # add --format options as appropriate

и используйте эти имена, чтобы убедиться, что у вас есть ваши собственные имена ветвей, указывающие на тот же коммит, что и эти имена для удаленного отслеживания.Нижеследующее не проверено, поэтому сначала проверьте его.Он также на самом деле не терпит неудачу , когда что-то не так (потому что prog | while ... делает это слишком сложно), он просто печатает предупреждения.

git for-each-ref --format='%(refname)' refs/remotes/origin |
    while read name; do
        shortname=${name#refs/remotes/}
        localname=${name#refs/remotes/origin/}
        # if we have a branch named $localname, make sure it
        # identifies the same commit as $name.  If not, create
        # one pointing to $name.
        fullname=refs/heads/$localname  # use full name in case of tags etc
        if hash=$(git rev-parse $fullname); then
            if test $hash != $(git rev-parse $name); then
                echo "WARNING: local branch $localname differs from $shortname"
            else
                echo "local branch $localname is good (matches $shortname)"
            fi
        else
            echo "creating local branch $localname to match $shortname"
            # NB: you can add --track here but that is the default anyway
            if ! git branch $localname $name; then
                echo "WARNING: failed to create $localname"
            fi
        fi
    done

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

Есть еще одна проблема, возможно незначительная или не относящаяся к делу.Ваша ветвь фильтра говорит:

... --tag-name-filter cat ...

, что говорит вашему git filter-branch обновить любой из ваших тегов.Но ваш окончательный git push говорит git push --force --all, а --all в git push означает толкать все ветви , а не толкать все ветви и теги .Если ваш git filter-branch обновил некоторые теги , вы, вероятно, также должны их подтолкнуть.

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

...