git: zmiana jednej linii w pliku dla pełnej historii
Kiedy uruchomiłem mój Git repo, dodałem do niego kilka plików jako początkowy commit. Teraz, wiele commitów później, zauważyłem, że umieściłem w tych plikach linię z informacjami, których nie chcę publikować (w przeciwieństwie do reszty kodu). Dlatego chcę usunąć / zmienić ten jeden wiersz i zachować resztę kodu.
Szukając wokół znalazłem takie rozwiązanie: wstawić pusty commit jako początkowy commit (opisany tutaj: wstawić commit przed głównym commitem w Git?), do rebase na nim, a następnie edytować stary pierwszy commit poprzez amend. Niestety, wiele okrutnych konfliktów merge powstaje podczas rebase (jak opisano tutaj: git: rozwiązywanie konfliktów wywołanych przez rebase ).
Czy jest inny sposób na rozwiązanie mojego problemu, czy trzeba ręcznie zmieniać i edytować wszystkie konflikty?
Z góry dzięki:)
4 answers
Oto polecenie, które usunie obrażony wiersz z historii Pliku we wszystkich gałęziach:
git filter-branch --tree-filter 'sed -i "/sensitive information/ d" filename' -- --all
Sprawdza każdą rewizję, uruchamia na niej polecenie sed
, a następnie zatwierdza tę rewizję z powrotem.
Polecenie sed
w tym przypadku pasuje do linii zawierających wzorzec sensitive information
w pliku o nazwie filename
i usuwa te linie.
Uwaga: dobrze jest, jeśli masz kopię zapasową i najpierw wypróbuj skrypt sed
na własną rękę, aby upewnić się, że robi to, co chcesz, ponieważ może zająć sporo czasu, aby uruchomić na długiej historii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-25 22:39:45
Wykonałem polecenie, które nie wyświetla się, gdy plik nie istnieje:
filename=./path/to/your/filename
filter=your_regex_here
git filter-branch --tree-filter 'test -f $filename && sed -i.bak "/$filter/d" $filename || echo “skipping file“' -- --all
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 22:06:11
Możesz rzucić okiem na git filter-branch
Przykłady w linku powinny cię zachęcić: http://git-scm.com/docs/git-filter-branch
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-25 18:14:03
Moja odpowiedź łączy w sobie to, co najlepsze. Zastępuje on tylko podany łańcuch filtrów zamiast całej linii i ładnie pomija, jeśli plik nie zostanie znaleziony w zatwierdzeniu. Istnieje wiele uciekających cytatów, ale druga odpowiedź miała naprawdę dziwne cytaty, które nie działały dla mnie.
git filter-branch --tree-filter "test -f \"$filename\" && sed -i \"s/$filter//g\" \"$filename\" || echo \"skipping $filename\"" -- --all
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-03 15:38:49