Tại sao không cam kết thay đổi chưa được giải quyết?


15

Trong một VCS truyền thống, tôi có thể hiểu lý do tại sao bạn không cam kết các tệp chưa được giải quyết vì bạn có thể phá vỡ bản dựng. Tuy nhiên, tôi không hiểu tại sao bạn không nên cam kết các tệp chưa được giải quyết trong DVCS (một số trong số chúng thực sự sẽ ngăn bạn thực hiện các tệp).

Thay vào đó, tôi nghĩ rằng kho lưu trữ của bạn nên được khóa khỏi đẩykéo , nhưng không cam kết.

Có thể cam kết trong quá trình hợp nhất có một số lợi thế (như tôi thấy):

  • Những thay đổi hợp nhất thực tế là trong lịch sử.
  • Nếu sự hợp nhất là rất lớn, bạn có thể thực hiện các cam kết định kỳ.
  • Nếu bạn mắc lỗi, việc quay trở lại sẽ dễ dàng hơn nhiều (mà không phải làm lại toàn bộ hợp nhất).
  • Các tập tin có thể vẫn được gắn cờ là chưa được giải quyết cho đến khi chúng được đánh dấu là đã giải quyết. Điều này sẽ ngăn đẩy / kéo.

Bạn cũng có khả năng có một tập hợp các thay đổi đóng vai trò là sự hợp nhất thay vì chỉ một tập hợp duy nhất. Điều này sẽ cho phép bạn vẫn sử dụng các công cụ như git rerere.

Vậy tại sao cam kết với các tệp chưa được giải quyết lại nhăn mặt / ngăn chặn? Có bất kỳ lý do khác ngoài truyền thống?


1
Nó bị ai cau mày hay ngăn cản?
pdr

@pdr Một số nhà phát triển tôi đã làm việc với nó cau mày với nó. Ít nhất là hg 1.6sau khi hợp nhất, các tệp được đánh dấu là chưa được giải quyết. hgsẽ không cho phép bạn cam kết cho đến khi bạn đánh dấu chúng là đã giải quyết (không nhất thiết có nghĩa là bạn thực sự phải giải quyết chúng, nhưng tôi cho rằng đó là ý tưởng).
Thuốc nổ

1
Vì vậy, bằng "các tập tin chưa được giải quyết", bạn thực sự có nghĩa là "hợp nhất chưa được giải quyết"?
pdr

@pdr không, hgthực sự duy trì một danh sách các tệp đã hoặc chưa được gắn cờ là "đã giải quyết" (sử dụng hg resolve). Nếu có bất kỳ Utệp nào trong danh sách này, nó sẽ không cho phép bạn cam kết.
Thuốc nổ

1
hg resolveđược sử dụng đặc biệt để hợp nhất với xung đột; xem selenic.com/mercurial/hg.1.html#resolve . Note that Mercurial will not let you commit files with unresolved merge conflicts. You must use hg resolve -m ... before you can commit after a conflicting merge.
Mike Partridge

Câu trả lời:


6

Vấn đề lớn nhất mà tôi có thể thấy là nó tạo ra một cửa sổ cam kết trong đó mọi thứ được hợp nhất một nửa và (có lẽ) không hoạt động chính xác. Khi bạn đẩy tập hợp cuối cùng của các xác nhận cục bộ, tất cả các cam kết trung gian đó cũng sẽ xuất hiện cho mọi người khác. Trong thế giới lý tưởng, tôi sẽ có thể thực hiện bất kỳ cam kết nào và mã sẽ hoạt động. Nếu bạn bắt đầu cam kết ở giữa các hợp nhất, trạng thái của mã không được xác định rõ.

Một điều bạn có thể làm là thực hiện các cam kết cục bộ cho việc hợp nhất của mình và sau đó bó chúng thành một cam kết lớn khi bạn đẩy (mặc dù tôi không chắc làm thế nào (nếu?) Bất kỳ vcs ​​nào hỗ trợ điều này). Mặc dù điều này có thể mang lại một số lợi ích mà bạn đã đề cập, tôi không chắc nó có giá trị phức tạp thêm (chúng tôi đã xử lý một khu vực khá khó hiểu và phức tạp).


