Câu hỏi Cam kết chỉ là một phần của tệp trong Git


Khi tôi thực hiện thay đổi đối với tệp trong Git, làm cách nào tôi có thể cam kết chỉ một số thay đổi?

Ví dụ, làm thế nào tôi có thể cam kết chỉ có 15 dòng trong số 30 dòng đã được thay đổi trong một tập tin?


2242
2017-07-06 02:25


gốc




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


Bạn có thể dùng git add --patch <filename> (hoặc là -p trong ngắn hạn), và git sẽ bắt đầu chia nhỏ tệp của bạn thành những gì mà nó cho là "các khối" hợp lý (các phần của tệp). Sau đó nó sẽ nhắc bạn với câu hỏi này:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

Dưới đây là mô tả về từng tùy chọn:

  • y giai đoạn này hunk cho các cam kết tiếp theo
  • n không điều chỉnh đoạn này cho lần commit tiếp theo
  • q bỏ thuốc lá; không đặt đoạn này hoặc bất kỳ phần nào còn lại
  • một giai đoạn này hunk và tất cả sau này hunks trong các tập tin
  • d không đặt đoạn này hoặc bất kỳ phần nào của phần sau trong tệp
  • g chọn một hunk để đi đến
  • / tìm kiếm một đoạn phù hợp với regex đã cho
  • j để lại đống rác này chưa quyết định, xem đoạn tiếp theo chưa quyết định
  • J để lại đống rác này chưa quyết định, xem hunk tiếp theo
  • k để lại hunk này chưa quyết định, xem trước đó chưa quyết định hunk
  • K để lại hunk này chưa quyết định, xem hunk trước
  • S chia hunk hiện tại thành những hunks nhỏ hơn
  • e chỉnh sửa thủ công đoạn hiện tại
  • ? in hunk giúp

Nếu tệp chưa có trong kho lưu trữ, trước tiên bạn có thể làm git add -N <filename>. Sau đó bạn có thể tiếp tục với git add -p <filename>.

Sau đó, bạn có thể sử dụng:
git diff --staged để kiểm tra xem bạn đã tổ chức các thay đổi chính xác chưa
git reset -p để unstage hull nhầm lẫn thêm
git commit -v để xem cam kết của bạn trong khi bạn chỉnh sửa thông báo cam kết.

Lưu ý điều này khác xa so với git format-patch lệnh, mục đích là phân tích dữ liệu cam kết thành một .patch các tập tin.

Tham khảo cho tương lai: https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging


2939
2017-07-06 11:49



Nó có thể hữu ích để lưu ý rằng -p/--patch là lối tắt cho hành động vá bên trong -i/--interactive lệnh khởi tạo hữu ích Chế độ tương tác. - tutuDajuju
> Điều gì sẽ xảy ra nếu tệp đó đã được dàn dựng? Nó sẽ chỉ hiển thị những thay đổi không được tổ chức. Giống như git diff làm. - Eugen Konkov
Làm thế nào tôi có thể chỉnh sửa hunk hiện tại theo cách thủ công? Tôi không biết phải làm gì sau khi tôi gõ e. - Hunsu
Sau khi nhấn e, Bạn có thể chỉnh sửa thủ công bằng cách thay thế + hoặc là - bởi # - veksen
làm s không còn tồn tại nữa? - tam5


Bạn có thể dùng git add --interactive hoặc là git add -p <tập tin>, và sau đó git commit (không phải  git commit -a); xem Chế độ tương tác trong git-add manpage hoặc đơn giản là làm theo hướng dẫn.

Git hiện đại cũng có git commit --interactive (và git commit --patch, đó là phím tắt để tùy chọn vá trong cam kết tương tác).

Nếu bạn thích làm nó từ GUI, bạn có thể sử dụng git-gui. Bạn có thể chỉ cần đánh dấu các khối mà bạn muốn có trong cam kết. Cá nhân tôi thấy dễ dàng hơn việc sử dụng git add -i. Các git GUI khác, như QGit hoặc GitX, cũng có thể có chức năng này.


216
2017-07-06 02:41



