2016-06-30 86 views
7

C'è un modo per lavorare sullo stesso file ma su diverse funzionalità/rami in GIT? Sono sicuro che c'è un modo, ma qual è il più semplice? Non voglio mettere da parte i miei cambiamenti perché sono ingombranti. Con SVN sono stato in grado di lavorare su 2 rami separati come 2 entità diverse senza alcun intervento e facile passare da uno all'altro.Come lavoro sullo stesso file in GIT ma su 2 rami diversi in cui posso passare facilmente tra i 2

+0

Intendi dire che ti piacerebbe avere due copie di lavoro separate e lavorare in entrambe in parallelo? Nessun problema con questo se hai un repository remoto. –

+0

No. Un repository e passare tra i rami senza problemi dove il file si trova nell'ultimo stato in cui l'ho lasciato. – KingKongFrog

+1

Git è uno strumento di controllo della versione basato su repository (piuttosto che basato su file, ad esempio SVN o Perforce). La risposta @CodeWizard potrebbe funzionare per te, ma in generale credo che tu debba lavorare solo su un ramo alla volta. –

risposta

13

utilizza l'albero di lavoro git.

git worktree

Git worktree è stato introdotto nel 2007 sotto la cartella contrib in git repo ed è stato chiamato new-workdir.

In git V2.5 è stato denominato worktree e consente di disporre di più istanze dello stesso repository su cartelle diverse.

ad esempio:

git worktree add <second path> 

creerà un'altra cartella sul computer che ti permettono di lavorare su diversi ramo contemporaneamente.


Se si desidera rimuovere il worktree utilizzare il prugna sottocomando

prune
Potare lavorando informazioni albero in $ GIT_DIR/worktrees.

Un'altra opzione per rimuoverlo è quello di eliminare la cartella .git/worktrees

enter image description here


Se si utilizza rebase seguito:

  • Nota: (Since Git 2.7)
    voi può anche usare il git rebase [--no]-autostash come bene.
0

Penso che il flusso di lavoro possa essere influenzato da come il cambio di ramo lento è in SVN. In Git, non devi preoccuparti di questo: il checkout del nuovo ramo richiederà una frazione di secondo (forse pochi secondi per progetti molto grandi).

La cosa più sensata per voi sarebbe quella di lavorare su un ramo singolo e una volta che si eseguiranno alcuni commit, cherry-pick ad altro ramo. Esempio: (supponiamo che si desidera lavorare su f.txt file, che è identica su entrambi i rami)

$ git fetch 
$ git checkout branch-1 # assuming remote branches exists already 
$ vim f.txt # do some editing 
$ git commit -am "f file changed" 
$ git checkout branch-2 
$ git cherry-pick branch-1 # <- this will pick single last commit from branch-1 
          # and apply it to branch-2 

Non si sono limitati alla raccolta dell'ultimo commit, ovviamente - si può scegliere per commettere id, etichetta , puoi usare l'operatore ~ per selezionare commit antenato, ecc. Puoi anche fare molti cherry-pick in una sola volta, rebasing o, ancora più bello, rebasing interattivo.

