Ho trovato una raccolta di slackbuild, alcuni di cui ho bisogno sono su GitHub. https://github.com/PhantomX/slackbuilds/ Non “voglio scaricare tutto git.
git clone https://github.com/PhantomX/slackbuilds.git
Ma prendi solo uno slackbuild, per questo .
Come si fa? È possibile?
Commenti
- stackoverflow.com/a/13738951/2072269
Risposta
Finirai per scaricare lintera cronologia, quindi non ci vedo molti vantaggi, ma tu può effettuare il checkout di parti specifiche utilizzando un checkout “sparse”. Citando questo post di Stack Overflow :
I passaggi per eseguire uno scarso clone sono i seguenti:
mkdir <repo> cd <repo> git init git remote add -f origin <url>
Questo crea un repository vuoto con il telecomando e recupera tutti gli oggetti ma non li controlla. Quindi fare:
git config core.sparseCheckout true
Ora è necessario definire quali file / cartelle si desidera effettivamente estrarre. Questo viene fatto elencandoli in
.git/info/sparse-checkout
, ad esempio:echo "some/dir/" >> .git/info/sparse-checkout echo "another/sub/tree" >> .git/info/sparse-checkout
Ultimo ma non meno importante, aggiorna il tuo repository vuoto con lo stato dal telecomando:
git pull origin master
Potresti voler dare unocchiata al tutorial esteso e probabilmente dovresti leggere la documentazione ufficiale per il checkout sparso .
Potrebbe essere meglio utilizzare un clone superficiale . Invece di git pull
comando fornito in precedenza, prova:
git pull --depth=1 origin master
Commenti
- Ricevo
error: Sparse checkout leaves no entry on working directory
dopo aver eseguito un git pull dopo aver apportato la modifica acore.sparseCheckout
e.git/info/sparse-checkout
- Correzione:
git init; git remote ...
imposta solo le cose, non viene scaricato nulla. Lo scopo dello sparse è ottenere solo gli oggetti che ti interessano. - @vonbrand che ‘ è ciò che
-f
è per: ” Con lopzione -f, git fetch < name > viene eseguito immediatamente dopo la configurazione delle informazioni remote. ” - Dopo
git remote add -f origin <url>
git sta ancora scaricando lintero repository . Nel mio caso, non ‘ voglio passare il tempo ad aspettarlo, anche se ‘ non controlla lintero repository. - Nel checkout sparse definiamo ciò che vogliamo estrarre, ma cè un modo per escludere alcune directory e controllare il resto?
Risposta
git clone --filter
da git 2.19 ora funziona su GitHub (testato 2020-09 -18, git 2.25.1)
Questa opzione è stata aggiunta insieme a un aggiornamento del protocollo remoto e impedisce veramente che gli oggetti vengano scaricati dal server.
Ad esempio, per clonare solo gli oggetti richiesti per d1
di questo repository: https://github.com/cirosantilli/test-git-partial-clone Posso fare:
git clone \ --depth 1 \ --filter=blob:none \ --no-checkout \ https://github.com/cirosantilli/test-git-partial-clone \ ; cd test-git-partial-clone git checkout master -- d1
Il comando clone ottiene solo:
- un singolo oggetto commit con la punta del
master
ramo - tutti i 4 oggetti albero del repository:
- directory di primo livello di commit
- le tre directory
d1
,d2
,master
Quindi, il comando checkout
recupera solo i blob (file) mancanti dal server:
-
d1/a
-
d1/b
Ancora meglio, in seguito GitHub inizierà probabilmente a supportare:
--filter=blob:none \ --filter=tree:0 \
dove --filter=tree:0
da Git 2.20 impedirà il clone
recupero non necessario di tutti gli oggetti albero e consentirne il rinvio a checkout
. Ma nel mio test del 18/09/2020 che fallisce con:
fatal: invalid filter-spec "combine:blob:none+tree:0"
presumibilmente perché il filtro composito --filter=combine:
( aggiunto in Git 2.24, implicito da più --filter
) non è ancora implementato.
Ho osservato quali oggetti sono stati recuperati con:
git verify-pack -v .git/objects/pack/*.pack
come indicato in: https://stackoverflow.com/questions/7348698/git-how-to-list-all-objects-in-the-database/18793029#18793029 Non fornisce unindicazione molto chiara di cosa sia esattamente ciascun oggetto, ma indica il tipo di ogni oggetto (commit
, tree
, blob
) e poiché ci sono così pochi oggetti in quel repo minimo, posso dedurre in modo inequivocabile cosa è.
git rev-list --objects --all
ha prodotto un output più chiaro con i percorsi per albero / blob, ma sfortunatamente recupera alcuni oggetti quando lo eseguo, il che rende difficile determinarlo cosa è stato recuperato quando, fammi sapere se qualcuno ha un comando migliore.
TODO trova lannuncio di GitHub che dice quando hanno iniziato a supportarlo. https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/ del 17/01/2020 menziona già --filter blob:none
.
git sparse-checkout
I penso che questo comando abbia lo scopo di gestire un file di impostazioni che dice ” Mi interessano solo questi sottoalberi ” in modo che i comandi futuri influenzeranno solo quelli sottoalberi. Ma è un po difficile esserne sicuri perché la documentazione corrente è un po … scarsa 😉
Non impedisce, di per sé, il recupero dei blob.
Se questa comprensione è corretta, allora questo sarebbe un buon complemento a git clone --filter
descritto sopra, poiché impedirebbe il recupero involontario di più oggetti se intendi eseguire operazioni git nel repository clonato parziale .
Quando ho provato su Git 2.25.1:
git clone \ --depth 1 \ --filter=blob:none \ --no-checkout \ https://github.com/cirosantilli/test-git-partial-clone \ ; cd test-git-partial-clone git sparse-checkout init
“non ha funzionato perché init
in realtà recuperava tutti gli oggetti.
Tuttavia, in Git 2.28 non recuperava gli oggetti come desiderato. Ma se lo faccio:
git sparse-checkout set d1
d1
non viene recuperato ed estratto, anche se questo lo dice esplicitamente dovrebbe: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/ # sparse-checkout-and-partial-clones Con disclaimer:
Tieni docchio la funzione di clonazione parziale per diventare generalmente disponibile [1].
[1]: GitHub sta ancora valutando questa funzione internamente mentre è abilitata su pochi repository selezionati (incluso lesempio utilizzato in questo post). Man mano che la funzione si stabilizza e matura, ti terremo aggiornato sui suoi progressi.
Quindi sì, è semplicemente troppo difficile essere certi al momento, grazie in parte alle gioie di GitHub come sorgente chiusa. Ma teniamolo docchio.
Ripartizione dei comandi
Il server deve essere configurato con:
git config --local uploadpack.allowfilter 1 git config --local uploadpack.allowanysha1inwant 1
Ripartizione comandi:
-
--filter=blob:none
ignora tutti i BLOB, ma recupera comunque tutti gli oggetti albero -
--filter=tree:0
ignora gli alberi non necessari: https://www.spinics.net/lists/git/msg342006.html -
--depth 1
implica già--single-branch
, vedere anche: https://stackoverflow.com/questions/1778088/how-to-clone-a-single-branch-in-git -
file://$(path)
è necessario per superaregit clone
imbrogli del protocollo: https://stackoverflow.com/questions/47307578/how-to-shallow-clone-a-local-git-repository-with-a-relative-path -
--filter=combine:FILTER1+FILTER2
è la sintassi per utilizzare più filtri in una volta, il tentativo di superare--filter
per qualche motivo non riesce con: ” più specifiche di filtro non possono essere combinate “. Questo è stato aggiunto in Git 2.24 allindirizzo e987df5fe62b8b29be4cdcdeb3704681ada2b29e ” list-objects-filter: implementare filtri compositi ”Modifica: su Git 2.28, ho notato sperimentalmente che
--filter=FILTER1 --filter FILTER2
ha lo stesso effetto, poiché GitHub non implementa ancoracombine:
a partire dal 2020-09- 18 e si lamentafatal: invalid filter-spec "combine:blob:none+tree:0"
. TODO introdotto in quale versione?
Il formato di --filter
è documentato su man git-rev-list
.
Documenti sullalbero Git:
- https://github.com/git/git/blob/v2.19.0/Documentation/technical/partial-clone.txt
- https://github.com/git/git/blob/v2.19.0/Documentation/rev-list-options.txt#L720
- https://github.com/git/git/blob/v2.19.0/t/t5616-partial-clone.sh
Provalo in locale
Il seguente script genera in modo riproducibile il https://github.com/cirosantilli/test-git-partial-clone repository in locale, esegue un clone locale e osserva cosa è stato clonato:
#!/usr/bin/env bash set -eu list-objects() ( git rev-list --all --objects echo "master commit SHA: $(git log -1 --format="%H")" echo "mybranch commit SHA: $(git log -1 --format="%H")" git ls-tree master git ls-tree mybranch | grep mybranch git ls-tree master~ | grep root ) # Reproducibility. export GIT_COMMITTER_NAME="a" export GIT_COMMITTER_EMAIL="a" export GIT_AUTHOR_NAME="a" export GIT_AUTHOR_EMAIL="a" export GIT_COMMITTER_DATE="2000-01-01T00:00:00+0000" export GIT_AUTHOR_DATE="2000-01-01T00:00:00+0000" rm -rf server_repo local_repo mkdir server_repo cd server_repo # Create repo. git init --quiet git config --local uploadpack.allowfilter 1 git config --local uploadpack.allowanysha1inwant 1 # First commit. # Directories present in all branches. mkdir d1 d2 printf "d1/a" > ./d1/a printf "d1/b" > ./d1/b printf "d2/a" > ./d2/a printf "d2/b" > ./d2/b # Present only in root. mkdir "root" printf "root" > ./root/root git add . git commit -m "root" --quiet # Second commit only on master. git rm --quiet -r ./root mkdir "master" printf "master" > ./master/master git add . git commit -m "master commit" --quiet # Second commit only on mybranch. git checkout -b mybranch --quiet master~ git rm --quiet -r ./root mkdir "mybranch" printf "mybranch" > ./mybranch/mybranch git add . git commit -m "mybranch commit" --quiet echo "# List and identify all objects" list-objects echo # Restore master. git checkout --quiet master cd .. # Clone. Don"t checkout for now, only .git/ dir. git clone --depth 1 --quiet --no-checkout --filter=blob:none "file://$(pwd)/server_repo" local_repo cd local_repo # List missing objects from master. echo "# Missing objects after --no-checkout" git rev-list --all --quiet --objects --missing=print echo echo "# Git checkout fails without internet" mv ../server_repo ../server_repo.off ! git checkout master echo echo "# Git checkout fetches the missing directory from internet" mv ../server_repo.off ../server_repo git checkout master -- d1/ echo echo "# Missing objects after checking out d1" git rev-list --all --quiet --objects --missing=print
Risultato in Git v2.19.0:
# List and identify all objects c6fcdfaf2b1462f809aecdad83a186eeec00f9c1 fc5e97944480982cfc180a6d6634699921ee63ec 7251a83be9a03161acde7b71a8fda9be19f47128 62d67bce3c672fe2b9065f372726a11e57bade7e b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1 308150e8fddde043f3dbbb8573abb6af1df96e63 d1/a f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 d1/b 84de03c312dc741d0f2a66df7b2f168d823e122a d2 0975df9b39e23c15f63db194df7f45c76528bccb d2/a 41484c13520fcbb6e7243a26fdb1fc9405c08520 d2/b 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master 8b25206ff90e9432f6f1a8600f87a7bd695a24af master/master ef29f15c9a7c5417944cc09711b6a9ee51b01d89 19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch 1b671b190e293aa091239b8b5e8c149411d00523 mybranch/mybranch c3760bb1a0ece87cdbaf9a563c77a45e30a4e30e a0234da53ec608b54813b4271fbf00ba5318b99f root 93ca1422a8da0a9effc465eccbcb17e23015542d root/root master commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec mybranch commit SHA: fc5e97944480982cfc180a6d6634699921ee63ec 040000 tree b64bf435a3e54c5208a1b70b7bcb0fc627463a75 d1 040000 tree 84de03c312dc741d0f2a66df7b2f168d823e122a d2 040000 tree 7d5230379e4652f1b1da7ed1e78e0b8253e03ba3 master 040000 tree 19f7a4ca4a038aff89d803f017f76d2b66063043 mybranch 040000 tree a0234da53ec608b54813b4271fbf00ba5318b99f root # Missing objects after --no-checkout ?f70a17f51b7b30fec48a32e4f19ac15e261fd1a4 ?8b25206ff90e9432f6f1a8600f87a7bd695a24af ?41484c13520fcbb6e7243a26fdb1fc9405c08520 ?0975df9b39e23c15f63db194df7f45c76528bccb ?308150e8fddde043f3dbbb8573abb6af1df96e63 # Git checkout fails without internet fatal: "/home/ciro/bak/git/test-git-web-interface/other-test-repos/partial-clone.tmp/server_repo" does not appear to be a git repository fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. # Git checkout fetches the missing directory from internet remote: Enumerating objects: 1, done. remote: Counting objects: 100% (1/1), done. remote: Total 1 (delta 0), reused 0 (delta 0) Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done. remote: Enumerating objects: 1, done. remote: Counting objects: 100% (1/1), done. remote: Total 1 (delta 0), reused 0 (delta 0) Receiving objects: 100% (1/1), 45 bytes | 45.00 KiB/s, done. # Missing objects after checking out d1 ?8b25206ff90e9432f6f1a8600f87a7bd695a24af ?41484c13520fcbb6e7243a26fdb1fc9405c08520 ?0975df9b39e23c15f63db194df7f45c76528bccb
Conclusioni: tutti i blob dallesterno di d1/
mancano. Per esempio.0975df9b39e23c15f63db194df7f45c76528bccb
, che è d2/b
, non è presente dopo aver verificato d1/a
.
Tieni presente che mancano anche root/root
e mybranch/mybranch
, ma --depth 1
lo nasconde lelenco dei file mancanti. Se rimuovi --depth 1
, vengono visualizzati nellelenco dei file mancanti.
Ho un sogno
Questa funzione potrebbe rivoluzionare Git.
Immagina di avere tutta la base di codice della tua azienda in un unico repository senza brutti strumenti di terze parti come repo
.
Immagina di archiviare enormi BLOB direttamente nel repository senza brutte estensioni di terze parti .
Immagina se GitHub consentisse per metadati di file / directory come stelle e autorizzazioni, in modo da poter archiviare tutte le tue cose personali in un unico repository.
Immagina se i sottomoduli sono stati trattati esattamente come le normali directory : basta richiedere un albero SHA e un meccanismo simile a DNS risolve la tua richiesta , prima guardando il tuo locale ~/.git
, quindi prima su server più vicini (mirror / cache della tua azienda) e finire su GitHub.
Risposta
Prova questo:
svn export https://github.com/PhantomX/slackbuilds/trunk/${directory}
Commenti
- Questo è il modo più semplice. Non scarica tutto il repo. Tieni presente che dobbiamo aggiungere
/trunk
e rimuovere/tree/master
. Altro qui - Grazie! Voglio solo clonare una cartella del repository e non tutte le cartelle in un repository. E questo funziona davvero per me.
Answer
soluzione di lavoro:
tu è necessario disattivare la compressione:
git config --global core.compression 0
quindi è necessario utilizzare il clone superficiale
git clone --depth=1 <url>
quindi il passaggio più importante è inserire il cd nel progetto clonato
cd <shallow cloned project dir>
ora deopen il clone, passo dopo passo
git fetch --depth=N, with increasing N
ad es.
git fetch --depth=4
quindi
git fetch --depth=100
quindi
git fetch --depth=500
puoi scegliere quanti passaggi desideri sostituendo questo N,
e infine scaricare tutte le revisioni rimanenti utilizzando,
git fetch --unshallow
votare a favore se ti aiuta 🙂
Rispondi
Ho finalmente funzionato grazie a quanto sopra. Stavo modificando direttamente il file, ottenendo errori includendo accidentalmente le virgolette. Il tuo file .git / info / sparse-checkout dovrebbe includere solo la directory, senza virgolette. Ecco un esempio: questo gigantesco progetto: https://github.com/SharePoint/sp-dev-fx-webparts , volevo solo il react-script-editor nel directory dei campioni. https://github.com/SharePoint/sp-dev-fx-webparts / tree / master / samples / react-script-editor
Ho seguito le indicazioni sopra e lho fatto funzionare quando il mio file .git / info / sparse-checkout conteneva proprio questo
samples / react-script-editor
Risposta
Questa operazione clonerà una cartella specifica e rimuoverà tutta la cronologia non correlata ad essa.
git clone --single-branch -b {branch} [email protected]:{user}/{repo}.git git filter-branch --subdirectory-filter {path/to/folder} HEAD git remote remove origin git remote add origin [email protected]:{user}/{new-repo}.git git push -u origin master
Commenti
- Questa operazione clonerà comunque tutta la cronologia (
--depth=1
da evitare) e tutte le altre directory (???
da evitare?).
Risposta
Per i repository GitHub, puoi clonare qualsiasi sottotitolo -directory di qualsiasi repository GitHub (con qualsiasi riferimento) utilizzando https://github.com/HR/github-clone
Commenti
- Purtroppo questo non è adatto per gli scenari Dockerfile in quanto trasporterebbe lintero Python come una dipendenza solo per usarlo una volta durante la creazione dellimmagine.
Risposta
Risponderò con limitazioni specifiche che ho dovuto affrontare.
- In VSO, SSH era disabilitato dalla sicurezza, quindi non era possibile utilizzare larchivio git. Era supportato solo PAT / CredentialProvider.
- Il nostro ramo aveva un codice enorme, quindi git clone richiederebbe almeno 15 minuti.
Ecco cosa ho fatto:
- Processo manuale una tantum: nellinterfaccia utente VSO, crea un nuovo ramo remoto dice “ramo vuoto” che ha zero file (tutti vengono cancellati).
-
git clone --depth=1 --single-branch --branch emptyBranch <remote>
(abbastanza veloce) -
git checkout <branchToSyncTo> <directoryToSyncTo>
(controlla solo una cartella specifica)