Jeg fant en samling slakkbygg, noen jeg trenger er på GitHub. https://github.com/PhantomX/slackbuilds/ Jeg vil ikke få all git.
git clone https://github.com/PhantomX/slackbuilds.git
Men bare få en slackbuild, for denne .
Hvordan gjøre dette? Er det mulig?
Kommentarer
- stackoverflow.com/a/13738951/2072269
Svar
Du vil ende opp med å laste ned hele historikken, så jeg ser ikke mye nytte av den, men du kan kasse spesifikke deler ved hjelp av en «sparsom» kasse. Siterer dette Stack Overflow-innlegget :
Fremgangsmåten for å gjøre en sparsom klone er som følger:
mkdir <repo> cd <repo> git init git remote add -f origin <url>
Dette skaper et tomt lager med fjernkontrollen din, og henter alle objekter, men sjekker dem ikke ut. gjør:
git config core.sparseCheckout true
Nå må du definere hvilke filer / mapper du faktisk vil sjekke ut. Dette gjøres ved å føre dem opp i
.git/info/sparse-checkout
, f.eks:echo "some/dir/" >> .git/info/sparse-checkout echo "another/sub/tree" >> .git/info/sparse-checkout
Sist, men ikke minst, oppdater din tomme repo med tilstanden fra fjernkontrollen:
git pull origin master
Det kan være lurt å ta en titt på utvidet opplæring , og du bør sannsynligvis lese den offisielle dokumentasjonen for sparsom utsjekking .
Det kan være bedre å bruke en grunne klon også. I stedet for git pull
kommando gitt tidligere, prøv:
git pull --depth=1 origin master
Kommentarer
- Jeg får
error: Sparse checkout leaves no entry on working directory
etter å ha gjort en git pull etter endringen tilcore.sparseCheckout
og.git/info/sparse-checkout
- Retting:
git init; git remote ...
bare sett opp ting, ingenting lastes ned. Hele poenget med sparsom er å få bare gjenstander du er interessert i. - @vonbrand at ‘ er hva
-f
alternativet er for: » Med -f-alternativet, git hent < navn > kjøres umiddelbart etter at ekstern informasjon er satt opp. » - Etter at
git remote add -f origin <url>
fortsatt laster git ned hele repoen . I mitt tilfelle vil jeg ikke ‘ ikke bruke tid på å vente på det, selv om det ikke ‘ ikke sjekke hele repoen. - I sparsom kasse definerer vi hva vi vil sjekke ut, men er det en måte å ekskludere noen kataloger og sjekke ut resten?
Svar
git clone --filter
fra git 2.19 fungerer nå på GitHub (testet 2020-09 -18, git 2.25.1)
Dette alternativet ble lagt sammen med en oppdatering av fjernprotokollen, og forhindrer virkelig at objekter blir lastet ned fra server.
F.eks. for å klone bare objekter som kreves for d1
i dette depotet: https://github.com/cirosantilli/test-git-partial-clone Jeg kan gjøre:
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
Klonekommandoen får bare:
- et enkelt begå objekt med spissen av
master
grenen - alle 4 treobjekter i depotet:
- toplevel directory of commit
- de tre katalogene
d1
,d2
,master
Deretter henter checkout
-kommandoen bare manglende blobs (filer) fra serveren:
-
d1/a
-
d1/b
Enda bedre, senere vil GitHub sannsynligvis begynne å støtte:
--filter=blob:none \ --filter=tree:0 \
der --filter=tree:0
fra Git 2.20 vil forhindre unødvendig clone
henting av alle treobjekter, og la det bli utsatt til checkout
. Men på testen 2020-09-18 som mislykkes med:
fatal: invalid filter-spec "combine:blob:none+tree:0"
antagelig fordi --filter=combine:
komposittfilter ( lagt til i Git 2.24, underforstått av flere --filter
) er ennå ikke implementert.
Jeg observerte hvilke objekter som ble hentet med:
git verify-pack -v .git/objects/pack/*.pack
som nevnt på: https://stackoverflow.com/questions/7348698/git-how-to-list-all-objects-in-the-database/18793029#18793029 Det gir meg ikke en veldig klar indikasjon på hva hvert objekt er nøyaktig, men det står typen hvert objekt (commit
, tree
, blob
), og siden det er så få objekter i den minimale repoen, kan jeg utvetydig utlede hva hver objektet er.
git rev-list --objects --all
produserte tydeligere utdata med stier for tre / klatter, men det henter dessverre noen objekter når jeg kjører det, noe som gjør det vanskelig å bestemme hva ble hentet når, gi meg beskjed hvis noen har en bedre kommando.
TODO finner GitHub kunngjøring som sier når de begynte å støtte det. https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/ fra 2020-01-17 nevner allerede --filter blob:none
.
git sparse-checkout
I tror denne kommandoen er ment for å administrere en innstillingsfil som sier » Jeg bryr meg bare om disse undertrærne » slik at fremtidige kommandoer bare vil påvirke de undertrær. Men det er litt vanskelig å være sikker på fordi den nåværende dokumentasjonen er litt … sparsom 😉
Det forhindrer ikke i seg selv henting av klatter.
Hvis denne forståelsen er riktig, vil dette være et godt supplement til git clone --filter
beskrevet ovenfor, da det ville forhindre utilsiktet henting av flere objekter hvis du har tenkt å gjøre git-operasjoner i den delvis klonede repoen .
Da jeg prøvde 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
fungerte det ikke fordi init
hentet faktisk alle objekter.
I Git 2.28 hentet det imidlertid ikke objektene som ønsket. Men hvis jeg gjør det:
git sparse-checkout set d1
d1
blir ikke hentet og sjekket ut, selv om dette eksplisitt sier det skal: https://github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/ # sparse-checkout-and-partial-clones Med ansvarsfraskrivelse:
Hold øye med at den delvise klonfunksjonen blir generelt tilgjengelig [1].
[1]: GitHub evaluerer fortsatt denne funksjonen internt mens den er aktivert på noen få utvalgte arkiver (inkludert eksemplet som brukes i dette innlegget). Når funksjonen stabiliseres og modnes, holder vi deg oppdatert med fremdriften.
Så ja, det er bare for vanskelig å være sikker på øyeblikk, delvis takket være gleden ved at GitHub er lukket kilde. Men la oss holde øye med det.
Kommandooppdeling
Serveren skal konfigureres med:
git config --local uploadpack.allowfilter 1 git config --local uploadpack.allowanysha1inwant 1
Kommandooversikt:
-
--filter=blob:none
hopper over alle blobs, men henter fremdeles alle treobjekter -
--filter=tree:0
hopper over de unødvendige trærne: https://www.spinics.net/lists/git/msg342006.html -
--depth 1
innebærer allerede--single-branch
, se også: https://stackoverflow.com/questions/1778088/how-to-clone-a-single-branch-in-git -
file://$(path)
kreves for å overvinnegit clone
protokollskjermer: https://stackoverflow.com/questions/47307578/how-to-shallow-clone-a-local-git-repository-with-a-relative-path -
--filter=combine:FILTER1+FILTER2
er syntaksen for å bruke flere filtre på en gang, og prøver å passere--filter
av en eller annen grunn mislykkes med: » flere filter-spesifikasjoner kan ikke kombineres «. Dette ble lagt til i Git 2.24 på e987df5fe62b8b29be4cdcdeb3704681ada2b29e » list-objects-filter: implementer sammensatte filtre »Rediger: på Git 2.28 ser jeg eksperimentelt at
--filter=FILTER1 --filter FILTER2
også har samme effekt, siden GitHub ikke implementerercombine:
ennå fra og med 2020-09- 18 og klagerfatal: invalid filter-spec "combine:blob:none+tree:0"
. TODO introdusert i hvilken versjon?
Formatet til --filter
er dokumentert på man git-rev-list
.
Dokumenter på Git-treet:
- 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
Test det lokalt
Følgende skript genererer reproduserbart https://github.com/cirosantilli/test-git-partial-clone depot lokalt, gjør en lokal klon og observerer det som ble klonet:
#!/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
Utgang i 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
Konklusjoner: alle klatter utenfra d1/
mangler. F.eks.0975df9b39e23c15f63db194df7f45c76528bccb
, som er d2/b
er ikke der etter å ha sjekket ut d1/a
.
Merk at root/root
og mybranch/mybranch
også mangler, men --depth 1
skjuler det fra listen over manglende filer. Hvis du fjerner --depth 1
, vises de på listen over manglende filer.
Jeg har en drøm
Denne funksjonen kan revolusjonere Git.
Se for deg å ha hele koden til bedriften din i en enkelt repo uten stygge tredjepartsverktøy som repo
.
Se for deg lagre store klatter direkte i repoen uten stygge tredjepartsutvidelser .
Tenk deg om GitHub tillater per fil / katalogmetadata som stjerner og tillatelser, slik at du kan lagre alle dine personlige ting under en enkelt repo.
Tenk deg om submodules ble behandlet nøyaktig som vanlige kataloger : bare be om et SHA-tre, og en DNS-lignende mekanisme løser forespørselen din , først se på lokale ~/.git
, deretter først til nærmere servere (bedriftens speil / cache) og havner på GitHub.
Svar
Prøv dette:
svn export https://github.com/PhantomX/slackbuilds/trunk/${directory}
Kommentarer
- Dette er den enkleste måten. Den laster ikke ned all repoen. Merk at vi må legge til
/trunk
og fjerne/tree/master
. Mer her - Takk! Jeg vil bare klone en mappe med repoen og ikke alle mappene i en repo. Og denne fungerer virkelig for meg.
Svar
arbeidsløsning:
du må du slå av komprimeringen:
git config --global core.compression 0
så må du bruke grunne klone
git clone --depth=1 <url>
så er det viktigste trinnet å cd inn i ditt klonede prosjekt
cd <shallow cloned project dir>
nå åpner du klonen, trinn for trinn
git fetch --depth=N, with increasing N
f.eks.
git fetch --depth=4
deretter,
git fetch --depth=100
deretter,
git fetch --depth=500
du kan velge hvor mange trinn du vil ha ved å erstatte denne N,
og til slutt laste ned alle de gjenværende revisjonene bruker,
git fetch --unshallow
upvote hvis det hjelper deg 🙂
Svar
Jeg fikk dette til slutt takket være det ovennevnte. Jeg redigerte filen direkte, og fikk feil ved å ved et uhell inkludere tilbudene. .Git / info / sparse-checkout-filen din skal bare inneholde katalogen, ingen anførselstegn. Her er et eksempel: Dette gigantiske prosjektet: https://github.com/SharePoint/sp-dev-fx-webparts , jeg ville bare ha react-script-editoren i eksempler på katalog. https://github.com/SharePoint/sp-dev-fx-webparts / tree / master / samples / react-script-editor
Jeg fulgte instruksjonene ovenfor og fikk den til å fungere da .git / info / sparse-checkout-filen hadde akkurat dette
samples / react-script-editor
Svar
Dette vil klone en bestemt mappe og fjerne all historikk som ikke er relatert til den.
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
Kommentarer
- Dette vil fremdeles klone all historie (
--depth=1
for å unngå), og alle andre kataloger (???
for å unngå?).
Svar
For GitHub repos kan du klone hvilken som helst sub -kataloger for ethvert GitHub-arkiv (med hvilken som helst referanse) som bruker https://github.com/HR/github-clone
Kommentarer
- Dessverre er dette uegnet for Dockerfile-scenarier, da det ville hente hele Python som en avhengighet bare for å bruke den en gang under bildebyggingen.
Svar
Jeg svarer med spesifikke begrensninger jeg møtte.
- I VSO ble SSH deaktivert av sikkerhet, så vi kunne ikke bruke git-arkiv. Bare PAT / CredentialProvider ble støttet.
- Vår filial hadde enorm kode, så git klon i seg selv ville ta minst 15 minutter.
Her er hva jeg gjorde:
- Engangs manuell prosess: i VSO UI, opprett en ny ekstern gren sier «emptyBranch» som har null filer (alle slettes).
-
git clone --depth=1 --single-branch --branch emptyBranch <remote>
(ganske raskt) -
git checkout <branchToSyncTo> <directoryToSyncTo>
(sjekker ut bare spesifikk mappe)