Ошибка Git Svn dcommit - перезапустить фиксацию

На прошлой неделе я внес ряд изменений в свой местный филиал, прежде чем уехать из города на выходные. Сегодня утром я хотел зафиксировать все эти изменения в репозитории Svn компании, но у меня возник конфликт слияния в одном файле:

Конфликт слияния во время фиксации: вероятно, ваш файл или каталог build.properties.sample устарели: ресурс версии не соответствует ресурсу в транзакции. Либо запрошенный ресурс версии устарел (необходимо обновить), либо ресурс запрошенной версии новее, чем корень транзакции (перезапустите фиксацию).

Я не совсем уверен, почему я получаю это, но перед попыткой dcommit я выполнил git svn rebase. Это "перезаписало" мои коммиты. Чтобы исправить это, я выполнил git reset --hard HEAD @ {1}. Теперь моя рабочая копия оказалась там, где я ожидал, но я не знаю, как обойти конфликт слияния; на самом деле я не могу найти никакого конфликта, который нужно разрешить.

Любые мысли будут оценены.

РЕДАКТИРОВАТЬ: Просто хотел указать, что работаю локально. У меня есть локальная ветка для магистрали, которая ссылается на svn / trunk (удаленная ветка). Вся моя работа была проделана на локальном стволе:

$ git branch
  maint-1.0.x
  master
  * trunk
$ git branch -r
  svn/maintenance/my-project-1.0.0
  svn/trunk

Аналогичным образом, git log в настоящее время показывает 10 коммитов на моем локальном стволе с момента последнего коммита с идентификатором Svn.

Надеюсь, это ответит на несколько вопросов.

Еще раз спасибо.


person Rob Wilkerson    schedule 10.03.2009    source источник
comment
Может быть, сначала git svn rebase (на вашем локальном стволе) позволит вам затем git svn dcommit? Но сначала сделайте резервную копию ваших данных;)   -  person VonC    schedule 10.03.2009
comment
Собственно, это то, что я сделал сначала (я все еще привык выполнять svn update перед фиксацией). Это, конечно, перезаписало мои локальные коммиты. Я использовал reflog, чтобы вернуться к предыдущей фиксации (до перебазирования), и теперь я вернулся туда, где должен был быть ... за исключением того, что я не могу выполнить фиксацию. :-)   -  person Rob Wilkerson    schedule 10.03.2009
comment
Я добавил уточнения в комментарии к своим ответам, но вы должны оставить нетронутым свой локальный ствол (вся ваша работа должна быть воспроизведена в специальной ветке разработчика). Таким образом, вы можете svn перебазировать свой ствол, синхронизируя его с удаленным стволом, а затем перенастроить этот локальный ствол в выделенную главную ветку ...   -  person VonC    schedule 10.03.2009
comment
... а затем обновите эту ветку master (или dev) своими локальными коммитами, затем svn dcommit. Я считаю, что svn dcommit не будет работать, если локальный ствол и удаленный ствол не синхронизированы, и, поскольку вы фактически работаете над ним ... он будет * оставаться не синхронизированным   -  person VonC    schedule 10.03.2009
comment
так что теперь у меня будет удаленная ветка (svn / trunk), локальная ветка (trunk) и рабочий ствол (local-trunk)? Это кажется абсурдным количеством веток, просто чтобы выполнить некоторую простую работу. Является ли такой подход «3 к 1» действительно лучшей практикой? (Я имею в виду это как честный вопрос)   -  person Rob Wilkerson    schedule 10.03.2009
comment
Не обязательно: я имел в виду это только как способ позволить вам двигаться вперед и посмотреть, были ли ваши коммиты на локальном стволе основной причиной ваших проблем. Однако настоящей причиной может быть ваше расследование и эта локальная фиксация, записанная без svn id.   -  person VonC    schedule 10.03.2009
comment
См. Также stackoverflow.com/questions/1251895/   -  person VonC    schedule 10.08.2009


Ответы (6)


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

Поэтому я бы попытался скопировать изменения, чтобы сохранить их.

Создайте локальную ветку из точки синхронизации has svn, слейте туда свои изменения. Затем отмените изменения в основной ветке, выберите, переустановите в ветку, выполните слияние из локальной ветки, исправьте любые конфликты, затем dcommit.

$ git checkout -b backup    # create a local backup branch with all your work
$ git checkout master   
$ git checkout -b backup2   # 2nd copy just to be safe
$ git checkout master
$ git reset --hard <this is the revision of the last svn-id> # clean up master to make the svn merge easier
$ git svn fetch    # this should update to the current version on the svn server
$ git rebase master backup  # may get a conflict here, fix and commit
... # after conflict is fixed and commited
$ git checkout master 
$ git merge backup --ff  # merge in your local commits
$ git svn dcommit        # push back to the svn

Дополнительную информацию можно получить здесь

Еще один ответ вам может быть интересно.

статьи о рабочем процессе git-svn

Статья

