Есть ли способ объединить две ветви без потери файлов и изменений? - PullRequest
0 голосов
/ 20 марта 2019

есть ли способ объединить две ветви без потери файлов и изменений?

У меня такая ситуация:
Ветка A содержит:

  • файл A (отличается от файла A из ветви B)
  • файл B (отличается от файла B из ветви B)

Ветка B содержит:

  • файл A
  • файл B
  • файлC

Теперь я хочу объединить ветвь A с веткой B, проблема в том, что когда я пытаюсь это сделать, все изменения из ветки B игнорируются, даже файл C удаляется.Как я могу сделать это без потери изменений из ветви A, а также из ветви B?Потому что git не показывал мне никаких конфликтов между этими файлами.

Ответы [ 2 ]

0 голосов
/ 20 марта 2019

Ваша фундаментальная ошибка заключается в том, что git merge имеет два входа - вашу ветвь и некоторую другую ветвь. Это не тот случай: он имеет три входа, ни один из которых не является ответвлением . Три входа: совершает .

Давайте нарисуем некоторые коммиты и имена ветвей, которые помнят последний коммит, который идет в каждой ветке:

          o--o--A   <-- branch-A
         /
...--o--*
         \
          o--o--B   <-- branch-B

Если вы запустите git checkout branch-A, вы получите commit A, потому что имя branch-A указывает на этот конкретный коммит. То же самое относится к git checkout branch-B. Сравнение этих двух коммитов показывает некоторые различия в некоторых файлах. Это имеет значение, но не так уж много .

От коммита A мы можем работать в обратном направлении (как и git log) до безымянного коммита, затем другого безымянного коммита, затем коммита *. С B мы можем сделать то же самое, и если мы сделаем это, мы также получим commit *. Поэтому коммит * - база слияния предложенной операции слияния - это лучший общий коммит , лучший коммит, который находится на обеих ветвях.

Способ слияния заключается в запуске two git diff s:

  • Первый сравнивает снимок в коммите * с снимком в коммите A, чтобы увидеть, что кто-то изменил на этом пути.
  • Второй сравнивает снимок в коммите * со снимком в коммите B, чтобы увидеть, что кто-то изменил на этом пути.

Затем Git объединяет эти два набора изменений. Полученные объединенные изменения, если они не конфликтуют, применяются к снимку из коммита *.

Объединив два набора изменений и применив их правильно - или так правильно, как Git может определить - Git продолжает делать новый коммит, в основном обычным способом. Новая фиксация заставляет любую ветвь, которую вы извлекли (одно из двух имен ветки A или B), обновляться, чтобы указывать на новую фиксацию. Новый коммит имеет двух родителей, которые являются коммитами A и B. Итак, конечный результат:

          o--o--A
         /       \
...--o--*         M   <-- branch-<whichever> (HEAD)
         \       /
          o--o--B

с любым именем ветви не не двигалось, все еще указывая на A или B.

Снимок в новом коммите слияния M соответствует *, плюс оба набора изменений . Если A не изменил что-то с *, но B изменил что-то с *, вы получите B изменения. Если A что-то изменил, а B - нет, вы получите A изменения. Если оба изменили одинаковые строки одного и того же файла, , то вы получите конфликт слияния - и вы должны закончить задание слияния и сделать M самостоятельно .

(Если файл C находится в одном из A и B, но не в другом, файл C должен быть либо создан, так как - *, либо удален, поскольку - * Объединение объединяет создание нового файла с ничем путем взятия нового файла. Он объединяет удаление старых файлов с ничем путем удаления старого файла Учитывая ваше текстовое описание, C должен завершиться в *, что дает вам действие удалить файл .)

0 голосов
/ 20 марта 2019

Вы можете выполнить слияние, проверив ветвь B и не имея рабочих изменений, а затем выполните следующую команду git merge A.

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

CONFLICT (content): Merge conflict in [file A] или в файле B. Или оба.

Исправьте конфликты вручную, затем выполните git add [file A], чтобы продолжить слияние. Когда все конфликты кода разрешены и код компилируется, выполните git commit, чтобы завершить коммит слияния в ветке B.

...