2010-05-06 36 views
6

Có lệnh git để thêm sự khác biệt trong một dải số vào chỉ mục không?Git: Thêm một phần của tệp (đã thay đổi) vào chỉ mục * theo số dòng *

Tôi muốn có thể chọn các dòng trong trình chỉnh sửa của mình và chạy macro để thêm bất kỳ thay đổi nào trong lựa chọn vào chỉ mục.

+0

Bạn đính kèm ý tưởng thực hiện điều này từ bên trong trình soạn thảo như thế nào so với thông qua 'git add -i'? Bạn có thể có thể làm việc lên cái gì đó gọi là 'git diff', kéo ra những hunks chạm vào các dòng bạn đã chọn, và áp dụng bản vá đó cho chỉ mục, nếu bạn thực sự muốn ... – Cascabel

Trả lời

17

Nếu bạn có thể thuyết phục trình soạn thảo viết phiên bản tệp mà bạn muốn được dàn dựng, bạn có thể sử dụng lệnh git cấp nước để thêm nó vào chỉ mục dưới tên đúng. Bạn cần phải bỏ qua "git add" mà sẽ luôn luôn liên kết đường dẫn X trong cây làm việc với đường dẫn X trong chỉ mục (theo như tôi biết).

Khi bạn có nội dung bạn muốn đặt giai đoạn được ghi vào một tệp tạm thời $ tempfile, hãy chạy git hash-object -w $tempfile - điều này sẽ ghi đối tượng vào .git/objects và xuất ra id blob. Sau đó cấp id blob này cho chỉ mục bằng cách sử dụng git update-index --cacheinfo 100644 $blobid $path để liên kết đường dẫn $ path với đối tượng đó.

Dưới đây là một ví dụ mà các giai đoạn thay đổi về một kịch bản gọi là "post_load" trong repo của tôi mà không ghi đè lên các tập tin riêng của mình (cũng chứng tỏ bạn có thể làm mà không có một tập tin tạm thời):

git update-index --cacheinfo 100755 $(perl -lne 'print unless (/^#/)' post_load \ 
             | git hash-object -w --stdin) post_load 

Bạn không đề cập đến mà bạn đang lập kế hoạch để làm điều này từ, vì vậy thật khó để tư vấn cho bạn về cách tích hợp này. Như tôi đã đề cập, bạn cần phải bằng cách nào đó trình bày git với tệp như bạn muốn nó được dàn dựng (hãy nhớ, git không giải quyết việc lưu trữ thay đổi). Nếu bạn có thể viết macro để chỉ lưu tệp dưới dạng "$ file.tmp", thì hãy sử dụng một cái gì đó như ở trên để git update-index --cacheinfo $the_mode $(git hash-object -w $file.tmp) $file (lấy $ the_mode còn lại dưới dạng bài tập: p), xóa $ file.tmp và hoàn nguyên bộ đệm trình chỉnh sửa quay lại $ file mà về cơ bản những gì bạn đang yêu cầu.

Ví dụ: tập lệnh sau có ba đối số: M N path. Nó sẽ cập nhật nội dung chỉ mục cho các tập tin vào "con đường" để dòng M đến N (bao gồm) được thay thế bằng nội dung từ stdin:

#!/bin/sh 

start_line=$1 
end_line=$2 
path=$3 

mode=$(git ls-files -s $path | awk '{print $1}') 
blob_id=$(
    (
     head -n $(expr $start_line - 1) $path 
     cat 
     tail -n +$(expr $end_line + 1) $path 
     ) | git hash-object -w --stdin 
    ) 
exec git update-index --cacheinfo $mode $blob_id $path 

ví dụ echo "HELLO WORLD" | ./stage-part 8 10 post_load sẽ thay thế ba dòng 8-10 với chỉ là "HELLO WORLD".

3

Cách đơn giản nhất để làm điều đó hiện đang chơi cho git add trong chế độ tương tác:

git add -i path/to/file 

Nó sẽ khởi động giao diện người dùng đơn giản mà bạn có thể chọn những phần bạn muốn đến giai đoạn và cho phép bạn chỉnh sửa bất kỳ đoạn để loại bỏ dòng bạn don không muốn cam kết.

+0

Đó là thực tế hiện tại của tôi, nhưng khi có nhiều "tiếng ồn" trong diff tôi muốn thử nghiệm/cam kết tôi bị nhầm lẫn (do thiếu ngữ cảnh, vv). Thực sự muốn có thể thúc đẩy điều này từ trình soạn thảo của tôi trong các tình huống như vậy. – RobM

0

Công cụ dựng sẵn gần nhất thực hiện điều gì đó như thế này là git gui citool. Nó không hoạt động trực tiếp trong trình soạn thảo của bạn (không phải tất cả các trình soạn thảo đều có chế độ xem hữu ích và tôi nghi ngờ rằng hầu hết mọi người có thể không nhớ chính xác dòng nào họ đã thay đổi kể từ lần commit cuối cùng, vì vậy một chế độ xem khác rất hữu ích), nhưng dường như giống như nó gần với những gì bạn muốn.

git gui citool cho phép bạn xem lại các thay đổi theo giai đoạn và không được tổ chức trong các chế độ xem tương đương với git diff --cachedgit diff, tương ứng.

Trong khi xem lại các thay đổi chưa được chỉnh sửa, menu ngữ cảnh (nhấp chuột phải) có các tùy chọn để hiển thị các dòng được chọn (hoặc dòng được nhấp nếu không có lựa chọn) và tùy chọn để hiển thị toàn bộ đoạn. Tương tự như vậy khi xem xét các thay đổi theo giai đoạn, trình đơn ngữ cảnh có các tùy chọn để bỏ đoạn thẳng hoặc một đoạn.

Để có thêm ngữ cảnh, bạn có thể sử dụng mục menu "Hiển thị thêm ngữ cảnh" (hoặc "Hiển thị ít ngữ cảnh" hơn nếu bạn muốn thu nhỏ các khối).

Khi bạn đã tổ chức nội dung mới, bạn cũng có thể soạn thư cam kết và thực hiện cam kết từ bên trong GUI.

Tôi tưởng tượng rằng một số người sử dụng git gui trong một quy trình làm việc như thế này:

  1. Sử dụng CLI để thêm các tập tin được theo dõi mới và loại bỏ các tập tin cũ (các tùy chọn khác nhau để git add).
  2. Chỉnh sửa tệp được theo dõi trong trình chỉnh sửa/môi trường yêu thích của bạn.
  3. Trong git gui, chọn "Quét lại", xem lại các thay đổi, giai đoạn/bỏ bớt một số và cuối cùng cam kết.
  4. [lặp lại]
2

Theo kinh nghiệm của riêng tôi, git-cola làm một công việc tuyệt vời về điều này. Tôi muốn nó hỗ trợ tích hợp Atom ...

+0

Trong khi điều này về lý thuyết có thể trả lời câu hỏi, [nó sẽ là thích hợp hơn] (// meta.stackoverflow.com/q/8259) để bao gồm các phần thiết yếu của câu trả lời ở đây, và cung cấp liên kết để tham khảo. – manetsus

+0

Trong git-cola, chọn các dòng và chọn 'Stage Selected Lines' từ danh sách thả xuống, hoặc nhấn' H'. Nó yêu cầu chuyển đổi từ trình soạn thảo thường xuyên sang git-cola để dàn dựng nhưng cả hai có thể chạy cùng một lúc và tôi không thấy nó bất tiện. –

Các vấn đề liên quan