2010-08-06 2 views
21

Git có rất tiện dụng archive lệnh cho phép tôi để tạo ra một bản sao của một đặc biệt cam kết trong một kho lưu trữ .zip như vậy:Zip thay đổi cam kết mới nhất chỉ

git archive -o ../latest.zip some-commit

này sẽ chứa các cây làm việc toàn bộ cho rằng cam kết. Thông thường tôi chỉ cần các tập tin thay đổi kể từ một bản phát hành trước đó. Hiện tại, tôi sử dụng tính năng này để chuyển các tệp đó thành mã zip:

git diff --name-only previous-commit latest-commit | zip ../changes.zip [email protected]

Tuy nhiên, tệp này sẽ bị thay đổi không được cam kết. Có cách nào để chỉ nhận các tệp đã thay đổi khi chúng được cam kết trực tiếp vào mã zip không?

Trả lời

38

git archive sẽ chấp nhận đường dẫn làm đối số. Tất cả các bạn nên cần phải làm là:

git archive -o ../latest.zip some-commit $(git diff --name-only earlier-commit some-commit) 

hoặc nếu bạn có tập tin với không gian (hoặc các ký tự đặc biệt khác) trong đó, sử dụng xargs:

git diff --name-only earlier-commit some-commit | xargs -d'\n' git archive -o ../latest.zip some-commit 

Nếu bạn không có xargs cài đặt đúng cách , bạn có thể nấu một cách thay thế:

#!/bin/bash 

IFS=$'\n' 
files=($(git diff --name-only earlier-commit some-commit)) 

git archive -o ../latest.zip some-commit "${files[@]}" 

Được viết dưới dạng tập lệnh vỏ, nhưng cũng nên hoạt động như một lớp lót. Ngoài ra, hãy thay đổi earlier-commit, some-commit../latest.zip thành $1$2$3 và bạn đã có một tập lệnh có thể sử dụng lại.

+0

Đẹp nhất! Điều đó hoạt động rất tốt. –

+5

Hãy coi chừng việc trích xuất một bản lưu trữ như vậy sẽ không xóa bất kỳ tệp nào. Điều này có thể gây khó khăn cho việc chẩn đoán các vấn đề sau này. – jilles

+0

@jilles: Rất đúng. Đây là lý do tại sao các bản vá lỗi là tuyệt vời. @Marnix van Valen: Bạn có lẽ chỉ cần tạo bản vá sau đó gói nó bằng một tập lệnh (thậm chí bạn có thể sử dụng một heredoc để giữ tất cả trong một tệp) - sau đó nó có thể sử dụng được và, đúng, chính xác. – Cascabel

-1

lý do tại sao không tạo bản vá git mà bạn có thể áp dụng cho codebase khác?

$ git format-patch HEAD^..HEAD 
+1

Không phải ai cũng biết cách làm việc với các tệp vá tôi sợ.Tôi sử dụng điều này để cung cấp các bản phát hành mới cho khách hàng của mình. Giải nén một kho lưu trữ là một cái gì đó thậm chí không phải là nhà phát triển có thể làm. Áp dụng một bản vá đòi hỏi kỹ năng không phải tất cả các khách hàng của tôi đã làm chủ (hoặc thậm chí muốn làm chủ). –

4

Nếu tạo ra một bản vá không phải là một lựa chọn, sau đó như thế nào về một cái gì đó như thế này:

git stash 
git checkout latest-commit 
git diff --name-only previous-commit | zip ../changes.zip [email protected] 
git checkout master 
git stash apply 

LƯU Ý: Các git stashgit stash apply chỉ cần thiết nếu bạn có thay đổi bản sao làm việc chưa được cam kết .

CHÚ Ý 2: git checkout latest-commit sẽ đặt bạn trên đầu bị tách rời. Hãy chắc chắn để git checkout master khi bạn đang thực hiện hoặc bạn có thể gió lên có vấn đề với các cam kết trong tương lai.

+0

Tôi đã hy vọng cho một giải pháp lệnh duy nhất ... –

+0

@Marnix van Valen Sau đó, tại sao không biến nó thành một tập lệnh đơn giản (hoặc tập tin batch)? Vấn đề là bạn cần dịch danh sách tên tệp thành các phiên bản cụ thể. Cách duy nhất tôi có thể nghĩ là sử dụng 'git show latest-commit: file'. Tuy nhiên, tôi đã không thể đến với một lớp lót để làm điều này. Nó sẽ trông giống như sau: 'git diff --name-only-cam kết trước | xargs -I file git hiển thị commit mới nhất: file' ... nhưng đây là vấn đề. Điều này in các tập tin (không có tên của nó) để STDOUT. Làm thế nào điều này có thể được dịch sang tệp zip? –

2

Để thực hiện điều gì đó hữu ích để giải quyết một câu hỏi như vậy đối với tôi, tôi đã triển khai một tập lệnh bash đơn giản. Kịch bản lệnh lấy một bản băm sửa đổi và tạo một kho lưu trữ tar.gz với tất cả các tệp đã thay đổi bao gồm phân cấp thư mục. Bất cứ ai cũng có thể sử dụng hoặc sửa đổi, tôi sẽ rất vui nếu nó giúp ai đó.

Chỉ cần chạy tập lệnh trong thư mục gốc của kho git và chuyển băm phiên bản vào dòng lệnh argumens.

Link to the script on hithub

+0

Ví dụ sẽ giống như sau: #./do_delivery.sh -r a5ab48cdbb -n "vmeagt_delivery" ===> Tên tệp lưu trữ: "vmeagt_delivery-20120430" ===> Bản sửa đổi bị ảnh hưởng: "a5ab48cdbb -> HEAD" ===> Đường dẫn đầu ra: "/ Người dùng/crible/Projects/ServerView_Agents/" ===> Kho lưu trữ Git:"/Người dùng/crible/Projects/ServerView_Agents/" ===> Tạo bản lưu trữ tar.gz ... ===> Xong! –

+0

Nó chỉ là phiên bản đầu tiên, mà mạnh mẽ cần phải được cải thiện :) –

1

Tôi có comme ra một giải pháp, một dòng và khá đơn giản:

zip archive.zip $(git diff-tree --no-commit-id --name-only -r latest-commit) 

Bạn cũng có thể sử dụng bất kỳ phương pháp lưu trữ khác như tar với phương pháp này.