Câu hỏi Làm một "git xuất khẩu" (như "xuất khẩu svn")?


Tôi đã tự hỏi liệu có một giải pháp "git export" tốt tạo ra một bản sao của một cái cây không có .git thư mục kho lưu trữ. Có ít nhất ba phương pháp tôi biết:

  1. git clone theo sau bằng cách xóa .git thư mục kho lưu trữ.
  2. git checkout-index ám chỉ đến chức năng này nhưng bắt đầu với "Chỉ cần đọc cây mong muốn vào chỉ mục ..." mà tôi không hoàn toàn chắc chắn làm thế nào để làm.
  3. git-export là một tập lệnh của bên thứ ba về cơ bản git clone vào một vị trí tạm thời, tiếp theo là rsync --exclude='.git' vào điểm đến cuối cùng.

Không ai trong số các giải pháp này thực sự tấn công tôi như là thỏa đáng. Cái gần nhất với svn export có thể là tùy chọn 1, vì cả hai đều yêu cầu thư mục đích trống trước. Nhưng tùy chọn 2 có vẻ tốt hơn, giả sử tôi có thể tìm ra ý nghĩa của việc đọc một cây vào chỉ mục.


2165
2017-10-02 02:21


gốc


@rnrTom: Xem câu trả lời của Somov. (không có gì "nén" trong kho lưu trữ tar). - etarion
@mrTom git archive --format zip --output "output.zip" master -0 sẽ cung cấp cho bạn một kho lưu trữ không nén (-0 là cờ để giải nén). git-scm.com/docs/git-archive.
Tôi đồng ý với @mrTom, và tôi không nghĩ rằng các kho lưu trữ được nén hoặc giải nén là vấn đề chính. Với SVN, tôi có thể export một thư mục con 250 kB trực tiếp từ kho lưu trữ từ xa (có thể có kích thước 200 MB, không bao gồm sửa đổi) - và tôi sẽ chỉ truy cập mạng tải xuống 250 kB (hoặc lâu hơn). Với git, archive phải được kích hoạt trên máy chủ (vì vậy tôi không thể thử nó) - clone --depth 1 từ máy chủ vẫn có thể truy xuất repo có dung lượng 25 MB, trong đó .git thư mục con một mình mất 15MB. Vì vậy, tôi vẫn nói câu trả lời là "không". - sdaau
@mrTom câu trả lời là trên thực tế VÂNG Xem câu trả lời của OP - lệnh git checkout-index - nocache
Đây là một cách tốt đẹp và đơn giản: git archive -o latest.zip HEAD - Evgeni Sergeev


Các câu trả lời:


Có lẽ cách đơn giản nhất để đạt được điều này là git archive. Nếu bạn thực sự cần chỉ là cây mở rộng, bạn có thể làm một cái gì đó như thế này.

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

Hầu hết thời gian mà tôi cần phải 'xuất' một thứ gì đó từ git, tôi muốn một kho lưu trữ nén trong mọi trường hợp vì vậy tôi làm một cái gì đó như thế này.

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

Lưu trữ ZIP:

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

git help archive để biết thêm chi tiết, nó khá linh hoạt.


Lưu ý rằng mặc dù kho lưu trữ sẽ không chứa thư mục .git, tuy nhiên, nó sẽ chứa các tệp git cụ thể khác ẩn như .gitignore, .gitattributes, v.v. Nếu bạn không muốn chúng trong kho lưu trữ, hãy đảm bảo rằng bạn sử dụng thuộc tính export-ignore trong tệp .gitattributes và cam kết điều này trước khi thực hiện lưu trữ của bạn. Đọc thêm...


Lưu ý: Nếu bạn quan tâm đến việc xuất chỉ mục, lệnh

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

(Xem Câu trả lời của Greg để biết thêm chi tiết)


2198
2017-10-02 18:13