Al termine del lavoro, è necessario eseguire due distinte push per ramo (oppure è possibile modificare l'opzione di configurazione push.default su matching per eseguire una singola pressione da tutte le filiali locali).

1

Sembra che tu ti stia fissando sul voler fare il modo di Subversion. Posso capirlo; cambiare le abitudini di sviluppo può essere un processo piuttosto lungo, e fino a un certo punto potrebbe essere opportuno piegare gli strumenti alle proprie abitudini; va benissimo Quindi qui si va:

pensare in questo modo: con svn si dispone di un unico grande albero di directory in cui "rami" in realtà non sono entità di prima classe ma (tecnicamente) le sottodirectory arbitrari

mystuff/trunk 
mystuff/branches/feature1 
mystuff/branches/feature2 
... 
mystuff/tags/1.0 
mystuff/tags/1.1 
... 

Quindi, se si sono utilizzate questo e felice con esso, la stessa soluzione esatta è possibile con git così, verificando diverse copie del repository in una (non-git) parent:

mystuff/master 
mystuff/master/.git 
mystuff/feature1 
mystuff/feature1/.git 
... 

questo è concettualmente esattamente lo stesso come prima. Mantieni i diversi repository sul rispettivo ramo in ogni momento. Avrai un antenato comune da spingere/tirare a/da per le unioni, come al solito (nota che questo può essere gestito localmente, non c'è bisogno di una posizione fisicamente remota, a meno che tu ne abbia uno comunque, puoi/potresti anche in teoria utilizzare il repository master direttamente come origin).

Quello che non si ottiene e non otterrà mai con git, sta commettendo le modifiche in diversi rami in un colpo solo (sotto un "commit"). Un "ramo" in git è una cosa fondamentalmente diversa rispetto a Subversion, lo stesso di un "commit" in git è una cosa fondamentalmente diversa lì (commit! = Revisione). Si sarà devono avvolgere la testa intorno a questo, nessuno strumento ti salverà da quello.

Alcune operazioni:

  • creare un nuovo ramo di caratteristica feature2 (a partire da master):

    mystuff> git clone {URL-or-filesystem-path-of-common-origin-repository} feature2 
    mystuff/feature2> git checkout -b feature2 
    
  • Unisci il vostro lavoro da un ramo a master:

    mystuff/feature1> git add ... ; git commit ... 
    mystuff/feature1> git push 
    
    mystuff/master> git fetch 
    mystuff/master> git merge origin/feature1 
    

    Lo stesso per qualsiasi altra fusione; il ramo master non è tecnicamente diverso da qualsiasi altro ramo in git, è solo una convenzione di denominazione (come /trunk è una convenzione di denominazione in Subversion).

  • Sbarazzarsi di un ramo:

    mystuff/feature1> git push origin :feature1  # deletes the branch on the common repository 
    mystuff> rm -rf feature1 
    

Tutto questo utilizza un maggiore spazio di archiviazione HDD po ​​'più del necessario; esistono modi avanzati per clonare un repository localmente, riutilizzando l'archivio oggetti. Fatemi sapere in un commento se è importante per voi; a meno che tu non abbia davvero limiti di spazio, francamente non mi preoccuperei.

+0

Quindi, qual è stato il downvote per? – AnoE

+0

Non sei l'unico in downsoted:/ – Av4t4r

+0

Up-votato - questa è una buona risposta che affronta in aggiunta un processo mentale conciso per passare da 'svn' a' git'. –

1

Non voglio memorizzare le mie modifiche in quanto ingombrante.

Il modo migliore per farlo è semplicemente modificare il file su entrambi i rami.

L'idea sarebbe quella di avere la base comune sul ramo principale e aggiungere una funzionalità per ramo, dato il caso d'uso.

1

Da quello che ho capito dalla sezione commenti: è che si desidera avere 2 diverse "versioni" dello stesso file. (Come hai detto sui commenti, avendo file.txt hai la riga "AAAAAAA" su una, e "BBBBBBB" su una, ma non "AAAA").

Questo può essere ottenuto per ramificazione molto facilmente.

Prima di iniziare il lavoro, sarai "in piedi" su un ramo (probabilmente master). A questo punto è possibile creare un nuovo ramo git checkout -b feature1 (questo comando crea e passa alla funzione diramazione1). dove apporterai alcune modifiche a file.txt. Supponi di scrivere "AAAAAA". Quindi, dovrai impegnarlo. git commit -a -m "Added the AAAA line". Se ora git checkout master (si torna al master). Il tuo file NON avrà scritto "AAAAA", puoi quindi fare altre modifiche a questo file (su questo ramo o su un altro ramo). Puoi scrivere "BBBBBBB" in questo file, e avrai 2 "versioni" dello stesso file "file.txt", uno avrà "AAAA" (quello su feature1) e l'altro su master avrà BBBB.

Nota: ho creato uno scenario in cui non hai già modificato il file in origine, ma se lo hai, ci sono anche dei modi per ottenere questo tramite la ramificazione. Devi def leggi https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging