Разрешение конфликтов слияния

Введение

Внедрение новых технологий и инструментов в массы обычно происходит по одному сценарию. В самом начале небольшая группа энтузиастов рассказывает всему сообществу о том, что наконец-то у мира появился шанс, спаситель пришёл, и он нереально крут. При этом объяснить, почему он крут и что же именно в нём такого нереального, они ещё не готовы. Тем не менее, зачастую начавшееся оживление приводит к бурному развитию мессии, и он доводится до состояния, когда им уже можно начинать пользоваться не только апостолам и законченным фанатам, но и простым смертным. Смертные, кто добровольно, кто из-под палки, но все обязательно через ломку сознания постепенно обращаются в новую веру, и вот спаситель уже вовсю шагает по планете, одаривая своих приверженцев счастливыми мгновениями соприкосновения с добрым и вечным, вовлекая в их ряды всё новых и новых счастливцев. Затем к нему привыкают. Потом находят в нём фатальные недостатки. И вот на горизонте появляется новый спаситель и всё повторяется сначала.

Мессия, о котором пойдёт речь в данном руководстве – это Git, распределённая система контроля версий с открытым исходным кодом. На данном этапе его развития он уже доступен простым смертным.

Отмена слияний

Теперь когда вы знаете, как создать коммит слияния, вы можете сделать его по ошибке. Одна из замечательных вещей в работе с Git – это то, что ошибки совершать не страшно, так как есть возможность исправить их (и в большинстве случаев сделать это просто).

Коммит слияния – не исключение. Допустим, вы начали работать в ветке , случайно слили ее в , и теперь ваша история коммитов выглядит следующим образом:

Рисунок 137 – Случайный коммит слияния

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

Исправление ссылок

Если нежелаемый коммит слияния существует только в вашем локальном репозитории, то простейшее и лучшее решение состоит в перемещении веток так, чтобы они указывали туда, куда вам нужно. В большинстве случаев, если вы после случайного выполните команду , то указатели веток восстановятся так, что будут выглядеть следующим образом:

Рисунок 138 – История после git reset —hard HEAD~

Мы рассматривали команду ранее в «Раскрытие тайн », поэтому вам должно быть не сложно разобраться с тем, что здесь происходит. Небольшое напоминание: обычно выполняет три шага:

  1. перемещает ветку, на которую указывает . В данном случае мы хотим переместить туда, где она была до коммита слияния ();
  2. приводит индекс к такому же виду, что и ;
  3. приводит рабочий каталог к такому же виду, что и индекс.

Недостаток этого подхода состоит в изменении истории, что может привести к проблемам в случае совместно используемого репозитория. Посмотрите «», чтобы узнать, что именно может произойти; проще говоря, если у других людей уже есть какие-то из изменяемых вами коммитов, вы должны отказаться от использования . Этот подход также не будет работать, если после слияния уже был сделан хотя бы один коммит; перемещение ссылки фактически приведёт к потере этих изменений.

Отмена коммита

Если перемещение указателей ветки вам не подходит, Git предоставляет возможность сделать новый коммит, который откатывает все изменения, сделанные в другом. Git называет эту операцию «восстановлением» (revert); в данном примере вы можете вызвать её следующим образом:

Опция указывает какой родитель является «основной веткой» и должен быть сохранен. Когда вы выполняете слияние в (), новый коммит будет иметь двух родителей: первый из них (), а второй – вершина ветки, которую сливают с текущей (). В данном случае, мы хотим отменить все изменения, внесённые слиянием родителя #2 (), и сохранить при этом всё содержимое из родителя #1 ().

История с коммитом восстановления (отменой коммита слияния) выглядит следующим образом:

Рисунок 139 – История после git revert -m 1

Новый коммит имеет точно такое же содержимое как , таким образом, начиная с него всё выглядит так, как будто слияние никогда не выполнялось, за тем лишь исключением, что «теперь уже не слитые» коммиты всё также присутствуют в истории . Git придет в замешательство, если вы вновь попытаетесь слить в ветку :