5
Tôi không biết rằng tôi đồng ý với khả năng thực hiện bất kỳ cam kết nào và để nó hoạt động .. rất nhiều điểm cam kết trong DVCS là cam kết tiến trình của bạn , do đó, mọi thứ sẽ bị phá vỡ hoặc không hoàn thành trong phần lớn thời gian .
Thuốc nổ

2
Luôn luôn có cam kết làm việc có một số lợi ích tốt đẹp. Ví dụ: nếu bạn đang cố gắng theo dõi khi một lỗi được đưa ra, thật hữu ích khi có thể duyệt qua lịch sử để xem khi nào một cái gì đó bị phá vỡ (vcs thậm chí có các lệnh để thực hiện tìm kiếm nhị phân trong lịch sử). Nếu bạn không có các cam kết hoạt động, bạn sẽ không thể theo dõi các lỗi một cách hiệu quả.
Oleksi

1
Git hỗ trợ các cam kết đi kèm.
deltree

3

Tôi quen thuộc nhất với Git, vì vậy tôi sẽ trả lời cho quan điểm đó.

Tôi không thấy lý do tại sao bạn hoặc bất kỳ VCS tốt nào muốn cho phép thực hiện một tệp chưa được trộn, đặc biệt nếu đó là mã. Bạn cần giữ cho kho lưu trữ ở trạng thái nhất quán và những gì bạn đang đề xuất sẽ vi phạm nguyên tử cam kết. Nhiều VCS thay đổi vật lý tệp để hiển thị nơi xảy ra xung đột - Git, SVN và CVS sử dụng >>>> <<<< đánh dấu loại. Trong một VCS với các cam kết và sáp nhập cấp kho lưu trữ nguyên tử, bạn sẽ chỉ tạo một nút không có ý nghĩa với bất kỳ ai trừ bạn. Trong phát triển phần mềm, dự án của bạn không thể xây dựng. Trong tài liệu của một nhóm, không ai biết thay đổi nào là chính xác.

Bây giờ, Git cung cấp một số công cụ có thể giảm bớt điều này, là loại cam kết mà bạn đề xuất cho phép. Bạn có thể đè bẹp tất cả các cam kết hợp nhất với nhau trước khi bạn đẩy, chẳng hạn. Điều đó kết thúc giống như một cam kết hợp nhất điển hình.

Những lo ngại cụ thể về danh sách lợi ích của bạn:

  1. Những thay đổi hợp nhất thực tế là trong lịch sử. Tại sao bạn cần thêm thông tin? DVCS rất giỏi trong việc hạn chế xung đột ở các khu vực hạn chế. Khi bạn chọn giữ thay đổi nào, việc so sánh bản sao của nút xác nhận hợp nhất với bản sao trước đó sẽ cung cấp cho bạn chính xác điều này.
  2. Nếu sự hợp nhất là rất lớn, bạn có thể thực hiện các cam kết định kỳ. Đây là một mối quan tâm hợp lệ, nhưng bạn không nên đến đây ngay từ đầu. Các chi nhánh phải liên tục kéo theo những thay đổi ngược dòng chỉ để điều này không bao giờ xảy ra. Các công cụ như rebasehoặc anh đào chọn một cam kết tại một thời điểm cũng có thể hỗ trợ bạn ở đây trong một số tình huống.
  3. Nếu bạn mắc lỗi, việc quay trở lại sẽ dễ dàng hơn nhiều (mà không phải làm lại toàn bộ hợp nhất). Xem ở trên - xung đột của bạn không nên trở thành không thể kiểm soát này.

