Опасно ли git-svn dcommit после слияния с git?

Моя мотивация попробовать git-svn - это легкое слияние и ветвление. Затем я заметил, что man git-svn (1) говорит:

Running git-merge or git-pull is NOT recommended on a branch you plan to dcommit from. Subversion does not represent merges in any reasonable or useful fashion; so users using Subversion cannot see any merges you've made. Furthermore, if you merge or pull from a git branch that is a mirror of an SVN branch, dcommit may commit to the wrong branch.

Означает ли это, что я не могу создать локальную ветку из svn / trunk (или ветку), взломать, снова слить в svn / trunk, а затем выполнить dcommit? Я понимаю, что пользователи svn увидят тот же беспорядок, который всегда был в svn pre 1.5.x, но есть ли другие недостатки? Это последнее предложение меня тоже беспокоит. Люди обычно делают такие вещи?

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

Alexander Kitaev 02.09.2011 16:09

@AlexanderKitaev: git-svn документы изменились с тех пор, и, кроме того, есть опция --mergeinfo=<mergeinfo>, которая может передавать информацию о слиянии в SVN. Не знаю, как его использовать.

Mr_and_Mrs_D 12.02.2014 01:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
135
2
36 526
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

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

У меня есть «главная» ветка, которую я использую для отслеживания svn-сервера. Это единственная ветка, из которой я делаю коммит. Если я делаю какую-то работу, я создаю тематическую ветку и работаю над ней. Когда я хочу зафиксировать это, я делаю следующее:

  1. Закрепите все в ветке темы
  2. git svn rebase (разрешите любые конфликты между вашей работой и svn)
  3. мастер проверки git
  4. git svn rebase (это делает следующим шагом слияние с быстрой перемоткой вперед, см. комментарии Аарона ниже)
  5. git merge topic_branch
  6. разрешить любые конфликты слияния (на данный момент их не должно быть)
  7. git svn dcommit

У меня также есть другая ситуация, когда мне нужно поддерживать некоторые локальные изменения (для отладки), которые никогда не должны переноситься в svn. Для этого у меня есть указанная выше основная ветка, а также ветка под названием «работа», в которой я обычно работаю. Тематические ветки разветвляются от работы. Когда я хочу зафиксировать работу там, я проверяю мастер и использую вишневый выбор, чтобы выбрать коммиты из рабочей ветки, которые я хочу зафиксировать в svn. Это потому, что я хочу избежать фиксации трех локальных изменений. Затем я делаю фиксацию из основной ветки и все переустанавливаю.

Стоит сначала запустить git svn dcommit -n, чтобы убедиться, что вы собираетесь зафиксировать именно то, что собираетесь зафиксировать. В отличие от git, переписать историю в svn сложно!

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

Если я правильно понимаю, в git слияние git с svn в порядке, но не svn с svn? Значит, я не могу объединить мою svn / ветку с svn / trunk в git?

Knut Eldhuset 10.10.2008 12:08

Переписать историю в SVN сложно, если вы хотите сделать что-то тривиальное. В нетривиальных случаях это практически невозможно.

Aristotle Pagaltzis 10.10.2008 13:07

Jegern: Верно. Для слияния svn-to-svn я бы рекомендовал использовать для этого сам svn.

Greg Hewgill 10.10.2008 14:25

Ответ Грега Хьюджилла набрал много голосов, но я считаю, что это неверно. Слияние из topic_branch с мастером безопасно только в том случае, если это просто слияние с перемоткой вперед. Если это настоящее слияние, требующее фиксации слияния, то фиксация слияния будет потеряна при dcommit. В следующий раз, когда вы попытаетесь объединить topic_branch с мастером, git решит, что первого слияния не было, и начнется ад. См. Вопрос Почему git svn dcommit теряет историю коммитов слияния для локальных веток?

Aaron 07.07.2010 21:08

@Greg Hewgill, редактирование непонятно. Вы писали, что перебазирование «делает следующее коммитирование слиянием с перемоткой вперед». Я не знаю, что это значит, потому что слияние с быстрой перемоткой вперед не требует фиксации, но, возможно, вы имели в виду «делает следующее слияние слиянием с перемоткой вперед». Но если вы это имели в виду, это неверно. Является ли слияние topic_branch в master слиянием с перемоткой вперед или нет, зависит от того, были ли сделаны какие-либо коммиты на master с момента точки ветвления. Когда вы перебазируете мастер, это создает новые коммиты на мастере, поэтому последующее слияние обязательно нет слияние с ускоренной перемоткой вперед.