В ветке нет ничего, что ещё недоступно из ветки . Плохо, что в случае добавления новых наработок в , при повторении слияния Git добавит только те изменения, которые были сделаны после отмены слияния:

Рисунок 140 – История с плохим слиянием

Лучшим решением данной проблемы является откат коммита отмены слияния, так как теперь вы хотите внести изменения, которые были отменены, а затем создание нового коммита слияния:

Рисунок 141 – История после повторения отменённого слияния

В этом примере, и отменены. В коммите фактически сливаются изменения из и , а в – изменения из , таким образом, ветка полностью слита.

Просмотр истории и старых версий

git log

Для просмотра изменений (истории коммитов) используется команда

git log

, которая покажет список последних коммитов и их хеши SHA1. Первыми показываются последние коммиты.

Или можно использовать

git log --oneline

Или для конкретной ветки

git log master --oneline

У множество возможностей, например, мы можем выводить историю в более удобном формате:

git log --pretty=format:"%h - %an, %ar : %s"
  • – короткий код самого коммита;
  • – автор;
  • – когда был сделан;
  • — комментарий;
  • — Хеш-код коммита;

Ограничивать коммиты по времени:

git log --since=2.weeks

Показывать разницу, внесенную каждым коммитом:

git log -p -2
  • показывает разницу, внесенную каждым коммитом. ограничивает выводимый результат последними 2 записями.
  • используется для получения краткой статистики по каждому коммиту.
  • добавляет графику с историей ветвлений и слияний

git log ..

git log name_branch..origin/master

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

git log — выводим нужные коммиты

Зададим какие именно коммиты нужно выводить. по умолчанию выводит коммиты достижимые из . Но можно задать коммиты, например, по хэшу, ветке, и тогда будет выведены коммиты достижимые по хэшу, ветке.

git log master
git log 34assd

Из двух веток:

git log master feature --graph

Выведем коммиты достижимые из всех ссылок:

git log --all --graph

Просмотр коммитов (кроме)

Например, нам нужно просмотреть коммиты, которые произошли в ветке , которые, в свою очередь, произошли с момента ее расхождения от (то есть КРОМЕ коммитов на ветке master):

git log feature ^master

аналогично:

git log master..feature

Просмотр коммитов (И различий) по файлу

Выведем коммиты, в которых менялся файл :

git log index.html

Выведем конкретные различия, в которых менялся файл :

git log -p index.html

   Флаг-фильтр —grep

Поиск всех коммитов в описании которых есть слово :

git log --grep word

сделаем регистронезависимым:

git log --grep word -i

   Флаг-фильтр -G

Поиск по изменениям, например, была функция — нам нужно найти, что было с ней ранее. С флагом git выведет все коммиты, в изменениях которых есть строка, которая подпадает под регулярное выражение .

Найдем вызов функции:

git log -GdoAny() -p

Найдем объявление функции:

git log -G'function doAny\(' -p

Не забывайте, что это регулярное выражение.

Флаг позволяет увидеть непосредственно изменения.

   Флаг-фильтр -L

Выводи все коммиты с n-й по n-ю строку, например, выведем с 3-й по 7-ю строку:

git log -L 3,7:index.html

Или найдем фрагмент кода по регулярному выражению:

git log -L '/<head>/','/<\/head>/':index.html

Возможность очень полезная, так как позволяет отследить изменения любого блока кода в файле.

Как перенести изменения из локального репозитория в удаленный репозиторий в Git

Чтобы протолкнуть некоторые изменения в удаленный репозиторий, этот репозиторий должен, прежде всего, содержать некоторые коммиты в локальной системе. Поэтому в этом разделе мы сначала создадим некоторые изменения в репозитории. Во-вторых, мы зафиксируем эти изменения и, наконец, отразим их в удаленном репозитории.

Перед созданием изменений в репозитории убедитесь, что вы выполнили следующие операции:

  • У вас раздвоенный репозитория на GitHub.
  • Вы клонировали один и тот же репозиторий на локальную машину.

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

После выполнения команды git status появятся следующие строки:

