2009-08-10 9 views
25

Compte tenu de plusieurs validations git non bloquées, est-il possible de git-svn dcommit seulement un de ces commits?git-svn dcommiter un seul commit git

par exemple. J'ai commit foo, bar, et baz, mais maintenant je veux juste que le bar finisse dans le svn repo. Est-ce possible?

+0

Commit foo, bar et baz déjà dans la branche master qui suit le repo svn? – Pradeep

+0

Dans mon cas, non. Mais c'est bon de montrer comment faire les deux façons. – baudtack

Répondre

4

J'ai une sorte de réponse croustillante. Vous pouvez créer une nouvelle branche sans foo, bar et baz, puis cherry-pick barre à la nouvelle branche, puis git-svn dcommit cette branche et supprimez-le lorsque vous avez terminé. Cela ne semble pas très élégant cependant. Donc, en supposant que foo, bar et baz sont dans la branche x et que master n'en a aucune.

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

Si maître n'avoir ces commits vous pouvez réinitialiser la tête comme le suggère Sizzler. Git svn dcommit ne peut pas commettre sélectivement la barre de validation.

+0

Je désengagerais la branche principale et garderais ces autres bits séparés. Vous pouvez peut-être utiliser la cachette ici aussi. –

+0

@Ben Je ne suis pas sûr de savoir comment décentraliser la branche principale aiderait. J'ai déjà foo et bar et baz comme commit en git. Ils ne sont tout simplement pas encore arrivés au svn repo. Si je fais une nouvelle branche et que je sélectionne ceux que je veux, alors je ne reçois que ces commits. – baudtack

+0

Si vous travaillez sur le maître et que vous voulez toujours le faire comme ceci, vous pouvez utiliser: "git checkout trunk -by" - si cela ne fonctionne pas pour vous, regardez dans les docs Git svn et rechercher les options de mise en page – haggi

13

Si vous avez directement engagé foo, bar et baz sur votre branche master, alors vous devez faire ce qui suit pour obtenir seulement la barre dans svn.

On suppose bar Engageons sha est quelque chose comme 13abc ...

et maître git log montre tous vos 3 engage foo, bar et baz.

  • vous devez créer une branche de maître

    branche git wip

la branche WIP a maintenant foo, bar et baz

  • réinitialiser la tête du maître à un commit avant tout foo, bar ou baz. vous pouvez le faire en utilisant git reset (lire le manuel, les différences entre les options dures, douces et mixtes affecte les modifications non validées dans votre arbre de travail)

    git reset --hard (COMMIT-ID avant foo, bar, baz)

    (ou)

    git reset HEAD --hard ~ 3 (retour 3 révisions)

maintenant votre branche principale n'a pas de foo, bar ou baz. vérifier avec git log.

  • maintenant vous pouvez choisir seulement les commits que vous voulez convertir en svn de la branche wip en master. pour ainsi obtenir un bar

    git écrémer wip 13abc (sha de bar commit)

le maître ne reçoit que la barre engage seul.

  • maintenant git svn dcommit devrait pousser la barre seul.

suggéré l'utilisation future

Donc, pour git-svn il est préférable de ne pas faire directement sur la branche engage maître qui est suivi à distance svn. faites votre travail sur les succursales locales et fusionnez sélectivement pour maîtriser avant de débuter.

+0

I J'ai entendu des opinions divergentes sur l'endroit où la fusion devrait avoir lieu. La façon dont je le fais maintenant, est la branche et le dcommit, puis le maître rebase. Je garde maître comme branche de suivi canonique et fais mon travail dans d'autres branches. Je pousse alors ces changements jusqu'à svn et les fais descendre dans le maître. C'est comme ça qu'on m'a suggéré de le faire dans #git sur freenode. Je l'ai fait comme vous le suggérez auparavant, mais c'est une étape supplémentaire car vous devez fusionner les changements en master au lieu de simplement les pousser sur svn et de les redescendre avec rebase. – baudtack

26

(Ce qui suit suppose que votre travail est sur master.)

En premier lieu, réorganiser vos trois derniers commits afin que bar est le premier.

git rebase -i HEAD~3 

Un éditeur pop avec quelque chose comme ceci:

pick 498e4f4 foo 
pick 71547ae bar 
pick abf09c6 baz 

# Rebase 4d3fe72..abf09c6 onto 4d3fe72 
# 
# ... 

Réorganiser les dans l'éditeur qui apparaît pour que bar vient en premier.

pick 71547ae bar 
pick 498e4f4 foo 
pick abf09c6 baz 

# Rebase 4d3fe72..abf09c6 onto 4d3fe72 
# 
# ... 

Git tournera pendant quelques secondes et roter une confirmation:

Successfully rebased and updated refs/heads/master. 

Maintenant, vous pouvez rouler temporairement revenir à la bar commettras (HEAD~2 signifie deux commits retour de HEAD) et dcommit il:

git checkout HEAD~2 
git svn dcommit 

Si vous êtes paranoïaque comme moi, vous pouvez faire git svn dcommit -n d'abord être sûr que vous êtes seulement avoir commis ce tu veux.

maintenant revenir en arrière à master:

git checkout master 

Le dernier bit est de rebasage de sorte que master synchronise avec svn:

git svn rebase 

Il me est un peu floue pour expliquer pourquoi cela est nécessaire, mais Je suppose que dcommitting dans un état détaché de la tête a quelque chose à voir avec cela.

+0

Je trouve cette réponse plus facile à comprendre que les autres. Parfait cas d'utilisation pour 'git svn dcommit -n' ou' --dry-run'. – hdl

1

Je ne veux parfois que commettre quelques commits de ma branche. Par exemple.

A-----B-----C------D 
^    ^
|     | 
svn/trunk   trunk 

Si je veux engager B et C mais pas D je crée une nouvelle branche, faire svn dcommit, revenez à trunk et supprimer la branche.

Pendant que je suis sur la branche trunk je

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 

EDIT

Comme Stefan a commenté:

Avec un 'git svn rebase' supplémentaire, il a bien fonctionné pour moi .

Ceci est nécessaire car les validations validées par svn seront réécrites. git-svn ajoute le git-svn-id au message de validation et, par conséquent, le hachage de validation est modifié même si le contenu de la validation est le même. Mais puisque le contenu est le même, le rebasement ne provoquera pas de conflits.

PS: Je souvent omettent la nouvelle branche et juste votre commande individuelle. Par exemple.

git checkout --detach C 
git svn dcommit 
git checkout trunk 
git svn rebase 
+1

Avec un 'git svn rebase' supplémentaire ça a bien fonctionné pour moi. – Stefan

+0

@Stefan oui c'est vrai. Je le pardonne et mettra à jour ma réponse. La rebase est nécessaire car les validations seront réécrites par git-svn. Il ajoute le 'git-svn-id' au message de validation. –

Questions connexes