Удалите родительский коммит, тем самым сделав его первоначальным коммитом

Примечание. Я знаю, что это переписывает историю, изменит все хэши и запутает всех остальных.


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

Как это сделать? (Я мог бы, конечно, отредактировать объект коммита, но тогда коммиты не указывали бы друг на друга.) Кроме того, я хотел бы сделать это на новой ветке (имеется в виду, что теперь есть две истории: исходная , и еще один, где фиксация является начальной фиксацией.)


person PyRulez    schedule 28.01.2016    source источник
comment
Если вы хотите полностью отключить коммит от его родителя и не иметь истории, почему бы просто не скопировать все файлы и не создать новый репозиторий?   -  person elixenide    schedule 28.01.2016
comment
@EdCottrell, потому что я хочу, чтобы его дети/потомки выжили.   -  person PyRulez    schedule 28.01.2016
comment
Итак, я не уверен на 100%, что это поможет - я больше парень Mercurial, чем git, но см. stackoverflow.com/questions/9844082/   -  person elixenide    schedule 28.01.2016
comment
@EdCottrell Нет, извини, приятель. Это перепрошивка истории.   -  person PyRulez    schedule 28.01.2016
comment
Чтобы уточнить - вы хотите, чтобы выбранный вами коммит был корнем (теряя все «до» этого)? В противном случае я не уверен, что вы спрашиваете.   -  person M.M    schedule 28.01.2016
comment
Если это действительно то, о чем вы спрашиваете, см. здесь. Предполагая, что после рассматриваемой фиксации нет слияний, конечно, и в этом случае вам не повезло   -  person M.M    schedule 28.01.2016
comment
также см. здесь, как использовать git replace, чтобы скрыть историю, если ваша мотивация такова вы не особенно заботитесь о старых коммитах и ​​не хотите, чтобы они загромождали вывод инструментов   -  person M.M    schedule 28.01.2016


Ответы (3)


git rebase -i ГОЛОВА~

Затем в редакторе, который появляется после вышеуказанной команды терминала, измените начало дочерней строки фиксации с выбора на сквош. Или «p» и «s» соответственно. Запишите файл и выйдите из редактора, который появился после указанной выше команды.

Изменить: предполагая, что две фиксации являются самыми последними. Если нет, то вы можете проверить дочерний хэш коммита и вместо этого использовать git rebase -i HEAD~2

Edit2: или вы можете просто git rebase -i parentcommithash, и верхняя часть списка должна быть родителем

person bgarcia    schedule 28.01.2016

git checkout -b newbranch
git rev-parse @ >.git/info/grafts   # any equivalent for @ will work e.g. HEAD or newbranch
git filter-branch
rm .git/info/grafts

(изменить: добавлено rm. Без этого это репо по-прежнему будет отражать привитую родословную для исходного коммита)

person jthill    schedule 28.01.2016
comment
спасибо за добавление rm , я был сбит с толку, глядя на историю после перезаписи коммита :) - person shreyas; 28.01.2016

Допустим, вы хотите, чтобы ваш новый первоначальный коммит был 123456.

git checkout -b new_master
git filter-branch --commit-filter '
  if git merge-base --is-ancestor 123456 $GIT_COMMIT ;
  then
   git commit-tree "$@";
  else
   skip_commit "$@";
  fi' HEAD

Todo (для всех): Изменить в объяснении

person PyRulez    schedule 28.01.2016