Как повторно применить коммиты поверх несвязанной ветки?

У меня есть простой репозиторий с линейной историей коммитов, например:

[A] -> [B] -> [C] -> [D] -> [E] ...

Мне нужно удалить коммиты A и B, поэтому я решил создать новый репозиторий и хотел бы достичь чего-то вроде:

[X] -> [C] -> [D] -> [E] ...

Поэтому я создал новый репозиторий, создал вручную коммит X, в котором хранятся соответствующие данные из A и B, и теперь мне нужна команда, которая доставит коммиты C, D, E и т. Д. Из исходного репозитория и поместит его поверх моего нового совершить X.

Как это сделать?

Редактировать: У меня есть две проблемы с предложенным методом выбора вишни:

Переданные коммиты потеряли свои даты. Есть ли способ сохранить даты коммитов?Когда я выбрал мастер из исходного репозитория (а этот удаленный мастер не имеет ничего общего с новым репозиторием), у меня возникают проблемы при удалении этих извлеченных коммитов. Когда я делаюgit branch -D myoriginalrepo/master, это говорит о том, что такой ветки не существует, в то время как я ясно вижу эти коммиты в своем инструменте с графическим интерфейсом.
 John Zwinck01 февр. 2012 г., 03:22
Я думаю, тебе стоит взглянуть на мерзавца.
 thinsoldier20 июн. 2014 г., 19:40
Вы когда-нибудь выясняли, как сохранить даты от изменений?

Ответы на вопрос(3)

Вы можете использоватьgit cherry-pick, В твоем случае:

git cherry-pick C D E

пока Х твоя голова должна это сделать.

 Borek Bernard01 февр. 2012 г., 03:42
Cherry pick, похоже, теряет информацию о дате фиксации (вероятно, создает новый коммит), будет ли проблема такой же, как и с rebase? Это было бы очень плохо, мне нужно сохранить даты коммитов.
 Carl Norum01 февр. 2012 г., 03:36
Если у вас много, есть несколько вариантов выбора вишни, которые позволят вам сгруппировать их. Проверьте документацию. Rebase также будет работать - если вы используете его в исходном репозитории для замены A & B на X, вы получите тот же результат, который вы искали.
 Borek Bernard01 февр. 2012 г., 03:32
Спасибо, я думал, что rebase будет моим другом, но команда cherry pick - это команда, которую нужно использовать. Я надеюсь, что смогу указать коммиты типа "C ..", поскольку у меня их сотни в исходном репо.
Решение Вопроса

почему вам нужна дата фиксации, чтобы остаться прежней, но здесь идет:

git rebase B E --onto X --committer-date-is-author-date

ЕслиB..E не в том же хранилище, что иX (как они могут бытьесли вы создаете свойновый старт на месте), вам нужно сначала получить их:

git fetch <path_to_old_repos>

Конечно,B, E а такжеX здесь подразумеваются их идентификаторы коммитов, если вы на самом деле их не помечали / не разветвляли.

Вы также можете сделать что-то подобное (хотя дата фиксации не будет сохранена) путем ребазирования изA в вашем оригинальном хранилище и сквошB на него:

git rebase -i `A`

# change "pick b" to "squash b"

Вы получите возможность изменить сообщение о коммите, и в этот момент вы можете сделать это.X«S.

 antak02 февр. 2012 г., 02:00
git fetch создаст для вас удобную ветку под названиемFETCH_HEAD который будет указывать на что угодноHEAD был (т.е. все, что было проверено) в вашем старом хранилище. Более того, идентификаторы коммитов будут одинаковыми во всех репозиториях, так что вы можете просто перейтиgit log <B's commit-id> например. Вы также можете создать соответствующую ветку во время выборки:git fetch <path_to_old_repos> their_branch:my_branch.
 Borek Bernard01 февр. 2012 г., 13:56
Пока это звучит как лучший подход, однако у меня проблема с коммитами, полученными с использованиемgit fetch, Как я могу ссылаться на них? Их нет ни на одной ветке?

что создали «новый репозиторий». Вы, вероятно, не хотели этого делать. Если по какой-то причине коммиты A и B должны полностью прекратить существование (например, по юридическим причинам или из-за того, что вы случайно зафиксировали номер своей кредитной карты и свой секретный рецепт хаггиса) в своем хранилище, вам необходимо прочитать о том, как навсегда удалить коммит , Но сначала давайте исправим остальную часть дерева.

Попробуйте что-то вроде

git checkout -b freshstart A
# modify the state of the system until it reflects your desired new beginning X
git commit --amend
git cherry-pick C D E

Теперь у вас есть ветвь с именем freshstart, у которой есть новое начало X и фиксируются C, D и E, при условии, что они хорошо сливаются с X.

 Borek Bernard01 февр. 2012 г., 03:55
Правильно, A и B должны быть полностью удалены из истории, поэтому создание нового репо кажется хорошим способом начать. Я создал состояние X, получил удаленную ветку original-repo / master и теперь я могу выбрать коммиты из него в основную ветку. У меня две проблемы: 1) выбранные Cherry коммиты теряют свою дату 2) я не могу сослаться на ветку original-repo / master (так как у нее нет общего родителя с локальным master и я думаю, что она стоит рядом с моим 'master'). Я не могу удалить ту временную ветку, из которой я выбрал вишню.
 Borek Bernard01 февр. 2012 г., 11:28
А и Х не имеют каких-либо общих предыдущих коммитов, возможно ли создать ветку, у которой нет родителя в моем исходном репо?
 bames5301 февр. 2012 г., 06:17
Вам не нужен новый репо, чтобы полностью удалить коммиты. Вы можете использовать rebase, например, для устранения коммитов. Единственное, что если у вас есть юридические причины или что-то для удаления коммитов, убедитесь, что объекты, которые становятся мусором при удалении коммитов, будут очищены, чтобы они по-прежнему не были доступны людям, которые знают, что они делают. И, конечно же, вы должны идти к каждому клону репо повсюду и делать одно и то же, иначе вы не сможете выполнить юридическое обязательство.

Ваш ответ на вопрос