Zastanawiałem się, czy istnieje dobre rozwiązanie „git export”, które tworzy kopię drzewa bez .git
katalogu repozytorium. Znam co najmniej trzy metody:
git clone
a następnie usunięcie.git
katalogu repozytorium.git checkout-index
nawiązuje do tej funkcjonalności, ale zaczyna się od „Po prostu wczytaj wybrane drzewo do indeksu ...”, czego nie jestem do końca pewien, jak to zrobić.git-export
jest skryptem strony trzeciej, który zasadniczo wykonujegit clone
tymczasową lokalizacjęrsync --exclude='.git'
w miejscu docelowym.
Żadne z tych rozwiązań nie wydaje mi się satysfakcjonujące. Najbliższa svn export
może być opcja 1, ponieważ obie wymagają, aby katalog docelowy był najpierw pusty. Ale opcja 2 wydaje się jeszcze lepsza, zakładając, że mogę dowiedzieć się, co to znaczy wczytać drzewo do indeksu.
git
export
git-archive
svn-export
Greg Hewgill
źródło
źródło
git archive --format zip --output "output.zip" master -0
da ci nieskompresowane archiwum (-0 to flaga dla nieskompresowanych). git-scm.com/docs/git-archive .export
podkatalog 250 kB bezpośrednio ze zdalnego repozytorium (który w innym przypadku mógłby mieć rozmiar 200 MB, z wyłączeniem poprawek) - i trafię do sieci tylko dla transferu pobierania 250 kB (lub więcej). Za pomocągit
,archive
musi być włączony na serwerze (więc nie mogę go wypróbować) -clone --depth 1
z serwera nadal można pobrać repo powiedzmy 25 MB, gdzie.git
sam podfolder zajmuje 15 MB. Dlatego nadal powiedziałbym, że odpowiedź brzmi „nie”.git checkout-index
git archive -o latest.zip HEAD
Odpowiedzi:
Prawdopodobnie najprostszym sposobem na osiągnięcie tego jest
git archive
. Jeśli naprawdę potrzebujesz tylko rozwiniętego drzewa, możesz zrobić coś takiego.Przez większość czasu muszę „eksportować” coś z git, w każdym razie chcę skompresowane archiwum, więc robię coś takiego.
Archiwum ZIP:
git help archive
więcej szczegółów jest dość elastyczny.Pamiętaj, że chociaż archiwum nie będzie zawierało katalogu .git, będzie ono jednak zawierać inne ukryte pliki specyficzne dla git, takie jak .gitignore, .gitattributes itp. Jeśli nie chcesz ich w archiwum, upewnij się, że użyj atrybutu export-ignore w pliku .gitattributes i zatwierdź to przed zrobieniem archiwum. Czytaj więcej...
Uwaga: Jeśli jesteś zainteresowany eksportem indeksu, polecenie to
(Więcej informacji znajduje się w odpowiedzi Grega )
źródło
git archive --format zip --output /full/path master
git archive --format zip --output /path/to/file.zip --prefix=newdir/ master
pliku wyjściowego, będzie on nazywał się „file.zip”, ale po rozpakowaniu katalog najwyższego poziomu będzie miał nazwę „newdir”. (Jeśli pominiesz atrybut --prefix, katalogiem najwyższego poziomu będzie „plik”.)git archive -o latest.zip HEAD
tworzy archiwum Zip, które zawiera zawartość ostatniego zatwierdzenia w bieżącym oddziale. Zauważ, że format wyjściowy wynika z rozszerzenia pliku wyjściowego.Dowiedziałem się, co oznacza opcja 2. Z repozytorium możesz:
Ukośnik na końcu ścieżki jest ważny, w przeciwnym razie spowoduje to, że pliki znajdą się w / destination z prefiksem „path”.
Ponieważ w normalnej sytuacji indeks zawiera zawartość repozytorium, nic specjalnego nie można zrobić, aby „wczytać żądane drzewo do indeksu”. Już tam jest
-a
Flaga jest wymagane, aby sprawdzić wszystkie pliki w indeksie (nie jestem pewien, co to znaczy pominąć tę flagę w tej sytuacji, ponieważ nie robić to, co chcę). Te-f
siły flag zastępując wszystkie istniejące pliki w produkcji, które to polecenie normalnie nie robić.To wydaje się być rodzajem „eksportu git”, którego szukałem.
źródło
git add
Polecenie zmienia zawartość w indeksie, więc cokolwiekgit status
pokazuje, jak „być popełnione” jest różnice pomiędzy głowicą i zawartości indeksu.~
(nie'~'
!) Zostanie utworzony w twoim katalogu roboczym. Nie magit checkout-index
w tym nic specjalnego : to samo dotyczymkdir '~/dest'
( nie rób tego! ). Kolejny dobry powód, aby unikać nazw plików, które wymagają cytowania (np. Które mają w nich spację) :-)git archive
działa również ze zdalnym repozytorium.Aby wyeksportować określoną ścieżkę do repozytorium, dodaj tyle ścieżek, ile chcesz jako ostatni argument git, np .:
źródło
git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf -
(upewnia się, że twoje archiwum znajduje się w folderze)git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git master
I zginęło: Operacja nie jest obsługiwana przez protokół. Nieoczekiwany koniec strumienia poleceń.curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -
per docsSpecjalna odpowiedź na przypadek, jeśli repozytorium jest hostowane na GitHub.
Po prostu użyj
svn export
.O ile wiem Github nie pozwala
archive --remote
. Chociaż GitHub jest kompatybilny z svn i mają wszystkiesvn
dostępne repozytorium git, więc możesz używać gosvn export
tak, jak zwykle, z kilkoma zmianami adresu URL GitHub.Na przykład, aby wyeksportować całe repozytorium, zwróć uwagę, w jaki sposób
trunk
adres URL zastępujemaster
(lub dowolną inną gałąź HEAD projektu ):Możesz wyeksportować pojedynczy plik lub nawet określoną ścieżkę lub folder:
Przykład z biblioteką JavaScript jQuery
HEAD
Oddział lub mistrz oddział będzie dostępna za pomocątrunk
:Oddziały niebędące
HEAD
oddziałami będą dostępne pod/branches/
:Wszystkie tagi poniżej
/tags/
w ten sam sposób:źródło
git archive
współpracuje z GitHub, tak długo, jak używać protokołu git, po prostu wymienićhttps://
sięgit://
w adresie URL. Nie wiem, dlaczego GitHub nie reklamuje tej ukrytej funkcji.fatal: The remote end hung up unexpectedly
. Wypróbowałem na dwóch różnych serwerach z repozytorium jQuery github.git config url.<base>.insteadOf
do buforowania zdalnego repozytorium. Dlategofile://
w rzeczywistości używałem adresu URL. Wątpię, abygit archive
kiedykolwiek działał zgit://
adresami URL, ponieważ musi być w stanie działaćgit-upload-archive
na zdalnym końcu. Powinno to być możliwe przy użyciussh
protokołu, z wyjątkiem tego, że github nie pozwala na to (Invalid command: 'git-upload-archive'
).Z podręcznika Git :
Użycie git-checkout-index do „wyeksportowania całego drzewa”
Możliwość prefiksu sprawia, że trywialne jest użycie indeksu git-checkout jako funkcji „eksportuj jako drzewo”. Po prostu przeczytaj wybrane drzewo do indeksu i wykonaj:
$ git checkout-index --prefix=git-export-dir/ -a
źródło
git read-tree bar:foo
A potemgit checkout-index --prefix=export_dir/ -a
może powinieneś zrobićgit update-index master
Napisałem proste opakowanie
git-checkout-index
, którego możesz użyć w następujący sposób:Jeśli katalog docelowy już istnieje, musisz dodać
-f
lub--force
.Instalacja jest prosta; po prostu upuść skrypt gdzieś w swoim wnętrzu
PATH
i upewnij się, że jest wykonywalny.Repozytorium github dla
git-export
źródło
Wygląda na to, że jest to mniejszy problem z Git niż SVN. Git umieszcza tylko folder .git w katalogu głównym repozytorium, podczas gdy SVN umieszcza folder .svn w każdym podkatalogu. Tak więc „svn export” unika rekurencyjnej magii wiersza poleceń, podczas gdy w Git rekurencja nie jest konieczna.
źródło
Odpowiednik
wewnątrz istniejącego repozytorium jest
Odpowiednik
jest
źródło
git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)
... Jednak archiwizacja za pomocą znaczników czasu nie jest trywialna, więc opublikowałem przykład poniżej .git archive branchname | tar xC otherpath
C
opcja tar to tylko GNU Tar.Jeśli nie wykluczasz plików,
.gitattributes
export-ignore
spróbujgit checkout
i
Dodatkowo możesz uzyskać dowolny oddział lub tag lub z konkretnej rewizji zatwierdzenia, jak w SVN, po prostu dodając SHA1 (SHA1 w Git jest równoważny z numerem rewizji w SVN)
/path/to/checkout/
Musi być pusty, Git nie usunie dowolny plik, ale nadpisuje pliki o tej samej nazwie, bez żadnego ostrzeżeniaAKTUALIZACJA: Aby uniknąć problemu z ścięciem głowy lub pozostawienia nienaruszonego działającego repozytorium podczas korzystania z kasy do eksportu z tagami, gałęziami lub SHA1, należy dodać
-- ./
na końcuPodwójny myślnik
--
mówi gitowi, że wszystko po myślnikach to ścieżki lub pliki, a także w tym przypadku mówi,git checkout
aby nie zmieniaćHEAD
Przykłady:
To polecenie pobierze tylko katalog libs, a także
readme.txt
plik z tego właśnie zatwierdzeniaSpowoduje to utworzenie (nadpisanie)
my_file_2_behind_HEAD.txt
dwóch zatwierdzeń za głowąHEAD^2
Aby uzyskać eksport innego oddziału
Zauważ, że
./
jest względny względem katalogu głównego repozytoriumźródło
Używam git-submodules intensywnie. Ten działa dla mnie:
źródło
.htaccess
?rsync
listy wymienia argument jako--cvs-exclude
. Ponadto nadal kopiuje.gitattributes
i.gitignore
Często odwiedzam tę stronę, gdy szukam sposobu na wyeksportowanie repozytorium git. Moja odpowiedź na to pytanie dotyczy trzech właściwości, które eksport svn ma z założenia w porównaniu z git, ponieważ svn działa zgodnie ze scentralizowanym repozytorium:
Eksport określonej gałęzi za pomocą svn odbywa się poprzez określenie odpowiedniej ścieżki
Podczas budowania określonego wydania przydatne jest sklonowanie stabilnej gałęzi, na przykład
--branch stable
lub--branch release/0.9
.źródło
git archive | tar
Podejście zastosowania POSIX niekompatybilnych środowisku powłoki (np AppVeyor w CMD- lub CI PowerShell oparciu), który jest nie-idealne.git checkout
Podejście modyfikuje indeks głównej gałęzi roboczej, co jest okropne.git checkout-index
Podejście wymaga indeksu głównego drzewa roboczego zostać zmodyfikowany wcześniej, co jest nawet straszne-er. Tradycyjnegit clone
podejście klonuje całą historię repozytorium przed usunięciem tej historii, co jest marnotrawstwem. To jedyne rozsądne rozwiązanie.file://
protokołem (npgit clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo
.). Niezastosowanie się do tego spowoduje wyemitowanie"warning: --depth is ignored in local clones; use file:// instead."
i wykonanie standardowego, a nie płytkiego klonu, co zniweczy cały cel tej odpowiedzi. Salud!Spowoduje to skopiowanie całej zawartości minus pliki .dot. Używam tego do eksportowania sklonowanych projektów git do repozytorium git mojej aplikacji internetowej bez plików .git.
Zwykły stary bash działa po prostu świetnie :)
źródło
.gitignore
, to nie będzie.Tak proste jak klon, a następnie usuń folder .git:
git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git
źródło
W przypadku użytkowników GitHub
git archive --remote
metoda nie będzie działać bezpośrednio, ponieważ eksportowany adres URL jest efemeryczny . Musisz poprosić GitHub o adres URL, a następnie pobrać ten adres URL.curl
ułatwia to:To da ci wyeksportowany kod z lokalnego katalogu. Przykład:
Edytuj
Jeśli chcesz umieścić kod w określonym, istniejącym katalogu (zamiast losowego z github):
źródło
Tak, to jest czysty i schludny polecenia do archiwizowania kodu bez włączenia git w archiwum i jest dobry, aby przejść wokół bez obaw o jakiekolwiek git commit historię.
źródło
Chcę tylko podkreślić, że w przypadku, gdy jesteście
Następnie możesz po prostu użyć
cp foo [destination]
zamiast wspomnianegogit-archive master foo | -x -C [destination]
.źródło
Możesz zarchiwizować zdalne repo przy dowolnym zatwierdzeniu jako plik zip.
źródło
Bash-wdrożenie git-export.
Procesy tworzenia i usuwania plików .segmentowałem według własnych funkcji, aby ponownie wykorzystać je w implementacji „git-archive” (zostaną opublikowane później).
Dodałem również do procesu plik „.gitattributes”, aby usunąć niepotrzebne pliki z docelowego folderu eksportu. Uwzględniono szczegółowość procesu, jednocześnie zwiększając wydajność funkcji „git-export”.
EMPTY_FILE = ". Pusty";
źródło
Jeśli chcesz czegoś, co działa z podmodułami, warto spróbować.
Uwaga:
Założenia:
źródło
W rzeczywistości wolałbym mieć cel dist w twoim Makefile (lub innym systemie kompilacji), który eksportuje dystrybuowalne archiwum twojego kodu (.tar.bz2, .zip, .jar lub cokolwiek innego, co jest odpowiednie). Jeśli akurat używasz GNU autotools lub systemów MakeMaker Perla, myślę, że istnieje ono automatycznie. Jeśli nie, zdecydowanie polecam dodanie tego.
ETA (2012-09-06): Wow, surowe opinie. Nadal uważam, że lepiej jest budować swoje dystrybucje za pomocą narzędzi do budowania niż narzędzia do kontroli kodu źródłowego. Wierzę w budowanie artefaktów za pomocą narzędzi do budowania. W mojej obecnej pracy nasz główny produkt jest zbudowany z celem mrówek. Jesteśmy w trakcie przełączania systemów kontroli kodu źródłowego, a obecność tego celu mrówek oznacza o jeden problem z migracją.
źródło
Spowoduje to skopiowanie plików z zakresu zatwierdzeń (C do G) do pliku tar. Uwaga: spowoduje to tylko zatwierdzenie plików. Nie całe repozytorium. Lekko zmodyfikowany tutaj
Przykładowa historia zatwierdzeń
A -> B -> C -> D -> E -> F -> G -> H -> I
git-diff-tree Podręcznik strony
-r -> recurse w sub-drzewa
--no-commit-id -> git diff-tree wyświetla linię z identyfikatorem zatwierdzenia, jeśli dotyczy. Ta flaga pomija wyjściowy identyfikator zatwierdzenia.
- tylko nazwa -> Pokaż tylko nazwy zmienionych plików.
--diff-filter = ACMRT -> Wybierz tylko te pliki. Zobacz tutaj pełną listę plików
C..G -> Pliki w tym zakresie zatwierdzeń
C ~ -> Dołącz pliki z Commit C. Nie tylko pliki od Commit C.
| xargs tar -rf myTarFile -> wyjścia do tar
źródło
Jak rozumiem pytanie, chodzi bardziej o pobieranie określonego stanu z serwera, bez historii i bez danych innych gałęzi, zamiast wyodrębniania stanu z lokalnego repozytorium (jak robi to wielu anwsers).
Można to zrobić w następujący sposób:
--single-branch
jest dostępna od wersji Git 1.7.10 (kwiecień 2012 r.).--depth
jest (był?) podobno wadliwy, ale w przypadku eksportu wspomniane problemy nie powinny mieć znaczenia.źródło
--depth
, co oznacza,--single-branch
że jeśli nie--no-single-branch
zostanie podana, co oznacza, że prawdopodobnie ma to ten sam efekt. Nie jesteś pewien, czy jakiś ekspert może to potwierdzić?Potrzebowałem tego do skryptu wdrażania i nie mogłem zastosować żadnego z wyżej wymienionych podejść. Zamiast tego wymyśliłem inne rozwiązanie:
źródło
mkdir -p "$2" && git --git-dir="$1" archive HEAD | tar -x -C "$2"
ale nieco dłużej nakręcony.Robiąc to w prosty sposób, jest to funkcja dla .bash_profile, bezpośrednio rozpakowuje archiwum na bieżącą lokalizację, najpierw skonfiguruj swój zwykły [url: path]. UWAGA: Dzięki tej funkcji unikasz operacji klonowania, pobierana jest ona bezpośrednio ze zdalnego repozytorium.
Alias dla .gitconfig, wymagana taka sama konfiguracja (ZADBAJ o wykonanie polecenia w projektach .git, ZAWSZE przeskakuje do katalogu podstawowego, jak tu powiedziano , dopóki nie zostanie to naprawione Osobiście wolę funkcję
źródło
Zdecydowanie najłatwiejszym sposobem, w jaki to zrobiłem (i działa również w systemie Windows) jest
git bundle
:git bundle create /some/bundle/path.bundle --all
Zobacz tę odpowiedź, aby uzyskać więcej informacji: Jak mogę skopiować moje repozytorium git z mojego komputera z systemem Windows na komputer z systemem Linux za pomocą napędu USB?
źródło
git bundle
zawiera.git
folder, czego nie chce OP;git archive
wydaje się bardziej odpowiedni sposób--all
przełączniku?Mam inne rozwiązanie, które działa dobrze, jeśli masz lokalną kopię repozytorium na komputerze, na którym chcesz utworzyć eksport. W takim przypadku przejdź do tego katalogu repozytorium i wprowadź następującą komendę:
GIT_WORK_TREE=outputdirectory git checkout -f
Jest to szczególnie przydatne, jeśli zarządzasz witryną z repozytorium git i chciałbyś pobrać czystą wersję
/var/www/
. W takim przypadku dodaj tę komendę do.git/hooks/post-receive
skryptu (hooks/post-receive
w nagim repozytorium, co jest bardziej odpowiednie w tej sytuacji)źródło
Myślę, że post @Aredridel był najbliższy, ale jest w tym coś więcej - dodam to tutaj; chodzi o to,
svn
że jeśli jesteś w podfolderze repozytorium i robisz:następnie
svn
wyeksportuje wszystkie pliki, które są pod kontrolą wersji (mogły mieć również świeżo dodany lub status Zmodyfikowany) - a jeśli masz inne „śmieci” w tym katalogu (i nie liczę.svn
tutaj podfolderów, ale widoczne rzeczy takie jak.o
pliki) , nie będzie eksportowany; tylko pliki zarejestrowane przez repozytorium SVN zostaną wyeksportowane. Dla mnie jedną fajną rzeczą jest to, że ten eksport obejmuje również pliki z lokalnymi zmianami, które nie zostały jeszcze zatwierdzone; a kolejną fajną rzeczą jest to, że znaczniki czasu eksportowanych plików są takie same jak oryginalne. Lub, jaksvn help export
to ujmuje:Aby zdać sobie sprawę, że
git
nie zachowa znaczników czasu, porównaj dane wyjściowe tych poleceń (w podfolderze wybranegogit
repozytorium):... i:
... a ja w każdym razie zauważam, że
git archive
powoduje to, że wszystkie znaczniki czasu zarchiwizowanego pliku są takie same!git help archive
mówi:... ale najwyraźniej oba przypadki ustawiają „czas modyfikacji każdego pliku”; tym samym nie zachowując rzeczywistych znaczników czasu tych plików!
Tak więc, aby zachować także znaczniki czasu, oto
bash
skrypt, który w rzeczywistości jest „jednowierszowy”, choć nieco skomplikowany - więc poniżej jest opublikowany w wielu wierszach:Zauważ, że zakłada się, że eksportujesz zawartość do „bieżącego” katalogu (powyżej
/media/disk/git_svn/subdir
) - a miejsce docelowe, do którego eksportujesz, jest nieco niedogodnie umieszczone, ale znajduje się wDEST
zmiennej środowiskowej. Zauważ, że z tym skryptem; musisz utworzyćDEST
katalog ręcznie, przed uruchomieniem powyższego skryptu.Po uruchomieniu skryptu powinieneś być w stanie porównać:
... i mam nadzieję, że zobaczą te same znaczniki czasu (dla plików, które były pod kontrolą wersji).
Mam nadzieję, że to komuś pomoże,
zdrowie!
źródło
eksport gita do archiwum zip podczas dodawania prefiksu (np. nazwa katalogu):
źródło
Jeśli potrzebujesz również submodułów, powinno to załatwić sprawę: https://github.com/meitar/git-archive-all.sh/wiki
źródło
Mam następującą funkcję narzędzia w moim pliku .bashrc: tworzy archiwum bieżącego oddziału w repozytorium git.
źródło