Bir "git export" mı ("svn export" gibi)?


2356

.gitHavuz dizini olmadan bir ağacın kopyasını oluşturan iyi bir "git export" çözümü olup olmadığını merak ediyorum . Bildiğim en az üç yöntem var:

  1. git cloneardından .gitdepo dizini kaldırılır .
  2. git checkout-index Bu işlevselliği içerir ancak nasıl yapılacağından tam olarak emin olmadığım "Sadece dizindeki istenen ağacı okuyun ..." ile başlar.
  3. git-exportgit clonegeçici bir konuma, ardından rsync --exclude='.git'da son hedefe kadar devam eden bir üçüncü taraf betiğidir .

Bu çözümlerin hiçbiri beni tatmin edici bulmuyor. En yakın olan svn exportseçenek 1 olabilir, çünkü her ikisi de önce hedef dizinin boş olmasını gerektirir. Ancak seçenek 2, dizine bir ağaç okumanın ne anlama geldiğini varsayarak daha iyi görünüyor.


1
@rnrTom: Somov'un cevabına bakın. (katran arşivinde "sıkıştırılmış" hiçbir şey yoktur).
etarion

23
@mrTom git archive --format zip --output "output.zip" master -0size sıkıştırılmamış bir arşiv verecektir (-0 sıkıştırılmamış işarettir ). git-scm.com/docs/git-archive .

7
@MrTom ile hemfikirim ve arşivin sıkıştırılmış veya sıkıştırılmamış olduğunu düşünmüyorum. SVN ile, exportuzak depodan doğrudan 250 kB alt dizini (revizyonlar hariç, aksi takdirde 200 MB boyutunda olabilir) - ve sadece 250 kB (veya daha fazla) indirme aktarımı için ağa vuracağım. İle git, archivesunucuda etkinleştirilmesi gerekir (bu yüzden deneyemiyorum) - clone --depth 1sunucudan yine de .gitalt klasörün 15MB aldığı 25 MB'lık bir repo alabilir . Bu nedenle, hala cevabın "hayır" olduğunu söyleyebilirim.
sdaau

@mrTom cevap aslında EVET OP'nin cevabına bakın - komutgit checkout-index
nocache

İşte güzel ve basit bir yol:git archive -o latest.zip HEAD
Evgeni Sergeev

Yanıtlar:


2397

Muhtemelen bunu başarmanın en basit yolu şudur git archive. Gerçekten sadece genişletilmiş ağaca ihtiyacınız varsa böyle bir şey yapabilirsiniz.

git archive master | tar -x -C /somewhere/else

Çoğu zaman git 'bir şey ihracat' gerekir, her durumda sıkıştırılmış bir arşiv istiyorum, bu yüzden böyle bir şey yapmak.

git archive master | bzip2 >source-tree.tar.bz2

ZIP arşivi:

git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive daha fazla ayrıntı için oldukça esnektir.


Arşivde .git dizini bulunmasa da .gitignore, .gitattributes vb. Gibi gizli git'e özgü diğer dosyaları içereceğini unutmayın. Arşivde istemiyorsanız, .gitattributes dosyasında export-ignore niteliğini kullanın ve arşivinizi yapmadan önce bunu taahhüt edin. Daha fazla oku...


Not: Dizini dışa aktarmakla ilgileniyorsanız, komut

git checkout-index -a -f --prefix=/destination/path/

