LINUX.ORG.RU

Почему в Git получается удалить из истории только один файл?

 , ,


0

1

Нужно мне в локальном репозитарии удалить из Git несколько pyc-файлов.

Я даю такие команды:

$ git filter-branch --tree-filter 'rm -f configScript/mt2/lib/__pycache__/libCommand.cpython-35.pyc' HEAD
Rewrite 72e4719f86a600568a1a387a632a18fbdc1c6c03 (5/5) (1 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten

$ git filter-branch --tree-filter 'rm -f configScript/mt2/lib/__pycache__/libConfig.cpython-35.pyc' HEAD
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

Видно, что первая команда сработала нормально. А вторая точно такая же команда для другого файла - нет, хотя имя удаляемого файла правильное.

Что нужно сделать, чтобы и вторая команда правильно выполнилась? Видимо, надо перезаписать какой-то бекап, но что и как - неясно.

★★★★★

Последнее исправление: Xintrea (всего исправлений: 1)

Ответ на: комментарий от i-rinat

-f

В какой-то момент я перестал понимать людей. Ключ -f - это ключ какой команды?

Я пробовал так:

git filter-branch --tree-filter -f 'rm -f configScript/mt2/lib/__pycache__/libConfig.cpython-35.pyc'
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

Xintrea ★★★★★
() автор топика
Последнее исправление: Xintrea (всего исправлений: 1)

git - это дерьмище. там при каждом коммите добавленный файл сжимается с помощью zlib, а точнее zlib.compress(’blob ’ + размер + текущее содержимое файла) и сохраняется как .git/objects/{sha1_hex[0:2]}/{sha1_hex[2:38]}, а изменения с текущей версией сохраняюися в .git/packs/pack-<hash>.pack и .git/packs/pack-<hash>.pack, естественно имя файла добавляется в .git/index, его хеш светится .git/refs/heads/master и тп… и сам текст коммита как объект хранится. в общем он хорошенько трахает диск, оверхед довольно большой…

а по самому вопросу:

git rm --cached <file> # удаляет файл из ИНДЕКСА
git gc # удаляет из репозитория мусор (git_dir/objects), ну должен
tz4678_2
()
Последнее исправление: tz4678_2 (всего исправлений: 3)
Ответ на: комментарий от Xintrea

на меня ковид конечно подействовал, но читать хелп по ключам я не разучился

GIT-FILTER-BRANCH(1)                      Git Manual                     GIT-FILTER-BRANCH(1)

NAME
       git-filter-branch - Rewrite branches

SYNOPSIS
       git filter-branch [--setup <command>] [--subdirectory-filter <directory>]
               [--env-filter <command>] [--tree-filter <command>]
               [--index-filter <command>] [--parent-filter <command>]
               [--msg-filter <command>] [--commit-filter <command>]
               [--tag-name-filter <command>] [--prune-empty]
               [--original <namespace>] [-d <directory>] [-f | --force]
               [--state-branch <branch>] [--] [<rev-list options>...]
На мой взгляд тут все однозначно:

git filter-branch -f --tree-filter 'rm -f configScript/mt2/lib/__pycache__/libConfig.cpython-35.pyc'

или

git filter-branch --tree-filter 'rm -f configScript/mt2/lib/__pycache__/libConfig.cpython-35.pyc' -f

vel ★★★★★
()

Блин, долбаный google, похоже что в какой-то момент они стали понижать количество выдачи релевантных ответов в поиске. Какую-то белиберду подсовывают. Не первый раз такое замечаю, предыдущий раз был в 2014 году кстати. То ли по территориальному признаку это делают, то ли по языковому. Как говорится, в сложные моменты истории пользуйтесь блин отечественным, у Яндекса все в порядке.

В общем, решение следующее.


Из первой команды, которая завершилась удачно, нужно выделить путь:

Ref 'refs/heads/master' was rewritten
То есть, получаем refs/heads/master.


Из второй команды нужно выделить путь, на который git ругается что он существует:
A previous backup already exists in refs/original/
То есть, получаем refs/original.


Соединяем второе с первым: refs/original/refs/heads/master, этот путь понадобится дальше.


Далее надо выполнить команду обновления «Update the object name stored in a ref safely» с полученнымна предыдущем шаге путем:
git update-ref -d refs/original/refs/heads/master

Все, после этого новая команда git filter-branch ... выполнится без ошибок. Но выполнится только одна, после нее опять надо вызывать команду git update-ref ... и так далее.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

В какой-то момент я перестал понимать людей.

Это печально. Возможно, ты сильно устал, и нужно как следует выспаться.

Ключ -f - это ключ какой команды?

Это ключ для git filter-branch

пробовал так git filter-branch --tree-filter -f 'rm -f configScript/mt2/lib/__pycache__/libConfig.cpython-35.pyc'

Ключ «–tree-filter» требует значение. Значение представляет собой команду, которая будет выполняться. Раньше у тебя была команда «rm -f …», а теперь ты указал команду «-f». Вряд ли это даст нужный эффект. Для нужного эффекта ключ «-f» стоило указать там, где он опознался бы как именно ключ. Например, до --tree-filter. Или после значения для ключа --tree-filter, то есть после команды «rm …»

i-rinat ★★★★★
()
Ответ на: комментарий от Xintrea

Как говорится, в сложные моменты истории пользуйтесь блин …

… инструкцией.

Серьёзно. У git-filter-branch не такая уж и большая инструкция, в которой довольно подробно описано поведение утилиты.

i-rinat ★★★★★
()
pinkbyte@oas1 ~/dev/test $ git init
pinkbyte@oas1 ~/dev/test $ git add 1
pinkbyte@oas1 ~/dev/test $ git commit -m 'initial commit'
[master (корневой коммит) c3fe5ee] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 1
pinkbyte@oas1 ~/dev/test $ touch 2.err
pinkbyte@oas1 ~/dev/test $ git add 2.err 
pinkbyte@oas1 ~/dev/test $ git commit -m '2.err added'
[master c0bbce8] 2.err added
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 2.err
pinkbyte@oas1 ~/dev/test $ touch 3.err
pinkbyte@oas1 ~/dev/test $ git add 3.err 
pinkbyte@oas1 ~/dev/test $ git commit -m '3.err added'
[master 3edb0fd] 3.err added
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 3.err

Допустим 2.err и 3.err нам не нужны, не вопрос:

pinkbyte@oas1 ~/dev/test $ git filter-branch -f --tree-filter 'rm -f 2.err 3.err' --prune-empty HEAD
pinkbyte@oas1 ~/dev/test $ ls -la
итого 0
drwxr-xr-x 1 pinkbyte users  10 июл  6 16:20 .
drwxr-xr-x 1 pinkbyte users 548 июл  6 16:15 ..
-rw-r--r-- 1 pinkbyte users   0 июл  6 16:15 1
drwxr-xr-x 1 pinkbyte users 128 июл  6 16:20 .git
pinkbyte@oas1 ~/dev/test $ git log
commit c3fe5eeb1cac04039fe0b9a39294245eb622c6a6 (HEAD -> master)
Author: Sergey Popov <admin@pinkbyte.ru>
Date:   Wed Jul 6 16:15:46 2022 +0300

    initial commit

Удалились и файлы и пустые коммиты из истории.

Поздновато я правда спохватился(тред-то уже решенный судя по всему), ну да ладно.

Pinkbyte ★★★★★
()