Làm thế nào để cam kết tái cấu trúc trong tiến trình?


23

Vì vậy, tôi có dự án lớn này, đang trong quá trình được tái cấu trúc bởi tôi. Tôi đang thay đổi rất nhiều thứ, vì vậy không có cơ hội để có được nó để biên dịch sớm. Tôi đang sống trong một nhánh git đặc biệt mà tôi đặt tên cleanup( masterdĩ nhiên sẽ được sáp nhập vào cuối cùng).

Vấn đề là, tôi / chúng tôi có chính sách không bao giờ cam kết mã không biên dịch (lý tưởng là nó cũng sẽ hoạt động, nhưng ít nhất nó phải biên dịch và liên kết). Vì vậy, cho đến khi tôi hoàn thành nhiệm vụ to lớn này, tôi không thể cam kết bất cứ điều gì (để xem xét hoặc để ghi sổ).
Đây không phải là cách tôi thích làm việc (tôi tin rằng hầu hết mọi người cam kết ít nhất một lần một ngày hoặc lâu hơn).

Bạn nghĩ sao? Có một giải pháp tôi đang xem xét?
Sau này tôi có thể nói với git để tổng hợp các cam kết hay không? Tôi có thể sống với các cam kết không biên dịch miễn là họ trong cleanupchi nhánh.

Chỉnh sửa

Đối với chủ đề đẩy / cam kết: Tôi biết rằng đó là một sự khác biệt rất lớn, nhưng sau đó, sẽ có những sửa đổi bị phá vỡ, khi tôi hợp nhất công cụ của mình vào master. Vì vậy, nếu bạn duyệt qua lịch sử (hoặc git bisect...) thì bản sửa đổi "cục bộ" sẽ có thể truy cập được trên thế giới. Vì vậy, chỉ cam kết cục bộ và không đẩy không phải là giải pháp tốt nhất, bởi vì nó sẽ gây rắc rối cho bạn sau này (khi chủ đề bị đóng và quên trong một thời gian).

Tóm lại: Cam kết địa phương cuối cùng sẽ được đẩy. Lịch sử toàn cầu không nên hiển thị các cam kết không biên dịch.


1
Bạn có thể thu thập nhiều cam kết cục bộ trong một cam kết toàn cầu duy nhất.

@ Thorbjørn là đề xuất của Jim bên dưới, hay một cơ chế khác trong Git?
Brian

Tôi tin như vậy - tôi không thể nhớ lệnh chính xác.

5
Bạn không tái cấu trúc, bạn đang làm một cái gì đó lớn hơn. Sau mỗi lần tái cấu trúc trên một cơ sở mã, mã của bạn sẽ biên dịch và có hành vi chính xác có thể quan sát được. Bạn có thể muốn thay đổi tiêu đề câu hỏi của mình để phản ánh điều đó, vì phản ứng tức thời của tôi là "Cam kết những gì bạn có bất cứ khi nào, tất cả đều hoạt động".
David Thornley

1
@bitmask Viết lại như thế nào?
Dave Hillier

Câu trả lời:


21

Các git merge --squashlệnh cho phép bạn tạo ra một cam kết duy nhất trên đầu trang của các chi nhánh hiện có hiệu quả tương tự như việc sáp nhập chi nhánh khác. Lệnh cập nhật cây làm việc và thực hiện các thay đổi trong chỉ mục, vì vậy tất cả những gì bạn phải làm tiếp theo là cam kết:

git checkout master
git merge --squash cleanup
git commit -m "Merge cleanup branch"

Các git rebase -ilệnh cũng có thể bí cam kết nhưng đòi hỏi phải làm việc nhiều hơn.


14

Viết lại không phải là tái cấu trúc

Tôi nhận ra rằng bạn quan tâm đến cách sử dụng Git, nhưng tôi sẽ lập luận rằng bạn nên xem xét việc thay đổi cách bạn thực hiện tái cấu trúc hơn là cách bạn sử dụng Git (mặc dù tôi nghĩ Git có thể giúp bạn).

Martin Fowler định nghĩa tái cấu trúc là :

một kỹ thuật kỷ luật để tái cấu trúc một bộ mã hiện có, thay đổi cấu trúc bên trong của nó mà không thay đổi hành vi bên ngoài của nó.

