Subversion rebase?

je trouve cela plus facile de fusionner les branches et moins de conflits:

copier le tronc vers une nouvelle branche, le fusionner avec la/les branche (s) de fonctionnalité. Quand les choses sont faites, fusionnez la nouvelle branche avec le tronc. Cette technique est tout à fait comme le Mercurial et git rebasing.

j'avais l'habitude de fusionner n'importe quel changement du tronc vers la branche/s. Mais plus tard quand j'ai fusionné la branche de fonctionnalité retour à trunk, certains des trucs de trunk serait fusionné de nouveau à la tronc, qui a causé beaucoup de conflits. Il y a un choix de réintégrer fusion, mais il ne semble pas fonctionner pour moi.

est-ce que quelqu'un fait du rebasing subversion similiar? J'ai commencé à faire ça récemment, et je n'ai pas vu d'effets secondaires. Serait-ce la cause de tout imprévues problèmes?

34
demandé sur jpierson 2010-07-05 08:12:37

5 réponses

D'une manière générale, le rebasage est l'action d'incorporer des changements en amont dans une branche de fonctionnalité, avant de fusionner la branche de fonctionnalité à nouveau dans la branche en amont.

dans le git, le processus est encore plus sophistiqué, parce que les changements qui ont été faits depuis que la branche a été créée sont d'abord décollés et tamponnés, les changements en amont sont appliqués, puis les changements tamponnés sont appliqués. La prise en main ici est la fusion du tronc dans une branche de fonctionnalité n'est pas un rebase dans git termes, il ya plus à elle. L'approche git présente un certain nombre d'avantages, mais ne peut pas être implémentée de manière très claire dans svn puisque toutes les propagations doivent être stockées sur le serveur (svn n'est pas distribué), cependant il à faire en svn.

Un "svn rebase" (le git façon) pourrait ressembler à quelque chose comme ceci

  1. svn cp trunk feature
  2. s'engage à fonctionnalité & tronc
  3. svn cp trunk feature-rebase
  4. svn co feature-rebase
  5. cd feature-rebase
  6. svn merge feature
  7. svn commit
  8. svn rm feature
  9. svn mv feature-rebase feature
  10. (retour sur les longs-rebase WC) svn switch feature

puis éventuellement sur une copie de travail de trunk,svn merge --reintegrate feature

vous voyez la différence entre la simple fusion de trunk et la branche feature? Vous commencez avec la dernière en amont, trunk dans cet exemple, puis fusionnez les changements de fonction sur.

Imaginer certains s'engage sur le tronc pourrait provenir d'une fusion, d'une autre branche dans le tronc, donc je ne suis pas du tout en préconisant de commettre directement sur le tronc.

23
répondu quickshiftin 2013-09-30 02:09:22

j'aimerais avoir un truc intelligent pour vous dire comment réaliser le rebasage en SVN mais j'ai toujours évité le rafraîchissement manuel d'une branche avec des changements de tronc en SVN principalement en raison des complications nécessitant la cueillette manuelle de cerises que jdehaan mentionne.

ce que je fais généralement à la place est de suivre la pratique de fusionner les changements d'une branche au tronc, de supprimer la branche, puis de recréer la branche à partir du tronc. Cela me permet de rafraîchir/rebaser ma branche de fonctionnalité mais avec l'effet secondaire parfois malheureux que tout changement antérieur de cette branche font maintenant partie du tronc. Pour cette raison, je ne suis que cette pratique quand une branche est stable et utilisable point mais je souhaite toujours continuer à travailler sur cette fonctionnalité afin de compléter certaines plus grand objectif.

ce que je préférerais c'est que rafraîchir une branche en fusionnant les changements de tronc dans une branche ne cause pas de fusions subséquentes de réintégration à partir de cette branche pour tirer ceux rebasés révisions au cours du processus. Il devrait être possible de le faire en se basant sur les propriétés merge-info mais selon ce que jdehaan déclare et ce que j'ai craint c'est que faire ceci nécessite encore une sélection.

notez qu'une mise en œuvre correcte du rebasage devrait également pouvoir prendre en considération les exemples de coffrage d'escalier où une branche est faite à partir d'une autre branche.

mise à Jour: selon la documentation de Subversion, il apparaît que lors de l'utilisation du --réintégrer option que Subversion devrait être en mesure de réintégrer correctement le travail effectué dans une branche d'une manière qui tient compte de toute fusion de rafraîchissements possible qui pourrait avoir été faite pour apporter des changements de base dans la branche. Bien sûr, cela est techniquement un peu différent de la relocalisation, mais je pense que c'est assez similaire dans l'utilisation qu'il pourrait être désignée comme année de référence.

7
répondu jpierson 2011-02-09 20:16:12

Dans mon entreprise, nous utilisons l'approche suivante:

  1. pour chaque tâche NK-X$dans le bug tracker, nous avons une branche séparée des branches/NK-$X
  2. nous commençons à travailler sur une tâche par svn cp tronc branches/NK-$X
  3. nous ne commettons jamais de modifications directement dans le tronc. Pour chaque mise à jour programmée UPDNK-$X, nous avons une branche/UPDNK-$X. Nous La créons avec svn cp trunk branches/UPDNK-$x juste avant la mise à jour.
  4. lorsque la tâche NK - $ X est programmée pour un update UPDNK - $Y nous fusionnons branches/NK - $X inot UPDNK - $Y. C'est cd UPDNK-$Y; svn merge-R start:HEAD branches/NK-$X
  5. lorsque UPDNK-$y est prêt, nous le fusionnons avec trunk. C'est-à-dire cd trunk;svn merge-r start:HEAD branches/UPDNK - $y

S'il arrive que la tâche NK - $X dure plus d'un cycle d'itération, et a donc besoin d'être rafraîchie, nous ne fusionnons jamais, jamais, le tronc en NK - $X. Nous avons une règle qui veut que vous ne commettiez à votre branche que les choses que vous avez écrites vous-même, ce qui rend tout plus facile. Au lieu de nous faire:

cd NK-$X
svn log
//let L = the number of the last changeset to this branch changeset
//let F = the number of the first changeset to this branch
svn rm branches/NK-$X 
svn cp trunk branches/NK-$X 
svn up
svn merge -r F:L branches/NK-$X@L 
svn ci -m 'refereshed'

de cette façon, chaque fois que vous regardez le changelog de branches/NK-$X vous ne voyez que les changements réellement effectués par le développeur.

mise à Jour: Puisque le workflow ci-dessus peut être automatisé, j'ai commencé un projet sur github:svn rebase.

4
répondu qbolec 2013-07-28 08:19:13

j'utilise cette approche:

avec rebasing vous devez prendre soin de ne pas prendre les révisions rebasées lorsque vous fusionnez à nouveau. Quand il s'agit de fusionner, faites une sélection: sélectionnez seulement les révisions sur la branche de fonctionnalité qui implémentent quelque chose de nouveau, pas les changements de rebasement. Ensuite, il devrait fonctionner correctement. Commentaire: Je ne me souviens pas avoir utilisé la branche réintégration pour quelque chose. Je pense qu'il est destiné à des cas d'utilisation très simple.

Dans votre nouveau approche, il n'est pas clair de la description comment vous manipulez le rebase du tronc à vos branches de fonctionnalité si vous avez besoin. Voulez-vous interdire complètement la relocalisation? Comme brancher dans svn est une opération bon marché ce pourrait être une option aussi.

0
répondu jdehaan 2010-07-05 05:19:35

j'utilise un script qui fait un git comme rebase pour svn:

#!/bin/bash

set_safe()
{
    set -eo pipefail
}

validate_number()
(
    if (! [ "" -eq "" ] 2>/dev/null ) then
    {
        echo " is not a number"
        return 1
    }
    fi
)

get_line()
(
    set_safe
    #head -n "" | tail -n 1
    sed -n "p;$((+1))q"
)

split_trim()
(
    set_safe
    tr "" '\n' | sed -e 's/^\s*//;' -e 's/\s*$//'
)

run_svn()
(
    set +x
    #echo "svn $*" 1>&2
    svn --non-interactive --password "$svn_password" "$@"
)

rebase()
(
    set_safe

    url=""
    cur=""
    end=""

    validate_number "$cur"
    if ([ -z "$end" ] || [ "$end" = "HEAD" ]) then
    {
        end="$(run_svn info "$url" | grep "Last Changed Rev" | cut -d' ' -f4)"
        echo "end: $end"
    }
    else
    {
        validate_number "$end";
    }
    fi

    while (true) do
    {
        log="$(run_svn log "$url" -l1 -r "$cur:HEAD")"
        meta="$(echo -n "$log" | get_line 2 | split_trim '|')"
        next="$(echo -n "$meta" | get_line 1 | tail -c +2)"
        author="$(echo -n "$meta" | get_line 2)"
        date="$(echo -n "$meta" | get_line 3 | awk '{print , , }')"
        msg="$(echo -n "$log" | tail -n +4 | head -n -1)"
        cur=$next

        if ([ -z $cur ] || [ $cur -gt $end ]) then { break; } fi

        echo "$msg" > .msg

        echo "Merging revision $cur:"
        echo "========"
        cat .msg
        echo "========"

        run_svn merge "$url" -c $cur
        run_svn commit -F .msg
        rm -f .msg
        run_svn update

        echo "Success"
        echo

        cur=$(($cur + 1))
    }
    done
)

if ([ -z "" ]) then
{
    echo "Usage:"
    echo "    svn-rebase.sh <url> <begin revision> [end revision]"
    exit
}
fi

echo -n "svn password: "
read -s svn_password
echo

rebase "" "" ""
err=$?
if ([ $err -ne 0 ]) then { echo "rebase failed: $err"; } fi
exit $err

il fusionne les révisions des autres branches une par une.

0
répondu anton_rh 2018-05-08 11:22:53