Risposte:
Come da "export git" (come "export svn")?
Puoi usarlo git checkout-index
, questo è un comando di basso livello, se vuoi esportare tutto, puoi usare -a
,
git checkout-index -a -f --prefix=/destination/path/
Per citare le pagine man:
Il "/" [sul prefisso] finale è importante. Il nome esportato ha letteralmente il prefisso con la stringa specificata.
Se vuoi esportare una determinata directory, ci sono alcuni trucchi coinvolti. Il comando accetta solo file, non directory. Per applicarlo alle directory, usa il comando 'trova' e invia l'output a git.
find dirname -print0 | git checkout-index --prefix=/path-to/dest/ -f -z --stdin
Anche dalle pagine man:
L'intuitività non è l'obiettivo qui. La ripetibilità è.
GIT_WORK_TREE=../path/to/place git checkout
git worktree
(vedi sotto) imho è la risposta canonica oggi e potrebbe essere aggiunta qui.
Un'altra soluzione che è un po 'più pulita: basta specificare un diverso albero di lavoro.
Per effettuare il checkout di tutto, dal tuo HEAD (non dall'indice) a una directory di uscita specifica:
git --work-tree=/path/to/outputdir checkout HEAD -- .
Per effettuare il checkout di una sottodirectory o di un file da HEAD in una directory specifica:
git --work-tree=/path/to/outputdir checkout HEAD -- subdirname
--work-tree=/home/thomasg/okcopy
piuttosto che --work-tree=~/okcopy
(possibilmente usare un percorso relativo mentre sei seduto nello stesso albero git funziona anche, ma in questo modo risiede la follia e le git status
uscite in R'lyehian)
git status
mostra quindi molte mod (presumibilmente perché l'indice ora corrisponde all'altra directory e non all'albero di lavoro normale intatto). git reset
è tornato in buono stato.
git status
mostra molte mod e git reset
non aiuta. Ho dovuto git checkout -f HEAD
ripristinare lo stato del mio repository.
fatal: This operation must be run in a work tree
git reset
sufficiente ripristinare il principale albero di lavoro in sanità mentale. Per esportare in modo sicuro le sottodirectory del repository in qualsiasi SHA1, ramo o tag senza modificare l'albero di lavoro principale, vedere la famigerata git archive
soluzione di Charles Bailey . Allo stesso modo, per effettuare il checkout in sicurezza di più filiali contemporaneamente, il nuovo git worktree add
sottocomando è tuo amico.
Per un singolo file:
git show HEAD:abspath/to/file > file.copy
SHA1 ID
che può essere facilmente trovato tramite gitk
. Se avessi solo bisogno di "estrarre" quel file in una posizione temporanea (cioè non ripristinare), allora show
git show 82e54378856215ef96c5db1ff1160a741b5dcd70:MyProj/proguard/mapping.txt > myproj_mapping.txt
Le soluzioni di cui sopra non hanno funzionato per me perché dovevo controllare una versione con tag specifica dell'albero. Ecco come cvs export
dovrebbe essere usato, a proposito. git checkout-index
non accetta l'argomento tag, poiché estrae i file dall'indice. git checkout <tag>
cambierebbe l'indice indipendentemente dall'albero di lavoro, quindi avrei bisogno di ripristinare l'albero originale. La soluzione che ha funzionato per me è stata quella di clonare il repository. Il clone condiviso è abbastanza veloce e non occupa molto spazio extra. La .git
directory può essere rimossa se lo si desidera.
git clone --shared --no-checkout <repository> <destination>
cd <destination>
git checkout <tag>
rm -rf .git
Le versioni più recenti di git dovrebbero supportare git clone --branch <tag>
per verificare automaticamente il tag specificato:
git clone --shared --branch <tag> <repository> <destination>
rm -rf <destination>/.git
git --work-tree=/path/to/outputdir checkout <tag> -- .
non ha funzionato per te?
Se stai lavorando con la tua funzione e non vuoi tornare alla pagina principale, puoi eseguire:
cd ./myrepo
git worktree add ../myrepo_master master
git worktree remove ../myrepo_master
Creerà una ../myrepo_master
directory con master
commit delle filiali, dove puoi continuare a lavorare
git --work-tree=/path/to/outputdir checkout HEAD -- .
quanto non faccia nulla all'indice, copia semplicemente il ramo selezionato nella posizione specificata (con l'aggiunta di un file .git).
myrepo_master
directory
git worktree remove ../myrepo_master
La risposta di Adrian fu "fatale: questa operazione deve essere eseguita su un albero di lavoro". Quello che segue è ciò che ha funzionato per noi.
git worktree add <new-dir> --no-checkout --detach
cd <new-dir>
git checkout <some-ref> -- <existing-dir>
Appunti:
--no-checkout
Non effettuare il checkout di nulla nel nuovo worktree.--detach
Non creare un nuovo ramo per il nuovo worktree.<some-ref>
funziona con qualsiasi ref, ad esempio, funziona con HEAD~1
.git worktree prune
.Aggiunta alla risposta di @ hasen . Per elencare i file al checkout , potresti voler usare git ls-files
invece di find
come:
git ls-files -z *.txt | git checkout-index --prefix=/path-to/dest/ -f -z --stdin
-z
! È bello fornire script che non sono vulnerabili a determinati tipi di attacchi di iniezione.
Ho definito un alias git per raggiungere questo obiettivo (prima di trovare questa domanda).
È una breve funzione bash che salva il percorso corrente, passa al repository git, esegue un checkout e torna da dove è iniziato.
git check per sviluppare ~ / my_project_git
Questo ad esempio verificherebbe il ramo di sviluppo nella directory "~ / my_project_git".
Questo è il codice alias all'interno ~/.gitconfig
:
[alias]
checkTo = "!f(){ [ -z \"$1\" ] && echo \"Need to specify branch.\" && \
exit 1; [ -z \"$2\" ] && echo \"Need to specify target\
dir\" && exit 2; cDir=\"$(pwd)\"; cd \"$2\"; \
git checkout \"$1\"; cd \"$cDir\"; };f"
Sto usando questo alias per estrarre un ramo in una directory temporanea:
[alias]
cot = "!TEMP=$(mktemp -d); f() { git worktree prune && git worktree add $TEMP $1 && zsh -c \"cd $TEMP; zsh\";}; f" # checkout branch in temporary directory
Uso:
git cot mybranch
Si viene quindi rilasciati in una nuova shell nella directory temporanea in cui è possibile lavorare sul ramo. Puoi anche usare i comandi git in questa directory.
Al termine, elimina la directory ed esegui:
git worktree prune
Questo viene anche eseguito automaticamente nell'alias, prima di aggiungere un nuovo worktree.