Git -svn dcommiting один git commit
Учитывая, что множественные непроверенные git
фиксируют, возможно ли git-svn dcommit
выполнить только одну из этих коммитов?
например. У меня есть foo, bar и baz, но прямо сейчас я хочу, чтобы в конечном итоге в репозитории svn появился бар. Возможно ли это?
Ответы
Ответ 1
У меня есть один вид хрустящего ответа. Вы можете создать новую ветку с отсутствием foo, bar и baz, а затем cherry-pick
bar для новой ветки, а затем git-svn dcommit
, которая ответит и удалит ее, когда закончите. Тем не менее, это не очень элегантно.
Итак, предполагая, что foo, bar и baz находятся в ветке x, а master не имеет ни одного из них.
git branch y master
git checkout y
git cherry-pick <sha1 of bar>
git svn dcommit
git checkout x
git svn rebase
git branch -d y
Если у хозяина есть эти коммиты, вы можете reset голову, которую предлагает Sizzler.
Ответ 2
(Предполагается, что ваша работа находится на master
.)
Во-первых, измените порядок последних трех коммитов, чтобы bar
был первым.
git rebase -i HEAD~3
Редактор появится примерно так:
pick 498e4f4 foo
pick 71547ae bar
pick abf09c6 baz
# Rebase 4d3fe72..abf09c6 onto 4d3fe72
#
# ...
Замените их в редакторе, который появляется, чтобы bar
появился первым.
pick 71547ae bar
pick 498e4f4 foo
pick abf09c6 baz
# Rebase 4d3fe72..abf09c6 onto 4d3fe72
#
# ...
Git будет вращаться в течение нескольких секунд и отрывать подтверждение:
Successfully rebased and updated refs/heads/master.
Теперь вы можете временно вернуться к фиксации bar
(HEAD~2
означает, что две команды возвращаются из HEAD
) и dcommit:
git checkout HEAD~2
git svn dcommit
Если вы параноик, как я, вы можете сделать git svn dcommit -n
сначала, чтобы убедиться, что вы совершаете только то, что хотите.
Теперь вернитесь к master
:
git checkout master
Последний бит должен быть переупорядочен, так что master
синхронизируется с svn:
git svn rebase
Это немного нечеткое для меня, почему это требуется, но я предполагаю, что dcommitting в отдельном состоянии HEAD имеет к этому какое-то отношение.
Ответ 3
git svn dcommit не может выборочно фиксировать бар. если вы непосредственно совершили foo, bar и baz на своей основной ветке, тогда вам нужно сделать следующее, чтобы получить только бар в svn.
Предположим, что bar commit sha - это что-то вроде 13abc...
и git log master показывает все ваши 3 коммиты foo, bar и baz.
ветка wip теперь имеет foo, bar и baz
-
reset мастер-голова до фиксации до любого из foo, bar или baz. вы можете сделать это с помощью git reset (прочтите руководство, различия между жесткими, мягкими и смешанными параметрами влияют на незафиксированные изменения в вашей рабочей дерево)
git reset --hard (COMMIT-ID до foo, bar, baz)
(или)
git reset --hard HEAD ~ 3 (верните 3 версии)
теперь ваша мастер-ветвь не имеет ни одного foo, bar или baz. проверьте с помощью git log.
-
Теперь вы можете черри выбрать только те коммиты, которые вы хотите dcommit, чтобы svn из ветки wip в master. поэтому, чтобы получить бар
git вишня-pick wip 13abc (sha bar commit)
мастер получает только фиксацию бара.
- теперь git svn dcommit должен нажимать только клавишу.
Предлагаемое будущее использование
Итак, для git -svn предпочтительнее не совершать фиксации непосредственно на главной ветке, которая отслеживает удаленный svn. выполняйте свою работу над локальными веткими и выборочно сходите, чтобы овладеть до dcommiting.
Ответ 4
Я только хочу совершить несколько коммитов моей ветки. Например.
A-----B-----C------D
^ ^
| |
svn/trunk trunk
Если я хочу зафиксировать B
и C
, но не D
, я создаю новую ветку, сделаю svn dcommit
, вернусь к trunk
и удалю ветку.
Пока я на ветке trunk
, я делаю
git checkout -b temp `C`
git svn info // just to check that branch temp is properly connected to svn
git svn dcommit
git checkout trunk
git branch -D temp
ИЗМЕНИТЬ
Как сказал Стефан:
С дополнительной 'git svn rebase' это сработало для меня.
Это необходимо, потому что коммиты, привязанные к svn, будут переписаны. git-svn
добавляет сообщение git-svn-id
в сообщение фиксации, и поэтому хеш-код фиксации, даже если содержание фиксации одинаково. Но поскольку содержимое одного и того же, rebase не вызывает конфликтов.
PS: Я также часто опускаю новую ветку и только вычитал. Например.
git checkout --detach C
git svn dcommit
git checkout trunk
git svn rebase