Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ ΠΈΠ· ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ
Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ ΠΈΠ· ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ β ΡΡΠΎ Π΄Π²ΡΡ ΡΡΠ°ΠΏΠ½ΡΠΉ ΠΏΡΠΎΡΠ΅ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ ΠΊΠ°ΠΊ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ, ΡΠ°ΠΊ ΠΈ Π² ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ:
-
ΠΠΎΠΊΠ°Π»ΡΠ½Π°Ρ ΠΎΡΠΈΡΡΠΊΠ° ΠΈΡΡΠΎΡΠΈΠΈ. ΠΠ° ΡΡΠΎΠΌ ΡΡΠ°ΠΏΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅
git-filter-repoΠ΄Π»Ρ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠΈ ΠΈΡΡΠΎΡΠΈΠΈ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Π½Π° Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Π΅. ΠΡΠΎΡΠ΅ΡΡ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ², Π·Π°ΠΌΠ΅Π½Ρ ΡΠ΅ΠΊΡΡΠ° Π² ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠΌ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ/ΠΈΠ»ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ². ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Π»ΠΎΠΊΠ°Π»ΡΠ½Π°Ρ ΠΊΠΎΠΏΠΈΡ Π²Π°ΡΠ΅ΠΉ ΠΈΡΡΠΎΡΠΈΠΈ ΡΠΆΠ΅ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ . -
ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ°Ρ ΠΎΡΠΈΡΡΠΊΠ° Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅. ΠΠΎΡΠ»Π΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΎΡΠΈΡΡΠΊΠΈ Π²Ρ ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΠ΅ (
git push --force) ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½ΡΡ ΠΈΡΡΠΎΡΠΈΡ Π½Π° ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ. ΠΠ΄Π½Π°ΠΊΠΎ ΡΡΠΎΠ³ΠΎ ΡΠ°ΡΡΠΎ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠ΅ ΠΏΠ»Π°ΡΡΠΎΡΠΌΡ ΠΌΠΎΠ³ΡΡ ΠΊΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠ°ΡΡΠ΅ Π²Π΅ΡΡΠΈΠΈ Π΄Π°Π½Π½ΡΡ ΠΈΠ»ΠΈ ΡΠΎΡ ΡΠ°Π½ΡΡΡ ΡΡΡΠ»ΠΊΠΈ Π½Π° Π½ΠΈΡ Π² Π·Π°ΠΏΡΠΎΡΠ°Ρ Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅. ΠΠΎΡΡΠΎΠΌΡ Π²ΡΠΎΡΠΎΠΉ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈ Π²Π°ΠΆΠ½ΡΠΉ ΡΠ°Π³ β ΡΡΠΎ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ Π² ΡΠ»ΡΠΆΠ±Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ GitVerse Π΄Π»Ρ ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠΉ ΠΎΡΠΈΡΡΠΊΠΈ ΠΊΠ΅ΡΠ΅ΠΉ ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ Π²ΡΠ΅Ρ ΠΎΡΡΠ°Π²ΡΠΈΡ ΡΡ ΡΡΡΠ»ΠΎΠΊ Π½Π° ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π½Π° ΡΡΠΎΡΠΎΠ½Π΅ ΡΠ΅ΡΠ²Π΅ΡΠ°.
ΠΠΎΠΊΠ°Π»ΡΠ½Π°Ρ ΠΎΡΠΈΡΡΠΊΠ° ΠΈΡΡΠΎΡΠΈΠΈ
ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠ΅ ΡΡΠ΅Π΄ΡΡΠ²Π° Π΄Π»Ρ ΠΎΡΠΈΡΡΠΊΠΈ ΠΈΡΡΠΎΡΠΈΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ
ΠΠ·Π²Π΅ΡΡΠ½ΠΎΠ΅ ΠΠ Π΄Π»Ρ ΠΎΡΠΈΡΡΠΊΠΈ ΠΈΡΡΠΎΡΠΈΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ:
-
git-filter-repoβ ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠΈ ΠΈΡΡΠΎΡΠΈΠΈ Git, ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ. -
git filter-branchβ ΡΡΠ°ΡΡΠΉ, ΠΌΠ΅Π΄Π»Π΅Π½Π½ΡΠΉ ΠΈ ΠΈΠΌΠ΅Π΅Ρ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ.
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ git-filter-repo ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ Π²ΡΠ΅ Π²Π΅ΡΠΊΠΈ ΠΈ ΡΠ΅Π³ΠΈ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ:
- ΠΡΠ΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ Π²Π΅ΡΠΊΠΈ
- ΠΡΠ΅ ΡΠ΅Π³ΠΈ
- ΠΡΡ ΠΈΡΡΠΎΡΠΈΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ², Π΄ΠΎΡΡΠΈΠΆΠΈΠΌΠ°Ρ ΠΈΠ· ΡΡΠΈΡ Π²Π΅ΡΠΎΠΊ
Π§ΡΠΎ ΠΠ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ:
- Π£Π΄Π°Π»Π΅Π½Π½ΡΠ΅ Π²Π΅ΡΠΊΠΈ (remote branches) β ΠΎΠ½ΠΈ Π½Π΅ Π²ΠΊΠ»ΡΡΠ°ΡΡΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
- ΠΠ΅ΡΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ Π±ΡΠ»ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ (fetch).
ΠΠ»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΠ‘ΠΠ₯ Π²Π΅ΡΠΎΠΊ Π²ΠΊΠ»ΡΡΠ°Ρ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠ΅:
# Π‘Π½Π°ΡΠ°Π»Π° ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ Π²ΡΠ΅ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠ΅ Π²Π΅ΡΠΊΠΈ
git fetch --all
# Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΊΠΎΠΏΠΈΠΈ Π²ΡΠ΅Ρ
ΡΠ΄Π°Π»Π΅Π½Π½ΡΡ
Π²Π΅ΡΠΎΠΊ
git branch -r | grep -v '\->' | while read remote; do
git branch --track "${remote#origin/}" "$remote" 2>/dev/null || true
done
# ΠΠ°ΡΠ΅ΠΌ Π·Π°ΠΏΡΡΡΠΈΡΠ΅ git-filter-repo
git-filter-repo --replace-text sensitive_data_to_clean.txtΠΠ»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠΉ ΡΠΏΠΎΡΠΎΠ± β ΡΠΊΠ°Π·Π°ΡΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠ΅ Π²Π΅ΡΠΊΠΈ:
git-filter-repo --replace-text sensitive_data_to_clean.txt --refs refs/heads/ --refs refs/remotes/ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΎΡΠΈΡΡΠΊΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ
--invert-pathsΠΈ--invert-paths --pathβ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΈΠ· ΠΈΡΡΠΎΡΠΈΠΈ.--replace-textβ Π·Π°ΠΌΠ΅Π½Π° ΡΠ΅ΠΊΡΡΠ° Π² ΡΠ°ΠΉΠ»Π°Ρ ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ².--message-callbackβ ΠΎΡΠΈΡΡΠΊΠ° ΡΠ΅ΠΊΡΡΠ° Π² ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ Python-ΡΠΊΡΠΈΠΏΡΠ°.--mailmapβ Π·Π°ΠΌΠ΅Π½Π° email Π°Π΄ΡΠ΅ΡΠΎΠ² ΠΈ ΠΈΠΌΠ΅Π½ Π°Π²ΡΠΎΡΠΎΠ² Π² ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ².--commit-callbackβ Π³ΠΈΠ±ΠΊΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ Python-ΡΠΊΡΠΈΠΏΡΠ°.cat .git/filter-repo/changed-refs- ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΡ Π²Π΅ΡΠΎΠΊgrep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refsβ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° Π·Π°ΡΡΠΎΠ½ΡΡΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅.
--invert-paths ΠΈ --invert-paths --path
Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΈΠ· ΠΈΡΡΠΎΡΠΈΠΈ:
git-filter-repo --invert-paths --path ΠΠ£Π’Π¬-Π-ΠΠΠ¨ΠΠΠ£-Π€ΠΠΠΠ£-Π‘-ΠΠΠΠ€ΠΠΠΠΠ¦ΠΠΠΠ¬ΠΠ«ΠΠ-ΠΠΠΠΠ«ΠΠΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ --path ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, ΠΊΠΎΠ³Π΄Π° ΡΠ°ΠΉΠ» ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π» ΠΏΠΎ Π΄ΡΡΠ³ΠΈΠΌ ΠΏΡΡΡΠΌ ΠΈΠ·-Π·Π° ΠΏΠ΅ΡΠ΅ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠΉ. ΠΠ½Π°ΡΠ΅ Π΄Π»Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΡΠ°ΠΉΠ»Π° ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΡΡΠ΅Π±ΠΎΠ²Π°ΡΡΡΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΠΉ Π·Π°ΠΏΡΡΠΊ Ρ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΠΌ ΠΏΡΡΠ΅ΠΌ.
--replace-text
ΠΠ°ΠΌΠ΅Π½Π° ΡΠ΅ΠΊΡΡΠ° Π² Π½Π΅Π±ΠΈΠ½Π°ΡΠ½ΡΡ ΡΠ°ΠΉΠ»Π°Ρ ΠΈΡΡΠΎΡΠΈΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°. ΠΠ°ΠΌΠ΅Π½Π° ΡΠ΅ΠΊΡΡΠ° ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΈ ΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ², Π΅ΡΠ»ΠΈ Π½Π΅ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠ΅ ΠΏΡΡΠΈ:
git-filter-repo --replace-text path/to/file/file_with_passwords.txtΠ€Π°ΠΉΠ», ΠΊΠΎΡΠΎΡΡΠΉ Π²Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΠ΅ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° --replace-text, Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΡΡΡΠΎΠΊΠΈ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ search_string==>replacement_string.
ΠΠ°ΠΆΠ΄Π°Ρ ΡΡΡΠΎΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΠΈΡΠΊΠΎΠΌΡΠΉ ΡΠ΅ΠΊΡΡ, Π·Π°ΡΠ΅ΠΌ Π΄Π²Π° Π·Π½Π°ΠΊΠ° ΡΠ°Π²Π΅Π½ΡΡΠ²Π° (==>), Π° Π·Π°ΡΠ΅ΠΌ ΡΠ΅ΠΊΡΡ Π΄Π»Ρ Π·Π°ΠΌΠ΅Π½Ρ.
ΠΡΠΈΠΌΠ΅Ρ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΡΠΎ ΡΡΡΠΎΠΊΠ°ΠΌΠΈ Π΄Π»Ρ Π·Π°ΠΌΠ΅Π½Ρ:
ΠΌΠΎΡ_ΡΡΠ°ΡΠ°Ρ_ΡΡΠ½ΠΊΡΠΈΡ==>ΠΌΠΎΡ_Π½ΠΎΠ²Π°Ρ_ΡΡΠ½ΠΊΡΠΈΡ
ΡΡΡΠ°ΡΠ΅Π²ΡΠ°Ρ_ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ==>Π°ΠΊΡΡΠ°Π»ΡΠ½Π°Ρ_ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ
ΡΠ΅ΠΊΡΠ΅ΡΠ½ΡΠΉ_ΠΊΠ»ΡΡ_Π==>ΡΠΊΡΡΡΡΠΉ_ΠΊΠ»ΡΡ_BΠΡΠ»ΠΈ Π½Π΅ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ ΡΠ΅ΠΊΡΡ Π΄Π»Ρ Π·Π°ΠΌΠ΅Π½Ρ, ΡΠΎ Π²ΠΌΠ΅ΡΡΠΎ Π·Π°ΠΌΠ΅Π½Ρ Π½Π°ΠΉΠ΄Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΊΡΡ Π±ΡΠ΄Π΅Ρ ΡΠ΄Π°Π»Π΅Π½. ΠΡΠΈΠΌΠ΅Ρ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° Π΄Π»Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ:
ΠΌΠΎΡ_ΡΠ΅ΠΊΡΠ΅ΡΠ½Π°Ρ_ΡΡΡΠΎΠΊΠ°_123
API_KEY_Π’ΠΠΠΠ
ΠΏΠ°ΡΠΎΠ»Ρ_ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ--message-callback
ΠΡΠΈΡΡΠΊΠ° ΡΠ΅ΠΊΡΡΠ° Π² ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ². ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΡΡ ΠΎΡΠΈΡΡΠΊΡ ΠΈΠ»ΠΈ Π·Π°ΠΌΠ΅Π½Ρ ΡΠ΅ΠΊΡΡΠ° Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π² ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Python-ΡΠΊΡΠΈΠΏΡ:
git-filter-repo --message-callback '
import re
secret_to_find = r"ΡΠ΅ΠΊΡΠ΅Ρ" # ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠ° Ρ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ
replacement_text = b"Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠΈΡΠ΅Π½ΠΎ ΠΎΡ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ
Π΄Π°Π½Π½ΡΡ
" # Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π½Π° ΠΌΠ΅ΡΡΠ΅ Π·Π°ΠΌΠ΅Π½Ρ
if re.search(secret_to_find, message.decode("utf-8")):
return replacement_text
return message
'Π Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅, ΡΡΠΎΠ±Ρ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠΉ ΡΠ΅ΠΊΡΡ Π±ΡΠ» ΡΡΠ΅ΡΡ Π±Π΅Π· Π·Π°ΠΌΠ΅Π½Ρ, ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ replacement_text ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ ΠΏΡΡΡΡΡ Π±Π°ΠΉΡΠΎΠ²ΡΡ ΡΡΡΠΎΠΊΡ replacement_text = b"".
--mailmap
ΠΠ°ΠΌΠ΅Π½Π° email Π°Π΄ΡΠ΅ΡΠΎΠ² ΠΈ ΠΈΠΌΠ΅Π½ Π°Π²ΡΠΎΡΠΎΠ² Π² ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ². ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎΠ± Π°Π²ΡΠΎΡΠ°Ρ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² Π²ΠΎ Π²ΡΠ΅ΠΉ ΠΈΡΡΠΎΡΠΈΠΈ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ:
git-filter-repo --mailmap <(echo "ΠΠΎΠ²ΠΎΠ΅ ΠΠΌΡ <new-email@example.com> <old-email@personal.com>")- ΠΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅
<(echo ...)Π² Windows β ΡΡΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ Π² bash, Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠ°ΠΉΠ».mailmapΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ Π·Π°ΠΌΠ΅Π½ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π΅Π³ΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°. - Π mailmap-ΡΠ°ΠΉΠ»Π΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠ³Π»ΠΎΠ²ΡΠ΅ ΡΠΊΠΎΠ±ΠΊΠΈ Π΄Π»Ρ email. Π€ΠΎΡΠΌΠ°Ρ ΡΡΡΠΎΠΊΠΈ mailmap:
ΠΠΎΠ²ΠΎΠ΅ ΠΠΌΡ <Π½ΠΎΠ²ΡΠΉ-email@example.com> <ΡΡΠ°ΡΡΠΉ-email@personal.com>.
ΠΡΠΈΠΌΠ΅Ρ ΡΠ°ΠΉΠ»Π° mailmap.txt Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π·Π°ΠΌΠ΅Π½Π°ΠΌΠΈ (ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠ³Π»ΠΎΠ²ΡΠ΅ ΡΠΊΠΎΠ±ΠΊΠΈ):
ΠΠΈΡΠ½Π°Ρ ΠΏΠΎΡΡΠ° <public@example.com> <sensitive_personal@example1.com>
Π Π°Π±ΠΎΡΠ°Ρ ΠΏΠΎΡΡΠ° <new@company.com> <old@company.com>
ΠΠ½ΠΎΠ½ΠΈΠΌΠ½ΡΠΉ ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ <anon@example.com> <sensitive_personal@example2.com>ΠΡΠΈΠΌΠ΅Ρ Π·Π°ΠΏΡΡΠΊΠ° ΠΊΠΎΠΌΠ°Π½Π΄Ρ git-filter-repo --mailmap Ρ ΡΠ°ΠΉΠ»ΠΎΠΌ mailmap.txt (ΡΠ°ΠΉΠ» ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ Π² ΠΏΠ°ΠΏΠΊΠ΅ ΡΡΠΎΠ²Π½Π΅ΠΌ Π²ΡΡΠ΅):
bash copy git-filter-repo --mailmap ../mailmap.txt --commit-callback
ΠΠΈΠ±ΠΊΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ Python-ΡΠΊΡΠΈΠΏΡΠ°. ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ Π»ΡΠ±ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΊΠΎΠΌΠΌΠΈΡΠ°, Π²ΠΊΠ»ΡΡΠ°Ρ email Π°Π΄ΡΠ΅ΡΠ°, ΠΈΠΌΠ΅Π½Π°, Π΄Π°ΡΡ:
git-filter-repo --commit-callback '
# ΠΠ°ΠΌΠ΅Π½Π° email Π² ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ
ΠΊΠΎΠΌΠΌΠΈΡΠ°
if commit.author_email == b"sensitive_personal@example.com":
commit.author_email = b"public@email.com"
if commit.committer_email == b"sensitive_personal@example.com":
commit.committer_email = b"public@email.com"
# ΠΠ°ΠΌΠ΅Π½Π° ΠΈΠΌΠ΅Π½ Π°Π²ΡΠΎΡΠΎΠ²
if commit.author_name == b"ΠΠΈΡΠ½ΠΎΠ΅ ΠΠΌΡ":
commit.author_name = b"ΠΡΠ±Π»ΠΈΡΠ½ΠΎΠ΅ ΠΠΌΡ"
'Π‘ ΠΏΠΎΠΌΠΎΡΡΡ --commit-callback ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ:
- ΠΠ°ΡΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ².
- Π‘ΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ.
- ΠΡΡΠ³ΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΠ΅. ΠΡΠ΅ ΡΡΡΠΎΠΊΠΎΠ²ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π² Π±Π°ΠΉΡΠΎΠ²ΠΎΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅ (Ρ ΠΏΡΠ΅ΡΠΈΠΊΡΠΎΠΌ
b).
ΠΡΠΈΠΌΠ΅Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π΄Π°Ρ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ²:
git-filter-repo --commit-callback ' import time from datetime import datetime # ΠΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌ Π²ΡΠ΅ ΠΊΠΎΠΌΠΌΠΈΡΡ Π½Π° ΡΠ΅ΠΊΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ current_timestamp = str(int(time.time())).encode("ascii") commit.author_date = current_timestamp + b" +0000" commit.committer_date = current_timestamp + b" +0000" 'ΠΡΠΈΠΌΠ΅Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ²:
git-filter-repo --commit-callback ' import re # Π£Π΄Π°Π»ΡΠ΅ΠΌ Π½ΠΎΠΌΠ΅ΡΠ° Π·Π°Π΄Π°Ρ ΠΈΠ· ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ message_str = commit.message.decode("utf-8") # Π£Π΄Π°Π»ΡΠ΅ΠΌ ΠΏΠ°ΡΡΠ΅ΡΠ½Ρ Π²ΠΈΠ΄Π° "#1234" ΠΈΠ»ΠΈ "TASK-5678" clean_message = re.sub(r"#\d+|TASK-\d+", "", message_str).strip() commit.message = clean_message.encode("utf-8") '
ΠΡΠΎΠ²Π΅ΡΠΊΠ° ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π½Π½ΡΡ Π²Π΅ΡΠΎΠΊ
ΠΠΎΡΠ»Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ git-filter-repo ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ, ΠΊΠ°ΠΊΠΈΠ΅ Π²Π΅ΡΠΊΠΈ Π±ΡΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΠΎΡΠΈΡΡΠΊΠΈ:
cat .git/filter-repo/changed-refsΠΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ Π²ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ (refs), ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Ρ, Π²ΠΊΠ»ΡΡΠ°Ρ:
- ΠΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ Π²Π΅ΡΠΊΠΈ (
refs/heads/). - Π£Π΄Π°Π»Π΅Π½Π½ΡΠ΅ Π²Π΅ΡΠΊΠΈ (
refs/remotes/). - Π’Π΅Π³ΠΈ (
refs/tags/). - ΠΠ°ΠΏΡΠΎΡΡ Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅ (
refs/pull/).
ΠΡΠ»ΠΈ ΡΠ°ΠΉΠ» .git/filter-repo/changed-refs Π½Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ, ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ
git-filter-repo Π½Π΅ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ» ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π° Π±ΡΠ»Π° Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π° Π±Π΅Π·
ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈΡΡΠΎΡΠΈΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ.
ΠΠ»Ρ ΠΏΠΎΠ΄ΡΡΠ΅ΡΠ° ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½ΡΡ Π²Π΅ΡΠΎΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅:
# ΠΠΎΠ΄ΡΡΠ΅Ρ Π²ΡΠ΅Ρ
ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½ΡΡ
ΡΡΡΠ»ΠΎΠΊ
wc -l .git/filter-repo/changed-refs
# ΠΠΎΠ΄ΡΡΠ΅Ρ ΡΠΎΠ»ΡΠΊΠΎ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ
Π²Π΅ΡΠΎΠΊ
grep -c '^refs/heads/' .git/filter-repo/changed-refs
# ΠΠΎΠ΄ΡΡΠ΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΄Π°Π»Π΅Π½Π½ΡΡ
Π²Π΅ΡΠΎΠΊ
grep -c '^refs/remotes/' .git/filter-repo/changed-refsΠΡΠΎΠ²Π΅ΡΠΊΠ° Π·Π°ΡΡΠΎΠ½ΡΡΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅
ΠΠΎΡΠ»Π΅ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠΈ ΠΈΡΡΠΎΡΠΈΠΈ git-filter-repo Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ·Π½Π°ΡΡ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»ΡΠ½ΠΎ Π·Π°ΡΡΠΎΠ½ΡΡΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ grep. ΠΡΠΎ Π²Π°ΠΆΠ½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ GitVerse ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ ΡΡΡΠ»Π°ΡΡΡΡ Π½Π° ΡΡΠ°ΡΡΠ΅, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅, ΠΊΠΎΠΌΠΌΠΈΡΡ.
grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refsΠΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π° Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΡΡΠΎΠΊ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½Ρ ^refs/pull/.*/head$, Π² ΡΠ°ΠΉΠ»Π΅ .git/filter-repo/changed-refs. ΠΠ°ΠΆΠ΄Π°Ρ ΡΠ°ΠΊΠ°Ρ ΡΡΡΠΎΠΊΠ° ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΠΎ, ΡΡΠΎ ΡΠ²ΡΠ·Π°Π½Π½ΡΠΉ Ρ Π½Π΅ΠΉ Π·Π°ΠΏΡΠΎΡ Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΡΡΠ»Π°ΡΡΡΡ Π½Π° ΡΡΠ°ΡΡΡ ΠΈΡΡΠΎΡΠΈΡ Π΄ΠΎ ΠΎΡΠΈΡΡΠΊΠΈ.
Π§ΡΠΎΠ±Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΡΠΏΠΈΡΠΎΠΊ Π·Π°ΡΡΠΎΠ½ΡΡΡΡ
Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅ Π²ΠΌΠ΅ΡΡΠΎ ΠΈΡ
ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π°, ΡΠ±Π΅ΡΠΈΡΠ΅ ΡΠ»Π°Π³ -c:
grep '^refs/pull/.*/head$' .git/filter-repo/changed-refsΠΡΠ»ΠΈ ΠΏΡΠΈ ΠΎΡΠΈΡΡΠΊΠ΅ Π½Π΅ Π±ΡΠ» ΡΠΎΠ·Π΄Π°Π½ ΡΠ°ΠΉΠ» .git/filter-repo/changed-refs, ΡΠΎ
ΠΊΠΎΠΌΠ°Π½Π΄Π° Π²Π΅ΡΠ½Π΅Ρ Π²Π΅ΡΠ½Π΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ grep: .git/filter-repo/changed-refs: No such file or directory.
ΠΠΎΡΠ»Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΡΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄ Π²Π°Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½ Ρ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΌ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠ΅ΠΌ, ΠΈ Π²ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ git-filter-repo Π±ΡΠ΄ΡΡ ΠΎΡΠΌΠ΅Π½Π΅Π½Ρ.
ΠΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ°Ρ ΠΎΡΠΈΡΡΠΊΠ° Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅
ΠΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π²Ρ ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΎΡΠΈΡΡΠΈΠ»ΠΈ ΠΈΡΡΠΎΡΠΈΡ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΈ ΡΡΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΠΈ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ Π²ΡΠ΅ ΡΠ»Π΅Π΄Ρ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ ΡΠ΄Π°Π»Π΅Π½Ρ Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅. ΠΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ Π²ΠΊΠ»ΡΡΠ°Π΅Ρ ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΈ, ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΡΠΎ ΡΠ»ΡΠΆΠ±ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ.
ΠΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»ΡΠ½Π°Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ
ΠΠΎΠΌΠ°Π½Π΄Π° ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠ°ΡΡ Π²ΡΡ ΠΈΡΡΠΎΡΠΈΡ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Π²Π°ΡΠ΅ΠΉ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ, ΡΠΆΠ΅ ΠΎΡΠΈΡΠ΅Π½Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ:
git push --force --mirror originΠ³Π΄Π΅:
-
--forceβ ΡΠ»Π°Π³ ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π΄Π»Ρ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠΈ ΠΈΡΡΠΎΡΠΈΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π° ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΡΠ΅ΡΠ²Π΅Ρ. -
--mirrorβ ΡΠ»Π°Π³ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ, ΡΡΠΎ ΠΎΡΠΏΡΠ°Π²ΡΡΡΡ Π²ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ (Π²Π΅ΡΠΊΠΈ, ΡΠ΅Π³ΠΈ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ ΡΡΡΠ»ΠΊΠΈ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊrefs/pull/) ΠΈΠ· Π²Π°ΡΠ΅Π³ΠΎ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Π² ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ. ΠΡΠΎ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΡΠΎΡΠ½ΠΎΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ Π²Π°ΡΠ΅ΠΉ ΠΎΡΠΈΡΠ΅Π½Π½ΠΎΠΉ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ, Π²ΠΊΠ»ΡΡΠ°Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΡΡΠ»ΠΎΠΊ Π½Π° ΡΡΠ°ΡΡΠ΅, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΊΠΎΠΌΠΌΠΈΡΡ; -
originβ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ, ΠΊΡΠ΄Π° Π²Ρ ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ. ΠΠ±ΡΡΠ½ΠΎ ΡΡΠΎ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
ΠΠ΅ΡΠ΅Π΄ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ ΡΡΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΠΎΠ³Π»Π°ΡΡΠΉΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ ΡΠΎ Π²ΡΠ΅ΠΌΠΈ
ΡΡΠ°ΡΡΠ½ΠΈΠΊΠ°ΠΌΠΈ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ. ΠΡΠ΅ ΡΠΎΠ°Π²ΡΠΎΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ΄Π°Π»ΠΈΡΡ ΡΠ²ΠΎΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΊΠ»ΠΎΠ½Ρ
ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΈ ΡΠΎΠ·Π΄Π°ΡΡ ΠΈΡ
Π·Π°Π½ΠΎΠ²ΠΎ, Π»ΠΈΠ±ΠΎ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΠΆΠ΅ΡΡΠΊΠΈΠΉ ΡΠ±ΡΠΎΡ (git reset --hard) ΠΈ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ²ΠΎΠΈ Π²Π΅ΡΠΊΠΈ Ρ Π½ΠΎΠ²ΠΎΠΉ ΠΈΡΡΠΎΡΠΈΠ΅ΠΉ.
ΠΡΠ»ΠΈ Ρ Π²Π°Ρ Π²ΠΊΠ»ΡΡΠ΅Π½Π° Π·Π°ΡΠΈΡΠ° Π²Π΅ΡΠΎΠΊ, ΡΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π°
git push --force --mirror ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΠΊΠ»ΠΎΠ½Π΅Π½Π°. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π²Π°ΠΌ ΠΏΡΠΈΠ΄Π΅ΡΡΡ
Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡΠΊΠ»ΡΡΠΈΡΡ Π·Π°ΡΠΈΡΡ Π²Π΅ΡΠΎΠΊ, Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, Π° Π·Π°ΡΠ΅ΠΌ ΡΠ½ΠΎΠ²Π°
Π²ΠΊΠ»ΡΡΠΈΡΡ Π·Π°ΡΠΈΡΡ.
ΠΡΠΈΠΌΠ΅Ρ ΠΎΡΠΈΡΡΠΊΠΈ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΎΡ ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ
ΠΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ
- Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅
git-filter-repo, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ:
sudo apt update
sudo apt install git-filter-repo-
Π‘ΠΎΡ ΡΠ°Π½ΠΈΡΠ΅ Π²ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ. ΠΡΠ»ΠΈ Π΅ΡΡΡ Π½Π΅ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Π½ΡΠ΅ (unstaged) ΠΈΠ»ΠΈ Π½Π΅Π·Π°ΠΊΠΎΠΌΠΈΡΠ΅Π½Π½ΡΠ΅ (uncommitted) ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ, ΠΊΠΎΠΌΠ°Π½Π΄Π°
git-filter-repoΠ½Π΅ ΡΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ. -
Π‘Π΄Π΅Π»Π°ΠΉΡΠ΅ ΡΠ΅Π·Π΅ΡΠ²Π½ΡΡ ΠΊΠΎΠΏΠΈΡ Π²Π°ΡΠ΅Π³ΠΎ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ. ΠΡΠΎ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈ Π²Π°ΠΆΠ½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ
git-filter-repoΠ½Π΅ΠΎΠ±ΡΠ°ΡΠΈΠΌΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅Ρ ΠΈΡΡΠΎΡΠΈΡ.
ΠΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠ° ΠΊΠΎΠ½ΡΠΈΠ΄Π΅Π½ΡΠΈΠ°Π»ΡΠ½ΡΡ Π΄Π°Π½Π½ΡΡ
ΠΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Π²Ρ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎ Π·Π°ΠΊΠΎΠΌΠΌΠΈΡΠΈΠ»ΠΈ API-ΠΊΠ»ΡΡ MY_SECRET_API_KEY_123 Π² ΡΠ°ΠΉΠ» config.js ΠΈ ΡΠ°ΠΊΠΆΠ΅ ΡΠΏΠΎΠΌΡΠ½ΡΠ»ΠΈ Π΅Π³ΠΎ Π² ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΈ ΠΊΠΎΠΌΠΌΠΈΡΠ°.
Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ°ΠΉΠ» Π΄Π»Ρ Π·Π°ΠΌΠ΅Π½Ρ/ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΡΠ΅ΠΊΡΡΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, sensitive_data_to_clean.txt:
MY_SECRET_API_KEY_123==>***API_KEY_REMOVED***ΠΡΠ»ΠΈ Π²Ρ Ρ ΠΎΡΠΈΡΠ΅ ΠΏΡΠΎΡΡΠΎ ΡΠ΄Π°Π»ΠΈΡΡ, ΡΠΎ:
MY_SECRET_API_KEY_123ΠΡΠΈΡΡΠΊΠ° ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ
ΠΡΠΏΠΎΠ»Π½ΠΈΡΠ΅ git-filter-repo Π΄Π»Ρ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ API-ΠΊΠ»ΡΡΠ° ΠΈΠ· ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ²:
git-filter-repo --replace-text path/to/sensitive_data_to_clean.txtΠΡΠ»ΠΈ Π±Ρ API-ΠΊΠ»ΡΡ Π±ΡΠ» Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅, ΠΊΠΎΡΠΎΡΡΠΉ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠ΄Π°Π»ΠΈΡΡ:
git-filter-repo --invert-paths --path path/to/your/config.jsΠΡΠ»ΠΈ Π±Ρ Π²Ρ Ρ ΠΎΡΠ΅Π»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΄Π°Π»ΠΈΡΡ ΠΊΠ»ΡΡ ΠΈΠ· ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ²:
git-filter-repo --message-callback '
import re
secret_key = r"MY_SECRET_API_KEY_123"
replacement = b"***KEY_REMOVED_FROM_FROM_MESSAGE***"
decoded_message = message.decode("utf-8")
new_message = re.sub(secret_key, replacement.decode("utf-8"), decoded_message)
return new_message.encode("utf-8")
'ΠΡΠΎΠ²Π΅ΡΠΊΠ° Π·Π°ΡΡΠΎΠ½ΡΡΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅
ΠΡΠΎΠ²Π΅ΡΡΡΠ΅, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π·Π°ΠΏΡΠΎΡΠΎΠ² Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅ ΡΡΡΠ»Π°ΡΡΡΡ Π½Π° ΡΡΠ°ΡΡΠ΅ ΠΊΠΎΠΌΠΌΠΈΡΡ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠ΅ API-ΠΊΠ»ΡΡ:
grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refsΠΡΠ»ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π±ΠΎΠ»ΡΡΠ΅ Π½ΡΠ»Ρ, Π²Π°ΠΌ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠ²ΡΠ·Π°ΡΡΡΡ ΡΠΎ ΡΠ»ΡΠΆΠ±ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ GitVerse.
ΠΡΠΈΠ½ΡΠ΄ΠΈΡΠ΅Π»ΡΠ½Π°Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠ° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² ΡΠ΄Π°Π»Π΅Π½Π½ΡΠΉ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΉ
git push --force --mirror originΠΠ΅ΡΠ΅Π΄ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ ΡΠ±Π΅Π΄ΠΈΡΠ΅ΡΡ, ΡΡΠΎ Π²ΡΠ΅ ΠΊΠΎΠ»Π»Π΅Π³ΠΈ ΠΎΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½Ρ, ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡΠΊΠ»ΡΡΠΈΡΠ΅ Π·Π°ΡΠΈΡΡ Π²Π΅ΡΠΎΠΊ, Π΅ΡΠ»ΠΈ ΠΎΠ½Π° Π΅ΡΡΡ.
Π‘Π²ΡΠ·Ρ ΡΠΎ ΡΠ»ΡΠΆΠ±ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ GitVerse (ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ)
ΠΡΠ»ΠΈ Π·Π°ΠΏΡΠΎΡΡ Π½Π° ΡΠ»ΠΈΡΠ½ΠΈΠ΅ Π±ΡΠ»ΠΈ Π·Π°ΡΡΠΎΠ½ΡΡΡ (ΡΠ°Π³ 4), ΡΠ²ΡΠΆΠΈΡΠ΅ΡΡ ΡΠΎ ΡΠ»ΡΠΆΠ±ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ GitVerse ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΡΡΠ΅ ΠΈΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ ΠΌΠΎΠ³Π»ΠΈ ΠΎΡΠΈΡΡΠΈΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ½ΡΠ΅ ΠΊΡΡΠΈ ΠΈ ΡΡΡΠ»ΠΊΠΈ.