git rebase. Как я могу использовать его, чтобы свернуть пачки древних комитетов - PullRequest
5 голосов
/ 25 июля 2010

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

Я - и всегда буду - единственным пользователем этого частного репо.

В идеале я мог бы сделать что-то вроде:

git rebase с момента рождения репо до месяца назад

Спасибо
Дуг

Ответы [ 3 ]

7 голосов
/ 28 июля 2010

Опция --squash для git merge может быть полезна и доступна в git 1.4.1 и новее.Это ставит эффекты слияния, но не создает коммит.Таким образом, если 143eff является самым старым коммитом, который вы хотите включить в сдавленный коммит, текущая ветвь будет master, а коммит "один месяц назад" - dcb7e5, вы можете сделать:

# Save the old position of "master" by creating a branch old-master:
$ git checkout master
$ git branch old-master

# Create and checkout a branch called "new-master" that's at the old commit:
$ git checkout -b new-master 143eff

# Stage the effects of merging the "one month ago" commit:
$ git merge --squash dcb7e5
Updating 143eff3..dcb7e5b
Fast-forward
Squash commit -- not updating HEAD
[... status output showing the staged changes ..]

# Create the squashed commit:
$ git commit -m "A commit squashing history up to a month ago"
# (You could use --amend if you want them to be squashed into 143eff
# instead of being a commit after that.)

Теперь вы можете проверить с помощью git diff dcb7e5 new-master, что они действительно одинаковы.

Далее, вы хотите перенести остальную часть вашей работы на нового мастера:

$ git rebase --onto new-master dcb7e5 master

Это будетоставьте вас на перебазированном master, в котором должна быть нужная вам история.(Опять же, вы можете проверить это с помощью git diff old-master master и git log. При перемещении мастера на github вам нужно будет добавить --force, так как вы переписали историю:

# Push master to github, with "--force", since you've rewritten history:
$ git push --force origin master

Теперь вы можете удалить new-master, который находится в коммите сквоша, с:

git branch -d new-master

Очевидно, github запускает git gc --auto на толчках, так что вы скоро увидите немного экономии места ...

2 голосов
/ 28 июля 2010

На самом деле, я пойду со скучным старым git rebase -i HEAD ~ Number, где Number отведет меня от головы к начальному коммиту. Больше времени, но по крайней мере у меня есть смутное понимание того, что он делает. Спасибо за все предложения.

1 голос
/ 27 июля 2010

Вот рецепт, который будет работать в Git 1.7.2 или новее:

start=$starting_sha1
git checkout --orphan new_master $start
git commit -m 'new root'
git rebase --onto new_master $start master
git checkout master
git reset --hard new_master
git push -f origin master

Очистка старых объектов, на которые вы больше не ссылаетесь, - это больше работы, так как на них могут указывать reflogs, stash, теги, другие ветви и т. д. Если вы уверены, что они исправлены или удалены, должно помочь одно или несколько из следующих действий:

git prune
git gc
git repack -ad
...