Подтвердить что ты не робот

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

У меня очень большой репозиторий Git, который содержит только двоичные файлы, которые довольно часто меняются. Естественно, репозиторий Git значительно больше, чем фактические файлы в нем. Мне не очень-то нравится старая история, мне нужна только часть новой истории, чтобы вернуться к неправильным изменениям. Поэтому позвольте сказать, что я хочу удалить все коммиты, за исключением последних пяти.

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

И я хочу сделать все это неинтерактивно с помощью одной команды (псевдоним) или script. Как я могу это сделать?

4b9b3361

Ответ 1

Здесь существует псевдоним rebase-last-five, чтобы вы начали. Он воссоздает текущую ветвь, так что в истории будут только самые последние пять коммитов. Вероятно, лучше всего сделать это script (git-rebase-last-five.sh), который доступен в каталоге на вашем PATH; Git найдет и использует сценарии с именем git-....sh без необходимости в какой-либо специальной конфигурации. script должен выполнять дополнительную проверку и обработку ошибок, чем этот простой псевдоним.

$ git config --global alias.rebase-last-five '!b="$(git branch --no-color | cut -c3-)" ; h="$(git rev-parse $b)" ; echo "Current branch: $b $h" ; c="$(git rev-parse $b~4)" ; echo "Recreating $b branch with initial commit $c ..." ; git checkout --orphan new-start $c ; git commit -C $c ; git rebase --onto new-start $c $b ; git branch -d new-start ; git gc'

CAVEAT EMPTOR: обратите внимание на предупреждения об изменении истории.

Для получения дополнительной информации просмотрите страницы man (git help <command>или онлайн).

Пример использования:

$ git --version
git version 1.7.12.rc2.16.g034161a
$ git log --all --graph --decorate --oneline
* e4b2337 (HEAD, master) 9
* e508980 8
* 01927dd 7
* 75c0fdb 6
* 20edb42 5
* 1260648 4
* b3d6cc8 3
* 187a0ef 2
* e5d09cf 1
* 07bf1e2 initial
$ git rebase-last-five 
Current branch: master e4b2337ef33d446bbb48cbc86b44afc964ba0712
Recreating master branch with initial commit 20edb42a06ae987463016e7f2c08e9df10fd94a0 ...
Switched to a new branch 'new-start'
[new-start (root-commit) 06ed4d5] 5
 1 file changed, 1 insertion(+)
 create mode 100644 A
First, rewinding head to replay your work on top of it...
Applying: 6
Applying: 7
Applying: 8
Applying: 9
Deleted branch new-start (was 06ed4d5).
Counting objects: 35, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (35/35), done.
Total 35 (delta 4), reused 0 (delta 0)
$ git log --all --graph --decorate --oneline
* a7fb54b (HEAD, master) 9
* 413e5b0 8
* 638a1ae 7
* 9949c28 6
* 06ed4d5 5

Ответ 2

Хорошо, если вы хотите, что я думаю, вы хотите (см. мой комментарий), я думаю, что это должно работать:

  • Создайте ветку, чтобы сохранить все коммиты (и на всякий случай):

    git branch fullhistory

  • В то время как все еще на главном, reset - удержите фиксацию, которую вы хотите сохранить из истории:

    git reset --hard HEAD~5

  • Теперь reset без --hard до начала истории, это должно оставить ваше рабочее пространство нетронутым, поэтому оно остается в состоянии HEAD ~ 5.

    git reset --soft <first_commit>

  • Итак, теперь у вас есть пустая история на master и все изменения, которые вам нужны в рабочей области. Просто скопируйте их.

    git commit -m "all the old changes squashed"

  • Теперь вишня-выберите это 4 коммиты из fullhistory, которые вы хотите иметь здесь:

    git cherry-pick A..B

Где A старше B и помните, что A НЕ включено. Поэтому он должен быть родителем самого старого коммита, который вы хотите включить.