Удалить коммит на удаленных файлах - PullRequest
0 голосов
/ 26 сентября 2018

Я очистил свой репозиторий, используя git filter-branch, чтобы удалить некоторые папки, используя следующую команду:

git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch folder' \ 
    --prune-empty --tag-name-filter cat -- --all

После этого у меня все еще есть некоторые коммиты, которые относятся только к теперь удаленным файлам.Есть ли способ убрать это, то есть удалить коммиты для файлов, которых больше нет в истории?

Ответы [ 2 ]

0 голосов
/ 19 июня 2019

Я нашел ответ в шаге 6 на этой странице: https://github.com/epics-modules/motor/wiki/Creating-a-standalone-driver-module

git filter-branch --prune-empty --parent-filter 'sed "s/-p //g" | xargs -r git show-branch --independent | sed "s/\</-p /g"'
0 голосов
/ 26 сентября 2018

TL; DR

Если они действительно есть, вы можете просто запустить вторую бездействующую ветвь фильтра с --prune-empty, чтобы отбросить их.

Long, с экспериментом

После этого у меня все еще есть некоторые коммиты, которые имеют отношение только к теперь удаленным файлам.

Это должно быть редко, потому что вы включили:

--prune-empty

, который предписывает filter-branch пропустить любой простой (не объединяющий) коммит, соответствующий его родителю.

Возможно, у вас есть некоторые слияния, которые объединяют две ветви, которые в остальном идентичныв их входных точках, но эти коммиты не могут быть удалены, потому что они объединяют ветви, которые в остальном идентичны.

Предположим, например, что у нас есть следующая структура ветвей до фильтрации:

          B--C
         /    \
...--o--A      M--o--...
         \    /
          D--E

Commit M является слиянием и должен быть сохранен (так оно и есть), но предположим, что A -vs- B сворачивается, потому что после фильтрации B соответствует A и C -vs-B (или vs- A) также разрушается в течениеПо той же причине:

...--o--A'-----M'-o--...
         \    /
          D'-E'

(отметки или простые символы после букв указывают на то, что это копии оригинальных коммитов - возможно A' - A, если ничего не изменилось ранее, но это охватывает более общий случай).Здесь M действительно все еще требуется для поддержания логической структуры, даже если бы было возможно выполнить ускоренную перемотку вперед, если бы коммиты были сделаны без изначально удаленных файлов.

Более интересный случайкогда D и E сами исчезают, потому что теперь M все еще существует в качестве входных данных для процесса ответвления фильтра, и у него все еще есть два родителя, но оба родителя отображают для принятия A' самого себя .Я не уверен, не глядя, что здесь происходит: может ли filter-branch сделать коммит слияния с A', указанным дважды как два родителя для M'?Если это попытается сделать это, git commit-tree записывает коммит M' как обычный коммит без слияния?Тестирование говорит «нет»:

$ mkdir mtest
$ cd mtest
$ git init
Initialized empty Git repository in ...
$ echo test commit-tree > README
$ git add README
$ git commit -m initial
[master (root-commit) 1db1f76] initial
 1 file changed, 1 insertion(+)
 create mode 100644 README
$ echo log msg | git commit-tree -p HEAD -p HEAD HEAD^{tree}
error: duplicate parent 1db1f76a4e7217d5198c0f178464b7a087e94078 ignored
44f91061b7bd08c39a4dc9e8ebb1f4f7c588ea9e

Таким образом, получается, что наивный filter-branch попытается сделать M' и сделает это как однопользовательский коммит:

...--o--A'-M'-o--...

гдеM' и A' не имеют различий.Код ветки фильтра имеет проверку для этого:

    for parent in $parents; do
            for reparent in $(map "$parent"); do
                    case "$parentstr " in
                    *" -p $reparent "*)
                            ;;
                    *)
                            parentstr="$parentstr -p $reparent"
                            ;;
                    esac
            done
    done

(Если вы предоставите свой собственный родительский фильтр, это произойдет после проверки, и вам потребуется ваша собственная повторная проверка.)

Так что, если вы получаете такой результат ...--A'-M'-..., вторая ветвь фильтра с --prune-empty отбросит их.

...