Cách tốt nhất để hoàn tác hợp nhất Git sẽ xóa các tệp khỏi repo?


13

Vì vậy, hãy tưởng tượng những điều sau đây xảy ra (và tất cả chúng ta đều sử dụng SourceTree):

  1. Tất cả chúng ta đang làm việc không có nguồn gốc / phát triển.
  2. Tôi đi nghỉ một tuần.
  3. Đồng nghiệp của tôi đã làm việc tại địa phương trong nhiều ngày qua mà không hợp nhất nguồn gốc / phát triển trở lại chi nhánh phát triển địa phương của anh ấy.
  4. Anh ta cố gắng thực hiện một cú đẩy, được bảo rằng anh ta phải hợp nhất trước, và sau đó thực hiện một cú kéo.
  5. Anh ta nhận được một cuộc xung đột, ngăn chặn việc cam kết tự động sau khi hợp nhất tiến hành.
  6. Giả sử rằng Git giống như SVN, đồng nghiệp của tôi loại bỏ các tệp "mới" trong bản sao làm việc của anh ấy và sau đó cam kết hợp nhất - xóa sạch các tệp "mới" đó khỏi phần gốc / phát triển.
  7. Một tuần làm việc đáng giá của nhà phát triển diễn ra trên bản sửa đổi đó.
  8. Tôi trở về từ ngày lễ và phát hiện ra rằng một vài ngày làm việc của tôi bị mất tích.

Tất cả chúng ta đều rất mới với Git (đây là dự án đầu tiên của chúng tôi sử dụng nó), nhưng những gì tôi đã làm để khắc phục nó là:

  1. Đổi tên "phát triển" thành "Develop_old".
  2. Hợp nhất Develop_old thành một nhánh mới "Develop_new".
  3. Đặt lại nhánh Develop_new về lần xác nhận cuối cùng trước khi hợp nhất xấu.
  4. Cherry chọn từng cam kết kể từ đó, từng người một, giải quyết xung đột bằng tay.
  5. Đẩy Develop_old và Develop_new lên đến điểm gốc.

Tại thời điểm này, Develop_new, tôi hy vọng, một bản sao "tốt" của tất cả các thay đổi của chúng tôi với giá trị công việc trong những tuần tiếp theo được áp dụng lại. Tôi cũng giả định rằng "ngược cam kết" sẽ làm những điều kỳ lạ về một hợp nhất, đặc biệt là từ vài tuần tới giá trị của tác phẩm dựa vào nó - và kể từ khi hợp nhất có chứa rất nhiều thứ chúng tôi làm muốn cùng với các công cụ chúng tôi don' t.

Tôi hy vọng rằng điều này sẽ không bao giờ xảy ra nữa, nhưng nếu nó xảy ra một lần nữa, tôi muốn biết về một cách dễ dàng hơn / tốt hơn để sửa chữa mọi thứ. Có cách nào tốt hơn để hoàn tác một sự hợp nhất "xấu", khi rất nhiều công việc đã diễn ra trong repo dựa trên sự hợp nhất đó?


1
Bạn có thể đăng một ảnh chụp màn hình của cây git (được điều chỉnh lại một cách thích hợp) hoặc đầu ra của git logđịnh dạng yêu thích của bạn với các chú thích thích hợp về những gì đã xảy ra ở các cam kết khác nhau không? (Tôi sắp xếp lại / chú thích git log --graph --pretty=oneline --abbrev-commitvà đi từ đó)

1
Quá muộn cho bạn, nhưng các bài kiểm tra đơn vị sẽ bắt được điều đó.
nalply

1
@nalply: Không nếu hợp nhất xấu cũng xóa các bài kiểm tra đơn vị.
Aaronaught

Wow, thật là xui xẻo.
nalply

Câu trả lời:


6

Nếu tôi hiểu chính xác, đây là tình huống của bạn:

    ,-c--c--c--c--M--a--a--X ← develop
o--o--y--y--y--y-´

Sau một số lịch sử chung (o), bạn đã cam kết và thúc đẩy công việc của mình (y). Đồng nghiệp của bạn (c) đã làm việc trên kho lưu trữ cục bộ của anh ấy và đã hợp nhất (M). Sau đó, có thể có một số cam kết bổ sung (a) trên đầu M.

git reset --hard develop M^2
git branch coworker M^1

