Git: изменить одну строку в файле для полной истории - PullRequest
36 голосов
/ 25 августа 2011

Когда я запустил репозиторий git, я отправил несколько файлов в качестве первоначального коммита.Теперь, много коммитов позже, я заметил, что я включил в эти файлы строку с информацией, которую я не хочу публиковать (в отличие от остальной части кода).Поэтому я хочу удалить / изменить эту одну строку и оставить остальные кода.

Поиск вокруг, я нашел это решение: Вставить пустой коммит как начальный коммит(описано здесь: Вставить коммит перед корневым коммитом в Git? ), сделать на нем ребаз, а затем отредактировать старый первый коммит с помощью исправления.К сожалению, многие жестокие конфликты слияний возникают во время перебазирования (как описано здесь: git: разрешение конфликтов, вызванных перебазировкой ).

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

Заранее спасибо :))

Ответы [ 4 ]

47 голосов
/ 26 августа 2011

Вот команда, которая удалит поврежденную строку из истории файла во всех ваших ветках:

git filter-branch --tree-filter 'sed -i "/sensitive information/ d" filename' -- --all

Это проверяет каждую ревизию, запускает для нее команду sed, а затем фиксирует эту ревизию обратно.

Команда sed в этом случае сопоставляет любые строки, содержащие шаблон sensitive information в файле с именем filename, и удаляет эти строки.

Примечание: хорошо, если у вас есть резервная копия, и сначала попробуйте самостоятельно выполнить сценарий sed, чтобы убедиться, что он выполняет то, что вам нужно, потому что для запуска длинной истории может потребоваться довольно много времени.

8 голосов
/ 01 июля 2016

Я сделал эту команду, которая не выдает ошибку, когда файл не существует:

 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
1 голос
/ 25 августа 2011

Вы можете взглянуть на git filter-branch

Примеры, приведенные в ссылке, должны помочь вам: http://git -scm.com / docs / git-filter-branch

0 голосов
/ 03 мая 2018

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

 git filter-branch --tree-filter "test -f \"$filename\" && sed -i \"s/$filter//g\" \"$filename\" || echo \"skipping $filename\"" -- --all
...