Điều thú vị là, windows.github.com đã hỗ trợ cho các cam kết một phần nhưng dường như đã xóa nó gần đây .. - Juri
@ Juri Tôi nghĩ rằng sự hỗ trợ cho một phần cam kết tập tin là trở lại trong. - Ela782
@ Ela782 oh..yes, bạn nói đúng. Thx để chỉ ra điều đó. - Juri
@Juri Bạn được chào đón. Tôi thực sự không bao giờ nhận thấy rằng nó đã có trong đó trước đây - tôi đã thấy nó tuần trước và nghĩ rằng "oh, một tính năng mới tuyệt vời" là gì! :-) - Ela782
Ngày nay, windows.github.com chuyển hướng đến GitHub Desktop được đổi tên thành đẹp hơn Git GUI và hỗ trợ cam kết một phần ... nhưng không hỗ trợ ký cam kết. Thở dài. - hacksalot


git gui cung cấp chức năng này dưới chế độ xem khác. Chỉ cần nhấp chuột phải vào (các) dòng bạn quan tâm và bạn sẽ thấy mục menu "giai đoạn này để cam kết".


115
2017-09-25 20:45



đối với các bản vá phức tạp, đây thường là cách tiếp cận nhanh nhất đối với tôi. - hochl
Đây là một cách rất hiệu quả và trực quan để thêm các thay đổi vào khu vực dàn dựng một cách tốt đẹp. Cũng có thể chọn nhiều dòng và tất cả thay đổi trong lựa chọn đó sẽ được thêm vào. - jox


Tôi tin rằng git add -e myfile là cách dễ nhất (tùy chọn của tôi ít nhất) vì nó chỉ đơn giản là mở một trình soạn thảo văn bản và cho phép bạn chọn dòng bạn muốn hiển thị và dòng nào bạn không muốn. Về chỉnh sửa lệnh:

nội dung được thêm vào:

Nội dung được thêm được thể hiện bằng các dòng bắt đầu bằng dấu "+". Bạn có thể ngăn chặn dàn dựng bất kỳ dòng bổ sung nào bằng cách xóa chúng.

nội dung bị xóa:

Nội dung bị xóa được thể hiện bằng các dòng bắt đầu bằng "-". Bạn có thể ngăn chặn dàn dựng của họ bằng cách chuyển đổi "-" thành "" (không gian).

nội dung sửa đổi:

Nội dung sửa đổi được thể hiện bằng các dòng "-" (loại bỏ nội dung cũ), theo sau là dòng "+" (thêm nội dung thay thế). Bạn có thể ngăn chặn việc sửa đổi bằng cách chuyển đổi các dòng "-" thành "" và xóa "+"              dòng. Cẩn thận rằng việc sửa đổi chỉ một nửa của cặp có khả năng giới thiệu những thay đổi khó hiểu cho chỉ mục.

Mọi chi tiết về git add có sẵn trên git --help add 


55
2018-02-23 10:37



Điều này sẽ hữu ích hơn nếu có giải thích rõ ràng ở đâu đó về cách thực sự chọn những dòng đó (tức là các lệnh thực tế để nhập). Tôi không thể tìm thấy một trong tài liệu. Bạn có thể thêm tham chiếu không? - Alex
Đối với những người không thích các tùy chọn viết tắt, -e Là --edit. - Kolyunya
@Alex Các trích dẫn tham chiếu được thêm bởi theFreedomBanana là từ phần EDITING PATCHES git --help add - Randall
Đây là câu trả lời duy nhất (yêu cầu chỉ git) mà giải quyết vấn đề thêm / loại bỏ dòng khôn ngoan khi bạn không thể làm cho khối nhỏ hơn với s trong chế độ vá tương tác. - cdosborn
Xin lỗi, tôi không muốn tạo câu hỏi mới, nhưng cách sử dụng ký tự đại diện khi chạy lệnh này? Tôi đã thử nó với git add -e - ** / * Activity.java nhưng nó không hoạt động. Tuy nhiên git diff - ** / * Activity.java hoạt động. Có vẻ như tùy chọn -e yêu cầu xử lý đặc biệt trong trường hợp này. - ka3ak


Nếu bạn đang sử dụng vim, bạn có thể muốn thử plugin tuyệt vời được gọi là chạy trốn.