Lưu trữ ZIP: git archive --format zip --output /full/path master - Stream
Lưu ý rằng kho lưu trữ sẽ không chứa thư mục .git, nhưng sẽ chứa các tệp git-specific ẩn khác như .gitignore, .gitattributes, vv Vì vậy, nếu bạn không muốn chúng, hãy đảm bảo bạn sử dụng thuộc tính export-ignore trong tệp .gitattributes và cam kết tệp này trước khi lưu trữ của bạn. Xem feeding.cloud.geek.nz/2010/02/… - mj1531
Để theo dõi lưu ý của luồng: bạn có thể thêm chuỗi '--prefix = something /' vào lệnh để kiểm soát tên thư mục sẽ được đóng gói bên trong mã zip. Ví dụ: nếu bạn sử dụng git archive --format zip --output /path/to/file.zip --prefix=newdir/ master đầu ra sẽ được gọi là 'file.zip' nhưng khi bạn giải nén nó, thư mục cấp cao nhất sẽ là 'newdir'. (Nếu bạn bỏ qua thuộc tính --prefix, thư mục cấp cao nhất sẽ là 'tệp'.) - Alan W. Smith
Cách dễ nhất: git archive -o latest.zip HEAD Nó tạo ra một kho lưu trữ Zip chứa nội dung của cam kết mới nhất trên nhánh hiện tại. Lưu ý rằng định dạng đầu ra được suy ra bởi phần mở rộng của tập tin đầu ra. - nacho4d
Nó không hỗ trợ git submodules :( - umpirsky


Tôi phát hiện ra lựa chọn 2 có nghĩa là gì. Từ kho lưu trữ, bạn có thể thực hiện:

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

Dấu gạch chéo ở cuối đường dẫn là quan trọng, nếu không nó sẽ dẫn đến các tệp đang ở trong / đích với tiền tố của 'đường dẫn'.

Vì trong một tình huống bình thường chỉ mục chứa nội dung của kho, không có gì đặc biệt để làm "đọc cây mong muốn vào chỉ mục". Nó đã ở đó rồi.

Các -a cờ là cần thiết để kiểm tra tất cả các tập tin trong chỉ mục (Tôi không chắc chắn những gì nó có nghĩa là bỏ qua lá cờ này trong tình huống này, vì nó không làm những gì tôi muốn). Các -f cờ hiệu lực ghi đè lên bất kỳ tập tin hiện có trong đầu ra, mà lệnh này thường không làm.

Đây dường như là loại "git export" mà tôi đang tìm kiếm.


301
2017-10-02 03:03



... và KHÔNG QUÊN TIẾT KIỆM TRONG CUỐI CÙNG, hoặc bạn sẽ không có hiệu ứng mong muốn;) - conny
Các git add lệnh thay đổi nội dung trong chỉ mục, do đó, bất cứ điều gì git status hiển thị là "được cam kết" là sự khác biệt giữa HEAD và nội dung của chỉ mục. - Greg Hewgill
@conny: đọc bình luận của bạn, quên nó đi và chạy lệnh mà không có dấu gạch chéo. tip: làm theo lời khuyên của conny -.- - Znarkus
+1 cho lời khuyên của conny. Ngoài ra, đừng cố tạo '~ / dest /', vì điều này tạo ra một thư mục có tên '~' trong thư mục làm việc của bạn, thay vì những gì bạn thực sự muốn. Đoán xem chuyện gì sẽ xảy ra khi bạn vô tình gõ rm -rf ~ - Kyle Heironimus
@KyleHeironimus - cảnh báo của bạn về việc sử dụng '~ / dest / `là true iff bạn sử dụng dấu ngoặc kép xung quanh đường dẫn tiền tố của bạn để cho trình bao không thực hiện mở rộng dấu ngã. Một đạo cụ gọi là ~ (không phải '~' !) sẽ được tạo trong thư mục làm việc của bạn. Không có gì đặc biệt về git checkout-index về vấn đề này: Điều này cũng đúng mkdir '~/dest' (đừng làm thế!). Tuy nhiên, một lý do khác để tránh các tên tệp cần trích dẫn (ví dụ: có một khoảng trống trong chúng) :-) - Matt Wallis