(Daha fazla ayrıntı için Greg'in cevabına bakınız)


198
ZIP arşivi:git archive --format zip --output /full/path master
Vadim

221
Arşivin .git dizinini içermeyeceğini, ancak .gitignore, .gitattributes vb. Gibi diğer gizli git'e özgü dosyaları içerdiğini unutmayın. Bu nedenle, istemiyorsanız, export-ignore özniteliğini kullandığınızdan emin olun. bir .gitattributes dosyası ve arşivinizi yapmadan önce bunu taahhüt edin. Bkz feeding.cloud.geek.nz/2010/02/...
mj1531

54
Akışların notunu takip etmek için: zip içinde paketlenecek dizin adını kontrol etmek için komuta '--prefix = bir şey /' dizesi ekleyebilirsiniz. Örneğin git archive --format zip --output /path/to/file.zip --prefix=newdir/ master, çıktıyı kullanırsanız 'file.zip' olarak adlandırılır ancak paketten çıkardığınızda, üst düzey dizin 'newdir' olur. (--Prefix özniteliğini atlarsanız, en üst düzey yön 'dosya' olur.)
Alan W. Smith

89
En kolay yol: git archive -o latest.zip HEADGeçerli daldaki en son taahhüdün içeriğini içeren bir Zip arşivi oluşturur. Çıktı biçiminin çıktı dosyasının uzantısı tarafından çıkartıldığını unutmayın.
nacho4d

37
Git alt modüllerini desteklemez :(
umpirsky

320

Seçenek 2'nin ne anlama geldiğini öğrendim. Bir depodan şunları yapabilirsiniz:

git checkout-index -a -f --prefix=/destination/path/

Yolun sonundaki eğik çizgi önemlidir, aksi takdirde dosyaların / yolun öneki 'yol' öneki olmasıyla sonuçlanır.

Normal bir durumda dizin, deponun içeriğini içerdiğinden, "istenen ağacı dizine okumak" için yapılacak özel bir şey yoktur. Zaten orada.

-aBayrak (Emin buna ne istiyorum yapmaz, çünkü bu durumda bu bayrağı atlamak için ne anlama geldiğini değilim) endeksindeki tüm dosyaları kontrol etmek gereklidir. -fBu komut normalde yapmaz çıktı, herhangi bir varolan dosyaların üzerine bayrak kuvvetleri.

Bu aradığım "git export" gibi görünüyor.


73
... ve SONDA SLASH'I UNUTMAYIN, ya da istediğiniz etkiye sahip olmayacaksınız;)
conny

1
git addKomut indeksi, her neyse içeriği değiştirir git status"kararlı olmak" olarak gösterileri olduğunu fark HEAD ve Dizinin içeriğinden arasında.
Greg Hewgill

7
@conny: yorumunuzu okuyun, unutun ve komutu eğik çizgi olmadan çalıştırın. ipucu:
conny'nin

35
Conny'nin tavsiyesine +1. Ayrıca, gerçekten istediğiniz şeyden ziyade çalışma dizininizde '~' adlı bir dizin oluşturduğundan '~ / dest /' oluşturmaya çalışmayın.
Tahminsizce

5
@KyleHeironimus - '~ / dest / `kullanmayla ilgili uyarınız, önek yolunuzun çevresinde kabuğa tilde genişletme gerçekleştirmemesini söyleyen tırnak işaretleri kullandığınızda doğrudur. Çalışma dizininizde ~(değil '~'!) Adlı bir dizin oluşturulacaktır. git checkout-indexBu konuda özel bir şey yok : Aynı şey doğrudur mkdir '~/dest'( bunu yapma! ). Alıntı gerektiren dosya adlarından kaçınmak için bir başka iyi neden (örneğin, içinde bir boşluk var) :-)
Matt Wallis

254

git archive ayrıca uzak depo ile çalışır.

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

Repo içinde belirli bir yolu dışa aktarmak için git'e son bağımsız değişken olarak istediğiniz sayıda yol ekleyin, örneğin:

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv

6
Bu en çok sevdiğim seçenektir. Çıplak depolarda da çalışmasının ek bir yararı vardır.
innaM

5
Geliştirilmiş sürüm: git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf - (arşivinizin bir klasörde olmasını sağlar)
Nick

7
Not : sunucunun bu özelliği etkinleştirmesi gerekir.
Jakub Narębski

12
Denedim: git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git masterÖlümcül oldu: İşlem protokol tarafından desteklenmiyor. Komut akışının beklenmeyen sonu.
andyf

7
@andyf GitHub kendi yolu vardır: curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -başına docs
fil

62

resim açıklamasını buraya girin

Depo GitHub'da barındırılıyorsa özel bir vaka yanıtı.

Sadece kullan svn export.

Bildiğim kadarıyla Github izin vermiyor archive --remote. GitHub svn uyumlu ve tüm git depolarına sahip olmalarına rağmen, GitHub URL'nizde birkaç ayarlamayla normalde yaptığınız gibi svnkullanabilirsiniz svn export.

Örneğin, bir deponun tamamını dışa aktarmak trunkiçin URL'de nasıl yer değiştirdiğine master(veya projenin HEAD şubesinin ne şekilde ayarlandığına ) dikkat edin:

svn export https://github.com/username/repo-name/trunk/

Ayrıca tek bir dosyayı veya belirli bir yolu veya klasörü dışa aktarabilirsiniz:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

JQuery JavaScript Kütüphanesi ile örnek

HEADŞube veya ana dal mevcuttur kullanıyor olacak trunk:

svn ls https://github.com/jquery/jquery/trunk

Olmayan HEAD dallar erişilebilir altında olacak /branches/:

svn ls https://github.com/jquery/jquery/branches/2.1-stable

Altındaki tüm etiketler/tags/ aynı şekilde:

svn ls https://github.com/jquery/jquery/tags/2.1.3

1
git archivesürece git protokolünü kullanmak gibi, Sadece değiştirin GitHub'dan ile para cezası çalışır https://ile git://URL'de. GitHub'ın neden bu gizli özelliğin reklamını yapmadığını bilmiyorum.
Neil Mayhew

1
@NeilMayhew Benim için çalışmıyor, anladım fatal: The remote end hung up unexpectedly. JQuery github repo ile iki farklı sunucu üzerinde çalıştı.
Anthony Hatzopoulos

Haklısın. git config url.<base>.insteadOfUzak depoyu önbelleğe almak için kullandığımı unutmuştum . Bu yüzden file://gerçekte bir URL kullanıyordum . Uzak uçta çalışabilmesi gerektiğinden URL'lerle git archiveçalışabileceğinden şüpheliyim . Protokolün kullanılması mümkün olmalıdır , ancak github buna izin vermez ( ). git://git-upload-archivesshInvalid command: 'git-upload-archive'
Neil Mayhew

Dahili olarak barındırılan git depolarında yapmak istiyorsanız github gibi davranan bir yerel sunucu aracı kullanmak için herhangi bir yolu?
kriss

1
seçildi - Git'in bu özelliğe sahip olmaması tamamen garip ve svn'ye başvurmalıyız
Jason S

40

Gönderen Git Manuel :

"Tüm ağacın dışa aktarılması" için git-checkout-index özelliğini kullanma

Önek yeteneği temel olarak git-checkout-index'ini "ağaç olarak dışa aktar" işlevi olarak kullanmayı önemsiz kılar. İstediğiniz ağacı dizine okuyun ve şunları yapın:

$ git checkout-index --prefix=git-export-dir/ -a


19
Bence karışıklık "istenen ağacı indekse okuyun" ifadesidir.
davetron5000

4
Şube çubuğunda dizin foo vermek istiyorsanız, o zaman bu olur git read-tree bar:fooVe bundan git checkout-index --prefix=export_dir/ -asonra belki de yapmalısınızgit update-index master
Pascal Rosin

1
@JohnWeldon Önce repoyu klonlaman gerekiyor mu? Eğer öyleyse, o zaman kabul etmem, çünkü bir alt dizinin "svn export" bütün noktası doğrudan o alt dizinin bir kopyasını almaktır; Birinin 1GB Git repo'su varsa ve tek istediğim 10kB'lik bir alt dizinse, her şeyi klonlamamı gerektiriyor.
Jason S

3
Ayrıca ne demek hakkında hiçbir fikrim yok "İstediğiniz ağacı dizine okumak" yorum ile yankı @ davetron5000.
Jason S

38

Etrafında git-checkout-indexbu şekilde kullanabileceğiniz basit bir paket yazdım :

git export ~/the/destination/dir

Hedef dizin zaten varsa, -fveya eklemeniz gerekir --force.

Kurulum basit; komut dosyasını içinde bir yere bırakın ve PATHçalıştırılabilir olduğundan emin olun.

Github deposu git-export


15
Bu sargı platform agnostik değildir; / bin / sh kullanır. Yani Windows'daysanız, bu çözüm muhtemelen sizin için çalışmaz.
shovavnik

18
Uhh, bu senaryo 57 satırlık dokümantasyon, boşluk, kurulum, argüman ayrıştırma ve aslında bir şey yapan tek satır ...
Vladimir Panteleev

36

Bu, Git ile ilgili olarak SVN'den daha az sorun olduğu anlaşılıyor. Git sadece depo köküne bir .git klasörü koyarken SVN her alt dizine bir .svn klasörü koyar. Bu nedenle "svn export" özyinelemeli komut satırı sihrini önlerken Git özyineleme ile gerekli değildir.


26
SVN 1.7'den itibaren yalnızca bir .svn klasörü vardır: subversion.apache.org/docs/release-notes/1.7.html#single-db
kostmo

Bu, dışa aktarma svn siler ek dosyalardan kurtulmak olmaz. Yani bu kesinlikle cevap değil.
ygoe

28

Eşdeğeri

svn export . otherpath

mevcut bir repo içinde

git archive branchname | (cd otherpath; tar x)

Eşdeğeri

svn export url otherpath

dır-dir

git archive --remote=url branchname | (cd otherpath; tar x)

1
teşekkürler, bu eksikti oldu ... Ayrıca, ihracat zaman damgalarını kontrol etmek için (onlar dosyaları gibi korunmaz), kullanın git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)... Ancak, zaman damgaları ile arşivleme tam önemsiz değil, bu yüzden bir Aşağıdaki örnek .
sdaau

1
Subshell yerine katran için C seçeneğini kullanabilirsiniz, örneğin: git archive branchname | tar xC otherpath
James Moore

CKatran seçeneğinin sadece GNU Tar olduğunu belirtir .
aredridel

22

İle dosyaları hariç tutmuyorsanız .gitattributes export-ignoredeneyingit checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f Dizinden
yolları kontrol ederken, birleştirilmemiş girdiler başarısız olmaz; bunun yerine birleştirilmemiş girişler yok sayılır.

ve

-q
Ayrıntılı kaçının

Buna ek olarak, herhangi bir Şube veya Etiketi veya SVN'deki gibi belirli bir Tamamlama Revizyonundan sadece SHA1'i ekleyebilirsiniz (Git'teki SHA1, SVN'deki Revizyon Numarasına eşdeğerdir)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

/path/to/checkout/Git herhangi bir dosyayı silmez, boş olmalıdır, ancak herhangi bir uyarı olmadan aynı isimde dosyalar üzerine yazılır

GÜNCELLEME: Etiketleri, dalları veya SHA1 ile dışa aktarma için ödeme kullanırken başlı sorunu önlemek veya çalışma havuzunu olduğu gibi bırakmak için -- ./, sonuna eklemeniz gerekir

Çift çizgi --tire sonra her şey yolları veya dosyaları vardır ve bu durumda da söyler git'e anlatıyor git checkoutdeğişmez etmekHEAD

Örnekler:

Bu komut sadece libs dizini alacak ve ayrıca readme.txtbu dosya tam olarak taahhüt

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

Bu my_file_2_behind_HEAD.txt, kafanın arkasında iki komisyon oluşturacak (üzerine yazacak)HEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

Başka bir şubenin ihracatını almak

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

Deponun ./kökü ile ilgili uyarı


Aslında, diğerleri ve upvotes arasında, bu benim için en iyi çalıştı, herhangi bir sıkıştırma olmadan, çıplak depolarla (gitolit) iyi çalışıyor.
takeshin

1
SHA1 kasasında depoda bir "baş" sorunu oluşturacağına dikkat edin
user5286776117878

Aslında @ITGabs, bu ".git" klasörü indirmez. Bu yüzden indirilen klasör git deposu değildir, bu nedenle teknik olarak "kafalı" değildir
Fabio Marreco

@FabioMarreco Behead sorunu dışa aktarılan / indirilen dosyalarda olmayan depoda, daha fazla ayrıntı için cevabı güncelliyoruz
user5286776117878

3
Bu benim için harika çalıştı. Ama ilk başta "Git git deposu değil" hata mesajları aldım. Sonra "/ path / to / repo /" .git klasörünü işaret etmek zorunda bulundu. Bu işe yaradı: --git-dir = / path / to / repo / .git
philburk

21

Git-submodülleri çok yoğun kullanıyorum. Bu benim için çalışıyor:

rsync -a ./FROM/ ./TO --exclude='.*'

1
Bu, adları bir nokta ile başlayan dosyaları kaçırmaz .htaccessmı?
Greg Hewgill

8
İyi bir çözüm,
--exclude

18
--exclude-vcs eğer bu taktikte olsaydınız
plod

./FROM/ uzak bir repo olabilir mi?
Direnç Tasarım

2
Bir FYI olarak, kopyamda rsyncargüman olarak listelenir --cvs-exclude. Ayrıca, yine de kopyalanıyor .gitattributesve.gitignore
Ryan Ransford

19

Git deposunu dışa aktarmanın bir yolunu ararken bu sayfaya sık sık vurdum. Bu soruya cevabım, svn dışa aktarmanın tasarım ile git'e göre üç özelliğini ele alıyor, çünkü svn merkezi bir depo yaklaşımını izliyor:

  • Tüm revizyonları dışa aktarmayarak uzak bir depo konumuna giden trafiği en aza indirir
  • Dışa aktarma dizinine meta bilgileri içermez
  • Svn kullanarak belirli bir dalın dışa aktarılması, uygun yol belirtilerek gerçekleştirilir

    git clone --depth 1 --branch master git://git.somewhere destination_path
    rm -rf destination_path/.git
    

Belirli bir salıverme oluştururken, örneğin --branch stableveya gibi kararlı bir dalı klonlamak yararlıdır --branch release/0.9.


Hedef varsa ve boş değilse bu çalışmaz.
İsimsiz

2
Tek Doğru Cevap: derinliklerden doğar. git archive | tarYaklaşım POSIX uyumlu kabuk ortamlarda ideal olmayan (örneğin, AppVeyor en cmd veya PowerShell tabanlı CI) için uygulanamaz. git checkoutYaklaşım korkunç ana çalışma ağacının dizinini değiştirir. git checkout-indexYaklaşım bile korkunç-er olduğunu önceden değiştirilecek ana çalışma ağacının dizinini gerektirir. Geleneksel git cloneyaklaşım, savurgan olan tarihi silmeden önce deponun tarihinin tamamını klonlar. Geriye kalan tek aklı başında çözüm bu.
Cecil Curry

1
Yerel olarak dışa aktarmak için, klonlanacak Git çalışma ağacının mutlak yolunun file://protokolün önüne (ör git clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo.) Konması gerektiğini unutmayın . Bunu yapmazsanız "warning: --depth is ignored in local clones; use file:// instead.", bu cevabın tüm amacını yenerek sığ klon yerine standart bir standart yayar ve gerçekleştirir. Salud!
Cecil Curry

16

Bu işlem tüm içeriği kopyalar, .dot dosyaları eksi. Git klonlanmış projeleri web uygulamamın git repo'suna .git şeyler olmadan dışa aktarmak için bunu kullanıyorum.

cp -R ./path-to-git-repo / yol / / hedef /

Düz eski bash sadece harika çalışıyor :)


