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:)

Author: tbolender, 2011-08-25

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.

 43
Author: Karl Bielefeldt,
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
 6
Author: Ted Yavuzkurt,
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

 1
Author: manojlds,
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
 0
Author: Jacob Kern,
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