On branch master: означает, что в данный момент мы находимся в главной ветви. Поскольку других ветвей пока нет, мы по умолчанию находимся в главной ветви.

Your branch is up to date with origin/master: Origin — это имя удаленного репозитория, которое мы дали при подключении локального репозитория к удаленному репозиторию.

Последовательность действий

  1. Перечислите все файлы с командой ls в репозитории.

Так как существует только один файл (README.md это всего лишь инструкция), давайте внесем некоторые изменения в его содержание.

  1. Откройте файл с помощью вашего любимого редактора и внесите в него любые изменения.
  2. Мы изменили файл на следующий код.
  1. Добавьте внесенные изменения в промежуточную область и зафиксируйте их.

Примечание: GitHub и Git распознают любые изменения только через коммиты (commits). Если пользователь не зафиксировал изменения и пытается протолкнуть их на GitHub, он отобразит сообщение “Everything is up-to-date”

  1. Введите следующую команду, чтобы перенести эти изменения в репозиторий GitHub, и нажмите клавишу enter.

git push origin master

  1. Пользователь получает приглашение предоставить учетные данные с помощью GitHub в качестве части безопасности. Введите свои учетные данные и нажмите на кнопку входа в систему.
  1. Как только пользователь получит одобрение и изменения объединятся, он получит следующее сообщение в Git Bash.

Примечание: последние две строки выглядят следующим образом:

https://github.com/harishrajora805/ToolsQA.git: URL-адрес репозитория, который отражает изменения.

1в4522а..285f559: показывает хэш-значение обеих ветвей. Таким образом, хэш-значение конечного коммита, отраженного на GitHub, равно 285f559.

master -> master: строка master — > master показывает исходную ветвь, из которой происходит слияние с целевой ветвью. В приведенном выше сценарии обе ветви являются главными.

Строка Writing Objects: 100% имеет важное значение. В Git можно сказать, была ли команда push выполнена успешно или нет, только взглянув на эту строку

Если она показывает 100%, то все изменения успешно перенесены в облако.

Наряду с простой и понятной командой, которую мы обсуждали выше, как и любую другую команду в Git, мы можем использовать параметры при выполнении команды для достижения конкретной задачи. Например, если вы хотите протолкнуть все ветви, вы будете использовать опцию all и так далее. Давайте рассмотрим некоторые из вариантов в Git.

Удаленный репозиторий

Команда позволяет просмотреть удаленные репозитории

git remote -v

параметр позволяет увидеть URL-адреса.

git remote add (добавляем уд. реп., для работы локально)

Добавление удаленных репозиториев под коротким именем:

git remote add  
git remote add alias_repo 

— теперь вместо полного URL-адреса в командную строку можно вводить имя

В уже сущест. реп. добавляем реп. сторонний и стягиваем из него ветку :

git remote add interview https://github.com/asdasd/interview.git
git pull interview master

Пример использования:

  • Иниц. пустой реп.
  • Добавляем реп.
  • извлекаем все данные ()
  • и стягиваем ветку из реп.
git init
git remote add kuku https://github.com/denzLLL/test.git
git fetch kuku
git pull kuku master

git fetch (Извлечение данных из уд. реп.)

Извлечение данных из удаленного репозитория выполняется командой:

git fetch 

После исполнения данной команды у вас должны появиться ссылки на все ветки удаленного проекта.

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

git fetch origin

Получаем данные из удаленного репо, но при этом они есть лишь в папке , в рабочей папке их нет. Для того чтобы данные появились в рабочей папке необходимо выполнить команду:

$ git pull

git push (проталкиваем изменения на уд. сервер)

Отправляем изменения в удаленный репозиторий:

git push  

Отправим ветку на удаленный репозиторий :

git push origin master

Или, что тоже самое:

git push origin master:master
git push -u origin master

Параметр (флаг представляет краткой обозначение для , который устанавливает конфигурацию ветки) позволит нам в будущем не указывать дополнительные параметры: локальная ветка будет автоматически связана с удаленной веткой, и вы можете использовать без каких-либо аргументов.

