Сквозь полную историю перед определенным тегом - PullRequest
2 голосов
/ 31 мая 2011

Следующий сценарий: у меня есть репозиторий с большой историей (перенесенный из SVN, который использовался с 2006 года), и я хочу перенести более новую историю на внешний сервер.

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

Я пытался сделать это, как в принятом ответе Перебазировать много коммитов в один в Git. Что я делаю не так? , но это приводит к бесконечному разрешению конфликтов.

Я просто хочу выбросить историю при возможности слияния моего локального репо (который все еще содержит большую историю) с удаленным репо (с короткой историей).

Как мне этого добиться?

Ответы [ 2 ]

3 голосов
/ 31 мая 2011

Обновление: обратите внимание, что ниже я предполагаю, что mytag имеет только один родительский коммит, в противном случае это немного сложнее.

Во-первых, давайте предположим, что вы толькоесть один корневой коммит и что он f414f31.(Если вам нужно найти все корневые коммиты, вы можете сделать это с помощью первой команды в этом ответе .)

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

git checkout -b new-master

Сбросьте эту ветку в корневой коммит:

git reset --hard f414f31

Теперьизмените рабочее дерево и индекс так, чтобы он совпадал с коммитом непосредственно перед mytag:

git merge --squash mytag^

Затем создайте коммит из индекса - если вы хотите переписать корневой коммит, вы можете сделать этос git commit --amend, но я бы предпочел сохранить один коммит между вашей старой и новой историями, поэтому я бы просто сделал:

git commit

Теперь вам нужно воспроизвести всю вашу работупоскольку (и в том числе) mytag поверх этого коммита.Для этого и предназначен git rebase, но по умолчанию он линеаризует всю историю, которую вы пытаетесь воспроизвести.Если у вас много коммитов слияний в истории с mytag, это может быть причиной того, что вы видите много конфликтов.

Итак, если вы не возражаете против линеаризации истории, и вы можете исправить конфликты (возможно, с помощью git rerere) вы могли бы просто сделать:

git rebase --onto new-master mytag^ master

Однако, если в этой истории есть слияния, и вы бы предпочли сохранить их, вы можете попробовать добавить -p (--preserve-merges) опция, которая попытается воссоздать их:

git rebase -p --onto new-master mytag^ master

В комментариях ниже вы задаете дополнительный вопрос о случае, когда у вас есть две корневые фиксации.В этом случае вы можете просто выбрать один из них и использовать git commit --amend после сдавленного слияния, чтобы создать совершенно новый корневой коммит для переписанной истории.

2 голосов
/ 31 мая 2011

Если вы хотите переписать / удалить историю, то вы ищете git filter-branch . Вот хороший поток , в котором обсуждается, как удалять коммиты. Переменная $ drop будет коммитом перед вашим тегом.

...