Invia una richiesta pull su GitHub solo per l'ultimo commit


280

Ho elaborato un progetto su Github e sto apportando con successo modifiche al mio maestro locale e spingendo verso l'origine su Github. Voglio inviare una richiesta pull, ma voglio solo includere l'ultimo commit. L'interfaccia della richiesta pull su github.com mostra gli ultimi 9 commit e non so come filtrarlo.

Stavo cercando di capire se avrei dovuto creare un nuovo ramo locale, verificarlo e in qualche modo ripristinare o reimpostare a monte? Quindi applicare il mio ultimo commit dal mio master per ID al nuovo ramo locale e utilizzarlo per la richiesta pull?

Sto cercando di ottenere i concetti giusti e capire le giuste linee di comando per fare ciò di cui ho bisogno.


E cosa succede se si effettua una richiesta pull con tutti gli altri commit? Ho pensato che Git sia abbastanza intelligente da ignorare (o superare) i commit che ha già inserito?
jayarjo,

3
Presumibilmente l'upstream non ha ancora accettato, o non vuole, gli impegni intermedi.
Michael Scott Cuthbert,

@jayarjo Ad esempio ho apportato altre modifiche che non voglio inviare a monte. Ad esempio, le modifiche a git ignorano il repository principale. Niente di facile con Git.
Martin

Correlati: alcuni buoni dettagli su come le richieste pull sono diverse in Git (il software) e GitHub (il servizio web)
RBT

Risposte:


302

Devi fondamentalmente creare una nuova filiale e selezionare i commit che desideri aggiungere ad essa.

Nota: potresti averne bisogno prima dei comandi checkout / cherry-pick

git remote add upstream <git repository>

git remote update

git checkout -b <new-branch-name> upstream/master

git cherry-pick <SHA hash of commit>

git push origin <new-branch-name>

Successivamente, vedrai il <new-branch-name>ramo su github, passerai ad esso e potrai inviare la richiesta pull con le modifiche che desideri.


32
Ho anche bisogno di git remote add upstream <git repository>e git remote updateprima di eseguire git checkout -b upstream upstream / master.
plainjimbo,

6
Funziona, ma non è come dovresti farlo, perché ora il tuo ramo upstream e upstream / master sono diversi e saranno sempre diversi se l'unione della tua richiesta pull non è la prima cosa che fa upstream. Per questo motivo dovresti preferire fare stackoverflow.com/a/5256304/1904815 .
JonnyJD il

2
Per elaborare: questo non è un problema tecnico, ma logico. Quando vuoi fare qualcosa con upstream (come unire da lì) devi aggiungere un ramo "real-upstream" o ripristinare il tuo upstream (non lasciando alcun ramo locale per la tua richiesta pull per ulteriori modifiche).
JonnyJD il

15
Perché mai ho bisogno di un ramo in più, solo per creare un PR per una singola riga di codice modificata ?! Qualcuno di Github ci ha pensato?
CodeManX

2
@JonHanna No ... perché devi unire un ramo? Perché non puoi semplicemente unire un commit?
Kevin Krumwiede,

57

Crea un nuovo ramo a partire dall'ultimo commit, che si trova anche nel repository di origine:

git branch new-branch origin/master
git checkout new-branch

Quindi utilizzare git cherry-pickper ottenere il singolo commit per cui si desidera la richiesta pull. Se viene chiamato il ramo con questo commit featuree il commit desiderato è l'ultimo commit in questo ramo, lo sarà

git cherry-pick feature

Supponendo che questa patch si applichi senza conflitti, ora hai un ramo per il quale puoi fare la tua richiesta pull.

