2011-08-22 12 views
18

Spesso mentre si lavora su un ramo è necessario introdurre alcune modifiche "temporanee" (ad esempio informazioni di debug aggiuntive o una modifica che mi consente di osservare meglio la cosa sono in realtà su cui lavorare).Gestione di modifiche temporanee (da non commettere) in Git

A proposito di questi cambiamenti "temporanei":

  • li voglio nella mia copia di lavoro del mio ramo, perché mi aiutano a lavorare sul cambiamento reale,
  • Non voglio li hanno commessi al ramo, perché il ramo verrà unificato in master un po 'di tempo e non sono codice di produzione.

Attualmente li tengo come non inattivo e li salto manualmente durante la gestione di ogni commit. Tuttavia non posso stare con questa soluzione perché:

  • Per tutto il tempo che ho di ricordare quali file ho bisogno di saltare,
  • Un giorno ho intenzione di finire con 2 cambi in un unico file, uno essere temporaneo, uno da impegnarsi e sarà davvero fastidioso.

Come devo gestirlo?


gitignore è ovviamente fuori questione perché non voglio ignorare i file intere e sono ancora interessati a modifiche da altri committer (ho bisogno di rebase il ramo di maestro di tanto in tanto) .

+0

Sembra un'idea interessante provare a estendere l'ignoranza alla granularità dell'hunk. Potrebbe anche valere la pena provare a chiedere sulla mailing list git (non è necessario iscriversi per postare e dato che è un volume piuttosto alto, probabilmente non lo si vuole). –

+0

In realtà gitignore non è fuori questione, perché se il file è in versione, si * otterrà la versione confermata di esso. E 'solo aggiungere che lo ignorerà. Tuttavia, non gestisce il caso quando si desidera ignorare solo alcune modifiche a un determinato file e prima o poi lo si desidera. –

+0

Ho aggiunto una mia idea, mi sembra OK, ma sarei grato se qualcuno di più esperto potrebbe dare un'occhiata se non ci sono problemi con esso. – Kos

risposta

12

Io di solito affrontare questo utilizzando:

git add -p 

... mettere in scena i cambiamenti pezzo-per-pezzo. Quindi devi solo assicurarti di premere n per le tue modifiche di debug.


Se ho i cambiamenti più coinvolti di questo tipo, io creare un ramo chiamato qualcosa come local-changes con un impegno alla sua punta che introduce il codice di debug. Dopo aver creato un paio di commit, mi piacerebbe quindi utilizzare:

git rebase -i master 

... per riordinare in modo che il commit con i cambiamenti locali è sulla punta di nuovo. Poi per aggiornare master e tornare al ramo modifiche locali, si può fare:

git checkout master 
git merge local-changes^ 
git checkout local-changes 
+0

Selezionare manualmente le modifiche rilevanti è quello che sto cercando di evitare qui :) Voglio farlo solo una volta. – Kos

+1

:) Bene, ho aggiunto un suggerimento alternativo alla mia risposta. –

0

Le funzionalità di archiviazione di GIT forniscono esattamente quello che stai chiedendo. Almeno per la parte "custodia". Non è possibile evitare la selezione buona/cattiva durante il commit in questo modo.

6

Prova git update-index --assume-unchanged <file>. In questo modo git non aggiungerà il file all'indice quando usa git add o git commit -a.

MODIFICA: questo non consente di trattare il caso di un file con modifiche sia temporanee che permanenti.

+0

Probabilmente vale la pena sottolineare le conseguenze dell'uso di '--assume-unchanged' può anche essere davvero confuso :) –

+1

@Mark Non sono mai stato confuso quando si utilizza' --assume-unchanged'. Puoi elaborare? L'unica difficoltà che ho affrontato una volta o due è scoprire quali file hanno questo flag impostato. –

+0

Solo che è facile dimenticare che lo hai usato. Potrebbe essere solo io ... –

2

È possibile utilizzare

git stash 

per salvarla in uno spazi temporanei. Dopo aver eseguito l'unione, è possibile utilizzare

git stash pop 

per caricare nuovamente le modifiche temporanee nella directory di lavoro.

+0

questo non discrimina tra le modifiche globali utili e le modifiche solo locali, come richiesto dall'OP .. – naught101

0

