Перебазирование к новым версиям в апстримном git (GitHub) с потерей всех локальных изменений - PullRequest
3 голосов
/ 30 сентября 2011

Я хочу иметь следующую структуру версий:

                  (my private changes to 0.1.0) - A - B - C - ...
                    /
(upstream repo) - 0.1.0 - 0.2.0 - ...
                            \
                  (my private changes to 0.2.0) - D - E - F - ... 

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

git rebase не то, что я хочу. Согласно Pro git book , при перебазировании попытка повторно применить патчи A-B-C до 0.2.0. Вот пример ситуации между вышедшими версиями 0.1.0 и 0.2.0:

(upstream) - 0.1.0 - (my master) - A - B - C

Сейчас вышел 0.2.0:

              (my master) - A - B - C 
               /   
(upstream) - 0.1.0 - 0.2.0

Я не хочу переоценивать свои изменения A - B - C из-за слишком большого количества конфликтов. Я хочу пометить свою ветвь A - B - C как «my-0.1.0» и начать «новую» основную ветку с 0.2.0:

              (my-0.1.0) - A - B - C
                 /
 (upstream) - 0.1.0 - 0.2.0 - (my new master)

Я хочу, чтобы моя новая основная ветвь была чистой копией восходящей версии 0.2.0, без каких-либо попыток повторно применить к ней мои старые наборы изменений A-B-C. Так что позже я могу выбирать изменения A-B-C один за другим, если они понадобятся мне в мире после версии 0.2.0.

Как мне поставить метку my-0.1.0? Это метка, метка, ветка? Как мне запустить пустую главную ветку с 0.2.0? Обратите внимание, что есть два разных репо: мое репо и обратное репо. Нужно ли мне копировать восходящую ветку из восходящего репо в мой репо? Как я могу убедиться, что 0.2.0 тянет после 0.1.0, а не после C? Если я просто сделаю запрос на получение после

(вверх по течению) - 0.1.0 - (мой мастер) - A - B - C

Я получаю

(вверх по течению) - 0.1.0 - (мой мастер) - A - B - C - «0.2.0 объединено с ABC»

это не то, что я хочу.

Также иногда я хочу отодвинуть определенные изменения (например, E) обратно в восходящий поток. Можно ли создать запрос на извлечение только для изменения E? В дарках это возможно. Если это невозможно с Git / GitHub, тогда мне нужно будет создать отдельную ветку, повторно применить изменения в E вручную. Как мне поступить?

Ответы [ 3 ]

3 голосов
/ 30 сентября 2011

git rebase твой друг.

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

Чтобы создать запрос на извлечение только для E, вы можете:

  1. Создайте новую ветку и git cherry-pick E к ней (старая ветка будет иметь старую версию E).
  2. git rebase -i ветвь и изменение порядка коммитов, чтобы поставить E первым. Чем вы можете пометить E и создать запрос извлечения из этого тега. Когда апстрим применяет его, перебазировка должна правильно применить оставшиеся коммиты

В любом случае, если rebase не осознает, что E объединен, когда в конечном итоге это делает upstream (что происходит, если они его изменили), просто используйте интерактивную rebase, чтобы отбросить устаревшую версию.

Darcs фактически делает то же самое, но darcs перезагружается автоматически, если он может делать это без конфликтов (и отказывается делать это вообще, если не может), тогда как в git вы явно перебазируете и если возникают конфликты (E получается зависеть от D), он выплевывает конфликт и позволяет вам разобраться с ним так, как вы хотите.

Редактировать : Ах, вы просто хотите отложить А, В и С в сторону и начать с чистого 0.2.0. Вы можете использовать любую ветку (на master, do):

git branch -m my-0.1
git checkout -b master 0.2.0

или тег (на мастере, делай):

git tag my-0.1
git reset --keep 0.2.0

В ветке будут храниться рефлоги, вы сможете проверить их и изменить. У тега не будет reflog, и вы не сможете его проверить (checkout переведет вас в состояние «detached HEAD», если вы не дадите ему ветку для создания).

2 голосов
/ 30 сентября 2011

Возможно, вы захотите взглянуть на git rebase --onto, который позволит вам применить набор изменений на другой базе, чем они есть на

1 голос
/ 19 января 2012

Обратите внимание, что начиная с git1.7.2rc2 , параметр git reset --keep 0.2.0, упомянутый Ян Худеком в его ответ , также может быть записан:

git checkout -B master 0.2.0

В объявлении упоминается:

git checkout -B <current branch> <elsewhere>" 

- более интуитивно понятный способ написания "git reset --keep <elsewhere>".

...