我正试图在本教程中过滤分支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/branches。我不得不写这个脚本:
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
有什么想法可以让第一个命令循环所有引用,这样我就不必自己循环了吗?
[
git filter-branch ... --all
]只过滤分支主机,而不是组织/分支。。。
这是正常且可取的,因为origin/
名称实际上根本不是分支名称。(Git称它们为远程跟踪分支名称,我认为这听起来太像"分支名称"了——毕竟里面有"分支名称"这个短语!——所以我开始称它们为"远程跟踪名称"来帮助区分它们。(
远程跟踪名称是您的Git对某些其他Git分支的内存。当你使用git filter-branch
时,你告诉你的Git在你的存储库中复制提交,在提交副本之前做一些更改,然后更新你的分支名称,指向新的复制的——可能是新的和改进的——提交,而不是原始的(旧的和糟糕的?(提交。
您随后的git push --force --all
要求您的Git向他们的Git发送您的所有分支名称和相应的提交哈希ID,以及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
现在,每个远程跟踪分支实际上都有一个分支(加上您自己的任何没有远程跟踪名称的分支(现在filter-branch
上的--all
将执行您想要的操作。
还有另一个问题,也许是次要的或无关紧要的。你的过滤分支说:
... --tag-name-filter cat ...
告诉您的CCD_ 10更新您的任何标签。但您的最终git push
表示git push --force --all
,而git push
中的--all
表示推送所有分支,而不是推动所有分支和标签。如果您的git filter-branch
确实更新了一些标签,您可能也应该推送它们。
请注意,更改公共存储库中的标记通常是个坏主意,因为要确保这些存储库的所有其他用户都能获得与现有标记名称对应的新标记值是很困难的。不过,如果合适的话,应该继续这样做,只需警告该公共存储库的所有用户标签已经更改。