Восстановление репозитория git-svn после изменения исторической версии Subversion
Я использую git-svn, чтобы сохранить клон общего хранилища Subversion. Недавно кто-то отредактировал сообщение коммита ревизии (а-ля этот вопрос ТАК) после того, как я git svn fetch
редактировал эту ревизию. Как я могу исправить свой клон Git, чтобы получить правильное сообщение о коммите?
Я ожидал git svn reset
с последующим git svn fetch
чтобы повторно загрузить этот коммит и обновить вещи, оставив мне только необходимость исправить мои локальные ветви, но на самом деле это ничего не делает; git svn fetch
не перечитывает коммиты, к которым я возвращаюсь.
(Да, я думаю, что изменение сообщения коммита было плохой идеей, но я не могу это контролировать.)
Обновление: я попробовал процесс, который предложил Sleske (на самом деле, я попробовал это, прежде чем задавать вопрос, но я просто попробовал еще раз на всякий случай), но безуспешно. Я получаю вывод, как показано ниже:
me_and@centos ~/code ((358a2dd...)) Fri 16 Jan 15:31:27
$ git svn reset -p 55102
r55094 = 25d126219f7eeddfc7d0842704c7efcc0443dd70 (refs/remotes/origin/branchname)
me_and@centos ~/code ((358a2dd...)) Fri 16 Jan 15:33:06
$ git svn fetch
me_and@centos ~/code ((358a2dd...)) Fri 16 Jan 15:33:08
$
Там нет выхода из git svn fetch
(или есть, если были коммиты с тех пор, как я в последний раз запускал их, но это просто выборка новых коммитов, а не повторная загрузка старых), и, в частности, нет rereading
сообщение как в примере Слеське.
В случае, если это актуально, я использую Git v2.0.4.
Обновление 2: слегка отредактирован .git/config
ниже:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[svn-remote "svn"]
url = http://server/repos/repo
fetch = trunk:refs/remotes/origin/trunk
branches = branches/*:refs/remotes/origin/*
tags = tags/v10/*:refs/remotes/origin/tags/*
tags = tags/v11/*:refs/remotes/origin/tags/*
tags = tags/v12/*:refs/remotes/origin/tags/*
tags = tags/v13/*:refs/remotes/origin/tags/*
Я не буду публиковать полный вывод git branch -avv
потому что это много, но вот где это становится действительно интересным, поэтому я опубликую список всего, что я сделал:
У меня была проверка ветви, отличной от ветви, с ошибкой. Бег
git svn reset
не имеет значенияremotes/origin/branchname
продолжал указывать на более поздний коммит. Неудивительно,git svn fetch
Ничего не сделал.Я проверил
remotes/origin/branchname
и побежалgit svn reset
снова. Это сработало:remotes/origin/branchname
указал на родителя Даффа.Я побежал
git svn fetch
, Это абсолютно ничего не сделало: никакие коммиты не были получены иremotes/origin/branchname
не двигалсяЯ создал пару фиктивных коммитов в этой ветке в хранилище Subversion (один добавил пустой файл, другой снова удалил его), затем запустил
git svn fetch again
,Вот где это становится действительно странным: Дафф коммит не был обновлен. Вместо этого выборка началась с коммита, где я добавил фиктивный файл, и сообщил о "несоответствии индекса" в процессе.
git show
на коммите, в который был добавлен фиктивный файл, он показывает все различия между коммитом, на который я сбросил, и фиктивным коммитом.Сейчас работает
git log --graph --decorate --pretty=oneline --abbrev-commit HEAD origin/branchname
выглядит так:* 7b12bbc (origin/branchname) Remove dummy file * 730c2ab Add dummy file # But `git show 730c2ab` includes the diffs between b89af06 and 93920f9 as well | * 93920f9 (HEAD) Uninteresting commit | * 91c7163 Uninteresting commit | * ce51022 Commit with the changed commit message |/ * b89af06 Uninteresting commit
Обратите внимание, что, кроме
HEAD
, теперь нет ничего, указывающего на некоторые коммиты в этой ветке.
Я быстро прихожу к выводу, что, по крайней мере, некоторые из этих действий просто ошибка в git svn
, Конечно, то, что я видел в пункте 4 выше, совсем не должно происходить, по крайней мере, по моему пониманию.
2 ответа
git svn reset <revision-number>
работает, но вы должны указать номер ревизии, который предшествует нарушающей фиксации, а затем повторно сделать git svn fetch
, Допустим, измененный коммит R.100, вам нужно git svn reset 99
тогда делай git svn fetch
Только для того, чтобы заново получить новый измененный коммит.
По вашему случаю 730c2ab
содержащий раздавленный b89af06
в 93920f9
:
* 7b12bbc (origin/branchname) Remove dummy file
* 730c2ab Add dummy file # But `git show 730c2ab` includes the diffs
between b89af06 and 93920f9 as well
| * 93920f9 (HEAD) Uninteresting commit
| * 91c7163 Uninteresting commit
| * ce51022 Commit with the changed commit message
|/
* b89af06 Uninteresting commit
git-svn иногда делает это на коммитах, которые изменились. Я не уверен в специфике, но я иногда сталкивался, когда рабочая копия конкретного коммита в svn изменилась с момента последней выборки, git svn будет сбрасывать изменения вместе со следующим коммитом при следующей выборке. Чтобы решить эту проблему, вы можете сбросить до предыдущего коммита, и повторно получить снова
РЕДАКТИРОВАТЬ:
Я не заметил ранее, что ce51022
уже отделен от вашей основной ветки. SVN делает ветвления по-другому, и git-svn не сможет сохранить ваши ветки git на svn. Это также приведет к сжатому коммиту, когда вы выполните git svn dcommit или git svn fetch/rebase
git svn reset
это действительно правильный способ сделать это. Предполагая, что редакция SVN 4711 была изменена, выполняются следующие шаги:
1) Отменить измененную версию SVN (и все после нее):
$ git svn reset -p 4711
r1 = 18614es3df44c30da07 (refs/remotes/git-svn)
2) Получить измененную ревизию:
$ git svn fetch
rereading 18614es3df44c30da07
A trunk/a
r4711 = 8dfb7d0758dbbc1d06004 (refs/remotes/git-svn)
A trunk/b
r4712 = e7337af3743e48c90ef3fa09906378b95997314c (refs/remotes/git-svn)
[...]
3) Теперь данные git-svn восстановлены. Вы должны все еще восстановить свои местные отделения. Например, если мастер отслеживает соединительную линию SVN, выполните:
git rebase remotes/git-svn
(где "remotes/git-svn" - это ветка удаленного отслеживания, созданная git svn
- может иметь другое имя).
Это хорошо объяснено на странице руководства git svn, в разделе подкоманды reset.
Если вы столкнулись с той же проблемой, что и я, это может быть вызвано примечанием в этом справочном документе об обновлении ветки-maxrev.
https://git-scm.com/docs/git-svn
"Обратите внимание, что git-svn отслеживает наивысшую ревизию, в которой появилась ветка или тег. Если после выборки подмножество веток или тегов изменяется, то $GIT_DIR/svn/.metadata необходимо отредактировать вручную, чтобы удалить (или сбросить).) ветки-maxRev и / или теги-maxRev в зависимости от ситуации."
В моем случае история веток изменилась, и сброс не был достаточно умен, чтобы перенастроить его между ветвями, чтобы пересматривать ревизии, но вместо этого использовал самый высокий оборот другой ветки.