Neden sadece uzaktan kumandaya basmıyorsun? Bash'tan bile daha basit.
nurettin

2
Web uygulamalarının bir parçası olan ve adı dot ile başlayan dosyalara ne dersiniz? :) .htaccess hakkında düşünün
Artur

3
Bazen içinde olanları da göz ardı etmek istersiniz .gitignore, bu olmaz.
fregante

14

Klonlama kadar basit .git klasörünü silin:

git clone url_of_your_repo path_to_export && rm -rf path_to_export/.git


4
Dürüst olmak gerekirse - bu soruda da 1 numara olan bu cevap, zamanın% 99'unu yapacağınız şeydir. Bu cevapların çoğu aşırı derecede karmaşık.
Geoff Nixon

11

GitHub kullanıcıları için, dışa aktarma URL'si geçici olduğundan git archive --remoteyöntem doğrudan çalışmaz . GitHub'dan URL'yi istemeniz ve ardından bu URL'yi indirmeniz gerekir. bunu kolaylaştırır:curl

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf -

Bu, size yerel bir dizindeki dışa aktarılan kodu verecektir. Misal:

$ curl -L https://api.github.com/repos/jpic/bashworks/tarball | tar xzf -
$ ls jpic-bashworks-34f4441/
break  conf  docs  hack  LICENSE  mlog  module  mpd  mtests  os  README.rst  remote  todo  vcs  vps  wepcrack

