Come estrarre directory specifiche con git


193

Ho un progetto con git e voglio solo clonare o estrarre una directory specifica, come myproject / javascript proprio come fa Subversion.
apportare alcune modifiche, eseguire il commit e inviare nuovamente.
È possibile?


3
checkout sparse acquistato anche (anche se è ancora necessario prendere tutto): vedi stackoverflow.com/questions/2416815/...
VonC

Risposte:


205
  1. cd nella parte superiore della copia del repository
  2. git fetch
  3. git checkout HEAD path/to/your/dir/or/file

    • Dove " path/..." in (3) inizia nella directory appena sotto la radice repo contenente il tuo " .../file"

    • NOTA che invece di "HEAD", è possibile utilizzare il codice hash di un commit specifico e quindi otterrai la revisione (file) o le revisioni (dir) specifiche per quel commit.


1
Ho appena capito di aver frainteso la domanda. La mia risposta affronta invece come effettuare il checkout di un singolo file, che può quindi essere modificato e sottoposto a commit.
vergueishon,

Hai affrontato il titolo della domanda, che è abbastanza buono. Questo mi ha appena salvato, per quanto mi riguarda, questa è la risposta corretta, soprattutto perché questo è stato un grande successo su Google per questo problema.
Morgon,

21
Questo comunque ottiene comunque l'intero repo. Per un progetto di dimensioni di 2 GB, questo non fa risparmiare molto tempo ..
Pithikos,

5
Per coloro che leggono questi commenti e non sanno come questo non risponda alla domanda, ciò che questa soluzione fa è darti una copia di quella sola cartella, ma non è una copia funzionante, il che significa che non puoi modificare e ri -commettere. Quindi, come ha detto @Morgon, si rivolge al titolo della domanda (PUOI tirare solo una dir), ma non risponde al corpo della domanda ("apporta alcune modifiche, esegui il commit e rispedisci di nuovo").
msb,

@StanHolodnak --non è richiesto però. Forza i bit dopo di esso ad essere interpretato come un percorso. Quindi, sì, se si dispone di un file con il nome --helpche si desidera verificare, sarebbe necessario prefissarlo con questi trattini:git checkout HEAD -- --help
Tim Visée

105

In una directory vuota:

git init
git remote add [REMOTE_NAME] [GIT_URL]
git fetch REMOTE_NAME
git checkout REMOTE_NAME/BRANCH -- path/to/directory

funziona se vuoi solo usare la versione remota di un file per sostituire il file locale, penso
John

questo tira anche la cartella, come non caricare la cartella, ma solo cose all'interno della cartella?
Al Kasih,

Non c'è bisogno fetcho checkoutcomandi, possiamo semplicemente fare la richiesta pull dopo il remote addcomando per ottenere l'intero ramo master.
Iqra.

2
Come sottolinea Pithkos nella risposta accettata, questa risposta scaricherà anche TUTTO il repository remoto sul tuo computer locale. La risposta di Shingara è la più chiara: non c'è modo di estrarre in remoto una parte di un repository. Tuttavia, per coloro che non si preoccupano della larghezza di banda dell'intero recupero e sono interessati a creare una copia funzionante di una porzione della cache locale, la risposta accettata mostra come. Ma voglio solo chiarire che l'intera cronologia del repository (in un formato compresso) deve essere scaricata sul tuo computer.
Gabe Halsmer,

39

Dopo aver cercato molto una risposta, non aver trovato, rinunciato, riprovando e così via, ho finalmente trovato una soluzione a questo in un altro thread SO:

Come estrarre tutte le cartelle tranne una

Per copiare e incollare cosa c'è:

git init
git remote add -f origin <url>
git config core.sparsecheckout true
echo <dir1>/ >> .git/info/sparse-checkout
echo <dir2>/ >> .git/info/sparse-checkout
echo <dir3>/ >> .git/info/sparse-checkout
git pull origin master

Per fare ciò che vuole OP (lavorare solo su una dir), basta aggiungere quella dir .git/info/sparse-checkout, quando si eseguono i passaggi precedenti.

Mille grazie a @cforbish!