person sfossen    schedule 10.03.2009
comment
Новый пользователь git, так что помедленнее. :-) У меня есть локальная ветка, магистраль, извлеченная из удаленной ветки, svn / trunk. Работа ведется в моем локальном магистральном филиале. Есть около 12 коммитов, многие с общими файлами. Мне нужно сохранить историю коммитов, а не перестраивать ее, если это вообще возможно. - person Rob Wilkerson; 10.03.2009
comment
запустите ветку git, если у вас есть только мастер, у вас нет локальной ветки: P - person sfossen; 10.03.2009
comment
сделайте журнал git, чтобы найти последнюю точку, помеченную svn id. - person sfossen; 10.03.2009
comment
У меня есть: ›$ git branch maint-1.0.x master * trunk. Команда git log показывает 10 моих локальных коммитов с момента последнего коммита Svn другим членом команды. - person Rob Wilkerson; 10.03.2009
comment
(извините за форматирование в последнем комментарии. Я предположил, что в комментариях можно использовать также разметку) - person Rob Wilkerson; 10.03.2009
comment
Я попробовал описанные здесь шаги (замена мастера на ствол), и это не сработало. Я все еще получаю точно такую ​​же ошибку. Спасибо за вашу помощь с этим. - person Rob Wilkerson; 10.03.2009
comment
Сделайте git stash save backup-untracked перед тем, как делать git reset. Избегайте потери неотслеживаемых файлов, которые вы, возможно, захотите сохранить. - person vitaly; 07.09.2012

Благодаря большой признательности VonC и необычайному терпению Сфассена со мной решение вроде сработало. Я не знаю, как и почему, но, возможно, моя первоначальная перезагрузка не сработала. Чтобы исправить это, я снова перебазировал. Из моего местного магистрального отделения:

$ git co -b backup  # backup the commits to my local trunk
$ git co trunk      # return to the local trunk
$ git svn rebase    # rebase the trunk from the Svn server
$ git br -d backup  # delete the backup branch

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

Еще раз спасибо за все предложения и терпение с новичком.

person Rob Wilkerson    schedule 10.03.2009
comment
Да! Рад, что ты решил это! Однако я бы сохранил локальный ствол как локальное зеркало svn / trunk, не внося в него никаких изменений: поскольку ветвление и (прежде всего) слияние дешево в Git ... работа с master или локальной веткой dev, как описано в моем ответ может быть проще, когда дело доходит до dcommit - person VonC; 10.03.2009
comment
Рад, что все получилось. Однако вам нужно будет принять один из ответов, чтобы убрать его из оставшихся без ответа вопросов. - person sfossen; 10.03.2009
comment
@sfossen: Подойдет. @VonC: Я вообще не уверен, что понимаю этот путь. Похоже, у меня есть одна удаленная и две локальные ветки, и это почему-то не имеет для меня смысла. Дешево или нет, но для меня это просто перебор. Можете ли вы найти средство, чтобы изложить рассуждения? - person Rob Wilkerson; 10.03.2009
comment
@ Роб Вилкерсон: Причина, по которой локальный ствол должен быть зеркалом svn / trunk, заключается в том, чтобы у вас была стабильная / легкая для обновления / ветвления от точки. Наличие второй локальной ветки разработки магистрали упрощает слияние и резервное копирование. - person sfossen; 10.03.2009
comment
... Также, если вам нужно выполнить ветвление для особой функции, у вас уже есть подходящая точка. Я добавлю несколько статей к своему ответу. - person sfossen; 10.03.2009
comment
@Rob: Как я объясняю в stackoverflow.com/questions/16142#114384, ветка предназначена для конкретных усилий по разработке. Здесь ствол представляет собой усилие для отражения удаленного ствола. Если это становится несовместимым с текущим разработчиком (из-за сложного dcommit), необходима другая ветка. Так просто. - person VonC; 10.03.2009

Для завершения sfossen отличный ответ, вот некоторые подробности:

С git-svn вы по умолчанию получаете локальную ветку с именем master. Вы не должны работать с ним, только поддерживайте его в актуальном состоянии с помощью ветки ствола svn с помощью:

  • git svn fetch, чтобы получить историю из ветки магистрали svn в локальной ветке магистрали: эти изменения не будут применяться в вашем рабочем каталоге.
  • git checkout master, чтобы включить магистральную ветку (только если вы были в другой ветке)
  • git rebase trunk для синхронизации мастера с транком.

Однако все ваши изменения должны выполняться в другой локальной ветке (назовем ее local-devel).

  • git branch local-devel
  • git checkout local-devel

Если вам нужно срочно исправить:

  • git checkout master: переключить на master (),
  • git svn fetch && git rebase trunk, чтобы обновить его с помощью svn trunk.
  • git branch fastfix && git checkout fastfix, разветвите его
  • исправить ошибку, скомпилировать, протестировать,
  • git commit -a: локальная фиксация,
  • git svn dcommit обновить модификацию до удаленного репозитория svn
  • git checkout master && git rebase trunk: обновить мастер еще раз
  • git branch -D fastfix: удалить ветку исправлений
  • git checkout local-devel && git rebase master: вернитесь к разработчику с обновленной историей, сделанной на мастере, воспроизведенной в вашей ветке разработки