git archive cũng làm việc với kho lưu trữ từ xa.

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

Để xuất đường dẫn cụ thể bên trong repo, hãy thêm bao nhiêu đường dẫn như bạn muốn làm đối số cuối cùng cho git, ví dụ:

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

241
2017-12-09 18:59



Đây là tùy chọn tôi thích nhất. Nó có lợi ích bổ sung mà nó cũng làm việc trên kho trần. - innaM
Phiên bản cải tiến là: git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf -  (đảm bảo lưu trữ của bạn nằm trong một thư mục) - Nick
chú thích: máy chủ phải bật tính năng này. - Jakub Narębski
Tôi đã thử: git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git master Và đã gây tử vong: Hoạt động không được hỗ trợ bởi giao thức. Kết thúc luồng lệnh bất ngờ. - andyf
@andyf GitHub có cách riêng của mình: curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf - mỗi tài liệu - bishop


enter image description here

Một câu trả lời trường hợp đặc biệt nếu kho lưu trữ được lưu trữ trên GitHub.

Chỉ dùng svn export.

Theo như tôi biết Github không cho phép archive --remote. Mặc dù GitHub là svn tương thích và họ có tất cả repo git svn có thể truy cập để bạn có thể sử dụng svn export như bạn thường làm với một vài điều chỉnh đối với url GitHub của bạn.

Ví dụ để xuất toàn bộ kho lưu trữ, hãy lưu ý cách trunktrong URL thay thế master (hoặc bất kỳ nhánh HEAD của dự án được đặt thành):

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

Và bạn có thể xuất một tệp hoặc thậm chí một đường dẫn hoặc thư mục nhất định:

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

Ví dụ với Thư viện JavaScript jQuery

Các HEAD chi nhánh hoặc bậc thầy nhánh sẽ có sẵn bằng cách sử dụng trunk:

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

KhôngHEAD  cành cây sẽ có thể truy cập trong /branches/:

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

Tất cả các thẻ Dưới /tags/ cùng một phong cách thời trang:

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

48
2017-10-30 17:03



git archive hoạt động tốt với GitHub, miễn là bạn sử dụng giao thức git, chỉ cần thay thế https:// với git:// trong URL. Tôi không biết tại sao GitHub không quảng cáo tính năng ẩn này. - Neil Mayhew
@NeilMayhew Nó không có tác dụng với tôi, tôi nhận được fatal: The remote end hung up unexpectedly. Đã thử trên hai máy chủ khác nhau với jQuery github repo. - Anthony Hatzopoulos
Bạn đúng. Tôi đã quên rằng tôi đã sử dụng git config url.<base>.insteadOf để lưu trữ bộ nhớ cache từ xa. Do đó tôi đã sử dụng file:// URL trong thực tế. Tôi nghi ngờ điều đó git archive có thể làm việc với git:// URL vì nó cần để có thể chạy git-upload-archive ở đầu từ xa. Có thể sử dụng ssh giao thức, ngoại trừ github không cho phép nó (Invalid command: 'git-upload-archive'). - Neil Mayhew
Bất kỳ cách nào để sử dụng một công cụ máy chủ địa phương hành xử như github nếu tôi muốn làm điều đó trên kho lưu trữ git nội bộ lưu trữ? - kriss
upvoted - nó hoàn toàn kỳ lạ mà Git không có tính năng này và chúng tôi phải nghỉ mát để svn - Jason S


Từ Git Manual:

Sử dụng git-checkout-index để "xuất toàn bộ cây"

Khả năng tiền tố cơ bản làm cho nó tầm thường để sử dụng git-checkout-index như một hàm "export as tree". Chỉ cần đọc cây mong muốn vào chỉ mục và thực hiện:

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


