Восстановление репозитория 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потому что это много, но вот где это становится действительно интересным, поэтому я опубликую список всего, что я сделал:

  1. У меня была проверка ветви, отличной от ветви, с ошибкой. Бег git svn reset не имеет значения remotes/origin/branchname продолжал указывать на более поздний коммит. Неудивительно, git svn fetch Ничего не сделал.

  2. Я проверил remotes/origin/branchname и побежал git svn reset снова. Это сработало: remotes/origin/branchname указал на родителя Даффа.

  3. Я побежал git svn fetch, Это абсолютно ничего не сделало: никакие коммиты не были получены и remotes/origin/branchname не двигался

  4. Я создал пару фиктивных коммитов в этой ветке в хранилище 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 в зависимости от ситуации."

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

Другие вопросы по тегам