2017-02-06 2 views
1

У меня есть эти коммиты: (TL; DR ниже ...)Git: Скопировать цепочку фиксаций на какой-то другой не совершал, не ветви, участвующие в одной команде

A <- B <- C 

Они находятся на вершине совершающие коллеги:

U <- V <- W <- A <- B <- C 

Теперь коллега перебазировать его ветвь к новым master, толкнул на GitHub репо, который обновил PR затем добавил коммит, толкнул GitHub репо, то я решил конфликты на GitHub и совершил в отрасль на github, то коллега раздавил t wo коммитов и добавил еще один, а затем наша команда вошла в игру и начала редактирование с помощью редактора github. Так что в конце концов, как это: [1]

X' <- A'' <- U -> C <- W -> B ---> L --> O --> O 
<--- master' / |     / <------ master 
G ---------> M --/  \- abyssmal' <-- P --/ 

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

Я пишу историю, потому что обычно люди пытаются предложить решения моей основной проблемы, что здорово, но я бы предпочел знать эту конкретную операцию, если у github есть средства для ее выполнения. Кроме того, я заявляю, что нет ветвей, потому что, когда мало кто работает на одной ветке, вещи становятся беспорядочными и ветвями теряют смысл. Отсутствие дисциплины или использование Git неправильным способом. Я знаю. Не решая этого, я буду доволен решением этого.

Все, что имеет значение для меня:


TL; DR:

Как скопировать любую цепочку фиксаций (при условии, что они прикованы) к какой-либо другой коммит, в одной команде? То есть У меня есть:

...hicSuntLeones <- myCommitA <- myCommitB <- myCommitC <- whatever... 

Я хочу супер-простой команды:

git copyCommits --since myCommitA --until myCommitC --putThemTo terraInrecognita 

Я хочу, чтобы в конечном итоге, как это:

...terraIncognita <- myCommitA' <- myCommitB' <- myCommitC' 

С промежуточных конфликтов разрешающих конечно.


Я смотрел на git rebase --onto, но это похоже на работу с иной логикой, что мне нужно - это позволит мне «развод» еще одна ветвь, но у меня нет этой ветви. Если я это правильно пойму.

Я просматриваю переполнение стека и сеть, но все еще не могу найти. Ответы git, как правило, объясняют, как работает git, how git rebase works, что такое contrast of the design philosophy of git with the philosophy of a more traditional source control tool like svn, как работает SCM вообще, как relationships with parents are important и прочим. Я не хочу звучать высокомерно, но я ищу команду, чтобы сделать выше. Есть ли? Спасибо :)

[1] Это не так уж плохо, просто нормальный ежедневный хаос. Но все же это делает этот подход более легким, чем мышление в ветвях.

Редактировать: Не дать ответ: Difference between 'rebase master' and 'rebase --onto master' from a branch derived from a branch of master Этот дублированный ссылка, также упоминаемая в вопросе, не отвечает на мой вопрос. Он имеет подробные ответы о том, как работает git, как работают ветки, но не дает ответа на мой вопрос. Возможно, это подразумевается там, но не дано.

+0

Что о 'мерзавец --onto terraIncognita myCommitA^myCommitC'? Разве этого недостаточно? Конечно, имя 'myCommitC' - название ветки. – rodrigo

+0

Нет ветвей, только фиксируется. Я мог бы создать временные ветви. Или, может быть, это может быть хеширование? –

+0

Да, это также принимает хеши. – amenthes

ответ

2

Моей первой идеей было бы сделать git rebase. Существует эта rebase с тремя аргументами в man git-rebase странице есть это хороший пример (среди многих других):

       H---I---J topicB 
          /
        E---F---G topicA 
        /
     A---B---C---D master 

$ git rebase --onto master topicA topicB 

        H'--I'--J' topicB 
       /
        | E---F---G topicA 
        |/ 
     A---B---C---D master 

Аналогичный эффект будет достигнут в репозитории с помощью следующих команд.

Сначала мы создаем ветвь с последней фиксации мы заинтересованы в том, и проверка его:

$ git checkout -b newC myCommitC 

Тогда мы перебазироваться эту ветвь на нужное место. Не забудьте указать родителя первого коммита, потому что вы должны сообщить последнему коммиту, не включенному в rebase;

$ git rebase --onto terraIncognita myCommitA^ newC 

И сделано! Теперь вы NEWC указывая на кончик новой ветви:

terraIncognita <- myCommitA' <- myCommitB' <- myCommitC' 
1

Что вы хотите - это просто git cherry-pick, который может выбрать цепочку совершений.

Это займет две команды (если вы не написали свой собственный сценарий), поскольку вам нужно указать git checkout место, куда вы хотите, чтобы копии приземлились. Затем, если первый совершить копируемый S (для начала), а последний E (на конец):

git cherry-pick S^..E 

Вам нужно хет-суффикс, чтобы сделать выбор, включает обязательство S себя.

+0

Я пробовал «cherry-pick», но это 1) раздавил коммиты на один, 2) оставил последнюю фиксацию по неизвестным мне причинам. Последнее, не первое. –

+1

'git cherry-pick' должен делать отдельные коммиты от каждой скопированной фиксации, если вы не используете' -n'.(Обратите внимание: если вы столкнетесь с конфликтами, Git посоветует вам исправить конфликт и при необходимости зафиксировать его, а затем использовать git cherry-pick -continue для продолжения остальных коммитов, если таковые имеются. Я также должен отметить, что возможность выбора несколько коммитов были новыми в очень старой версии Git-1.7.2, поэтому, если ваш Git еще старше, у вас может не быть этого.) – torek

+0

Просто попробовал еще раз. У меня есть 4 фиксации для перемещения: d5c22cb, 7c01600d, ce0d010, 088eaa67. «Git co terraIncognita; git cherry-pick d5c22cb^.. 088eaa67'. Разрешенные конфликты, добавлены, '--continue'd. Завершено с двумя последними коммитами, без изменений в первых двух. (Мой комментарий 1 не так.) Не уверен, что я делаю что-то неправильно? –

Смежные вопросы