Aaron 08.07.2010 15:00

@Aaron: Да, я не знаю, о чем я там думал. Я исправил это снова, надеюсь, это имеет смысл. Одна из проблем заключается в том, что в Git так много способов делать что-то, что требуется некоторое объяснение, чтобы описать последовательность действий специфический.

Greg Hewgill 08.07.2010 23:56

Я думаю, что это утверждение «пока вы просто используете локальные ветки для себя и не пытаетесь использовать git для слияния между ветвями восходящего потока svn, все будет в порядке», на мой взгляд, вводит в заблуждение, что это невозможно и / или полезно для используйте GIT для реальных слияний SVN. ИМХО, верно и обратное, см. Ответ luntain ниже и мой @ stackoverflow.com/questions/2945842/…

inger 29.11.2010 18:54

@Greg Hewgil Вы говорите, что «следующим шагом будет быстрое слияние», но я не уверен, как это может быть, если разработка продолжается на master. Когда вы являетесь мастером git svn rebase, он может вносить новые изменения, о которых ваша тематическая ветка не знает. Таким образом, страхование вашего слияния будет чем-то, кроме быстрой перемотки вперед. Может быть, на всякий случай использовать --ff-only? Но на самом деле вы должны быть --squashing

jemmons 05.04.2011 19:26

@jemmons: если между шагами 2 и 4 нет новых коммитов Subversion, тогда шаг 5 действительно будет слиянием с перемоткой вперед. Если кто-то еще выполняет Subversion между шагами 2 и 4, затем вернитесь в ветку темы и повторите с шага 2.

Greg Hewgill 06.04.2011 00:26

Безопасный способ объединить ветки svn в git - использовать git merge --squash. Это создаст одну фиксацию и остановит вас, чтобы добавить сообщение.

Допустим, у вас есть ветка svn в теме, которая называется svn-branch.

git svn fetch
git checkout remotes/trunk -b big-merge
git merge --squash svn-branch

на этом этапе у вас есть все изменения из svn-ветки, сжатые в одну фиксацию, ожидающую в индексе

git commit

Однако, как отмечали другие, при этом теряется детализация коммитов.

Kzqai 29.01.2010 23:12

@Tchalvak: Иногда хочется именно этого. Я часто совершаю коммиты в ветке функций, а именно «исправленный беспорядок из предыдущего коммита», и эти тупики я люблю скрывать из-за хорошей репутации :-)

schoetbi 14.01.2011 13:56

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

Kzqai 15.01.2011 10:59

@schoetbi да, иногда вам нужно очистить грязную историю перед публикацией. Здесь очень помогает git rebase -i <trunk>: вы можете присоединяться / переупорядочивать / удалять и даже разделять (!) Коммиты, выборочно исправлять сообщения.

inger 16.02.2012 22:24

Переустановите локальную ветку git на основную ветку git, затем dcommit, и тогда будет похоже, что вы выполнили все эти коммиты последовательно, чтобы люди svn могли видеть это линейно, как они привыкли. Итак, если у вас есть локальная ветка под названием topic, вы могли бы сделать

git rebase master topic

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

Ответ принят как подходящий

На самом деле, я нашел даже лучший способ с опцией --no-ff в git merge. Вся эта техника сквоша, которую я использовал раньше, больше не требуется.

Мой новый рабочий процесс выглядит следующим образом:

  • У меня есть «главная» ветка, которая является единственной веткой, из которой я делаю фиксацию и которая клонирует репозиторий SVN (-s предполагает, что у вас есть стандартный макет SVN в репозитории trunk/, branches/ и tags/):

    git svn clone [-s] <svn-url>
    
  • Работаю на локальной ветке "работа" (-b создает ветку "работа")

    git checkout -b work
    
  • выполнить локальную фиксацию в «рабочую» ветку (-s для подписи вашего сообщения о фиксации). В дальнейшем я предполагаю, что вы сделали 3 локальных коммита

    ...
    (work)$> git commit -s -m "msg 1"
    ...
    (work)$> git commit -s -m "msg 2"
    ...
    (work)$> git commit -s -m "msg 3"
    

