Come posso inviare un commit specifico su un telecomando e non i commit precedenti?


Risposte:


1087

Per eseguire il push up attraverso un determinato commit, puoi scrivere:

git push <remotename> <commit SHA>:<remotebranchname>

purché <remotebranchname>esista già sul telecomando. (In caso contrario, è possibile utilizzare git push <remotename> <commit SHA>:refs/heads/<remotebranchname>per crearlo automaticamente.)

Se si desidera inviare un commit senza eseguire il push di commit precedenti, è necessario innanzitutto utilizzare git rebase -iper riordinare i commit.


66
git push <remotename> <commit SHA>:<remotebranchname>lavori. il trucco è combinarlo con git rebase -iper spostare il commit desiderato come primo commit e specificare quel commit-sha
dminer

29
un altro buon consiglio è assicurarti di copiare lo SHA del commit che vuoi spingere dopo aver fatto quel rebase -i, e non prima, come ho appena fatto :)
estan,

33
Tenere presente che ciò non riesce se il ramo remoto non esiste ancora. La creazione del ramo può essere effettuata con git push <remotename> <commit SHA>:refs/heads/<new remote branch name>. Successivamente, premi come descritto nella risposta.
Wes Oldenbeuving il

32
Ad esempio, per inviare tutto tranne l'ultimo commit con alcuni nomi standard git push origin HEAD~1:master.
rumore senza arte

3
Inoltre, se hai già inviato un SHA successivo a quel ramo remoto, dovrai forzare il push di questo. Usa la -fbandiera.
Ian Vaughan,

79

Le altre risposte mancano sulle descrizioni riordinanti.

git push <remotename> <commit SHA>:<remotebranchname>

spingerà un singolo commit, ma quel commit deve essere il PIÙ VECCHIO dei tuoi commit locali, senza push, da non confondere con il commit top, first o tip, che sono tutte descrizioni ambigue secondo me. Il commit ha bisogno del più vecchio dei tuoi commit, vale a dire il più lontano dal tuo commit più recente. Se non è il commit più vecchio, verranno inviati tutti i commit dal tuo SHA più vecchio, locale e non spinto allo SHA specificato. Per riordinare i commit utilizzare:

git rebase -i HEAD~xxx

Dopo aver riordinato il commit, puoi tranquillamente inviarlo al repository remoto.

Per riassumere, ho usato

git rebase -i HEAD~<number of commits to SHA>
git push origin <post-rebase SHA>:master

per inviare un singolo commit al mio ramo master remoto.

Riferimenti:

  1. http://blog.dennisrobinson.name/push-only-one-commit-with-git/
  2. http://blog.dennisrobinson.name/reorder-commits-with-git/

Guarda anche:

  1. git: duplica commit dopo il rebase locale seguito da pull
  2. git: Push di Single Commit, Riordino con rebase, Duplicate Commit

3
Alcune origini potrebbero non permetterlo, a quanto pare. Ad esempio con GitLab vedo "Non è consentito forzare il codice push in un ramo protetto su questo progetto". Il che è un po 'strano dal momento che non pensavo di forzare nulla, semplicemente facendo una spinta normale. Qualche idea su come farlo senza "forzare"?
Ed Avis,

1
@Ed Shoudl non è necessario forzare la spinta. Sembra che tu abbia un problema con la tua configurazione git specifica. Forse hai superato il commit HEAD remoto? Non so cosa sia un ramo protetto, sembra un problema di autorizzazione.
Samuel,

1
Samuel - avrebbe senso, ma git rebase -i mostra solo i commit locali che sono successivi alla HEAD remota, quindi non so come avrei potuto farlo.
Ed Avis,

1
Samuel - in effetti ora posso fare delle spinte parziali, quindi non so cosa sia andato storto, ma deve aver cercato di spingere un commit non derivato da HEAD remoto in un modo o nell'altro.
Ed Avis,

1
@Ed Hai detto "git rebase -i mostra solo i commit locali che sono successivi alla HEAD remota", non credo sia vero. Ho testato ed è stato in grado di reimpostare oltre il HEAD remoto.
Samuel,

25