Cách duy nhất mà đề xuất này có thể hoạt động là nếu nhánh là nếu toàn bộ hợp nhất là nguyên tử - bạn có thể thấy một loạt các cam kết, nhưng chúng sẽ chỉ là các bước trong một cam kết hợp nhất lớn hơn phải được coi là một nút trong cây cam kết . Tôi không nghĩ rằng bất kỳ VCS hiện tại nào cũng hỗ trợ cho loại quy trình này và tôi không nghĩ rằng điều đó là cần thiết.


Xung đột có lẽ không nên trở thành điều này, nhưng thường là (ít nhất là theo kinh nghiệm của tôi). Tôi nghĩ rằng toàn bộ hợp nhất nên là nguyên tử; đó là những gì tôi đề nghị. Có thể không cần thiết, tôi chỉ tự hỏi tại sao nó không được thực hiện. Bạn cũng không nhất thiết phải chọn một hoặc tùy chọn khác trong xung đột; đôi khi nó là sự kết hợp của cả hai thay đổi. Điều này đặc biệt khó hiểu.
Thuốc nổ

"Bạn cần giữ cho kho lưu trữ ở trạng thái nhất quán". Tôi không nghĩ đó là sự thật. Một kho lưu trữ cục bộ là một không gian làm việc , không phải là một ngôi đền. Nếu nó giúp cam kết ở giữa hợp nhất, hãy thực hiện IMHO. Nếu bạn làm điều này bởi vì bạn không biết gì hơn, tôi sẽ khuyên bạn không nên làm điều đó. Tuy nhiên, nếu bạn là một lập trình viên có kinh nghiệm, bạn nên làm bất cứ điều gì tốt nhất cho bạn. Đừng giáo điều về việc giữ cho kho lưu trữ địa phương của bạn nguyên sơ.
Bryan Oakley

1

Trải nghiệm chính của tôi nằm ở Mercurial, mặc dù tôi cũng sử dụng git một cách rời rạc.

Mercurial không cho phép bạn thực hiện các tệp chưa được giải quyết, điều này chỉ khiến bạn nản lòng . Tương tự với việc đẩy trước khi kéo những thay đổi mà bạn không có.

Tất cả những gì bạn cần làm trong Mercurial là, một khi bạn có các tệp theo cách bạn muốn cam kết chúng:

hg resolve --mark --all
hg commit -m "I'm such a rebel"

--mark sẽ ... đánh dấu các tệp là đã giải quyết mà không nhắc bạn với công cụ hợp nhất. --all sẽ đảm nhiệm việc chọn tất cả các tệp đánh dấu có xung đột.

Nếu bạn muốn đẩy mà không kéo (và do đó phải hợp nhất các thay đổi của người khác), hãy làm như một Jedi :

hg push --force

Người tiếp theo kéo sẽ nhận được +1 đầu (không có ý định chơi chữ)

Tôi chắc chắn có một cách để làm những thứ tương tự với Git (mặc dù nó có thể phức tạp hơn).


1

Khi tôi hợp nhất trong git, tôi ngay lập tức cam kết tất cả các thay đổi (bao gồm cả xung đột hợp nhất). Sau đó, trong (các) cam kết tiếp theo của tôi, tôi giải quyết xung đột hợp nhất thông qua trình soạn thảo văn bản. Sau khi các xung đột được giải quyết, tôi sau đó Đẩy nếu muốn.

Thành thật mà nói tôi không hiểu tại sao những người khác không làm theo cách này hoặc git không thực thi nó.

  • "Cam kết hợp nhất" hiện là một lịch sử rõ ràng về chính xác những gì cần được sáp nhập.
  • (Các) cam kết sau đây hiển thị chính xác những gì bạn đã làm để giải quyết xung đột hợp nhất.
  • Khi bạn Đẩy, xung đột sẽ được giải quyết và bản dựng không bị phá vỡ ở đầu nhánh.
  • Tại bất kỳ thời điểm nào, nếu bạn tăng độ phân giải xung đột, bạn chỉ cần quay lại một trong các cam kết "hợp nhất bài" và thử lại.

