"Невозможно определить информацию SVN вверх по истории работы дерева"
Я пытаюсь использовать зеркало GCC git, зарегистрированное здесь.
Некоторое время назад я клонировал репозиторий 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:
-
Обновление из git miror:
$ git rebase
-
Убедитесь, что у меня есть последняя версия 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
, который, кажется, опровергает это, no?
Итак, я попробовал новый клон из git://gcc.gnu.org/git/gcc.git, и в этом репозитории git svn rebase
работает нормально. Как два репозитория, в котором оба имеют git rebase
из того же источника, имеют разные истории? Предположительно, они не могут, и разница в локальных метаданных?
Теперь я не хочу уничтожать репо, в котором я работал (хотя мог), и экспортировать патчи на другое репо, чтобы совершить поражения, имея в виду наличие git -svn в первую очередь, Итак, как я могу его восстановить?
Ответы
Ответ 1
Вы должны сделать это с помощью трансплантата. Привилегирование предназначено для использования для хранения устаревших репозиториев - это мое понимание. Он позволяет вам вручную сообщить git, что некоторые ref имеют общий родительский элемент.
Как упоминалось в комментариях, может быть более простое решение. Это будет работать, если все остальное не удалось.
Вы вытащите текущее репо git (либо с помощью git, либо git -svn) и добавьте старый git -svn repo в качестве удаленного. Они не будут связаны, поэтому gitk будет выглядеть так:
![unrelated ancestry]()
У меня был инцидент на работе, где у нас были некоторые копии файловой системы вместо SVN-копии, поэтому некоторые из моих имен ветвей ссылаются на это. Надеюсь, все это имеет смысл. Довольно повезло, что у меня просто все эти образы и история. Каковы шансы!? Вероятно, довольно хорошо, git -svn легко путать.
![naming branches]()
Отредактирована копировальная ветвь с копией. Graft_ref - это место, где это встретилось. Они добавили кучу файлов, изменили свойства, а затем изменили некоторые файлы. Это был немного беспорядок.
Общая идея состоит в том, чтобы получить индекс исходного источника, но содержимое файла соответствует модификациям. Итак, мы начинаем в ветки ref, затем reset смешиваем, чтобы получить индекс.
$ 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 это не большая проблема, потому что вы просто фиксируете изменения, а затем извлекаете исходный код снова как чистую копию.
Ответ 2
Это довольно распространенный сценарий. Я также столкнулся с этим при попытке синхронизировать мои новые репозитории Git с моим старым хранилищем данных с поддержкой SVN.
Секрет заключается в том, чтобы SVN соответствовал рабочей ветки мастера в Git. Общими командами для этого являются, как вы сказали, git svn rebase
(для размотки изменений и синхронизации с SVN) и git reset --hard
(чтобы выполнить жесткий откат предыдущей ревизии, когда ваш внутренний индекс находится в противоречивом состоянии), Для меня потребовалось много усилий, чтобы искоренить эту процедуру. (Возьмите резервную копию, прежде чем выполнять любую из них.)
Причина, по которой это происходит, заключается в том, что Git становится глубоко запутанным, когда вы управляете двумя или более историями изменений одновременно с одной и той же рабочей ветвью, которая по умолчанию должна быть HEAD
. Если что-то изменится в восходящем SVN-репозитории и истории изменений нисходящего потока, которые Git не может смириться, он теряет свое место и выдает ошибку, указанную выше.
Эта проблема дополнительно адресована здесь. Как уже упоминалось в главном ответе, вы хотите исключить возможность обновления вашей версии Git и исправить исправления, которые они рекомендовали.
Ответ 3
Простейшая вещь, которая может работать, - запустить git svn fetch
. Если вы повторно присоедините существующий репозиторий git к svn, вы получите эту ошибку без уважительной причины, когда вы git svn rebase
. Основная проблема заключается в том, что git -svn делает предположения о состоянии вашего репо, которое не всегда выполняется, если вы не начали с чистого svn-клона.
Следующий параметр - резервное копирование master git branch master-bkp
. Затем запустите git reset --hard <way-back>
. Затем запустите git svn rebase
.
Только в том случае, если вы работаете с репо git, которое вы никоим образом не можете присоединить обратно к svn, вы можете попробовать трансплантацию. Прививка - умная и сложная, но возможная. Это также трудно сделать правильно, легко ввернуть и очень трудоемко. Не рекомендуется в качестве первого варианта.