В Git, как я могу сделать новый коммит на ветке с деревом, равным дереву из другого коммита - PullRequest
0 голосов
/ 15 июня 2019

У меня есть ситуация, когда у меня

...--x--y--z   master

...--a--b--c  someOtherBranch

Я бы хотел сделать новый коммит в ветке master, который просто меняет дерево файлов, чтобы оно выглядело как дерево someOtherBranch. Я хочу попасть в состояние

...--x--y--z--c1 master

...--a--b--c  someOtherBranch

, где commit c1 имеет дерево файлов, которое выглядит так же, как дерево c. (Что, вероятно, означает, что это точно такой же объект файлового дерева.)

Как я могу это сделать?

Я знаю, что это создаст потенциально большой и нежелательный разрыв между z и c1.

1 Ответ

2 голосов
/ 16 июня 2019

Не совсем понятно , почему вы хотите это сделать (обычные причины покрываются git merge -s ours, что делает фиксацию merge вместо фиксации с одним родителем), но это легко сделать, , используя либо git merge --squash -s ours, затем git commit, либо , используя git commit-tree. Редактировать : -s ours от мастера сохранит неправильное дерево (z вместо c). можно использовать, но если вам нужен коммит merge .См. Раздел ниже.

(Все приведенные ниже команды предполагают, что вы находитесь на master сейчас.)

Чтобы использовать git commit-tree, вы должны предоставить несколько дополнительных аргументов, которые требуют дополнительной настройки: *Например, 1026 *

hash=$(git commit-tree -p HEAD -F /tmp/commit-msg someOtherBranch^{tree})

, с сообщением о фиксации, хранящимся в файле /tmp/commit-msg.Полученный в результате хеш-идентификатор представляет собой новый объект фиксации, который еще не находится ни в одной ветви, но теперь его легко «переместить вперед-слияние» в:

git merge --ff-only $hash

или git reset в:

git reset --hard $hash

Вы также можете, как заметил Джон Шакмейстер , использовать git checkout для наложения индекса другого рабочего дерева и рабочего дерева на текущий.Вы должны git rm все сначала, если у вас есть файл с именем README, а у них нет README, например, README.md.

Или вы можете использовать git read-treeсделать это, как мне кажется, проще:

git read-tree -m -u someOtherBranch; git commit

(здесь не нужно ^{tree}, так как git read-tree разрешит коммит в дерево сам по себе).

Если вы действительно хотите объединение после всех

Трюк дерева чтения (или удаления и извлечения) также можно использовать после установки истинного объединения с помощью git merge -s ours.То есть:

git merge -s ours someOtherBranch
git read-tree -m -u someOtherBranch
git commit

подготовит к объединению, которое сохранит z, затем заменит индекс и рабочее дерево на значения из c, затем сделает новый коммит c1, дерево которого соответствуетc вместо z:

...--x--y--z--c1   <-- master
             /
...--a--b---c   <-- someOtherBranch
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...