Bạn có thể thấy sự khác biệt của một tệp giữa bản sao làm việc và chỉ mục với :Gdiffvà sau đó thêm dòng hoặc khối vào chỉ mục bằng cách sử dụng các lệnh khác vim khác như dp. Lưu các sửa đổi trong chỉ mục và cam kết với :Gcommitvà bạn đã hoàn tất.

Chương trình phát sóng giới thiệu rất tốt đây (xem đặc biệt. phần 2).


41
2017-08-12 13:32



Cảm ơn bạn rất nhiều vì liên kết này. Chính xác những gì tôi cần. Đặc biệt :diffget/:diffput trong chế độ trực quan, nơi tôi có thể chọn các dòng cụ thể mà tôi muốn đặt lại / cam kết. Vì vậy, hãy chắc chắn một lần nữa: vim là tuyệt vời. - goodniceweb


Tôi thực sự khuyên bạn nên sử dụng SourceTree từ Atlassian. (Nó hoàn toàn miễn phí.) Nó khiến việc này trở nên tầm thường. Bạn có thể đặt từng đoạn mã riêng lẻ hoặc các dòng mã riêng lẻ một cách nhanh chóng và dễ dàng.

enter image description here


26
2017-12-05 17:29



Tôi đồng ý rằng SourceTree là một công cụ tốt cho mục đích này, bởi vì nó cho phép bạn kiểm soát chi tiết hơn so với những gì có thể thông qua dòng lệnh.
@cupcake Tôi sẽ tranh luận ngược lại, thấy rằng SourceTree có thể sử dụng các lệnh thực thi dòng lệnh đó, vốn dĩ sẽ luôn có thể thực hiện các hành động giống nhau (hoặc nhiều hơn) thông qua "dòng lệnh". - tutuDajuju
Bất kể tinh xảo đối số tôi rất muốn giới thiệu SourceTree như dàn dựng và các dòng cá nhân là siêu dễ dàng: i.imgur.com/85bNu4C.png - Michael Freeman
@tutuDajuju Trong trường hợp này, tôi không chắc đó là sự thật. SourceTree có khả năng chọn phần nào đến giai đoạn từng dòng. Bạn không phải lên sân khấu toàn bộ một đoạn; bạn có thể giai đoạn 2 dòng ở giữa một hunk. Tôi không có ý tưởng làm thế nào nó hoàn thành điều đó, mặc dù. (Hiện tại, tôi đang cố gắng làm việc xung quanh SourceTree không có khả năng diễn tả các dòng cụ thể cho một tập tin không được theo dõi. Tôi đã đến đây để tìm cách giải quyết, chỉ để thấy rằng dường như git dường như không cung cấp khả năng theo từng dòng Ít nhất là không phải một cách đơn giản.) - jpmc26
Bạn đã có thể sử dụng --patch (như các câu trả lời khác gợi ý) và chia nhỏ đoạn cho đến khi bạn có thể sắp xếp các dòng bạn muốn .. Ngoài ra còn có nhiều trình bao bọc và phần mở rộng khác cung cấp giao diện người dùng (thường ở dạng khác) cho phép apply một bản vá từ các dòng được chọn; chẳng hạn như được tích hợp sẵn git gui và git-meld-index. Chỉ cần nói, cây nguồn không phải là tuyệt vời (người dùng cũ) - tutuDajuju


Đáng chú ý là sử dụng git add --patch cho một tập tin mới trước tiên bạn cần thêm tệp để lập chỉ mục git add --intent-to-add:

git add -N file
git add -p file

20
2018-06-06 22:14





Khi tôi có nhiều thay đổi và sẽ kết thúc việc tạo ra một vài cam kết từ những thay đổi, sau đó tôi muốn lưu điểm xuất phát của mình tạm thời trước khi dàn dựng mọi thứ.

Như thế này:

$ git stash -u
Saved working directory and index state WIP on master: 47a1413 ...
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 1st commit"
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 2nd commit"
$ git stash pop

Câu trả lời của Whymarrh là những gì tôi thường làm, ngoại trừ đôi khi có rất nhiều thay đổi và tôi có thể nói rằng tôi có thể phạm sai lầm trong khi dàn dựng mọi thứ, và tôi muốn có một trạng thái cam kết mà tôi có thể quay lại lần thứ hai.


17
2017-07-08 07:00