In un secondo momento, ora devi decidere cosa fare con il tuo featureramo. Se non hai ancora pubblicato le modifiche su questo ramo, la procedura migliore è probabilmente quella di riassegnare questo ramo su new-branch (e rimuovere l'ultimo commit, se questo non viene eseguito automaticamente da git rebase).


Ricevo questo messaggio dopo la scelta della ciliegia. non è stato aggiunto nulla per il commit ma sono presenti file non tracciati (utilizzare "git add" per tracciare). Tutto è nel mio padrone, ma devo creare il mio ramo da monte.
Kevin Hakanson,

5
Se featureè già stato eseguito il commit origin/master, non accade nulla durante cherry-pick. Il nuovo ramo dovrebbe provenire da upstream/master(cioè, la risposta di Kevin Hakanson)
oh,

26

Sono finito in una situazione in cui avevo biforcuto una forchetta e volevo inoltrare una richiesta pull al progetto originale.

Avevo:

  • orignal_project
  • forked_project (creato dal progetto originale in SHA: 9685770)
  • my_fork (creato dal progetto biforcato presso SHA: 207e29b)
  • un commit nel mio fork (SHA: b67627b) che volevo sottoporre al progetto originale

Per fare questo, io:

  1. creato un nuovo ramo dalla SHA in cui è stato biforcato il progetto originale
  2. tratto tutto dal progetto originale
  3. cherry ha scelto il commit che volevo inviare come richiesta pull
  4. ha spinto tutto verso Github

I comandi git erano qualcosa del tipo:

  1. git branch my-feature-request 9685770
  2. git checkout richiesta-mia-funzionalità
  3. git pull https://github.com/original_project/original_project.git
  4. git cherry-pick b67627b
  5. git push origin my-feature-request

Quindi ho scelto my-feature-request come branch per la mia richiesta pull al progetto originale.


6

Questo ha funzionato quasi per me:

git checkout -b upstream upstream/master

git cherry-pick <SHA hash of commit>

git push origin upstream

L'unica differenza era questa:

git push origin upstream:upstream

Avevo bisogno di cambiare l'ultima riga in modo che git push facesse il ramo a monte nel mio repository GitHub in modo da poter fare PR da esso.


5

Avevo già eseguito il commit che volevo poter isolare come richiesta pull nel ramo corrente.

Quindi ho controllato una nuova filiale

git checkout -b isolated-pull

Ed ecco dove la mia soluzione differisce da quella di @Kevin Hakanson , poiché devo reimpostare questo ramo sul posto nella storia da cui voglio differire

git reset --hard [sha-to-diff-by]

E scegli il commit da cui voglio creare una richiesta pull isolata

git cherry-pick [my-isolated-commit-sha]

Finalmente spingilo fino al telecomando

git push origin isolated-pull

E pull richiesta dati shi.


1

La soluzione per creare un nuovo ramo (temporaneo), cherry-pick e creare la richiesta pull per quel ramo non mi ha soddisfatto. Non volevo cambiare il mio repository per rendere disponibile una serie di commit, quindi ho trovato la seguente alternativa:

Innanzitutto creare file patch per tutti gli commit di interesse:

git format-patch -1 <sha>

Se il commit dell'interesse risulta essere l'ultimo, è possibile utilizzare HEADinvece <sha>.

Ora puoi inviare le patch al manutentore del repository di origine, che può applicarle:

git branch new-branch <master or some older commit where the fork diverged>
git checkout new-branch

git am < <the patch>
...

git checkout master
git merge new-branch

Infine, dovrebbe apparire come se un ramo temporaneo fosse unito da una richiesta pull, ma senza quel ramo aggiuntivo nel repository fork.


0

Sulla base della risposta di @ kevin-hakanson, ho scritto questo piccolo script bash per semplificare questo processo. Aggiungerà il repository upstream se non esiste già (richiedendo l'URL), quindi richiederà sia il nome del nuovo ramo da creare sia il tag / SHA del commit da selezionare su quel ramo. Verifica su quale ramo o commit sei attualmente, quindi annulla eventuali modifiche in modo da poter verificare il nuovo ramo. La strategia di unione mantiene le modifiche dal commit selezionato. Dopo aver spinto il nuovo ramo in origin(presumibilmente il nome del repository remoto), il ramo o il commit su cui ci si trovava prima viene estratto di nuovo e le modifiche precedenti sono saltate fuori dalla scorta.

if ! git remote | grep -q upstream; then
    read -p "Upstream git repo URL: " upstream
    git remote add upstream $upstream
    git remote update
fi

read -p "Feature branch name: " feature_branch
# note: giving "master" is the same as giving the SHA it points to
read -p "SHA of commit to put on branch: " sha

current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" == "HEAD" ]; then
    # detached HEAD; just get the commit SHA
    current_branch=$(git rev-parse --short HEAD)
fi
git stash
git checkout -b $feature_branch upstream/master
git cherry-pick --strategy=recursive -X theirs $sha
git push origin $feature_branch
git checkout $current_branch
git stash pop

(Questo ha funzionato per me in un paio di semplici test, ma non sono un programmatore bash o un esperto di git, quindi fatemi sapere se ci sono casi che mi sono perso che potrebbero essere automatizzati meglio!)

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.