1
votes

Comment pousser un commit spécifique vers un repo, sans inclure les commits précédents, sans l'historique?

J'essaie de pousser un commit spécifique vers un dépôt en amont , qui est le même que celui sur lequel je travaille, mais avec de légères modifications.

Le dépôt actuel est en avance sur celui en amont et je souhaite appliquer certaines des modifications que j'ai apportées au dépôt actuel, mais pas tous.

Quand je fais quelque chose comme

git push upstream :

Cela fonctionne, mais cela pousse également tous les autres commits effectués entre le dernier commit dans mon dépôt amont et le commit que je pousse.

Je souhaite cependant appliquer uniquement les modifications apportées à cette validation , et non les modifications effectuées avant cette validation.

Comment éviter leur intégration?

MISE À JOUR Les réponses données expliquent comment pousser un commit spécifique (avec tout l'historique devant lui), mais je veux pousser juste le commit spécifique sans l'historique derrière lui .


1 commentaires

essayez de vérifier une branche en amont, choisissez le commit que vous souhaitez pousser. make --set-upstream vers la branche dans laquelle vous voulez pousser le commit ou faire un PR


3 Réponses :


0
votes

Vous devez d'abord faire en sorte que votre histoire locale ressemble à ce que vous voulez voir pousser. Ensuite, vous pouvez pousser.

Une des milliers de façons possibles est d'utiliser git rebase, par exemple:

git tag usefultagname

vous montrera une fenêtre d'édition avec une liste de commits vous avez fait qui ne sont pas encore poussés avec un petit document sur ce qu'il faut faire. Laissez simplement les lignes avec les validations que vous voulez pousser intactes, mais supprimez les lignes que vous ne voulez pas pousser. Puis enregistrez et quittez. J'espère que vous n'aurez pas de conflits (fichiers modifiés dans les commits que vous voulez et dans ceux que vous ne voulez pas).

Ensuite, vous pouvez pousser.

(Si vous voulez conserver localement les commits que vous ne voulez pas pousser (pour une raison quelconque), commencez par créer, par exemple, une balise:

git rebase -i upstream/remotebranchname


5 commentaires

Oui, mais dans ce cas, disons, je reviens à ce commit, je vais aussi pousser toute l'histoire derrière ce commit. Et je veux pousser UNIQUEMENT les modifications apportées à ce commit.


Non, si vous rebasez sur la branche distante, vous obtiendrez exactement les commits que vous sélectionnez.


Git repoussera toujours la partie manquante complète de l'historique. La seule façon de ne pas pousser les commits est de les supprimer de l'historique local avant de pousser.


ce n'est pas vrai. Vous pouvez ajuster git pour qu'il ne pousse qu'un certain commit. Par exemple, en utilisant cherry-pick


@DmitryParanyushkin: notez que git push ne transmet pas les modifications . Il pousse commits . Les commits Git ne sont pas des changesets; ce sont des instantanés et des métadonnées.



0
votes

Afin d'éviter de pousser certaines modifications, votre branche doit être définie sur le dernier commit que vous voudriez inclure. Dans votre cas, la meilleure option serait de créer une nouvelle branche , de la réinitialiser au dernier commit que vous souhaitez inclure, de sélectionner le commit que vous souhaitez pousser et de le pousser.

git checkout -b new-branch # make sure to do this **while you're on** the upstream branch
git pull <remote> <upstream branch> #just to be sure you're right where the remote upstream branch is
git cherry-pick <commit hash>
git push <remote> new-branch


3 commentaires

Hum ... Je ne comprends pas vraiment ... Donc, pendant que je suis dans mon dépôt actuel , je dois créer une nouvelle branche, puis obtenir le commit et le pousser dans le en amont ? Mais pourquoi dans votre exemple il est écrit remote ?


De plus, lorsque je fais cela, parce que mon commit est un ancêtre, il ne revient pas à ce commit, donc je télécharge essentiellement toutes les modifications actuelles.


@DmitryParanyushkin upstream que vous mentionnez doit être le nom d'une télécommande particulière. Si je comprends bien, vous souhaitez appliquer un commit spécifique par-dessus une branche amont sans avoir les commits que vous avez poussés vers une autre branche qui est la vôtre, est-ce correct? Sinon, pourriez-vous s'il vous plaît faire un organigramme des commits afin qu'il soit plus facile à comprendre?



0
votes

Ceci est interdit.

Un commit Git inclut son ou ses ID de hachage parent . Si, en tant qu'expéditeur, vous proposez le commit H (pour certains ID de hachage H ) à un autre Git, cet autre Git n'a pas besoin d'accepter H tant que il a aussi le parent de H (ou les parents, s'il s'agit d'un commit de fusion). Vous devez donc proposer le (s) parent (s) de H . Il n'a pas besoin d'accepter ce commit tant qu'il n'a pas ce (ou ces) parent (s) de commit à son tour, et ainsi de suite.

Pour le dire autrement, l'ID d'un commit est son hachage, mais avoir ce commit dans un référentiel implique que vous avez aussi tous ses ancêtres . 1 Par conséquent, la seule façon de travailler avec un tel commit est d'avoir tous ses ancêtres.

À ce stade, vous pouvez faire une copie de ce commit - par exemple via git cherry-pick - pour obtenir un commit différent avec un identifiant de hachage différent , un parent différent et toutes les autres différences que vous pourriez souhaiter en raison de ce parent différent. 2 Vous pouvez alors fournir ce différent commit (par son ID de hachage différent) vers un autre référentiel Git. Si cet autre dépôt Git a le parent de cette nouvelle copie, ils ne demanderont pas de commits supplémentaires au préalable.


1 Cette règle est assouplie dans les clones peu profonds, et des travaux sont en cours pour l'assouplir d'autres manières, mais elle est toujours au moins requise en principe. Un commit qui n'a pas son ascendance est au moins suspect; ce pourrait être un faux; l'intégrité de la chaîne est déterminée en suivant la chaîne jusqu'à la racine.

2 En particulier, vous voudrez probablement également un instantané différent . N'oubliez pas que les commits Git contiennent des instantanés - une copie complète de chaque fichier - plutôt que des ensembles de modifications. Donc, si votre copie H ' du commit H doit être appliquée au commit B , ce que vous voulez dans H' n'est pas l'instantané qui se trouve dans H , mais plutôt l'instantané qui résulte de la modification H en un ensemble de modifications , puis appliquer cet ensemble de modifications à valider B , tout en tenant compte de toute autre différence entre le parent de H et B également. Pour changer H en un ensemble de modifications, nous (ou Git) comparerons son instantané à celui de son parent.

(La commande git cherry-pick est un outil pour créer H ' à partir de H -et-son-parent tout en ayant commit < code> B extrait.)


0 commentaires