Suggerirei di usare git rebase -i; sposta il commit che vuoi spingere in cima ai commit che hai fatto. Quindi utilizzare git logper ottenere lo SHA del commit rinnovato, verificarlo e inviarlo. Il rebase assicurerà che tutti gli altri tuoi commit siano ora figli di quello che hai spinto, quindi anche le future spinte funzioneranno bene.


3
Potresti forse dare una mossa esempio completo esp. re il git logpasso?
Drux,

4
Supponi di avere 3 commit relativamente indipendenti con i messaggi "A", "B", "C" impegnati in quell'ordine e che vuoi spingere "B". 'git rebase -i' dovrebbe farti elencare ed editore tutti e tre; sposta B in alto e salva / esci. 'git log --pretty = oneline -n3' elencherà B, A, C con gli hash prima di ogni messaggio, con B ora ultimo. 'git checkout -b temp $ hash_of_B; git push 'dovrebbe spingere B in quel punto. Probabilmente vorrai quindi 'git checkout -b master; git branch -d temp 'per tornare al tuo stato precedente, presumendo che tu fossi sul tuo ramo principale locale; sostituire se applicabile.
Walter Mundt,

1
+1 Hai mai incontrato la "collera degli dei git" dopo rebase-push-rebase? (È possibile che ciò accada anche per caso, giusto?)
Drux il

2
Se leggi attentamente la mia risposta, vedi che la spinta avviene solo dopo il rebase e il commit rinnovato viene spostato solo sopra altri commit che non sono stati ancora spinti. Una volta che un commit viene spinto, dovrebbe generalmente essere considerato impostato su pietra; lasciarlo da solo in futuro rebasing. Questa tecnica è solo per poter ordinare più modifiche locali in un buon ordinamento prima di inviarle. Se il tracciamento è stato impostato correttamente, "git rebase -i" senza altri argomenti per impostazione predefinita non mostrerà nemmeno i tuoi commit forzati, quindi è più sicuro dagli incidenti rispetto ad altri metodi.
Walter Mundt,

21

Cherry-pick funziona meglio rispetto a tutti gli altri metodi mentre si spinge un commit specifico.

Il modo per farlo è:

Crea una nuova filiale -

git branch <new-branch>

Aggiorna il tuo nuovo ramo con il tuo ramo di origine -

git fetch

git rebase

Queste azioni assicureranno che tu abbia esattamente le stesse cose della tua origine.

Scegli sha idquello che vuoi fare push -

git cherry-pick <sha id of the commit>

Puoi farlo sha idcorrendo

git log

Spingilo alla tua origine -

git push

Corri gitkper vedere che tutto sembra nello stesso modo in cui volevi.


2
L'uso git rebase -isarà la soluzione ideale come suggerito nelle soluzioni sopra. Cherry Pick deve essere utilizzato solo quando si desidera duplicare il commit.
Vinay Bhargav

13

Credo che dovresti "tornare indietro" a quel commit e poi spingerlo. Oppure è possibile cherry-pickeseguire il commit in un nuovo ramo e inviarlo al ramo sul repository remoto. Qualcosa di simile a:

git branch onecommit
git checkout onecommit
git cherry-pick 7300a6130d9447e18a931e898b64eefedea19544 # From the other branch
git push origin {branch}

9
git revert è una cattiva idea qui - crea un nuovo commit
hasen

1
@hasen: potresti quindi solo cherry-pickil commit che desideri.
Josh K,

4
sia il ritorno che la scelta della ciliegia sono cattive idee. git rebase -i è il tuo amico qui, vedi la risposta di Walter Mundt di seguito.
Nicolas C,

3
@Nicolas, perché cherry-pick è una cattiva idea?
Antoine,

3
@Antoine, in genere vuoi che il tuo ramo rimanga sincronizzato con quello che tiene traccia dell'origine. Se scegli la ciliegia, stai facendo una copia / incolla e dovrai occuparti della copia non inviata a un certo punto. Se rifai -i, fai "taglia e incolla" e mantieni il tuo ramo sincronizzato con il telecomando fino a dove vuoi che sia.
Nicolas C,

0

Puoi anche, in un'altra directory:

  • git clone [il tuo repository]
  • Sovrascrivi la directory .git nel tuo repository originale con la directory .git del repository che hai appena clonato in questo momento.
  • git add e git eseguono il commit dell'originale
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.