2016-12-18 27 views
0

Скажите, что вы клонировали репозиторий, а затем создали новую ветвь и сделали несколько коммитов на этой ветке (без создания новых ветвей или нажатия на любые пульты). В некоторых из этих коммитов вы внесли (зафиксировали) файл fileA с ошибкой. Теперь, как вы можете удалить этот файл из истории, но не из локальной файловой системы (т. Е. Сохранить файл как не проверенный)? Также предположим, что имя родительской ветви неизвестно (чтобы полностью автоматизировать процесс).Удалить файл из всех коммитов до первой точки ветвления, но не удалять из локальной файловой системы

ответ

0

Мы здесь используем git filter-branch, чтобы удалить файл из индекса. Важно, чтобы мы использовали только git filter-branch для фиксации до первой точки ветвления; если нет, мы не сможем связать ветвь с исходным родителем, и мы также можем случайно удалить файл с тем же именем в родительском ветви.

Сложность возникает, если предположить, что имя родительской ветви неизвестно. Однако это можно решить, используя git branch --contains:

filename=fileA 
# git filter-branch will delete the local copy also, see 
# http://stackoverflow.com/q/33333200/2173773. So take a backup first. 
cp "$filename" "$filename".bak 
readarray -t revlist < <(git rev-list HEAD) 
sha1="" 
for sha in "${revlist[@]}" ; do 
    readarray -t branches < <(git branch --contains "$sha") 
    # if there are more than a single branch that contains this commit 
    # we have reached the branch point 
    if ((${#branches[@]} > 1)) ; then 
     sha1="$sha" 
     break 
    fi 
done 

git filter-branch -f --index-filter \ 
    "git rm --cached --ignore-unmatch $filename" "$sha1"..HEAD 

# restore backup file 
mv "$filename".bak "$filename"