Tendo a mantenere le modifiche non salvate del genere. Semplicemente uso sempre git add -i o git add -p per modificare lo stage (a meno che non sia sicuro di volere che tutte le modifiche abbiano l'albero). In questo modo rivedo tutte le modifiche che voglio commesse e salta facilmente quelle temporanee. Aiuta anche a mettere in scena modifiche che ritieni di voler commettere in anticipo e mantenerle in scena o persino impegnarle e aggiungere ulteriori modifiche con git commit --amend.

4

Ecco un modo per affrontare questo che, una volta istituito, si richiede solo di ricordare un passo per configurarlo, e un passo prima di ogni spinta.

Il setup:

git branch tempChanges [branch for temporary changes] 
    [create your temporary changes] 
git add -A 
git commit 

Nota la sha per quel commit. Quindi passare al ramo di lavoro e:

git cherry-pick shaOfTempChangesCommit 

Ora avete le modifiche sul vostro ramo di lavoro. Fai il tuo lavoro e commetti. Poi, prima di spingere:

git rebase -i 

Vedrai qualcosa di simile:

pick bfd4d2e This first commit is your temporary changes. 
pick 186a99d Some stuff done on the working branch. 
pick ec871c6 More stuff done on the working branch. 
(etc.) 

eliminare la riga con le modifiche temporanee. Quindi salvare e uscire. La cronologia verrà riscritta per escludere le modifiche temporanee. (I cambiamenti saranno ancora esistere nel tempChanges ramo.) Una volta fatto, fare qualsiasi test è necessario e poi git push.

Quando si è pronti a lavorare di nuovo, si può tirare le modifiche temporanee indietro sul vostro ramo di lavoro corrente (o un nuovo ramo di lavoro):

git cherry-pick shaOfTempChangesCommit 

Così, insomma, tutto quello che hai da ricordare in questo metodo è

  • dopo aver creato un ramo di lavoro

    git cherry-pick shaOfTempChangesCommit

  • dopo aver finito di lavoro e pronto a spingere

    git rebase -i[per rimuovere le modifiche temporanee prima di spingere]

1

ho trovato una soluzione pulita a questo problema : (scusate la mia arte ascii). Richiede un ramo aggiuntivo per il ramo dell'argomento. (questo ha difetti ed è contestata/corretto, vedi commenti)

L'opera si presenta come segue inizialmente:

master 
    \ 
     \ 
    commit1 ---- commit2 ---- "branch" 

Il lavoro è fatto su "ramo".

di introdurre alcune modifiche temporanee:

  • creare ramo "branch-temp" da "master"
  • confermare le modifiche temporanee ci
  • rebase "ramo" da "master" su " branch-temp"

Il repo ora assomiglia:

master 
    \ 
     \ 
    "branch-temp" ----- commit1 ---- commit2 ---- "branch" 

Il lavoro è ora felicemente continuato su ramo e le modifiche temporanee non sono visibili nello stato.

Per modificare o estendere le modifiche temporanee:

  • cassa ramo-temp
  • commit --amend le modifiche temporanee là - questo è sbagliato, dal momento che rende "branch-temp" divergere

per unire le modifiche dal ramo di padroneggiare:

Questo è solo un po 'più complicato. Vogliamo unire in tutte le modifiche, tranne le modifiche introdotte da "branch-temp".La mia idea è:

  • eseguire una stampa normale da "ramo" su "master"
    (ora abbiamo una fusione, ma con alcune modifiche temporanee inutili - rimuoviamole)
  • git revert - -no-commit ramo-temp
  • git commit --amend
    (questi due passaggi dovrebbero modificare l'unione impegnano, in modo che esso non contiene le modifiche dalla derivazione-Temp)
+0

Vorrei invece rebase su master, utilizzando rebase interattivo e rimuovo solo i commit da non utilizzare (contrassegnati con [test] o qualcosa nei loro soggetti). Ciò eviterebbe anche la necessità di "branch-temp" e si tradurrebbe in una storia lineare. –

+0

Il 'git checkout branch-temp' +' git commit --amend' non funzionerà come presentato, perché dopo quel 'branch-temp' avrà la nuova versione, ma' branch' avrà ancora la vecchia versione del commit . E non sono sicuro che 'git rebase --onto branch-temp' possa risolvere il problema. È più facile 'git rebase -i' e modificare il commit in questo modo, ma questo lascerà il' branch-temp' indietro (questo è quello che userei e abbandonerò il commit usando rebase o unire + revert). –

+0

Sì, hai ragione- Ho controllato il documento e commit --amend crea un nuovo commit e aggiorna il ramo corrente, mentre pensavo che modificasse il commit su HEAD sul posto. – Kos

1

Di solito inserisco tutto il mio codice di debug nel proprio commit, quindi prima di eseguire l'unione, ho eseguito il commit di revert. Ho usato qualche variazione della maggior parte delle altre risposte, a volte, ma mi piace questo per la sua semplicità e il fatto che conserva la mia cronologia di sviluppo. Sì, non desidero il mio codice di debug nel prodotto finale, quindi lo revert, ma se il test rileva un problema, voglio essere in grado di ripristinare quel codice di debug per ulteriore lavoro.

+1

Che lascia il tuo albero pieno di brutti impegni indesiderati ... – naught101

1

Informazioni sulla scrittura di uno script di shell semplice che consente di correggere e annullare le modifiche di debug su richiesta (e quindi di trasformarlo in un alias git).

E.g.

git apply-my-debug 
... 
do coding 
... 
git remove-my-debug 
git add . 
git commit -m "Don't worry about debug changes" 
1

Per evitare di ingombrare la vostra area di sosta, come si sta creando una caratteristica, commettere le modifiche di debug con un luminoso lampeggiante di avvertimento che non dovrebbero farne l'unione finale:

#warning - DEBUG ONLY - DO NOT MERGE 

print(debugInfo) 

#warning - DEBUG ONLY - DO NOT MERGE 

Quando sei pronto per unire il ramo, se te ne sei dimenticato, queste modifiche verranno catturate da te o da qualcun altro nella revisione del codice della tua richiesta di pull.

Avrai quindi diversi modi per rimuovere il debug di impegna:

  1. revert debug specifica commette. Questo manterrà la loro storia nel ramo.

  2. cherry-pick il buono si impegna. Questo rimuoverà completamente il debug commit.

  3. Qualcosa di più complicato come rebase -interactive per rimuovere i commit sul posto.

Problemi correlati