Теперь вы хотите выполнить фиксацию на сервере SVN.

  • [В конце концов] спрятать изменения, которые вы не хотите фиксировать на сервере SVN (часто вы комментировали некоторый код в основном файле только потому, что хотите ускорить компиляцию и сосредоточиться на данной функции)

    (work)$> git stash
    
  • перебазировать основную ветку с репозиторием SVN (для обновления с сервера SVN)

    (work)$> git checkout master
    (master)$> git svn rebase
    
  • вернитесь в рабочую ветку и переустановите с мастером

    (master)$> git checkout work
    (work)$> git rebase master
    
  • Убедитесь, что все в порядке, например, используя:

    (work)$> git log --graph --oneline --decorate
    
  • Теперь пришло время объединить все три коммита из ветки "work" в "master", используя эту замечательную опцию --no-ff.

    (work)$> git checkout master
    (master)$> git merge --no-ff work
    
  • Вы можете заметить статус журналов:

    (master)$> git log --graph --oneline --decorate
    * 56a779b (work, master) Merge branch 'work'
    |\  
    | * af6f7ae msg 3
    | * 8750643 msg 2
    | * 08464ae msg 1
    |/  
    * 21e20fa (git-svn) last svn commit
    
  • Теперь вы, вероятно, захотите отредактировать (amend) последнюю фиксацию для своих парней из SVN (иначе они увидят только одну фиксацию с сообщением «Объединить ветку 'работает'».

    (master)$> git commit --amend
    
  • Наконец, выполните фиксацию на сервере SVN

    (master)$> git svn dcommit
    
  • Вернитесь к работе и в конечном итоге восстановите свои спрятанные файлы:

    (master)$> git checkout work
    (work)$> git stash pop
    

Это ТОЧНО рабочий процесс, который искал git n00b. Создайте локальную ветку, чтобы исправить ошибку, сделайте что угодно, а затем отправьте ее в svn с ОДНОЙ фиксацией. Использование здесь самого высокого рейтингового ответа испортило то, что я делал - не мог git svn rebase без ошибок.

João Bragança 23.12.2010 02:31

Я тоже считаю, что "ответ" нужно поменять на этот.

Srikumar 07.01.2011 12:19

Было бы неплохо, если бы вы могли удалить свой старый ответ на этот вопрос, так как этот способ лучше. Спасибо, что добавили это!

dpb 14.01.2011 02:10

Разве это не именно то, о чем предупреждают процитированные в операторе git-svn документы? Запустив слияние с параметром --no-ff, вы явно создаете фиксацию слияния (фиксацию с двумя родителями) вместо быстрой перемотки вперед. Чтобы гарантировать, что все коммиты в ветке svn-tracking являются одиночными коммитами, все слияния должны быть либо ускоренными (--ff-only может в этом помочь), либо, если ствол изменился за вашей спиной, --squash, верно?

jemmons 06.04.2011 19:34

Это работает для одноразовой ветки, которую вы немедленно удаляете, но git svn dcommit перезаписывает переданный вами коммит git. Это означает, что вы теряете другого родителя, и теперь в вашем репозитории git нет записи о том, что вы когда-либо объединяли эту ветвь с master. Это также может привести к тому, что ваш рабочий каталог окажется в несогласованном состоянии.

rescdsk 16.11.2011 04:01

используйте git merge --no-ff work -m "commit message" вместо дополнительного шага git commit --amend

tekumara 14.06.2012 06:06

Отличное резюме того, как заставить Git и SVN хорошо играть в песочнице вместе, не заставляя Git идти домой, плача с песком в глазах ...

tatlar 25.07.2012 01:51

для меня я бы предпочел использовать "git merge --ff-only work", так как я хочу сохранить все свои коммиты, а не только последний

Moataz Elmasry 13.09.2013 14:14

Это только у меня или есть причина удалить ветку work после слияния и повторно ветвиться в конце процесса? stackoverflow.com/q/26511177/671013

Dror 30.10.2014 19:32

Ответ Грега Хьюджилла сверху небезопасен! Если какие-либо новые коммиты появились в стволе между двумя "git svn rebase", слияние не будет ускорено.

Это может быть обеспечено с помощью флага «--ff-only» для git-merge, но я обычно не запускаю «git svn rebase» в ветке, а только на нем «git rebase master» (при условии, что это только локальный ветка). Затем после этого "git merge thebranch" гарантированно переместится вперед.

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