Close

Fork e upstream di Git: istruzioni e un suggerimento interessante

Primo piano di Nicola Paolucci
Nicola Paolucci

Developer Advocate


Il fork dei progetti per apportare le tue modifiche ti consentono di integrare facilmente i tuoi contributi. Tuttavia, se non stai inviando di nuovo quelle modifiche a monte, il che significa rispedirle al repository principale, rischi di perderne traccia, il che può causare righe divergenti nel tuo repository. Per assicurarti che tutti i collaboratori attingano alla stessa posizione, devi conoscere alcuni principi su come il forking git interagisce con git upstream. In questo blog, ti presenterò le nozioni di base, alcuni trucchi e ti lascerò anche un suggerimento interessante per portarti un passo avanti a tutti.

Git upstream: tieniti aggiornato e contribuisci


Vorrei iniziare descrivendo in dettaglio una configurazione comune e il flusso di lavoro più semplice per interagire con i repository upstream.

In una configurazione standard, generalmente hai un remoto di origine e un remoto upstream, quest'ultimo è il guardiano del progetto o l'origine di riferimento a cui desideri contribuire.

Innanzitutto, verifica di aver già configurato un remoto per il repository upstream e, si spera, anche un'origine:

git remote -v

origin  git@bitbucket.org:my-user/some-project.git (fetch)
origin  git@bitbucket.org:my-user/some-project.git (push)

Se non hai un upstream, puoi aggiungerlo facilmente con il comando remote:

git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git
Database
materiale correlato

Come spostare un repository Git completo

Logo di Bitbucket
Scopri la soluzione

Impara a utilizzare Git con Bitbucket Cloud

Verifica che il remoto sia aggiunto correttamente:

git remote -v

origin    git@bitbucket.org:my-user/some-project.git (fetch)
origin    git@bitbucket.org:my-user/some-project.git (push)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)

Ora puoi raccogliere le ultime modifiche del repository upstream con fetch. Ripeti l'operazione ogni volta che vuoi ricevere aggiornamenti:

Se il progetto ha tag che non sono stati uniti a main, dovresti utilizzare anche: git fetch upstream --tags.

git fetch upstream

In genere, vorrai mantenere il tuo branch main locale come equivalente prossimo di quello main upstream ed eseguire qualsiasi lavoro nei branch delle funzionalità, poiché potrebbero in seguito diventare pull request.

A questo punto, non importa se usi merge o rebase, poiché il risultato sarà in genere lo stesso. Usiamo merge:

git checkout main
git merge upstream/main

Quando vuoi condividere un po' di lavoro con i manutentori upstream del tuo branch main, crea un branch di funzionalità. Quando sei soddisfatto, invialo al tuo repository remoto.

Puoi anche usare rebase e quindi merge per assicurarti che l'upstream abbia un set pulito di commit (idealmente uno) da valutare:

git checkout -b feature-x

#some work and some commits happen
#some time passes

git fetch upstream
git rebase upstream/main

Pubblicare con git fork


Dopo i passaggi precedenti, pubblica il tuo lavoro nel fork remoto con un semplice push:

git push origin feature-x
git push -f origin feature-x

Personalmente preferisco mantenere la cronologia il più pulita possibile e optare per l'opzione tre, ma team diversi hanno flussi di lavoro diversi. Nota: fallo solo quando lavori con il tuo fork. Riscrivere la cronologia dei repository e dei branch condivisi è qualcosa che non dovresti MAI fare.

Suggerimento del giorno: numeri di anticipi/ritardi nel prompt


Dopo un'operazione fetch, git status ti mostra quanti commit sono in anticipo o in ritardo rispetto al branch remoto sincronizzato. Non sarebbe bello se potessi vedere queste informazioni nel tuo fedele prompt dei comandi? Lo pensavo anch'io, così ho iniziato a usare bash per riuscirci.

Ecco come apparirà sul tuo prompt una volta configurato:

nick-macbook-air:~/dev/projects/stash[1|94]$

E questo è ciò che devi aggiungere al tuo .bashrc o equivalente, solo una singola funzione:

function ahead_behind {
    curr_branch=$(git rev-parse --abbrev-ref HEAD);
    curr_remote=$(git config branch.$curr_branch.remote);
    curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
    git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"

Funzionamento interno

Per chi ama i dettagli e le spiegazioni ecco il funzionamento effettivo:

Otteniamo il nome simbolico dell'attuale HEAD, ovvero il branch attuale:

curr_branch=$(git rev-parse --abbrev-ref HEAD);

Otteniamo il remoto a cui punta il branch attuale:

curr_remote=$(git config branch.$curr_branch.remote);

Otteniamo il branch in cui questo remoto dovrebbe essere sottoposto a merge (con un trucco Unix comodo per scartare tutto fino all'ultima barra [/] inclusa):

curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);

Ora abbiamo ciò di cui abbiamo bisogno per raccogliere il numero di conteggi per i commit in anticipo o in ritardo:

git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';

Usiamo il vecchio comando Unix tr per convertire il TAB in un separatore |.

Guida introduttiva a git upstream


Questa è una guida di base su git upstream: come configurare un git upstream, creare un nuovo branch, raccogliere le modifiche, pubblicare con git fork e un buon consiglio su quanti commit in anticipo/ritardo sono presenti per il tuo branch remoto.

Bitbucket Data Center include la sincronizzazione dei fork, che sostanzialmente solleva gli sviluppatori dall'onere di tenersi aggiornati sui propri fork; Bitbucket Cloud ha invece una semplice sincronizzazione in 1 passaggio. Dai un'occhiata!

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Condividi l'articolo
Argomento successivo

Letture consigliate

Aggiungi ai preferiti queste risorse per ricevere informazioni sui tipi di team DevOps e aggiornamenti continui su DevOps in Atlassian.

Le persone collaborano utilizzando una parete piena di strumenti

Blog di Bitbucket

Illustrazione su Devops

Percorso di apprendimento DevOps

Funzione Demo Den per demo con esperti Atlassian

Come Bitbucket Cloud funziona con Atlassian Open DevOps

Iscriviti alla nostra newsletter DevOps

Thank you for signing up