Come faccio a mettere da parte un sacco di modifiche non impegnate mentre lavoro su qualcos'altro


98

Se ho un sacco di modifiche non confermate e voglio metterle da parte mentre lavoro su qualcos'altro, e poi più tardi (ad esempio dopo diversi giorni) torna ad esso e procedi a lavorare. Quale sarebbe il flusso di lavoro più semplice per ottenere questo risultato? (Finora ho solo esperienza con le funzionalità di base di Mercurial). Il mio metodo abituale era creare un nuovo ramo usando clone, ma potrebbero esserci modi migliori.

Risposte:


133

Hai una manciata di opzioni:

  1. Conserva gli oggetti. Ciò salva le modifiche e le rimuove dalla directory di lavoro in modo che il ramo possa continuare. Non crea un set di modifiche.

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    Aggiorna / Modifica : potrebbe essere necessario utilizzare versioni più recenti di Mercurial

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    Puoi ancora usare --namecome alternativa a -n, ma il mercurial non sembra --namepiù piacere . Inoltre, --allnon è più necessario e Mercurial andrà davvero fuori di testa per questo.

  2. Patch accoda gli elementi utilizzando mq. Questo non è troppo dissimile da accantonare per alcuni aspetti, ma si comporta in modo diverso. Il risultato finale è lo stesso, le modifiche vengono rimosse e possono essere eventualmente riapplicate in seguito. Quando vengono premute, le patch sono serie di modifiche logiche, quando vengono estratte vengono salvate altrove e non fanno parte della cronologia delle serie di modifiche.

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. Impegnali a livello locale, aggiorna al set di modifiche precedente e continua a lavorare e utilizza rami anonimi (o più teste). Se poi vuoi le modifiche, puoi unire le teste. Se non desideri le modifiche, puoi rimuovere la serie di modifiche.

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. Affidali a un ramo denominato. Il flusso di lavoro diventa quindi lo stesso dell'opzione 3: unisci o elimina quando sei pronto.

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

Personalmente utilizzo l'opzione 3 o 4 perché non mi dispiace rimuovere i set di modifiche o il check-in del codice parziale (a condizione che alla fine non venga spinto). Questo può essere usato insieme alle nuove cose di Phase per nascondere i tuoi set di modifiche locali ad altri utenti, se necessario.

Uso anche il rebasecomando per spostare le serie di modifiche per evitare unioni in cui un'unione non aggiungerebbe nulla alla cronologia del codice. Unioni che tendo a salvare per attività tra rami importanti (come rami di rilascio) o attività da un ramo di funzionalità di più lunga durata. C'è anche il histeditcomando che uso per comprimere i set di modifiche dove la loro "chiacchiera" ne riduce il valore.

Anche le code di patch sono un meccanismo comune per eseguire questa operazione, ma hanno la semantica dello stack. Si spingono e si aprono le patch, ma una patch che si trova "sotto" un'altra patch nello stack richiede che venga inserita anche quella sopra di essa.

Attenzione , come con tutte queste opzioni, se i file hanno più modifiche dopo le modifiche temporanee che hai accantonato / accodato / ramificato, sarà richiesta la risoluzione di unione quando rimuovi / spinge / unisci.


Grazie per l'ottima risposta e gli utili esempi. Sai se anche usare i segnalibri hg è un'opzione?
Erik

@Erik possibilmente, ma non ho esperienza nell'usarlo.
Adam Houldsworth

2
i segnalibri possono essere usati per aiutare con l'opzione 3 - puoi usarne uno per etichettare la revisione che hai creato per nascondere la tua modifica. Non possono svolgere il compito da soli.
Steve Kaye

l'opzione --allnon è riconosciuta. è comunque un comportamento predefinito accantonare tutte le modifiche.
naXa

@naXa Ciao amico, se uno dei miei comandi è leggermente sbagliato (forse perché la versione è cambiata), sentiti libero di modificare la risposta e la approverò se necessario :-)
Adam Houldsworth

23

Personalmente, non mi piace nessuna delle risposte pubblicate finora:

  1. Non mi piace il clone branching perché mi piace che ogni progetto abbia una sola directory. Lavorare su directory diverse allo stesso tempo rovina completamente la cronologia dei file recenti dei miei editor. Finisco sempre per cambiare il file sbagliato. Quindi non lo faccio più.
  2. Uso shelveper soluzioni rapide (solo per spostare le mie modifiche non autorizzate su un altro ramo, se mi rendo conto di essere in quello sbagliato). Stai parlando di giorni, in nessun modo accantonerei qualcosa per giorni.
  3. Penso che mqsia troppo complicato per una seduta così ordinaria