Trái tim của nó là một chuỗi các hành vi nhỏ bảo tồn các biến đổi. Mỗi phép biến đổi (được gọi là tái cấu trúc của người Viking) thực hiện rất ít, nhưng một chuỗi các phép biến đổi có thể tạo ra một sự tái cấu trúc đáng kể. Vì mỗi lần tái cấu trúc là nhỏ, nên nó ít có khả năng sai. Hệ thống được duy trì hoạt động hoàn toàn sau mỗi lần tái cấu trúc nhỏ, làm giảm khả năng hệ thống có thể bị hỏng nghiêm trọng trong quá trình tái cấu trúc.

Nếu bạn áp dụng phương pháp này, bạn có thể cam kết (và đẩy) một cách thường xuyên.

Bạn có thể lập luận rằng điều này là không thực tế, và nó không hoạt động cho một cái gì đó quy mô lớn. Đây là nơi mà phương pháp Mikado có thể giúp đỡ. Bạn phân tách một phép tái cấu trúc lớn thành một chuỗi các phép tái cấu trúc nhỏ bằng cách tạo một biểu đồ phụ thuộc. Phương pháp này là đệ quy, cố gắng thực hiện thay đổi của bạn, nó không phá vỡ bất cứ điều gì kiểm tra nó, nếu không thì hoàn nguyên thay đổi của bạn và ghi chú các điều kiện tiên quyết. Từng người một, bạn sửa chữa các phép tái cấu trúc cần thiết trước cho đến khi bạn có thể đạt được mục tiêu tái cấu trúc chính của mình.

Git thực sự có thể giúp phương pháp này. Bạn có thể giữ chi nhánh địa phương (bị hỏng) của bạn. Khi bạn cam kết (và đẩy) các mục tiêu phụ, bạn có thể phân rebasenhánh mục tiêu chính của mình lên trên các cam kết bạn vừa thực hiện, cho đến khi nó không còn bị phá vỡ.


5

Kiểm tra trang hướng dẫn git rebase, đặc biệt là các git rebase -ibiến thể. Nó cho phép bạn sắp xếp lại, xóa hoặc xóa bất kỳ số lần xác nhận nào trong lịch sử của bạn, nghe có vẻ giống như những gì bạn đang tìm kiếm. Tôi sử dụng nó mọi lúc trong chính xác tình huống mà bạn mô tả: thực hiện nhiều cam kết nhỏ không phù hợp với tiêu dùng công cộng, sau đó gộp chúng lại thành một cam kết "tái cấu trúc" duy nhất trước khi đẩy vào kho lưu trữ được chia sẻ.


3

Bạn đang sử dụng Git, do đó, cam kết không nhất thiết ngụ ý đẩy các thay đổi của bạn ....

IMHO và làm việc với Git, việc cam kết công việc của bạn là hoàn toàn tốt, ngay cả khi nó không biên dịch ... bởi vì, sau tất cả, một khi bạn cam kết thay đổi, sẽ không có ai có sẵn mã (cho đến khi bạn đẩy nó). Tất nhiên, trước khi đẩy nó, bạn phải đảm bảo nó hoạt động tốt và biên dịch, để những người khác có thể tìm nạp và hợp nhất các thay đổi của bạn mà không gặp vấn đề gì.

Ngoài ra, bạn đang làm việc trên một nhánh khác với chủ. Vì vậy, nếu bạn muốn (và tôi khuyên bạn nên điều này), bạn sẽ không đẩy chi nhánh của mình bao giờ. Khi bạn đã hoàn thành việc tái cấu trúc, chỉ cần kiểm tra nhánh chính, hợp nhất các thay đổi của bạn và đẩy nhánh chính.

Chỉnh sửa

Trong trường hợp đó, bạn có thể sử dụng git cherry-pickhoặc chơi xung quanh vớigit rebase


Một lưu ý quan trọng, nhưng tôi đã xem xét điều này. Xin vui lòng xem chỉnh sửa của tôi. Cảm ơn bạn.
bitmask

Xem chỉnh sửa của tôi ở trên.
Cristian

Tôi sẽ -1 nếu tôi có thể; các cam kết sẽ trở nên có sẵn! Cam kết công việc tại địa phương là tuyệt vời, nhưng không bao giờ đẩy chúng; nó làm cho mã khó hiểu hơn, làm gián đoạn git bisect và làm phức tạp lịch sử. Rebase hoặc squash thay thế.
RJFalconer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.