Git merge добавляет все коммиты или только последний коммит? - PullRequest
0 голосов
/ 24 августа 2018

Итак, я использую git merge и не понимаю, добавляет ли он все коммиты из объединенной ветви или только последний

, если, например, у меня есть ветвь A и ветвь B

  • A имеет коммит 1 2 5

  • B имеет коммит 3 4

Итак, что произойдет, еслия делаю git merge B в ветке A

и что произойдет, если я сделаю git merge A в ветке B

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

Я новичок в Git, поэтому, пожалуйста, извините

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Вы можете очень легко провести эксперимент самостоятельно (Требуется использование терминала)

Перейдите в свою любимую папку в командной строке:

Создайте пустой репо

mkdir test-repo
cd test-repo
git init

Добавить некоторый контент (Мы создадим файл, который мы будем изменять при каждом коммите)

echo 0 > file.txt
git add file.txt
git commit -m '0'

Создать ветвь A

git checkout -b A
echo 1 > file.txt; git add file.txt; git commit -m '1'
echo 2 > file.txt; git add file.txt; git commit -m '2'
echo 3 > file.txt; git add file.txt; git commit -m '3'
git log --graph --oneline --all

Создать ветвь B

git checkout master
git checkout -b B
echo 4 > file.txt; git add file.txt; git commit -m '4'
echo 5 > file.txt; git add file.txt; git commit -m '5'
git log --graph --oneline --all

Итак, в ветви A у нас есть файл с номером 3, а в B - файл с номером 5. Позволяет объединить A в B (ваша текущая ветвь B, помните)

git merge B

Вы увидите легкий конфликт для решения

cat file.txt

<<<<<<< HEAD
5
=======
3
>>>>>>> A

Исправлено и зафиксировано:

git commit
git log --graph --oneline --all

История будет выглядеть примерно так: enter image description here

Что здесь происходит, вы просто создаете новый коммит, который связывает A int B, этот коммит имеет разрешение конфликтов между двумя ветвями.И вы все еще в ветке B

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

git reset --hard HEAD~1
git log

Так что теперь давайте сделаем наоборот,перейдите к ветви A и давайте «объединить B в A».

git checkout A
git merge B

Исправьте конфликт, который выглядит довольно похожим, но не совсем

cat file.txt


<<<<<<< HEAD
3
=======
5
>>>>>>> B

Исправьте конфликт, и вы должны быть в том же состоянии, но технически нет :) Вы находитесь вветвь B

git commit
git log --graph --oneline --all 

enter image description here

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

Таким образом, объединение создает еще один коммит, чтобы связать другую историю ветки с другим (вот почемуcommit 0 не повторяется в этом примере).

Если вам нравится чистая история, где окончательная история выглядит примерно так: enter image description here

Youдолжен играть с rebase.Но это выходит за рамки этого вопроса.

Если вы хотите создать только один коммит из ветви для добавления в другую ветку, вы можете squash и rebase

Git isчто-то легче, когда вы учитесь на практике.Проверяйте свой git log часто.Узнайте, как использовать git reflog, чтобы обрести уверенность (вот почему Git великолепен) и дать шанс git rebase командам.Затем поговорите с вашей командой и определите лучший рабочий процесс.

0 голосов
/ 24 августа 2018
  1. коммиты не "перемещаются" в ветку.
  2. каждый коммит в git хранит ссылку на родительский коммит.
  3. коммиты слияния имеют 2 или более родительских коммитов (обычно это HEAD соответствующих ветвей)
  4. поскольку эти коммиты по-прежнему сохраняют свои родительские коммиты, операция слияния фактически "переносит все разные коммиты (ранее не существовавшие в текущей ветке) в текущую ветку". фактически означает, что вы «удалите» их из текущей ветви, как только удалите коммит слияния (с git reset или git revert)

напротив:

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

б. cherry-pick сделает копию всего за один коммит (последний, если вы используете имя ветви в качестве аргумента); но вы можете указать диапазон

...