«Невозможно определить восходящую информацию SVN из истории рабочего дерева» - PullRequest
14 голосов
/ 21 марта 2012

Я пытаюсь использовать зеркало git GCC, задокументированное здесь .

Некоторое время назад я клонировал репозиторий git:

git clone git://gcc.gnu.org/git/gcc.git

ДобавилGit-SVN вещи:

git svn init -Ttrunk --prefix=origin/ svn+ssh://gcc.gnu.org/svn/gcc

А потом git svn rebase и git svn dcommit и т. д. все работало хорошо.

Несколько месяцев спустя я провел различные работы по разработке локальных веток Gitи я пришел, чтобы совершить больше изменений в восходящем SVN:

  1. Обновление с git miror:

    $ git rebase
    
  2. Убедитесь, что у меня естьпоследняя версия SVN, но она не работает:

    $ git svn rebase -v
    Unable to determine upstream SVN information from working tree history
    

Каким-то образом я сломал метаданные!Как и выше, я думаю, что в какой-то момент я по ошибке сделал git svn fetch, но это не должно быть вредно, не так ли?

Итак, я попытался создать новую ветку из удаленного зеркала git:

$ git branch svntrunk remotes/origin/trunk
$ git checkout svntrunk
$ git svn rebase
Unable to determine upstream SVN information from working tree history

Веб-поиск показывает, что история веток каким-то образом отличается от SVN, но я проверил git log, и каждый коммит имеет соответствующий git-svn-id, что, кажется, опровергает это, нет?

Итак, я попробовал свежий клон из git: //gcc.gnu.org/git/gcc.git, и в этом хранилище git svn rebase работает нормально.Как два репо, в которых оба имели git rebase из одного и того же источника, могут иметь разную историю?Предположительно, они не могут, и разница в локальных метаданных?

Теперь я не хочу выбрасывать репо, в котором я работал (хотя я мог), и экспортироватьпатчи к другому репо для совершения поражений с точки зрения наличия git-svn на первом месте.Итак, как мне его починить?

Ответы [ 3 ]

12 голосов
/ 24 марта 2012

Вы должны быть в состоянии сделать это с помощью трансплантата. Как я понимаю, прививка предназначена для использования в старых хранилищах. Это позволяет вам вручную сообщить git, что у некоторого ref есть общий родительский элемент.

Как уже упоминалось в комментариях, может быть более простое решение. Это сработало бы, если бы все остальное не удалось.

Вы бы сбросили текущий репозиторий git (с помощью git или git-svn) и добавили свой старый репозиторий git-svn в качестве удаленного. Они не будут связаны, поэтому gitk будет выглядеть так:

unrelated ancestry

У меня произошел инцидент на работе, когда некоторые из нас делали копию файловой системы вместо svn-копии, поэтому некоторые из названий моих ветвей ссылаются на это. Надеюсь, это все равно имеет смысл. Очень повезло, что у меня просто есть все эти изображения и истории. Каковы шансы!? Наверное, довольно хорошо, git-svn легко запутать.

naming branches

В ветке copied_from они скопированы. Graft_ref - то, где это встретилось. Они добавили кучу файлов, изменили свойства, а затем изменили некоторые файлы. Это было немного беспорядка.

Общая идея состоит в том, чтобы получить индекс исходного источника, но содержимое файла, чтобы соответствовать изменениям. Итак, мы начинаем с ветки ref, затем сбрасываем смешанный, чтобы получить индекс.

$ git checkout graft_ref
$ git checkout -b graft_parent
$ git reset --mixed copied_from

reset mixed

Если вы не вносили изменения между двумя ветвями, когда он был сломан, вам не нужно беспокоиться об этом шаге.

$ git commit -a -m "svn_branch changes made on svn_trunk filesystem copy"

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

$ git log -1 --pretty=format:%H graft_ref
631d3c84e35de98236c3d36c08d14ec92f9c62ae
$ git log -1 --pretty=format:%H graft_parent
96a4e87b554e0030035d35ca3aac23e9d71962af
$ echo "631d3... 96a4e8..." > .git/info/grafts

grafted

Что выглядит так, как вы ожидаете. Теперь нам просто нужно перенести изменения в дерево. Мои записи для этого отсутствуют, но я думаю, что это то, что я бы сделал, хе-хе.

$ git checkout svn_branch/master
$ git checkout -b consolidate_changes

consolidated

$ git rebase master

rebase

Вы должны быть в состоянии протолкнуть эти изменения куда угодно. Хотя git не отслеживает прививки, поэтому привитая ветка (svn_branch / master и friends) снова сломается. Это фактически мертвое дерево, если вы снова не сделаете прививку. Для git-svn это не большая проблема, потому что вы просто фиксируете изменения, а затем снова перетягиваете исходный код в чистую копию.

3 голосов
/ 04 октября 2013

Самое простое, что может сработать, это запустить git svn fetch.Если вы повторно присоедините существующий репозиторий git к svn, вы получите эту ошибку без уважительной причины, когда вы git svn rebase.Основная проблема заключается в том, что git-svn делает предположения о состоянии вашего репо, которые не всегда сохраняются, если вы не начинали с чистого клона svn.

Следующая опция - резервное копирование мастера git branch master-bkp.А затем запустить git reset --hard <way-back>.Затем запустите git svn rebase.

Только если вы работаете с git-репо, которое вы никак не можете прикрепить обратно к svn обычным способом, вы можете попробовать прививание.Прививка умная и сложная, но возможная.Это также трудно сделать правильно, легко облажаться и очень много времени.Не рекомендуется в качестве первого варианта.

3 голосов
/ 24 марта 2012

Это довольно распространенный сценарий. Я тоже столкнулся с этим при попытке синхронизировать мои новые Git-репозитории с моим старым хранилищем данных с поддержкой SVN.

Секрет заключается в том, чтобы SVN соответствовал рабочей ветке master в Git. Обычные команды для этого: git svn rebase (чтобы отменить изменения и синхронизировать их с SVN) и git reset --hard (чтобы выполнить жесткий откат к предыдущей ревизии, когда ваш внутренний индекс находится в несогласованном состоянии) , Мне потребовалось немало усилий, чтобы откорректировать эту процедуру. (Сделайте резервную копию перед выполнением любого из них.)

Причина, по которой это происходит, заключается в том, что Git сильно запутался, когда вы управляете двумя или более историями изменений одновременно для одной и той же рабочей ветви, которая по умолчанию должна составлять HEAD. Если что-то изменится в исходном SVN-репозитории и последующих изменениях, которые Git не может согласовать, он теряет свое место и выдает ошибку, указанную выше.

Эта проблема дополнительно решается здесь . Как уже упоминалось в верхнем ответе, вы захотите исключить возможность обновления вашей версии git и попробовать исправления, которые они порекомендовали.

...