Отправим ветку на удаленный репозиторий :

git push origin master:masterB

Посредством : разделяем локальную ветку и удаленную ветку .

Удаляем ветку в удаленном репозитории:

git push origin --delete 

git pull (скачиваем изменения)

выполняет по сути команды и . Если ветка настроена на наблюдение, то обращение будет к ветке на сервере, за которой наблюдает текущая ветка.

git remote show (получаем инфо. об уд. реп.)

Команда позволяет просмотреть дополнительную информацию о конкретном удал. реп., включая удаленные ветки, локальные ветки, а также настройки для и .

git remote show 
git remote show origin

Команда также оповестит вас о том, что, если находясь на ветке master вы запустите , то ветка на удаленном репо. будет автоматически c вашей локальной веткой .

Удаленные ветки

Удаленные ветки — это ссылки на состояние веток в удаленных репозиториях.

Структура наименования удаленной ветки — (имя удаленного репозиория)/ветка. Например, .

Если вам потребуется своя локальная ветка (), аналогичная удаленной ветки, то можно воспользоваться командой:

git checkout -b name_branch origin/name_branch

Этим мы также говорим, что ветка следит за удаленной веткой .

Данную операцию можно реализовать при помощи параметра :

git checkout --track origin/name_branch

Будет создана локальная ветка , которая следит за удаленной веткой .

Или создадим локальную ветку, чье имя будет отличаться от имени удаленной ветки:

git checkout -b test-master origin/master

Локальная ветка ‘смотрит’ на удаленную ветку .

Если вам потребуется поменять удаленную ветку, за которой вы следите, используйте параметр или команды :

git branch -u origin/test-git

Текущая ветка начнет следить за удаленной

Параметр позволяет увидеть ветки наблюдения (локальная информация):

git branch -vv

Чтобы увидеть актуальные ветки наблюдения:

git fetch --all
git branch -vv

Работаем с bitbucket.org

1. кликаем по

2. клонируем

3. создадим ветку (на основе удаленной ветки )

4. и внесем в нее какие-либо изменения

5. Фиксация изменений

6. Отправка новой ветки в ветку на bitbucket

git push origin test-git-fork

Далее переходи на bitbucket

7. Находим нужную ветку и делаем (запрос на включение): где вы можете выбрать как проекты, так и ветки куда пойдет запрос на слияние.

Владелец проекта может выделить часть кода и написать к нему комментарий. Как только это произойдет пользователь, открывший запрос на включение получит уведомление. Пользователь вносит правки и отправляет его.

8. Принимаем

Настройки

Переменные конфигурации Git хранятся на windows в файле . каждого конкретного репозитория приоритетен.

Команды

git config

Данную информацию следует указать обязательно, так как она будет включаться во все ваши коммиты:

git config –global user.name "firstName  lastName"
git config –global user.email "[email protected]"

Git позволяет ставить настройки общесистемные (), на уровне конкретного пользователя (), на уровне проекта ().

Проверка настроек

git config --list

Узнаем подробности о том, как работает команда, например, :

git help 
git help log

Пример файла

    name = name_user
    email = [email protected]

    default = matching

    postBuffer = 524288000

    st = status
    ci = commit
    br = branch
    co = checkout
    df = diff
    lg = log -p

Псевдонимы (алиасы) в GIT

Команда позволяет создавать псевдонимы:

git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'

Что такое git? Основные понятия

Git (произн. «гит») — распределённая система управления версиями файлов. Проект был создан Линусом Торвальдсом для управления разработкой ядра Linux.

Системы управления версиями (Version Control Systems) – это программное обеспечение, призванное автоматизировать работу с историей файла (или группы файлов), обеспечить мониторинг изменений, синхронизацию данных и организовать защищенное хранилище проекта. Короче говоря, основная задача систем управления версиями – упростить работу с изменяющейся информацией.

