Git конфликты, порожденные вишнёвыми пиками
Для начала, я новичок в git, но поглощаю документацию и подобные вопросы по этой теме, как эта и эта (я буду ссылаться на этот последний вопрос позже в этом посте).
Краткое описание: я выбирал коммит из одной ветви в другую, и после того, как я сделал коммит в одной ветви и затем попытался объединить их, я получил конфликты. Смотрите мой ответ ниже, что я думаю, что происходит.
Сценарий: у меня есть два файла, один в "основной" ветке и один в "вторичной" ветви. "Вторичная" ветвь содержит некоторые файлы, которые нам не нужны в master, и используется только несколькими людьми, но большинство файлов, которые мы имеем как в "master", так и в "second", должны быть согласованными (все в master является во вторичном, но все во вторичном не в главном). Для этого я вносил изменения, сделанные в "master", используя git checkout secondary
оформить заказ на мою "вторичную" ветку, а затем запустить git merge master
, К сожалению, я однажды поднял конфликт, и теперь мой мозг суетится, пытаясь выяснить, что это за конфликт.
Попытка решения: сначала я подумал, что это потому, что я изменил файлы как в "Secondary", так и в "Master", который у меня был. Чтобы решить эту проблему, я использовал git cherry-pick [commit]
вытащить изменения, которые я сделал во вторичной ветви, в основную ветку. Тем не менее, я все еще не мог объединить мою основную ветку с вторичной веткой. Git предложил использовать git add/rm
(предположительно git add
или же git rm
хотя это заняло у меня немного времени, чтобы понять, какие из них я хотел. Поэтому я удалил версию в индексе и рабочее дерево во "вторичном" с помощью команды git rm. После этого я вернулся в свою "основную" ветку, подтвердил, что файлы, которые я хотел объединить в "вторичные", вернулся в "вторичные", а затем запустил git merge master
снова. К моему огорчению, конфликты.
Вопрос: Честно говоря, я думаю, что понятия не имею, что происходит. я думал так git merge master
(при запуске на вторичной ветке) будет принимать все изменения, сделанные в коммите git master, и помещать эти изменения во вторичную ветку. Если это то, что происходит, я не понимаю проблемы. Я удалил файлы из вторичного и зафиксировал свои изменения в master. Почему я не могу слиться? Решение последнего вопроса, о котором я говорил ранее, предполагает, что это может быть потому, что общий предок содержит что-то еще, но я подумал, что git cherry-pick [commit]
позаботился бы об этом. Проблема в том, что cherry-pick
не создает новую базу слияния, и поэтому даже после того, как cherry-pick
они все еще могут отличаться от их базы слияния?
Я прошу прощения за длину этого вопроса, я очень стараюсь понять, и я чувствую, что я бегаю кругами. Будем признательны любому совету.
Редактировать: Я думаю, я также запутался, потому что я не понимаю, почему git не позволяет мне менять ветки, чтобы попытаться решить эту проблему. Когда я пытаюсь git checkout secondary
сейчас, чтобы попробовать и, возможно, cherry-pick
коммит меняется на вторичный, я получаю error: you need to resolve your current index first
, Я предполагаю, что должна быть причина, по которой мерзавец не позволил бы такое поведение, я просто не уверен, что вижу, что это такое.
2 ответа
Нашел решение! Происходит то, что cherry-pick
не создает новую базу слияния (поэтому они оба имеют общего предка, но это отличалось от обоих их текущих состояний). Поэтому, когда я изменил мастер после cherry-pick
Все три моих файла были разными. Для визуализации:
Общий предок:File.txt: this is the common ancestor.
Затем я делаю изменения на вторичной ветке и фиксирую их.
Secondary:File.txt: now I've modified this file to be this!
Затем я git checkout master
а также git cherry-pick [commit made on secondary]
,
Мастер:File.txt: now I've modified this file to be this!
Тем не менее, общий предок все еще File.txt: this is the common ancestor.
Если я сделаю коммит на мастере, изменив его на File.txt: now this is the new master!
У меня было бы три разные версии File.txt
! Таким образом, когда я пытался слить, git жаловался на конфликты, потому что не знал, как объединить два разных файла. Чтобы решить эту проблему, просто запустите git merge secondary
сразу после cherry-pick
пока на хозяине! Итак, если мы сделаем это слияние сейчас, мы получим:
Общий предок:File.txt: now I've modified this file to be this!
Кажется, это не интуитивно понятно, потому что слияние между master и Secondary на самом деле ничего не делает с их файлами, поскольку на данный момент они идентичны. Тем не менее, необходимо сделать это слияние, чтобы создать общего предка, прежде чем мы будем вносить изменения в любую из ветвей. Надеюсь, это поможет кому-то!
Последний пункт первый - ваш репо находится в подвешенном состоянии. Вы можете отредактировать конфликт вручную и завершить коммит слияния или можете выйти из него
Я думаю, что один или несколько коммитов на мастере включают файлы, которые существуют только на мастере. Git не может объединить эти коммиты, так как они содержат изменения для файлов, которые не существуют.
Попробуйте "git status", чтобы увидеть, где вы сейчас находитесь; ищите "оба измененных" файла. затем 'git rm', чтобы вынуть файлы из слияния, или вы можете разрешить проблемы (конфликты) внутри файлов и добавить их обратно в коммит с помощью 'git add'. Затем "git commit", чтобы закончить слияние.