Поначалу это немного хлопотно, но гораздо удобнее, чем svn diff в файле, который нужно применить позже.

person VonC    schedule 10.03.2009
comment
Я отредактировал сообщение, чтобы указать это соответствующим образом, но я работаю в местном филиале. Однако я все еще не могу выполнить свои локальные коммиты. Git жалуется на файл, который я изменил в локальном коммите. Как я могу сказать ему, чтобы он оставался моим или, по крайней мере, видел различия? - person Rob Wilkerson; 10.03.2009
comment
Да, проблема связана с вашей работой в локальной магистральной ветке, а не в выделенной. local / trunk следует использовать только для синхронизации с удаленным транком svn. - person VonC; 10.03.2009
comment
Может быть, сначала git svn rebase (на вашем локальном стволе) позволит вам затем git svn dcommit? - person VonC; 10.03.2009
comment
Хм. Думаю, я не понимаю. Вы хотите сказать, что я должен работать непосредственно с svn / trunk моего репозитория git? Как в git co svn / trunk? - person Rob Wilkerson; 10.03.2009
comment
Я имею в виду: похоже, что ствол (над которым вы работали) и svn / trunk не синхронизированы, поэтому я предлагаю сделать git svn rebase на вашем стволе (не svn / trunk), прежде чем делать какие-либо git svn dcommit из любой ветки. Сначала синхронизируйте локальную и удаленную магистраль, затем dcommit - person VonC; 10.03.2009
comment
Приношу свои извинения за мою плоть ... разве я не этим занимался изначально? Это было первое, что я сделал, прежде чем попытаться зафиксировать. Я был на своем локальном стволе и выполнил git svn rebase, который перезаписал мои коммиты, поэтому я использовал reflog, чтобы вернуть точку, где мои коммиты были на месте. - person Rob Wilkerson; 10.03.2009
comment
Я выполнил перебазирование, потому что я так привык делать обновление svn перед тем, как делать коммит. :-) - person Rob Wilkerson; 10.03.2009
comment
Некоторое дальнейшее расследование встреч показывает, что произошла локальная фиксация, которая была отправлена, но не записана в git. Это в моем журнале svn, но в Git нет svn id. После него идут еще 9 локальных коммитов. Есть ли способ удалить это? Думаю, это должно позволить выполнить dcommit. - person Rob Wilkerson; 10.03.2009
comment
Не могли бы вы завершить свой вопрос точным выводом git log --pretty = oneline и вашего соответствующего журнала svn? - person VonC; 10.03.2009

У меня была похожая ситуация. Я выполнял git svn dcommit через плохое сетевое соединение, и в какой-то момент оно вышло из строя. Я обнаружил, что проблема была вызвана тем фактом, что в репозитории Subversion уже была новая фиксация, но локальный аналог git-svn посчитал, что фиксации еще нет в SVN. Решения из других ответов здесь не помогли, однако это помогло:

git svn reset -r <last_svn_commit_git_was_aware_of>
git svn fetch
git svn rebase

После этого я наконец смог обойтись git svn dcommit без ошибок.

person abbot    schedule 12.06.2010

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

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

Чтобы не копаться в рефлоге, вы можете иметь привычку делать быстрые теги перед тем, как делать свои git svn dcommit. После успешного выполнения dcommit удалите тег. Если тег не работает, вы можете сделать git reset --hard, а затем git merge <tag>. Повторно запустите перебазирование, чтобы вернуть историю в порядок, повторно пометьте теги и повторно зафиксируйте.

person Ryan Graham    schedule 10.03.2009
comment
Да, я все еще работаю над своим svn-мышлением, поэтому я продолжаю делать версию svn update для Git, прежде чем я сделаю dcommit. Тот факт, что он перезаписал мои коммиты, меня не удивил, когда я понял, что сделал. Однако, как только это было сделано, мне пришлось с трудом вернуться туда, где я был до перебазирования. - person Rob Wilkerson; 10.03.2009
comment
Вы не должны ни с чем бороться после перебазирования. Если да, то что-то не так. Все ваши локальные коммиты, которые не были отправлены в svn, должны оставаться там. Если вы получаете коллизии во время перебазирования, это совсем другая проблема. - person Ryan Graham; 10.03.2009
comment
Если вы еще этого не сделали, попробуйте использовать один из интерфейсов графического интерфейса для визуализации ветвления. Я предпочитаю "gitk --all". - person Ryan Graham; 10.03.2009

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

Следующий ответ от http://progit.org/book/ch8-1.html кажется самым чистым способом:

git svn rebase
git svn dcommit

Я также пробовал самый популярный вариант, описанный выше, но он не всегда работал у меня, так как git rebase не откатывает, чтобы соответствовать svn в восходящем потоке, а только вернуться к последней фиксации git.

person wildintellect    schedule 07.07.2011