Penso che il modo migliore sia semplicemente eseguire il commit delle modifiche, poi tornare al changeset prima di iniziare queste modifiche e lavorare da lì. Ci sono alcuni problemi minori, lasciatemi illustrare:

Supponiamo che tu abbia il changeset A. Quindi inizi le modifiche. A questo punto vuoi metterlo da parte per un po '. Prima di tutto, impegna il tuo lavoro:

hg ci -m "Working on new stuff"

Se lo desideri, puoi aggiungere un segnalibro per tornare più facilmente in seguito. Creo sempre segnalibri per i miei rami anonimi.

hg bookmark new-stuff

Torna al changeset prima di queste modifiche

hg update A

Da qui, lavori e generi il changeset C. Ora hai 2 teste (B e C), sarai avvisato quando proverai a spingere. Puoi eseguire il push di un solo ramo specificando il capo di quel ramo:

hg push -r C

Oppure puoi cambiare la fase del new-stufframo in segreto. I changeset segreti non verranno inviati.

hg phase -r new-stuff --secret --force

Grazie per la risposta dettagliata! Mi piace molto leggere i flussi di lavoro delle persone per quei problemi (ordinari?).
Erik

Penso che mqsia un po 'troppo complicato solo per questa situazione, ma ha una gamma di usi abbastanza ampia, incluso questo, che vale la pena investire il tempo per imparare a conoscerla.
Norman Gray,

12

Per mantenere le modifiche locali non autorizzate, il modo più semplice per me è salvarle come file di patch.

hg diff > /tmp/`hg id -i`.patch

e quando è necessario tornare allo stato precedente:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch

Mi spoglierei /tmpe hg id -ifunzionerà anche su Windoze.
anatoly techtonik

E hg upnon è necessario lì.
anatoly techtonik

1
@techtonik Cosa succederebbe se applicassi la patch su un'altra revisione? Soprattutto se vengono modificati i file con patch.
mapcuk

Mercurial proverà a fonderlo e dovrai comunque affrontare il conflitto.
anatoly techtonik

6

Puoi semplicemente clonare il tuo repository più volte. Tendo ad avere un clone di root, quindi più figli da lì. Esempio:

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

I 4 figli vengono tutti clonati dalla radice e spingere / tirare da / verso la radice. La radice quindi esegue il push / pull dal repository principale sulla rete / Internet da qualche parte. La radice agisce come una sorta di area di sosta personale.

Quindi, nel tuo caso, dovresti semplicemente clonare un nuovo repository e iniziare a lavorare. Lascia il tuo lavoro "accantonato" da solo nell'altro repo. È così semplice.

L'unico svantaggio è l'utilizzo dello spazio su disco, ma se questo fosse un problema non useresti affatto DVCS;) Oh, e in un certo senso inquina la tua lista di "progetti recenti" di Visual Studio, ma che diavolo.

[Modifica i seguenti commenti]: -

Per concludere quindi ... quello che stai facendo è completamente normale e normale. Direi che è il miglior modo possibile di lavorare quando quanto segue è vero: 1) è di breve durata 2) non è necessario collaborare con altri sviluppatori 3) le modifiche non devono lasciare il PC fino al commit / tempo di spinta.


Qualche motivo per non utilizzare i rami? Questo è ciò che servono e sono notevolmente più veloci della repo-clonazione.
Adam Houldsworth

Nella mia domanda ho affermato quanto segue: Il mio metodo abituale era creare un nuovo ramo usando clone, ma potrebbero esserci modi migliori.
Erik

1
@AdamHouldsworth, tecnicamente questi sono rami ... solo quelli di breve durata. Creare un ramo con nome per un lavoro di breve durata è completamente stupido. Abusa dello scopo denominato rami che sono per storie di lavoro longeve.
nbevans

@NathanE Se pensi che i branch con nome per lavori di breve durata siano "completamente stupidi", allora ci sono anche branching anonimi, shelving o la coda di patch come altre opzioni leggere. La ri-clonazione, a mio parere, è ugualmente stupida di fronte ad altre opzioni: è un potenziale vantaggio avere due set di codice aperti in due istanze VS, ma raramente devo farlo quindi usando i cloni come ovvio non servimi. Solo per chiarimenti, non ero il downvoter.
Adam Houldsworth

@NathanE Inoltre non sono esclusivi per "storie di lavoro longeve", questo è solo qualcosa in cui sono bravi se segui l'integrazione continua. Direttamente dai documenti : "Si verificano rami se le linee di sviluppo divergono", se stai accantonando un elemento di lavoro per lavorare su qualcos'altro, questo a me suona come una divergenza, indipendentemente da quanto sia longevo.
Adam Houldsworth
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.