В Git, как создать ветку после разрешения конфликтов? - PullRequest
3 голосов
/ 14 июня 2019

Я часто нахожусь в такой ситуации:

  • извлечение изменений из репозитория в восходящем направлении (слияние)
  • слияние вызывает конфликты
  • разрешить конфликты
  • решите зафиксировать не текущую ветку, а новую

На последнем шаге я использую git checkout -b new-branch-name, но после вызова этой команды текущая головка больше не имеет ссылок на извлеченные изменения. У него только один родитель. Это больше не слияние.

Как я могу, выполняя слияние, зафиксировать это слияние с новой веткой?

Ответы [ 3 ]

5 голосов
/ 14 июня 2019

Лично я избегаю git pull.Избегая этого, я могу сначала запустить git fetch, а затем проверить, что поступает. Посмотрев, я затем использую git merge, но обычно заканчиваю также , избегая, в первую очередь, этой конкретной ошибки, потому что я вижучто слияние может быть трудным и начинать с новой ветки заранее.

Тем не менее, полезно, чтобы иметь возможность восстановить ... и это легко!Просто сделайте это, как вы уже сделали:

git pull
# oh no, merge conflicts!
# resolve conflicts
git commit                    # or git merge --continue

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

git branch new-branch-name    # create new branch to contain the merge
git reset --hard HEAD^1       # back up current branch to first-parent
git checkout new-branch-name  # return to new branch

Схематически выначните с:

    o--o--o   <-- your-branch (HEAD)
   /
...
   \
    o--o--o   <-- origin/your-branch

Завершение слияния продвигается your-branch, чтобы указать на новый коммит слияния *, который вы делаете:

    o--o--o
   /       \
...         *   <-- your-branch (HEAD)
   \       /
    o--o--o   <-- origin/your-branch

Теперь мы добавляем новая ветка , указывающая на этот же коммит слияния:

    o--o--o
   /       \
...         *   <-- your-branch (HEAD), new-branch-name
   \       /
    o--o--o   <-- origin/your-branch

и затем с помощью git reset перетащите имя ветки, к которой HEAD присоединен, на один шаг назад, в направлении первого родителя, который восстанавливает его до предыдущего коммита:

    o--o--o   <-- your-branch (HEAD)
   /       \
...         *   <-- new-branch-name
   \       /
    o--o--o   <-- origin/your-branch

и все готово.

Все это опирается на полезный принцип о Git: Git на самом деле все о совершает .Имена ветвей постоянно перемещаются;они просто как мы находим коммиты. коммиты являются постоянными (ну, пока мы можем их найти) и неизменяемыми.Получайте коммиты так, как вам нравится, и затем вы можете переставлять имена на досуге.

(Если HEAD^1 сложно ввести по разным причинам, учтите, что вы можете использовать любой из HEAD^ или HEAD~ или даже @^ или @~. То есть:

  • HEAD и @ являются синонимами.
  • * ^1 и ^ без 1, как суффиксы, являются синонимами: 1 подразумевается, если вы его опускаете.
  • ~1 и ~ без 1, как суффиксы, являются синонимами: 1 являетсяподразумевается, если вы его опустите.
  • Хотя ^ и ~ делают разные вещи, оба означают «вернуться на некоторое количество шагов в графике».

Число после^ является номером родителя и имеет значение только для коммитов слияния: 1 означает первого родителя . Таким образом, HEAD^1 означает первого родителя HEAD, и HEAD~1 означает вернуться к одному первому родителю . Применение всех правил синонимов дает нам конструкции @^ и @~.)

1 голос
/ 14 июня 2019

Отвечая на немного другой вопрос - если вы уже использовали git checkout -b new-branch для создания ветки, ваше слияние не полностью потеряно. Вот как я выздоровел: во-первых, спрятать изменения. Затем повторите объединение, используя strategy=ours, затем повторно примените сохраненные изменения и подтвердите.

git merge upstream/master
# resolve conflicts
git checkout -b new-branch
# oh, noes! merge lost.
git stash
git merge upstream/master --no-commit --strategy=ours
git stash pop
git commit
1 голос
/ 14 июня 2019

Использовать несвязанные слияния, изменить ветку, зафиксировать там

git checkout <yourbranch>
git fetch
git merge --no-commit origin/<yourbranch>

# if conflicts : resolve conflicts then

git checkout -b <newbranch>

# if NO conflicts, just

git add path/to/relevant/files
git commit
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...