2
Lo sto pubblicando qui principalmente perché ogni volta che provo a google come farlo, questo è un risultato eccezionale e quel thread non è nemmeno vicino alla visualizzazione. :( Mi sento male incollare la copia, ma penso che sia così buone pratiche?
msb,

1
Questa è l'unica soluzione pulita. Ho provato le risposte sopra. Dopo aver controllato il mio ramo con le altre risposte, non sono riuscito a estrarre e ho avuto diversi nuovi file che necessitavano di commit. Con questa soluzione tutto sembra a posto. Ma NOTA: indipendentemente dal ramo che è stato estratto, git penserà che tu sia dentro master. Assicurati solo di fare git branch --set-upstream-to=origin/<branch>per tirare correttamente
vedi il

12

Non è possibile. È necessario estrarre tutto il repository o niente.


1
Anche se è necessario recuperare tutto, potrebbe interessare in questo caso un pull su un albero di lavoro di checkout scarso? Vedere stackoverflow.com/questions/2416815/...
VonC

10
Solo per aggiungere questo, il motivo per cui non è possibile estrarre solo una directory è perché git utilizza il tracciamento semantico dei dati, non il tracciamento semantico dei file, quindi puoi spostare senza problemi il codice (o altri dati) dentro e fuori dai file senza dover dire alla fonte sistema di tracciamento (fino all'aggiornamento, ovviamente.) Per questo motivo, anche il codice può spostarsi dentro e fuori le directory senza problemi, quindi prendere una sola directory non ha molto senso. Spero che questo ti aiuti.
Onnipotente:

12
@OmnipotentEntity Ci dispiace ma IMHO non ha senso. L'implementazione non dovrebbe limitare l'uso. Git sa quali sono le directory (almeno quando si crea una copia di lavoro locale), quindi non c'è motivo per cui non sia possibile eseguire un'operazione simile sul server e inviare semplicemente l'output pertinente. Certo, al momento non è implementato ma è dovuto alla mancanza di una funzionalità, non a un'impossibilità fondamentale. Personalmente penso che sia una caratteristica piuttosto importante, ma hey, è una delle ragioni per cui evito il git quando possibile.
Base

10

Forse questo comando può essere utile:

git archive --remote=MyRemoteGitRepo --format=tar BranchName_or_commit  path/to/your/dir/or/file > files.tar

"Et voilà"


2
Questo scarica una specifica directory di file per scopi di archiviazione, non estrae una copia che puoi modificare e respingere.
leetNightshade

Molto bello. Probabilmente non è accettabile come soluzione all'OP ma in realtà è quello che cercavo da quando ho solo bisogno di cercare il contenuto di una grande cartella in un repository ancora più grande che sicuramente non voglio recuperare, e non ho bisogno di modificare / spingere.
Oliver

7

Se si desidera ottenere le ultime modifiche in una directory senza inserirla, è possibile effettuare:

$ git -C <Path to directory> pull


2

Ho provato e testato questo funziona!

mkdir <directory name> ;  //Same directory name as the one you want to pull
cd <directory name>;
git remote add origin <GIT_URL>;
git checkout -b '<branch name>';
git config core.sparsecheckout true;
echo <directory name>/ >> .git/info/sparse-checkout;
git pull origin <pull branch name>

Spero sia stato utile!


0

A volte, vuoi solo dare un'occhiata alle copie precedenti dei file senza il rigmarole di passare attraverso i diff.

In tal caso, è altrettanto semplice creare un clone di un repository e verificare il commit specifico che ti interessa e dare un'occhiata alla sottodirectory in quel repository clonato. Poiché tutto è locale, puoi semplicemente eliminare questo clone al termine.


-1

Per tutte quelle difficoltà con percorsi di file teorici ed esempi come ho fatto io, ecco un esempio reale: Microsoft offre i loro documenti ed esempi su git hub, sfortunatamente raccolgono tutti i loro file di esempio per una grande quantità di argomenti in questo repository:

https://github.com/microsoftarchive/msdn-code-gallery-community-s-z

Mi interessava solo i file js di Microsoft Dynamics nel percorso

msdn-code-gallery-community-s-z/Sdk.Soap.js/

quindi ho fatto quanto segue

creare un

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

file nella cartella dei miei repository sul disco

git sparse-checkout init

in quella directory usando cmd su windows

Il contenuto del file di

msdn-code-gallery-community-s-zSdkSoapjs\.git\info\sparse-checkout

è

Sdk.Soap.js/*

finalmente fare un

git pull origin master
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.