Bây giờ biểu đồ của bạn trông giống hệt như trước khi hợp nhất xấu:

    ,-c--c--c--c ← coworker
o--o--y--y--y--y ← develop

Thực hiện hợp nhất (G):

git checkout develop
git merge coworker

Kết quả là:

    ,-c--c--c--c-、
o--o--y--y--y--y--G ← develop

Bây giờ ghép các cam kết bổ sung:

git reset --hard X
git rebase --onto G M develop

Điều này cho kết quả cuối cùng:

    ,-c--c--c--c-、
o--o--y--y--y--y--G--a--a--X ← develop

Hãy lưu ý rằng điều này có thể dẫn đến nhiều xung đột hợp nhất. Ngoài ra, bạn vừa thay đổi lịch sử, tức là tất cả đồng nghiệp của bạn nên sao chép / đặt lại / rebase vào lịch sử mới.

PS: tất nhiên bạn nên thay thế G, MXtrong các lệnh của bạn bằng cách tương ứng cam kết id.


Có vẻ như khá rõ ràng trong câu hỏi rằng tất cả các cam kết này đã được đẩy đến một kho lưu trữ được chia sẻ, vì vậy tôi không nghĩ rằng việc đánh bại là một lựa chọn tốt. Hoàn nguyên tất cả các cam kết gần đây và sau đó chọn anh đào hoàn nguyên không xung đột trên đỉnh hợp nhất tốt sẽ an toàn hơn.
Aaronaught

Đó là phần với bản sao / thiết lập lại / rebase. - Nếu chỉ có một vài nhà phát triển, việc bảo họ cập nhật kho lưu trữ của họ có thể là một tùy chọn hợp lệ.
michas

1

Thật tốt khi bạn nghĩ về cách sửa chữa kho lưu trữ, nhưng nếu đồng nghiệp của bạn chỉ xóa các tệp mới và không ghi đè lên nhiều bản cập nhật, thì cách tiếp cận đơn giản hơn nhiều sẽ là khôi phục các tệp đã bị xóa.

Có lẽ tôi sẽ bắt đầu bằng cách cố gắng chọn cherry (trên đầu hiện tại) các cam kết ban đầu mà bạn đã thêm mã đã bị mất. Nếu vì lý do nào đó không hoạt động, chỉ cần kiểm tra bản sửa đổi cũ với các tệp bạn đã thêm và thêm lại chúng trong một cam kết mới.

Những gì bạn mô tả thực sự là một tập hợp con của mô hình chống Git nổi tiếng, mà đối với cuộc sống của tôi, tôi không thể nhớ tên của nó - nhưng ý chính của nó là, thực hiện bất kỳ "chỉnh sửa thủ công" nào trong quá trình hợp nhất Git (tức là chỉnh sửa không thực sự giải quyết bất kỳ xung đột hợp nhất nào nhưng đang thực hiện một số thay đổi hoàn toàn không liên quan) được coi là một thực tiễn cực kỳ tồi tệ vì về cơ bản chúng bị che giấu bởi chính sự hợp nhất và dễ bị bỏ qua trong các đánh giá mã hoặc phiên gỡ lỗi.

Vì vậy, chắc chắn giải thích cho đồng nghiệp của bạn rằng đây là một thất bại sử thi, nhưng xem xét việc tát vào một hỗ trợ ban nhạc trước khi chuẩn bị cho cuộc phẫu thuật lớn.


Tôi đồng ý, nếu toàn bộ tập tin đã biến mất một điều bạn có thể làm là điều này nếu bạn không quan tâm đến lịch sử trong các tập tin cũ: 1. tạo một nhánh mới từ nhánh hiện đang bị rối. 2. chuyển trở lại nhánh xấu và tạo một nhánh mới khác là nhánh cứu hộ của bạn 3. Từ nhánh cứu hộ của bạn quay trở lại cam kết trước khi cam kết thất bại. 4. Sao chép các tệp đã xóa ở đâu đó bên ngoài git 5. Chuyển sang nhánh mới khác. 6. Sao chép các phiên bản mới của các tệp đã xóa sang nhánh mới và cam kết. Có một cách phức tạp hơn để lưu lại lịch sử đó là một bài đăng nổi tiếng của Linus T.
Elin

1
Trên thực tế, điều này cho thấy cách bạn có thể sử dụng thanh toán jasonrudolph.com/blog/2009/02/25/ khăn Điều đó đẹp hơn nhiều.
Elin
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.