38
2017-10-02 02:27



Tôi nghĩ rằng sự nhầm lẫn là cụm từ "đọc cây mong muốn vào chỉ mục". - davetron5000
Nếu bạn muốn xuất thư mục foo trong thanh chi nhánh, thì đây sẽ là git read-tree bar:foo Và sau đó git checkout-index --prefix=export_dir/ -a sau đó có lẽ bạn nên làm git update-index master - Pascal Rosin
Tôi không biết tại sao đây không phải là câu trả lời được chấp nhận. - John Weldon
@ JohnWeldon Liệu nó có đòi hỏi bạn phải sao chép repo đầu tiên? Nếu vậy, sau đó tôi sẽ không chấp nhận nó, vì toàn bộ điểm "xuất khẩu svn" của một thư mục con là trực tiếp nhận được một bản sao của thư mục con đó; nếu ai đó có một repo 1GB Git và tất cả những gì tôi muốn là một thư mục con 10kB, thật điên rồ khi yêu cầu tôi sao chép toàn bộ thứ đó. - Jason S
Ngoài ra tôi muốn echo @ davetron5000 với nhận xét "đọc cây mong muốn vào chỉ mục" mà tôi không biết ý nghĩa của nó. - Jason S


Tôi đã viết một wrapper đơn giản xung quanh git-checkout-index mà bạn có thể sử dụng như thế này:

git export ~/the/destination/dir

Nếu thư mục đích đã tồn tại, bạn sẽ cần phải thêm -f hoặc là --force.

Cài đặt rất đơn giản; chỉ cần thả kịch bản ở đâu đó trong PATHvà đảm bảo nó có thể thực thi được.

Kho lưu trữ github cho git-export 


37
2017-10-16 17:17



Trình bao bọc này không phải là nền tảng bất khả tri; nó dựa vào / bin / sh. Vì vậy, nếu bạn đang sử dụng Windows, giải pháp này có lẽ sẽ không làm việc cho bạn. - shovavnik
Uhh, kịch bản này là 57 dòng tài liệu, khoảng trắng, thiết lập, phân tích đối số và chỉ một dòng thực sự làm điều gì đó ... - Vladimir Panteleev


Dường như đây là vấn đề ít hơn với Git so với SVN. Git chỉ đặt một thư mục .git trong thư mục gốc của kho, trong khi SVN đặt một thư mục .svn trong mỗi thư mục con. Vì vậy, "xuất khẩu svn" tránh ma thuật dòng lệnh đệ quy, trong khi với đệ quy Git là không cần thiết.


35
2018-05-12 04:20



Kể từ SVN 1.7, cũng chỉ có một thư mục .svn: subversion.apache.org/docs/release-notes/1.7.html#single-db - kostmo
Điều này sẽ không loại bỏ bất kỳ tệp xây dựng bổ sung nào mà xuất khẩu svn sẽ xóa. Vì vậy, điều này chắc chắn không phải là câu trả lời. - ygoe
Đã bị bỏ phiếu vì câu trả lời không hợp lệ. - bahrep


Tương đương với

svn export . otherpath

bên trong một repo hiện tại là

git archive branchname | (cd otherpath; tar x)

Tương đương với

svn export url otherpath

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

26
2018-02-23 15:41



cảm ơn, đây là những gì tôi đã mất tích ... ngoài ra, để kiểm tra dấu thời gian xuất (chúng sẽ không được giữ nguyên như trên các tệp), hãy sử dụng git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -) ... Tuy nhiên, việc lưu trữ với dấu thời gian không chính xác là nhỏ, vì vậy tôi đã đăng ví dụ bên dưới. - sdaau
Bạn có thể sử dụng tùy chọn C cho tar thay cho subshell, như sau: git archive branchname | tar xC otherpath - James Moore
Cảnh báo rằng C tùy chọn tar chỉ là GNU Tar. - aredridel