Một nhược điểm lớn của quy trình làm việc tiêu chuẩn để giải quyết xung đột trước khi cam kết là các thay đổi từ bản sao cục bộ của bạn có thể lẻn vào. Các bổ sung được ẩn khỏi đánh giá mã bởi sự khác biệt lớn, vì vậy bạn không nhận thấy rằng mình đã vô tình phạm phải API chìa khóa hoặc vv

Quy trình làm việc của tôi được mô tả ở trên để tránh vấn đề sao chép cục bộ này và cũng cho phép người đánh giá mã kiểm tra (chỉ) các chi tiết về độ phân giải hợp nhất của bạn trong một khác biệt cam kết trông giống hệt như một cam kết khác.


0

Tôi nghĩ rằng tốt nhất là nên thay đổi nhỏ và đẩy thường xuyên, khi có thể (và tất nhiên là không phải lúc nào cũng vậy) và không cam kết mã không xây dựng hoặc hoàn thành một nửa (tất cả chúng ta đều mắc lỗi, nhưng không nên 'T làm điều đó trên mục đích). Tôi cũng đến từ git, và một trong những điều tốt nhất tôi nghĩ là thực tế là bạn có thể có một bản sao khả thi của repo trên máy tính để bàn của bạn ... sau đó bạn có thể sửa đổi nội dung trái tim của mình. Khi những thay đổi lớn của bạn được thực hiện, gửi nó đi.

Làm rất nhiều mã nguồn mở với git, sự thất vọng lớn nhất đối với tôi là nhận được một nửa mã được đưa vào repo và cố gắng xây dựng, nhưng không thể, bởi vì anh chàng đã làm một nửa công việc và nói "Bây giờ tôi đang bận , Tôi sẽ hoàn thành nó trong một tuần ". Vì vậy, cuối cùng tôi phải loại bỏ nó (điều này sẽ gây khó chịu cho anh chàng), hoặc dành thời gian để hoàn thành và tích hợp nó hoàn toàn.

Tôi đoán từ quan điểm của tôi, giữ những thứ nửa mông ở địa phương, gửi những thứ tốt qua dây.


0

Đừng làm nô lệ cho các công cụ của bạn.

Mục tiêu của một VCS là cho phép bạn thực hiện công việc của mình. Công việc của bạn không phải là giữ một kho lưu trữ cục bộ nguyên sơ, công việc của bạn là viết mã. Nếu cam kết sớm và thường xuyên tại địa phương cho phép bạn làm việc tốt hơn, hãy làm điều đó.

Tuy nhiên, bạn không nên đẩy mã bị hỏng ngược dòng.


0

Bởi vì về cơ bản đó là một ý tưởng tồi - nó sẽ dẫn bạn đến một kho lưu trữ ở trạng thái ngang ngược (và phát ban của nó để cho rằng bạn sẽ đẩy bất cứ nơi nào, mặc dù người ta sẽ tranh luận rằng bạn phải luôn có ít nhất một bản sao).

Tôi có thể thấy rằng trong trường hợp hợp nhất lớn / phức tạp, bạn có thể muốn lưu tiến trình công việc của mình và thiết lập một điểm tham chiếu nhưng bạn vẫn sẽ rời khỏi hệ thống trong trạng thái lộn xộn cần được giải quyết.

Và có những lựa chọn thay thế - bạn có tùy chọn hợp nhất từ ​​sớm hơn đầu - có thể cung cấp cho bạn khả năng thích ứng với các thay đổi mà không cần hợp nhất sử thi (hoặc ít nhất là với các kết hợp lớn hơn dễ hiểu hơn).

Đây là trường hợp tôi thấy rebase của git đặc biệt hữu ích (tuân theo những cảnh báo thông thường về việc nổi loạn) bởi vì bạn đang phát lại các thay đổi của mình trên trạng thái hiện tại mà bạn có để khắc phục xung đột trong các phần nhỏ hơn.

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.