Как удалить файл из истории git при сохранении (разрешенных вручную) слияний? - PullRequest
0 голосов
/ 04 августа 2020

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

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

Репо, которое иллюстрирует проблему, может быть построено следующим образом:

# intitial setup
mkdir rebase-across-manually-resolved-merge-conflicts
cd rebase-across-manually-resolved-merge-conflicts/
git init

# root commit, w/ garbage
echo "foo" > foo.txt
echo "unrelated-garbage" > unrelated-garbage.txt
git add foo.txt unrelated-garbage.txt 
git commit -m "initial checkin with undesirable content"

# branch a
git checkout -b branch-a
echo bar > foo.txt
git add foo.txt 
git commit -m "foo must be bar"

# branch b
git checkout master
git checkout -b branch-b
echo baz > foo.txt 
git add foo.txt 
git commit -m "foo must be baz"

# merging both branches into master; manual resolution of conflicts
git checkout master
git merge branch-a
git merge branch-b
echo barz > foo.txt
git add foo.txt 
git commit  -m "Merge branch 'branch-b' (manual resolution of merge conflicts)"

Результат будет выглядеть примерно так:

*   4b874d0 (HEAD -> master) Merge branch 'branch-b' (manual resolution of merge conflicts)
|\  
| * 16e2bc4 (branch-b) foo must be baz
* | fa7418a (branch-a) foo must be bar
|/  
* ff8aa1b initial checkin with undesirable content
git rebase -r -i --root  # in the editor, change "pick" to "edit" for the line "initial checkin w..."
git rm unrelated-garbage.txt 
git commit --amend -m "initial checkin with no undesirable content"
git rebase --continue

Это не так:

# Auto-merging foo.txt
# CONFLICT (content): Merge conflict in foo.txt
# Could not apply 819e457... branch-b # Merge branch 'branch-b' (manual resolution of merge conflicts)

Попытка с git rebase -p -i --root (с использованием устаревшей опции -p) также неудачна.

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

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Попробуйте

git filter-branch --tree-filter 'rm -f unrelated-garbage.txt' HEAD

, как описано на https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History. Обратите внимание на предупреждение «Осторожно» в этом разделе. Вы можете сначала сделать резервную копию.

0 голосов
/ 04 августа 2020

Нашел ... без перебазирования работает

git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch unrelated-garbage.txt" \
  --prune-empty --tag-name-filter cat -- --all
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...