Распределённые системы управления версиями – это СУВ, главной парадигмой которых является локализация данных каждого разработчика проекта. Иными словами, если в централизованных СУВ все действия, так или иначе, зависят от центрального объекта (сервер), то в распределенных СУВ каждый разработчик хранит собственную ветвь версий всего проекта. Удобство такой системы в том, что каждый разработчик имеет возможность вести работу независимо, время от времени обмениваясь промежуточными вариантами файлов с другими участниками проекта.

Рассмотрим пример:
У каждого разработчика на машине есть свой локальный репозиторий – место хранения версий файлов. Работа с данными проекта реализуется над вашим локальным репозиторием, и для этого необязательно поддерживать связь с остальными (пусть даже и главными) ветвями разработки. Связь с другими репозиториями понадобится лишь при изменении/чтении версий файлов других ветвей. При этом каждый участник проекта задает права собственного хранилища на чтение и запись. Таким образом, все ветви в распределенных СУВ равны между собой, и главную из них выделяет координатор. Отличие главной ветви лишь в том, что на неё мысленно будут равняться разработчики.

Запись изменений в репозиторий (commit)

Допустим, у вас имеется репозиторий Git и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать состояния этих изменений (commit) в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить.
Запомните, каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (не отслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем слепке состояния проекта; они могут быть не измененными, измененными или подготовленными к коммиту (staged). Все изменения в них, будут отслеживаться. Не отслеживаемые файлы — это всё остальное, любые файлы в вашем рабочем каталоге, которые не входили в ваш последний слепок состояния и не подготовлены к коммиту. Когда вы впервые клонируете репозиторий, все файлы будут отслеживаемые и не измененные, потому что вы только взяли их из хранилища и ничего пока не редактировали.
Как только вы отредактируете файлы, Git будет рассматривать их как измененные, т.к. вы изменили их с момента последнего коммита. Вы индексируете (stage) эти изменения и затем фиксируете (делаете коммит) все индексированные изменения.

Что такое ветка?

Ветка (или «branch») — это своеобразное «место» разработки. Например, после клонирования репозитория мы по-умолчанию находимся в ветке master, создаём ветку test (в которую будет всё слито из master), затем делаем в ней какие-то изменения, делаем коммит, а потом переключиться обратно в ветку master. С помощью команды

$ git log

в каждой из веток, можно будет посмотреть все коммиты. В ветке master вы увидите, что ваш коммит из test на ветку не распространяется, и те файлы, которые вы изменили в ветке test будут возвращены к состоянию последнего коммита в ветке master. Таким образом ветка — это что-то вроде текущего состояния вашей разработки.

Ветвление

Ветки в Git всего лишь указатели на предыдущие коммиты, перед каждым коммитом указатель автоматически сдвигается вперед.

git branch (создаем ветку)

При создании новой ветки создается новый указатель, который, как отмечалось выше, автоматически сдвигается вперед (при каждом коммите).

git branch 

Указатель указывает на текущую локальную ветку.

Узнаем указатели веток:

git log --decorate --oneline

Обратите внимание. Узнаем указатели веток, историю коммитов, точки расхождения:

git log --decorate --oneline --graph --all

Удалим ветку:

git branch -d clean_up

git branch (управление ветками)

Отобразим все ветки:

git branch

указывает на ветку с указатедем HEAD(текущая).

Отобразим ветку с информацией о коммите:

git branch -v

Ветки слитые с текущей:

git branch --merged

Ветки не слитые с текущей:

git branch --no-merged

Перейдем в существующую ветку:

git checkout 

git checkout -b (смена + создание веток)

Создадим и сразу перейдем в нее:

git checkout 

Создадим ветку , взяв за основу удаленную ветку master:

git checkout -b test origin/master

Переносим коммиты в другую ветку или Передвигаем (Откатываем) коммиты

Создадим ветку () от текущей:

git branch feature

Теперь нам нужно передвинуть на то количество коммитов, которое нам необходимо.

git branch --force master 0b335

Команда выше создаст ветку , последний коммит которой будет указывать на коммит с хэшем . Флаг (или ) позволяет проигнорировать информацию о том, что такая ветка уже есть (иначе ветка просто не будет ‘передвинута’). Но перед этим необходимо перейти в другую ветку:

git checkout new_f
git branch --force master 0b335

Или, пусть указывает туда же куда и :

git branch -f master new_f

Создадим ветку на указанном коммите и переключимся на нее:

git checkout -b master 0b335

Флаг применяется в случае, если такая ветка уже есть и в этом случае ветка будет передвинута:

git checkout -B master 0b335

Управление ветвлением и слиянием

Один git репозиторий может заключать в себе множество ветвей разработки. Чтобы создать новое ответвление под именем «experimental», выполните команду

Теперь если вы выполните

то получите список всех существующих ветвей:

Ветка «experimental» это та, которую вы только что создали, а ветка «master» это ветка по умолчанию которая создается автоматически. Звездочка указывает в какой ветке вы в данный момент находитесь; наберите

чтобы переключиться в ветку experimental. Теперь отредактируйте файл, выполните комит, и переключитесь обратно в главную ветку «master»:

Убедитесь, что сделанные изменения невидимы, поскольку они были сделаны в ветке experimental, а вы сейчас в главной ветке «master».

Вы можете сделать другое изменение в ветке «master», затем выполнить коммит:

на этом этапе две ветки разошлись, поскольку в каждой из них различные изменения. Чтобы включить изменения в ветке experimental в master, выполните

Если изменения не конфликтуют, то вы закончили. Если же существуют какие либо конфликты, то в проблемных файлах останутся заметки которые можно увидеть выполнив;

Как только вы отредактировали файлы вызывающие конфликты выполните,

это выполнит коммит результат слияния. В заключении,

покажет наглядное графическое представление истории.

Теперь вы можете удалить ветку experimental командой

Эта команда гарантирует что изменения в ветке experimental уже в текущей активной ветке.(Прим. переводчика: если вы попытаетесь удалить ветку которую вы не слили со своей рабочей git выведет предупреждение и попросит вас выполнить след.команду $ git branch -D experimental)

Если вы отрабатываете в ветке сумашедшие идеи, и уже пожалели об этой ветке, вы всегла можете удалить ветку выполнив

Ветки это легко и просто, и это хороший способ попробовать что то новое.

Как сливать ветки

Вы можете объединить две разошедшиеся ветки разработки используя
git merge:

сливает изменения сделанные в ветке «branchname» в активную(рабочую) ветку. Если присутствуют конфликты — например один и тот же файл модифицирован разными способами в удаленной и локальной ветках — то вы будете предупреждены; вывод будет выглядеть след. образом:

Отметки конфликтов останутся в проблемных файлах, и после того как вы исправите их вручную, вы можете обновить индекс и выполнить git commit, как вы обычно это делаете когда изменяете файл.

Если вы просмотрите результирующий коммит используя gitk, вы увидите что у него два родителя: один указывает на последний коммит активной ветки, а другой на последний коммит другой ветки.

Исправление конфликтов при слиянии

Когда слияние не происходит автоматически, git оставляет индекс и рабочее дерево в особом состоянии которое дает всю информацию необходимую чтобы разрешить конфликт.

Файлы с конфликтами отмечаются в индексе особым образом, так что до тех пор пока вы не исправите проблему и не обновите индекс, выполненить git commit не удастся:

Также, git status перечислит эти файлы как «unmerged», а файлы с конфликтами будут иметь добавленные отметки, и выглядеть след.образом:

Все что вам нужно это отредактировать файлы, исправить конфликты, а затем выполнить

Заметьте что сообщение-описание коммита уже будет содержить некоторую информацию о слиянии. Обычно вы можете оставить это сообщение-описание, а также можете добавить свои дополнительные комментарии, если пожелаете.

Теперь вы знаете все что вам нужно чтобы выполнить простое слияние. Но git предоставляет больше информации, чтобы помочь разрешить конфликты:

Отменить слияние

Если в процессе слияния и исправления конфликтов,вы застряли и решили сдаться и выбросить все к черту, то вы всегда можете вернуться с состоянию pre-merge (такое же как и было до того как вы запустили слияние) выполнив

Если вы уже выполнили коммит после слияния, и вы хотите сбросить его,

Как бы там ни было, последняя команда может быть опасной в некоторых случаях —никогда не сбрасывайте коммит если этот коммит возможно уже был использован в слиянии в другую ветку, если вы это сделаете то это запутает последующие слияния.

fast-forwarding слияния

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

Однако в некоторых случаях когда активная ветка не отклонилась от другой — и каждый коммит в активной ветке уже содержится в другой — то git просто выполняет «fast forward»; голова активной ветки перемещается вперед и указывается на голову сливаемой ветки, без создания каких-либо новых коммитов.

3 ответа

Лучший ответ

Метод грубой силы заключается в форсировании общего корня — поскольку вы пытаетесь перебазировать корни без истории содержимого, сделайте одноразовый пустой коммит и скажите git, что он является родителем историй, которые вы объединяете:

6

jthill
24 Мар 2017 в 21:58

Когда завершается неудачно при слиянии, он не прерывает перебазирование, поэтому у вас есть возможность вмешаться вручную.

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

В идеале, у Git был бы способ справиться с этим без ручного вмешательства.

10

vossad01
24 Мар 2017 в 22:06

В документации git-rebase говорится, что не нужно объединять и .

Но даже без он все равно не работает с .

Часть проблемы в том, что является прямым предком . Ваше тестовое репо выглядит так:

из равен 5. равен 3. Ваша команда эквивалентна:

5 является прямым предком 3, так что команда не имеет особого смысла. Если это вообще сработает, то будет что-то странное.

Это неуместное использование rebase. Rebase превращает параллельные истории в линейные истории, в основном притворяясь, что один набор изменений был сделан поверх другого набора все время. Это хорошо для таких вещей, как поддержание ветвей функций в актуальном состоянии, пока они работают, ведение бухгалтерии и рецензирование проще, если у вас нет группы промежуточных коммитов слияния, которые ничего не делают, кроме обновления ветки. Это просто шум для любого, кто читает код и фиксирует историю в будущем.

Но когда у вас есть две действительно расходящиеся истории, лучше оставить их как расходящиеся истории. Объединение их рассказывает правильную историю: веб-сайт и документы разрабатывались отдельно, но затем объединялись в одно целое.

Вы можете посмотреть их отдельно в топологическом порядке (8, 7, 6, 5, 3, 1, 4, 2), используя , или вы можете посмотреть их с чередованием в порядке дат (8, 7, 6, 5 , 4, 3, 2, 1), по умолчанию. Визуализатор истории, такой как или GitX, покажет оба ордера одновременно.

Перебрасывание одного поверх другого говорит неправду: мы работали над сайтом, а затем мы работали над документацией, а затем в какой-то момент (момент, который вам нужно найти), и по какой-то причине мы работали над сайтом и документация вместе.

Это теряет жизненно важную информацию и делает загадкой, почему некоторые изменения были сделаны более трудными в будущем.

Сделайте слияние, это правильная вещь.

1

Schwern
24 Мар 2017 в 22:33

.gitignore

В файле перечисляются шаблоны файлов/папок, которые git должен игнорировать. Пример :

Игнорируем имена файлов:

npm-debug.log
.DS_Store

Звезда означает фрагмент в имени:

*.launch

Указываем диапозон (для игнорирования файлов):

project-201*

— означает ровно 1 произвольный символ (который обязателен):

.ло?

Если нужно игнорировать директорию, то ставим в конце имени директории , при этом будет игнорироваться любая директория, а не только корневая:

build/

Игнорируем от корня проекта:

/build/

При этом данные конструкции работают одинаково:

/build/key
build/key

используются, чтобы обозначить произвольное количество фрагментов пути:

**/*.txt

используется, когда требуется игнорировать все кроме чего-либо конкретного:

/folder/*
!folder/package.json

Проверяем состояние файла в :

git check-ignore -v folder/package.json
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: