Да, я знаю, что я должен был просто разветкить проект с самого начала, но вот в какой ситуации я сейчас.:)
У меня есть локальный репозиторий git, содержащий мой блог, на моем локальном компьютере, который имеет несколько месяцев истории фиксации. Первоначально я просто загрузил файлы из этого репо:
http://github.com/mojombo/mojombo.github.com и продолжался с моим локальным репо git, причем первая фиксация выглядела как последние файлы из mojombo repo.
Теперь я хотел бы разветкить проект, и мои локальные репозитории git будут переигрываться поверх него, так что похоже, что я начинал проект с самого начала, а затем нажимал его
назад к моему раздвоенному verson mojombo repo, на моей учетной записи github:
Я хотел бы знать, какие команды git, я могу использовать именно это, чтобы сделать это?
Ответ 2
Короче:
Одним из решений является использование трансплантатов для подключения истории, а затем используйте git filter-branch
, чтобы переписать историю в соответствии с этими графтами, а затем дополнительно merge strong > .
Обратите внимание, что решение для повторного изменения ваших изменений (ваших коммитов) поверх новой разработки в оригинальном репозитории (решение rebase) - еще одно жизнеспособное решение.
Более длинная версия:
Предположим, что вы либо помните, либо можете найти, исследуя исходный код и/или используя команды git, ревизию репозитория, который вы загрузили моментальный снимок, и начали локальную разработку. Позвольте называть эту версию START или A.
Предположим, что локальная несвязанная история находится в клоне исходного репозитория. Это означает, что локальная отключенная разработка находится в том же хранилище, что и полная история проекта. Предположим, что локальные ветки находятся в ветке "master" (и для простоты есть только одна ветка).
Если вы не выбрали проект в репозиторий с локальной отключенной работой, вы можете сделать это с помощью
$ git remote add origin git://github.com/mojombo/mojombo.github.com.git
$ git fetch origin
Теперь история выглядит следующим образом:
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
x---y---*---*---* <--- master (your local disconnected history)
Конец с именем A на приведенной выше диаграмме - это транзакция START, которую вы загрузили в качестве моментального снимка, и отключили локальную разработку.
Есть две возможности: у вас есть моментальный снимок "A" в качестве первоначальной фиксации "x", или первая фиксация, которую вы сделали, была связана с вашими локальными изменениями.
В первом случае (вы выполнили исходное начальное состояние, например, как "Первичная фиксация" или "Импорт" ), вы хотите, чтобы связанная история выглядела так:
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
\
\-y---*---*---* <--- master (your local disconnected history)
то есть. ваш первый оригинал зафиксировать "y" , чтобы иметь "A" в качестве родителя.
Во втором случае (вы совершили с вашими изменениями) вы хотели бы, чтобы связанная история выглядела так:
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
\
\-x---y---*---*---* <--- master (your local disconnected history)
то есть. вы хотите сначала зафиксировать "x", чтобы иметь "A" в качестве родителя.
В обоих случаях вы хотите найти полный идентификатор SHA-1 для фиксации "A" и полные идентификаторы SHA-1 для коммитов "x" и "y" .
Вы можете найти SHA-1 для фиксации "A" (если вы этого еще не знаете) с git rev-parse:
$ git rev-parse A # or A^{commit}
437b1b20df4b356c9342dac8d38849f24ef44f27
(может потребоваться суффикс "^ {commit}", чтобы убедиться, что вы обнаружили commit SHA-1, что важно, если вы, например, знаете "A" по его тегу, например "v0.99"; случай не требуется, поскольку в рассматриваемом репозитории не используются теги).
Вы можете найти SHA-1 коммитов 'x' и 'y', используя git rev-list (предполагая, что разработка была выполнена на сервере master):
$ git rev-list --topo-order master | tail -2
8bc9a0c769ac1df7820f2dbf8f7b7d64835e3c68
e83c5163316f89bfbde7d9ab23ca2e25604af290
( "| tail -2
" здесь, чтобы найти последние два коммита в сгенерированном списке, вам не нужно использовать его, если у вас его нет).
Примечание: во всех приведенных выше примерах полный SHA-1 является примерами и не должен использоваться как есть!
Назовите фиксацию, в которой вы хотите иметь "A" (или "START" ) в качестве родителя, как FIRST (это будет "x" или "y" , в зависимости от вашего случая, как указано выше). использовать механизм трансплантатов для подключения истории:
$ echo "<SHA-1 of FIRST> <SHA-1 of START>" > .git/info/grafts
Затем вы должны проверить, есть ли у вас правильно подключенная (объединенная) история, с помощью графического браузера истории, такого как gitk или QGit, или GitX - вы находитесь на MacOS X или даже "git log --graph
" или "git show-branch
", например:
$ gitk master origin/master # or --all
(где gitk здесь только как пример, если вы используете "git show branch
", вы не всегда можете использовать опцию "--all
" ).
Наконец, мы, вероятно, захотим сделать эти изменения постоянными, так что любой, кто выберет из нашего репозитория, также связал историю. Мы можем сделать это, используя git ветвь фильтра:
$ git filter-branch master
У вас будет оригинальная (отключенная) история в 'refs/original/master'.
Теперь вы можете удалить файл графтов:
$ rm .git/info/grafts
Теперь вы сможете объединиться в новой разработке для оригинального репозитория:
$ git merge origin/master
Настройка конфигурации каждой ветки, чтобы было достаточно просто "git pull", когда на ветке "master", чтобы вытащить (объединить) изменения в исходном (al) репозитории, остается как упражнение для читателя...: -)
Примечание. решение приведет к следующей истории (при условии, что у нас есть случай, когда первый comit был простым импортом):
*---*---*---*---*---A---*---*---*---* <--- origin/master (remote-tracking branch)
\
\-y'---*'---*'---*' <--- master (your local disconnected history)
(где y'
означает, что commit y
был изменен: он должен быть о том же наборе изменений, но он отличается как commit).