Vous pourriez fusionner votre branche amont avec votre dev
la branche, avec un conducteur de fusion personnalisé "keepTheirs" :
Voir " " git merge -s theirs
"nécessaire - mais je sais qu'il n'existe pas ".
Dans votre cas, un seul .gitattributes
serait nécessaire, et un keepTheirs
script comme :
mv -f $3 $2
exit 0
git merge --strategy=theirs
Simulation n° 1
Il s'agit d'une fusion, avec l'amont comme premier parent.
Jefromi mentionne (dans les commentaires) le merge -s ours
en fusionnant votre travail sur l'amont (ou sur une branche temporaire partant de l'amont), puis en faisant avancer rapidement votre branche vers le résultat de cette fusion :
git checkout -b tmp origin/upstream
git merge -s ours downstream # ignoring all changes from downstream
git checkout downstream
git merge tmp # fast-forward to tmp HEAD
git branch -D tmp # deleting tmp
Cela présente l'avantage d'enregistrer l'ancêtre en amont en tant que premier parent, de sorte que l'élément merge signifie "absorber cette branche thématique périmée" plutôt que "détruire cette branche thématique et la remplacer par l'amont". .
(Edit 2011) :
Ce flux de travail a été rapporté dans ce billet de blog de l'OP :
Pourquoi est-ce que j'en veux encore ?
Tant que mon repo n'avait rien à voir avec la version publique, tout allait bien, mais comme je veux maintenant pouvoir collaborer sur le WIP avec d'autres membres de l'équipe et des contributeurs extérieurs, je veux m'assurer que mes branches publiques sont fiables pour que d'autres puissent s'en inspirer, c'est-à-dire qu'il n'y a plus de rebase et de reset sur les choses que j'ai poussées sur la sauvegarde distante, puisqu'elles sont maintenant sur GitHub et publiques.
Il me reste donc à savoir comment je dois procéder.
99% du temps, ma copie ira dans le master amont, donc je veux travailler mon master et pousser dans l'amont la plupart du temps.
Mais de temps en temps, ce que j'ai en tête wip
sera invalidée par ce qui se passe en amont et j'abandonnerai une partie de mon wip
.
À ce moment-là, je veux ramener mon master en synchronisation avec upstream, mais sans détruire aucun point de commit sur mon master poussé publiquement. C'est à dire que je veux une fusion avec upstream qui se termine avec les changements qui rendent ma copie identique à upstream. .
Et c'est ce que git merge --strategy=theirs
devrait faire.
git merge --strategy=theirs
Simulation n°2
Il s'agit d'une fusion, avec le nôtre comme premier parent.
(proposé par jcwenger )
git checkout -b tmp upstream
git merge -s ours thebranch # ignoring all changes from downstream
git checkout downstream
git merge --squash tmp # apply changes from tmp but not as merge.
git rev-parse upstream > .git/MERGE_HEAD #record upstream 2nd merge head
git commit -m "rebaselined thebranch from upstream" # make the commit.
git branch -D tmp # deleting tmp
git merge --strategy=theirs
Simulation n°3
Ce site mentions d'articles de blog :
git merge -s ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git/COMMIT_EDITMSG --amend
parfois, vous avez envie de le faire, et pas parce que vous avez des "conneries" dans votre histoire, mais peut-être parce que vous voulez changer la ligne de base pour le développement dans un dépôt public où le rebasage doit être évité. .
git merge --strategy=theirs
Simulation n°4
(même article de blog)
Alternativement, si vous voulez garder les branches locales amont en avance rapide, un compromis potentiel est de travailler avec la compréhension que pour sid/unstable, la branche amont peut de temps en temps être réinitialisée/rebasée (basée sur des événements qui sont finalement hors de votre contrôle du côté du projet amont).
Ce n'est pas un gros problème et travailler avec cette hypothèse signifie qu'il est facile de garder la branche locale en amont dans un état où elle ne prend que les mises à jour en avance rapide.
git branch -m upstream-unstable upstream-unstable-save
git branch upstream-unstable upstream-remote/master
git merge -s ours upstream-unstable
git diff --binary ref-to-be-merged | git apply -R --index --exclude="debian/*"
git commit -F .git/COMMIT_EDITMSG --amend
git merge --strategy=theirs
Simulation n°5
(proposé par Barak A. Pearlmutter ):
git checkout MINE
git merge --no-commit -s ours HERS
git rm -rf .
git checkout HERS -- .
git checkout MINE -- debian # or whatever, as appropriate
git gui # edit commit message & click commit button
git merge --strategy=theirs
Simulation n°6
(proposé par le même Michael Gebetsroither ):
Michael Gebetsroither est intervenu, affirmant que je "trichais" ;) et a proposé une autre solution avec des commandes de plomberie de niveau inférieur :
(ce ne serait pas git si ce n'était pas possible avec des commandes git uniquement, tout ce qui est dans git avec diff/patch/apply n'est pas une vraie solution ;).
# get the contents of another branch
git read-tree -u --reset <ID>
# selectivly merge subdirectories
# e.g superseed upstream source with that from another branch
git merge -s ours --no-commit other_upstream
git read-tree --reset -u other_upstream # or use --prefix=foo/
git checkout HEAD -- debian/
git checkout HEAD -- .gitignore
git commit -m 'superseed upstream source' -a
git merge --strategy=theirs
Simulation n°7
Les étapes nécessaires peuvent être décrites comme suit :
- Remplacez votre arbre de travail en amont
- Appliquez les changements à l'index
- Ajouter l'amont comme deuxième parent
- Engagez-vous
La commande git read-tree
écrase l'index avec un arbre différent, ce qui permet d'atteindre l'objectif de l'opération. deuxième étape et dispose de drapeaux pour mettre à jour l'arbre de travail, ce qui permet d'atteindre l'objectif suivant première étape . Lors d'un commit, git utilise le SHA1 dans .git/MERGE_HEAD comme second parent, nous pouvons donc le remplir pour créer un commit de fusion. Par conséquent, ceci peut être accompli avec :
git read-tree -u --reset upstream # update files and stage changes
git rev-parse upstream > .git/MERGE_HEAD # setup merge commit
git commit -m "Merge branch 'upstream' into mine" # commit
12 votes
Si vous ne vous souciez pas de préserver les changements, pourquoi ne pas simplement supprimer et recréer la branche ? "L'histoire du projet" n'a pas besoin d'être sacrée. Git est un outil pour aider les développeurs à communiquer. Si ces changements n'aident pas à cela, jetez-les.
0 votes
+100 @wnoise - surtout si les changements ont déjà été fusionnés.
13 votes
Je tiens à préserver l'histoire à la fois parce qu'elle est publiée à des fins de collaboration et parce que je pourrais avoir envie d'y revenir. Pourquoi s'embêter à utiliser le contrôle de révision si vous ne gardez que la dernière version ?
1 votes
C'est un argument subjectif, mais pour moi, le but d'un VCS n'est pas d'enregistrer chaque détail de l'histoire du projet, mais seulement d'enregistrer les changements du contenu (commits), de vous permettre de manipuler l'arbre/historique basé sur ces commits (branching, merging, rebasing, resetting, etc), et de vous permettre de visualiser des rapports basés sur l'histoire (diffs, logs, blame, etc). git est le "stupide traqueur de contenu" - je le vois comme un outil pour gérer le code source, pas une machine à remonter le temps.
9 votes
Comme vous l'avez dit, c'est subjectif. Ce qui m'importe, c'est de pouvoir examiner les approches abandonnées et de voir quelles décisions ont été prises à un moment donné dans le passé. Et je tiens à ce que ma décision d'abandonner quelque chose ne détruise pas les points de convergence que d'autres pourraient pointer du doigt.