Düzenleme
Kodun belirli bir varolan dizine (github'dan rastgele bir dizin yerine) koyulmasını istiyorsanız :

curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | \
tar xzC /path/you/want --strip 1

11

Evet, bu , arşive herhangi bir git eklemesi olmadan kodunuzu arşivlemek için temiz ve düzgün bir komuttur ve herhangi bir git kesin geçmişi hakkında endişelenmeden dolaşmak iyidir.

git archive --format zip --output /full/path/to/zipfile.zip master 

Bu harika, sonra gitignore kaldırmak gerekir ve yapılır ve paylaşmaya hazır.
Sogger

.Gitgnore vb Çıkarma kabul cevap yorumlarda: kullanım dosyası .gitattributes Görmekten feeding.cloud.geek.nz/posts/excluding-files-from-git-archive
Sogger

10

Sadece şunu belirtmek istiyorum ki

  1. deponun bir alt klasörünü dışa aktarma (SVN dışa aktarma özelliğini bu şekilde kullandım)
  2. bu klasörden dağıtım hedefine her şeyi kopyalamakta sorun yoktur
  3. ve zaten tüm deponun bir kopyasına sahip olduğunuzdan.

Sonra sadece cp foo [destination]belirtilen yerine kullanabilirsiniz git-archive master foo | -x -C [destination].


9

Uzak bir repoyu herhangi bir taahhütte zip dosyası olarak arşivleyebilirsiniz.

git archive --format=zip --output=archive.zip --remote=USERNAME@HOSTNAME:PROJECTNAME.git HASHOFGITCOMMIT

8

Git-dışa aktarmanın bas-uygulaması.

'Git-archive' uygulamasında yeniden kullanmak amacıyla .empty dosyası oluşturma ve kaldırma işlemlerini kendi işlevlerine göre bölümlere ayırdım (daha sonra yayınlanacaktır).

İstenmeyen dosyaları hedef dışa aktarma klasöründen kaldırmak için işleme '.gitattributes' dosyasını da ekledim. 'Git-export' işlevini daha verimli hale getirirken sürece ayrıntı katma.

EMPTY_FILE = "boş";

function create_empty () {
## Processing path (target-dir):
    TRG_PATH="${1}";
## Component(s):
    EXCLUDE_DIR=".git";
echo -en "\nAdding '${EMPTY_FILE}' files to empty folder(s): ...";
    find ${TRG_PATH} -not -path "*/${EXCLUDE_DIR}/*" -type d -empty -exec touch {}/${EMPTY_FILE} \;
#echo "done.";
## Purging SRC/TRG_DIRs variable(s):
    unset TRG_PATH EMPTY_FILE EXCLUDE_DIR;
    return 0;
  }

declare -a GIT_EXCLUDE;
function load_exclude () {
    SRC_PATH="${1}";
    ITEMS=0; while read LINE; do
#      echo -e "Line [${ITEMS}]: '${LINE%%\ *}'";
      GIT_EXCLUDE[((ITEMS++))]=${LINE%%\ *};
    done < ${SRC_PATH}/.gitattributes;
    GIT_EXCLUDE[${ITEMS}]="${EMPTY_FILE}";
## Purging variable(s):
    unset SRC_PATH ITEMS;
    return 0;
  }

function purge_empty () {
## Processing path (Source/Target-dir):
    SRC_PATH="${1}";
    TRG_PATH="${2}";
echo -e "\nPurging Git-Specific component(s): ... ";
    find ${SRC_PATH} -type f -name ${EMPTY_FILE} -exec /bin/rm '{}' \;
    for xRULE in ${GIT_EXCLUDE[@]}; do
echo -en "    '${TRG_PATH}/{${xRULE}}' files ... ";
      find ${TRG_PATH} -type f -name "${xRULE}" -exec /bin/rm -rf '{}' \;
echo "done.'";
    done;
echo -e "done.\n"
## Purging SRC/TRG_PATHs variable(s):
    unset SRC_PATH; unset TRG_PATH;
    return 0;
  }

function git-export () {
    TRG_DIR="${1}"; SRC_DIR="${2}";
    if [ -z "${SRC_DIR}" ]; then SRC_DIR="${PWD}"; fi
    load_exclude "${SRC_DIR}";
## Dynamically added '.empty' files to the Git-Structure:
    create_empty "${SRC_DIR}";
    GIT_COMMIT="Including '${EMPTY_FILE}' files into Git-Index container."; #echo -e "\n${GIT_COMMIT}";
    git add .; git commit --quiet --all --verbose --message "${GIT_COMMIT}";
    if [ "${?}" -eq 0 ]; then echo " done."; fi
    /bin/rm -rf ${TRG_DIR} && mkdir -p "${TRG_DIR}";
echo -en "\nChecking-Out Index component(s): ... ";
    git checkout-index --prefix=${TRG_DIR}/ -q -f -a
## Reset: --mixed = reset HEAD and index:
    if [ "${?}" -eq 0 ]; then
echo "done."; echo -en "Resetting HEAD and Index: ... ";
        git reset --soft HEAD^;
        if [ "${?}" -eq 0 ]; then
echo "done.";
## Purging Git-specific components and '.empty' files from Target-Dir:
            purge_empty "${SRC_DIR}" "${TRG_DIR}"
          else echo "failed.";
        fi
## Archiving exported-content:
echo -en "Archiving Checked-Out component(s): ... ";
        if [ -f "${TRG_DIR}.tgz" ]; then /bin/rm ${TRG_DIR}.tgz; fi
        cd ${TRG_DIR} && tar -czf ${TRG_DIR}.tgz ./; cd ${SRC_DIR}
echo "done.";
## Listing *.tgz file attributes:
## Warning: Un-TAR this file to a specific directory:
        ls -al ${TRG_DIR}.tgz
      else echo "failed.";
    fi
## Purgin all references to Un-Staged File(s):
   git reset HEAD;
## Purging SRC/TRG_DIRs variable(s):
    unset SRC_DIR; unset TRG_DIR;
    echo "";
    return 0;
  }

Çıktı:

$ git-export /tmp/rel-1.0.0

Boş klasörlere '.empty' dosyaları ekleniyor: ... tamamlandı.

Check-Out Dizin bileşenleri: ... bitti.

HEAD ve Index'in sıfırlanması: ... bitti.

Git'e Özgü bileşenleri temizleme: ...

'/tmp/rel-1.0.0/{.buildpath}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.project}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.gitignore}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.git}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.gitattributes}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{*.mno}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{*~}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.*~}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{*.swp}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{*.swo}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.DS_Store}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.settings}' dosyalar ... bitti. '

'/tmp/rel-1.0.0/{.empty}' dosyalar ... bitti. '

yapılır.

Check-Out bileşenlerini arşivleme: ... bitti.

-rw-r - r-- 1 yönetici tekerleği 25445901 3 Kas 12:57 /tmp/rel-1.0.0.tgz

Şimdi 'git archive' işlevselliğini 'create_empty' işlevini ve diğer özellikleri kullanan tek bir sürece dahil ettik.

function git-archive () {
    PREFIX="${1}"; ## sudo mkdir -p ${PREFIX}
    REPO_PATH="`echo "${2}"|awk -F: '{print $1}'`";
    RELEASE="`echo "${2}"|awk -F: '{print $2}'`";
    USER_PATH="${PWD}";
echo "$PREFIX $REPO_PATH $RELEASE $USER_PATH";
## Dynamically added '.empty' files to the Git-Structure:
    cd "${REPO_PATH}"; populate_empty .; echo -en "\n";
#    git archive --prefix=git-1.4.0/ -o git-1.4.0.tar.gz v1.4.0
# e.g.: git-archive /var/www/htdocs /repos/domain.name/website:rel-1.0.0 --explode
    OUTPUT_FILE="${USER_PATH}/${RELEASE}.tar.gz";
    git archive --verbose --prefix=${PREFIX}/ -o ${OUTPUT_FILE} ${RELEASE}
    cd "${USER_PATH}";
    if [[ "${3}" =~ [--explode] ]]; then
      if [ -d "./${RELEASE}" ]; then /bin/rm -rf "./${RELEASE}"; fi
      mkdir -p ./${RELEASE}; tar -xzf "${OUTPUT_FILE}" -C ./${RELEASE}
    fi
## Purging SRC/TRG_DIRs variable(s):
    unset PREFIX REPO_PATH RELEASE USER_PATH OUTPUT_FILE;
    return 0;
  }

Kullanım: git-archive [/ var / www / htdocs] /repos/web.etkialanı/website:rel-1.0.0
tocororo

8

Alt modüller ile çalışan bir şey istiyorsanız, bu gitmeye değer olabilir.

Not:

  • MASTER_DIR = alt modüllerinizin de teslim alındığı bir ödeme
  • DEST_DIR = bu dışa aktarmanın biteceği yer
  • Eğer rsync'iniz varsa, sanırım aynı şeyi daha az top ağrısıyla da yapabileceksiniz.

Varsayımlar:

  • Bunu MASTER_DIR üst dizininden çalıştırmalısınız (yani MASTER_DIR cd'sinden ..)
  • DEST_DIR'in oluşturulduğu varsayılıyor. İsterseniz bir DEST_DIR oluşturmayı içerecek şekilde değiştirmek oldukça kolaydır.

cd MASTER_DIR && tar -zcvf ../DEST_DIR/export.tar.gz --exclude = '. git *'. && cd ../DEST_DIR/ && tar xvfz export.tar.gz && rm export.tar.gz


6

Benim tercih aslında bir var olacaktır dist sizin Makefiledaki hedef (veya diğer yapı sistemi) o ihracat (uygun ne olursa olsun .tar.bz2, .zip, .jar veya) Kodunuzun dağıtılabilir arşivi. GNU otoklavları veya Perl'in MakeMaker sistemlerini kullanıyorsanız, bunun sizin için otomatik olarak mevcut olduğunu düşünüyorum. Değilse, eklemenizi kesinlikle tavsiye ederim.

ETA (2012-09-06): Vay canına, sert inişler. Hala dağıtım kodlarınızı kaynak kodu kontrol aracından ziyade derleme araçlarınızla oluşturmanın daha iyi olduğuna inanıyorum. Yapım araçlarıyla eserler inşa etmeye inanıyorum. Şu anki işimde ana ürünümüz bir karınca hedefi ile inşa edildi. Kaynak kodu kontrol sistemlerinin anahtarlanmasının ortasındayız ve bu karınca hedefinin varlığı, göç konusunda daha az güçlük anlamına gelir.


Aklımda olan proje bir kod projesi değil; daha çok bir web sitesi projesi boyunca olur.
Greg Hewgill

Soruyu ele almıyor.
Andrew Ferrier

1
Evet, böyle bir cevap herkesin ihtiyaçlarına uymayabilir, ancak aşağı oylar tuhaftır. Bu ise , birçok senaryolarda, aslında sadece doğru cevap tamamen geçerli cevap, vb. Bu konuyu bir "vc aracı sorunu" olarak düşünmenin çoğu zaman yanlış yoldan gittiği çok geçerli bir nokta.
snogglethorpe

6

Bu işlem, bir dizi işlemdeki dosyaları (C'den G'ye) bir tar dosyasına kopyalar. Not: Bu yalnızca dosyaların işlenmesini sağlar. Deponun tamamı değil. Buradan biraz değiştirildi

İşlem Geçmişi Örneği

A -> B -> C -> D -> E -> F -> G -> H -> I

git diff-tree -r --no-commit-id --name-only --diff-filter=ACMRT C~..G | xargs tar -rf myTarFile.tar

git-diff-tree Kılavuz Sayfası

-r -> alt ağaçlara geri dönüş

--no-commit-id -> git diff-tree uygulanabilir olduğunda kesin kimliğe sahip bir satır verir. Bu bayrak, taahhüt kimliği çıktısını bastırdı.

- yalnızca ad -> Yalnızca değiştirilen dosyaların adlarını göster.

--diff-filter = ACMRT -> Yalnızca bu dosyaları seçin. Dosyaların tam listesi için buraya bakın

C..G -> Bu taahhüt aralığındaki dosyalar

C ~ -> C Grubundan dosyaları dahil et.

| xargs tar -rf myTarFile -> tar çıkışları


5

Soruyu anladığım kadarıyla, yerel bir depodan bir durumu ayıklamak yerine (burada birçok anws gibi) sunucudan, tarih olmadan ve diğer dalların verileri olmadan sadece belirli bir durumu indirmeyle ilgili.

Bu şu şekilde yapılabilir:

git clone -b someBranch --depth 1 --single-branch git://somewhere.com/repo.git \
&& rm -rf repo/.git/
  • --single-branch Git 1.7.10 (Nisan 2012) tarihinden beri kullanılabilmektedir.
  • --deptholduğu (? idi) bildirildiğine hatalı ama bir ihracat durum için, belirtilen sorunların meselesi olmamalı.

Not: Sadece 2 sayfa anwsers olduğunu fark ettim, göndermeden önce sadece birine baktım. Yalnızca bir kez benzer anwser vardır --depthima, --single-branchsürece --no-single-branchverilen bu muhtemelen aynı etkiye sahiptir yani edilir. Yine de emin değilim, bazı uzmanlar onaylayabilir?
Ondra Žižka

4

Bir dağıtım komut dosyası için buna ihtiyacım vardı ve yukarıda belirtilen yaklaşımlardan hiçbirini kullanamadım. Bunun yerine farklı bir çözüm buldum:

#!/bin/sh
[ $# -eq 2 ] || echo "USAGE $0 REPOSITORY DESTINATION" && exit 1
REPOSITORY=$1
DESTINATION=$2
TMPNAME="/tmp/$(basename $REPOSITORY).$$"
git clone $REPOSITORY $TMPNAME
rm -rf $TMPNAME/.git
mkdir -p $DESTINATION
cp -r $TMPNAME/* $DESTINATION
rm -rf $TMPNAME

Okuma ağacı / ödeme dizini veya arşiv çözümüyle ilgili sorun neydi? Bildiğim kadarıyla mkdir -p "$2" && git --git-dir="$1" archive HEAD | tar -x -C "$2"biraz daha uzun sarılmış gibi bir şeyin eşdeğerini yaptığınızı söyleyebilirim .
CB Bailey

1
Okuma ağacını uzak bir depodan çalıştıramadım ve arşiv çözümü github ile çalışmıyor.
troelskn

Evet arşivi ile Geçersiz bir komut alın: 'git-upload-archive' ... hatası var ve core.gitProxy yapılandırma seçeneği ve GIT_PROXY_COMMAND ortam değişkeni seti yok
tgkprog

4

Bunu kolay bir şekilde yapmak, bu .bash_profile için bir işlevdir, mevcut konumdaki arşivi doğrudan açar, önce her zamanki [url: yol] 'u yapılandırır. NOT: Bu işlevle klonlama işleminden kaçınırsınız, doğrudan uzak repodan alır.

gitss() {
    URL=[url:path]

    TMPFILE="`/bin/tempfile`"
    if [ "$1" = "" ]; then
        echo -e "Use: gitss repo [tree/commit]\n"
        return
    fi
    if [ "$2" = "" ]; then
        TREEISH="HEAD"
    else
        TREEISH="$2"
    fi
    echo "Getting $1/$TREEISH..."
    git archive --format=zip --remote=$URL/$1 $TREEISH > $TMPFILE && unzip $TMPFILE && echo -e "\nDone\n"
    rm $TMPFILE
}

.Gitconfig için diğer ad, aynı yapılandırma gerekli (.git projeleri içindeki komutu yürütürken BAKIM ALIN, her zaman burada belirtildiği gibi temel direklere atlar , bu düzeltilene kadar kişisel olarak işlevi tercih ederim

ss = !env GIT_TMPFILE="`/bin/tempfile`" sh -c 'git archive --format=zip --remote=[url:path]/$1 $2 \ > $GIT_TMPFILE && unzip $GIT_TMPFILE && rm $GIT_TMPFILE' -


4

Verme işlemini oluşturmak istediğiniz makinede deponun yerel bir kopyasına sahipseniz, iyi çalışan başka bir çözümüm var. Bu durumda bu depo dizinine gidin ve şu komutu girin:

GIT_WORK_TREE=outputdirectory git checkout -f

Bu özellikle git deposuna sahip bir web sitesini yönetiyorsanız ve içinde temiz bir sürüm almak istiyorsanız kullanışlıdır /var/www/. Bu durumda, bu .git/hooks/post-receivekomut dosyasını bir komut dosyasına ekleyin ( hooks/post-receivebu durumda daha uygun olan çıplak bir depoda)


3

Sanırım @Aredridel'in gönderisi en yakındı , ama bundan biraz daha fazlası var - bunu buraya ekleyeceğim; şey, svnbir repo alt klasöründe iseniz ve yaparsanız:

/media/disk/repo_svn/subdir$ svn export . /media/disk2/repo_svn_B/subdir

daha sonra svnrevizyon kontrolü altındaki tüm dosyaları dışa aktarır (ayrıca yeni eklenmiş olabilir; veya Değiştirilmiş durum) - ve bu dizinde başka "önemsiz" varsa (ve .svnburada alt klasörleri saymıyorum , ancak .odosyalar gibi görünür şeyler ) bu olacak değil ihraç edilecek; yalnızca SVN repo tarafından kaydedilen dosyalar dışa aktarılır. Benim için güzel bir şey, bu dışa aktarmanın aynı zamanda henüz yapılmayan yerel değişikliklere sahip dosyaları içermesidir ; ve güzel bir şey de, dışa aktarılan dosyaların zaman damgalarının orijinal dosyalarla aynı olmasıdır. Veya svn help exportbelirttiği gibi:

  1. PATH1 tarafından belirtilen çalışma kopyasından temiz bir dizin ağacını, aksi takdirde ÇALIŞMA durumunda verilirse REV revizyonunda PATH2'ye dışa aktarır. ... REV belirtilmezse, tüm yerel değişiklikler korunur. Sürüm kontrolü altında olmayan dosyalar kopyalanmayacaktır.

Bunun gitzaman damgalarını korumadığını anlamak için, bu komutların çıktılarını karşılaştırın ( gitseçtiğiniz bir repo alt klasöründe ):

/media/disk/git_svn/subdir$ ls -la .

... ve:

/media/disk/git_svn/subdir$ git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -)

... ve ben, her halükarda, git archivearşivlenen dosyanın tüm zaman damgalarının aynı olmasına neden olduğunu görüyoruz ! git help archivediyor:

git arşivi, ağaç kimliği verildiğinde, taahhüt kimliği veya etiket kimliği verildiğinde farklı davranır. İlk durumda, geçerli saat arşivdeki her dosyanın değişiklik zamanı olarak kullanılır. İkinci durumda, bunun yerine atıfta bulunulan tamamlama nesnesine kaydedilen tamamlama süresi kullanılır.

... ancak görünüşe göre her iki durumda da " her dosyanın değişiklik zamanı " belirlendi; böylelikle değil bu dosyaların gerçek damgalarını koruyarak!

Yani, zaman damgalarını korumak için, burada bashbiraz karmaşık olsa da, aslında bir "tek satır" olan bir komut dosyası var - bu yüzden aşağıda birden çok satırda yayınlanmıştır:

/media/disk/git_svn/subdir$ git archive --format=tar master | (tar tf -) | (\
  DEST="/media/diskC/tmp/subdirB"; \
  CWD="$PWD"; \
  while read line; do \
    DN=$(dirname "$line"); BN=$(basename "$line"); \
    SRD="$CWD"; TGD="$DEST"; \
    if [ "$DN" != "." ]; then \
      SRD="$SRD/$DN" ; TGD="$TGD/$DN" ; \
      if [ ! -d "$TGD" ] ; then \
        CMD="mkdir \"$TGD\"; touch -r \"$SRD\" \"$TGD\""; \
        echo "$CMD"; \
        eval "$CMD"; \
      fi; \
    fi; \
    CMD="cp -a \"$SRD/$BN\" \"$TGD/\""; \
    echo "$CMD"; \
    eval "$CMD"; \
    done \
)

İçeriği "geçerli" dizinde (yukarıda /media/disk/git_svn/subdir) dışa aktardığınızı ve dışa aktardığınız hedefin biraz uygunsuz bir şekilde yerleştirildiğini, ancak DESTortam değişkeninde olduğunu unutmayın. Bu komut dosyası ile; DESTyukarıdaki komut dosyasını çalıştırmadan önce dizini kendiniz oluşturmalısınız .

Komut dosyası çalıştırıldıktan sonra aşağıdakileri karşılaştırabilmeniz gerekir:

ls -la /media/disk/git_svn/subdir
ls -la /media/diskC/tmp/subdirB   # DEST

... ve umarım aynı zaman damgalarını görürsünüz (sürüm kontrolü altındaki dosyalar için).

Umarım bu birine yardımcı olur,
Şerefe!


3

ön ek eklerken bir zip arşivine git dışa aktarma (ör. dizin adı):

git archive master --prefix=directoryWithinZip/  --format=zip -o out.zip


1

i .bashrc dosyamda aşağıdaki yardımcı program işlevi var: git deposunda geçerli dalı bir arşiv oluşturur.

function garchive()
{
  if [[ "x$1" == "x-h" || "x$1" == "x" ]]; then
    cat <<EOF
Usage: garchive <archive-name>
create zip archive of the current branch into <archive-name>
EOF
  else
    local oname=$1
    set -x
    local bname=$(git branch | grep -F "*" | sed -e 's#^*##')
    git archive --format zip --output ${oname} ${bname}
    set +x
  fi
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.