Представьте себе замок из git! Подожди секунду. Это не предложение, с которого я хотел начать. Тем не мение.
Проблема
Если бы вы когда -либо работали вместе с командой над проектом в GIT, вы, возможно, закончили работу над Цепочка коммитов Анкет Все хорошо, готовые к тому, чтобы их подтолкнули к общему удаленному репозиторию, который находится за Gihub/Bitbucket/Gerrit/любым сервером. Это когда один из ваших коллег скажет что -то вроде этого:
«Эй, Карен, ты забыл добавить в этот файл полуколон. Вы знаете тот, который вы добавили в середине своей цепочки коммит ».
И именно здесь вы начинаете проверять и переживать и, возможно, в конечном итоге в аду слияния.
Если вы действительно не понимаете, что здесь происходит, эта статья для вас!
Давайте обнаружим проблему с очень простым примером. Здесь замок приходит на картинку.
Познакомьтесь с вашим замком Git!
Мы создадим наше Гит замок так просто:
mkdir git-castle cd git-castle git init touch castle.yaml
Как вы могли подумать, что наш замок Git будет Просто файл, представляющий кусок кода что мы отредактируем и совершаем общение, пока мы должным образом не задушим себя конфликтами слияния.
Давайте создадим наше Представление кода , как файл YAML, описывающий параметры нашего замка. Мы также создадим цепочку коммитов для работы.
Наш файл представления кода:
# This is my git castle! -------- location: Camelot built: 2010-10-10 owner: Penny Bunn rooms: - room_name: Living Room - room_name: Kitchen
Давайте создадим наш первоначальный коммит с добавлением этого файла.
git add castle.yaml git commit -m "Initial Commit"
Теперь добавляем несколько параметров и Создайте второй коммит как «Добавить параметры комнаты» :
# This is my git castle! -------- location: Camelot built: 2010-10-10 owner: Penny Bunn rooms: - room_name: Living Room size: 30m2 windows: 2 doors: 2 - room_name: Kitchen size: 15m2 windows: 2 doors: 1
Теперь добавляем еще одну комнату и третий коммит названный «Добавить ванную» *:
- room_name: Bathroom, size: 10m2 windows: 1 doors: 1
Прохладный! У нас есть три коммита с длинными коммит!
Возвращаясь, чтобы что -то исправить
Но нет! Мы вдруг узнаем, что в соответствии с нашими планами Гостиная должна иметь 3 окна!
Естественно, было бы лучше исправить это на исходном коммите «Добавить параметры комнаты». Особенно сейчас, что мы заметили нашу ошибку в цепочке коммита, прежде чем подтолкнуть ее к удаленному мастеру.
Вот где Interactive Rebase приходит на картинку.
В git Rebase
Команда используется, чтобы повторно применить коммерцию в выбранную базовую наконечник. К счастью, у него есть интерактивный флаг, и вместе с ним вы можете просто вернуться к выбранному коммитию, отредактировать его и повторно применить все следующие поступки до мастера.
git rebase -i $ {base_tip}
Как base_tip
Мы выберем любой коммит, который Старший (Далее), чем тот момент, когда мы хотим отредактировать. Когда у вас будет удаленное репо, этот момент будет отдаленным мастером, который также станет основой вашей цепочки коммит, так что лучше всего поднять. Теперь в нашем случае мы просто будем использовать хэш нашего первоначального коммита.
Мы можем выяснить это с git log
или Гитк
, или git rev-parse Head ~ $ num
где $ num наш расстояние от первоначального коммита.
После Smashing Enter, нас встретят с Интерактивное окно редактора Анкет Мы увидим все коммиты выше нашего выбранного base_tip
И мы можем выбрать, какой коммит для редактирования просто замена Выбранный Выберите
с е -
. Как это:
e ddbef6b Add room parameters pick 607bd93 Add bathroom # Rebase cf0e9f4..550ab2c onto cf0e9f4 (3 commands) # # Commands: # p, pick= use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop = remove commit # l, label
Если вы никогда не видели эти интерактивные окна ни здесь, ни при совершении совершения, и вы также не знаете редактора по умолчанию GIT (EMACS или VIM), у вас могут возникнуть проблемы с редактированием и сохранением документа. Возможно, вы захотите изучить Vim/emacs, если это так.
После успешного редактирования мы можем проверить с gitk
или git rev-parse Head
что мы действительно находимся в коммите, который мы хотели редактировать. Мы сделаем наше исправление так:
rooms: - room_name: Living Room size: 30m2 windows: 2 doors: 2
С git добавить
и git commit -Amend
Мы можем добавить изменение в коммит «Добавить параметры комнаты». После этого мы можем поставить на себя коммит «Добавить ванную» и проверить его по одной простой команде: git rebase -continue
На самом деле даже сам git предупреждает нас, если мы сделаем GIT Статус
что мы находимся в интерактивной сеансе рефейса, и мы должны прервать или продолжить его.
Теперь все кажется таким простым, но все же …
Давайте сделаем ванную намного больше и с 2 окнами, также добавим кладовую и сделаем коммит, названный «Изменить размер ванной комнаты и добавить кладовую»:
- room_name: Bathroom, size: 20m2 windows: 2 doors: 1 - room_name: Pantry, size: 5m2 windows: 0 doors: 1
Теперь идет проблема. Мы решаем сделать туалет, а не ванную на этом уровне замка. Итак, чтобы прояснить, мы решаем сделать это так:
# This is my git castle! -------- location: Camelot built: 2010-10-10 owner: Penny Bunn rooms: - room_name: Living Room size: 30m2 windows: 3 doors: 2 - room_name: Kitchen size: 15m2 windows: 2 doors: 1 - room_name: Toilet size: 3m2 windows: 0 doors: 1 - room_name: Pantry, size: 5m2 windows: 0 doors: 1
ОК, достаточно просто. Мы знаем Interactive Rebase, поэтому мы можем сделать весь обмен на коммит «Добавить ванную». Мы просто возвращаемся к «добавлению ванной комнаты», чтобы сделать ее «добавить туалет», а также менять файл YAML. Мы делаем Rebase по сравнению с первоначальным коммитом, редактируем «Добавить ванную» и создаем туалет вместо ванной:
- room_name: Toilet size: 3m2 windows: 0 doors: 1
Сделать git добавить
и GIT Commit -Amend
как «добавить туалет», тогда просто git rebase --Продолжать
. Но на этот раз мы получаем Ошибка :
git-castle> git rebase --continue Auto-merging castle.yaml CONFLICT (content): Merge conflict in castle.yaml error: could not apply 30637b3... Resize bathroom and add pantry Resolve all conflicts manually, mark them as resolved with "git add/rm", then run "git rebase --continue". You can instead skip this commit: run "git rebase --skip". To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 30637b3... Resize bathroom and add pantry
Теперь это произошло, потому что в коммите «Изменение размера и добавить кладовую» мы также отредактировали те же линии. Все, что Git видит, это то, что мы сделали редактирование на новом коммите «Добавить туалет» на этих линиях, а затем, пока переживание понимает, что на одной линии существуют противоречивые изменения. Это имеет смысл, так как Как Гит должен знать, какое редактирование должно сохраняться Правильно? Вот почему на этом этапе останавливается перетасование, поэтому мы можем отредактировать файл, выбрав, какое изменение будет упорно на коммит, где произошел конфликт ( На этот раз это «Изменить ванную комнату и добавить кладовую» ).
Если вы откроете файл, вы можете увидеть, что GIT даже вставил помощь сепараторам, чтобы увидеть, какой контент у него есть дилемма о Анкет Мы делаем исправление и с git добавить
и git rebase --Продолжать
Переговоры проходят. Естественно, и отредактировать окно подпрыгнет для фиксированного коммита, который мы могли бы переименовать как «добавить кладовую», так как это истинный контент после того, как в ней нет изменения в ванной комнате.
Woila. Проверьте Gitk, чтобы быть уверенным. git push
Выгода.
Оригинал: «https://dev.to/pencillr/merge-conflict-hell-46on»