2015-02-09 18 views
11

Khi tôi làm việc trên hai tính năng khác nhau (trên hai chi nhánh khác nhau được tạo từ master), điều này khá khó chịu và không có lịch sử cam kết khi tiếp tục hợp nhất.Giữ lịch sử cam kết sau khi 'hợp nhất git'

Tôi sẽ giải thích rõ hơn. Khi tôi hoàn thành công việc trên Chi nhánh-A, tôi hợp nhất nó vào chính. Và đó là tốt, nếu tôi git log Tôi thấy tất cả các cam kết tôi đã thực hiện trên Chi nhánh-A.

Thay vào đó, khi tôi hoàn thành công việc trên Chi nhánh-B và tôi cố gắng kết hợp nó với chủ (sau đó Chi nhánh-A đã được đã được sáp nhập), tôi phải chỉ định một cam kết thông báo cho việc sáp nhập (trong khi đối với chi nhánh đầu tiên tôi chưa được hỏi bất kỳ điều gì). Và sau khi sáp nhập để chủ, nếu tôi gõ git log, tôi không thể nhìn thấy các cam kết của Chi nhánh-B trong lịch sử của chủ của tôi chi nhánh

Hãy nói rằng tôi có

**Branch A** 

commit 09b2unfas9d781n2e 
    Add more stuff 

commit 8uj8masd89jas898a 
    Add stuff 

**Branch B** 

commit 09b2unfas9d781n2e 
    Add feature setting 

commit 8uj8masd89jas898a 
    Add feature 

Tôi hoàn thành việc có

**Master** 

commit 6hf6h8hd871udjkdn 
Merge: 09b2un 34osd6 
    Merge branch 'Branch-B' into master 

commit 09b2unfas9d781n2e 
    Add more stuff 

commit 8uj8masd89jas898a 
    Add stuff 

commit 34osd62dhc91123j8 
    I'm a previous commit from 'master'. 
    The last one before branching... 

trong khi Tôi muốn o btain cái gì đó như:

**Master** 

commit 09b2unfas9d781n2e 
    Add feature setting 

commit 8uj8masd89jas898a 
    Add feature 

commit 09b2unfas9d781n2e 
    Add more stuff 

commit 8uj8masd89jas898a 
    Add stuff 

commit 34osd62dhc91123j8 
    I'm a previous commit from 'master'. 
    The last one before branching... 

... đó sẽ phản ánh chính xác hơn về lịch sử của các cam kết thực hiện.

Tôi không hiểu tại sao tôi có thể giữ lịch sử chỉ từ một trong hai nhánh.

Làm cách nào để giữ mọi thứ rõ ràng nếu không có những người hợp nhất cam kết ẩn/bỏ qua lịch sử thực sự của các cam kết đã hợp nhất?

Trả lời

0

Sử dụng rebase thay vì merge. Từ tutorial:

Nếu bạn kiểm tra các bản ghi của một chi nhánh rebased, nó trông giống như một lịch sử tuyến tính: có vẻ như tất cả công việc đã xảy ra trong loạt, ngay cả khi nó ban đầu xảy ra song song.

Tôi tưởng tượng rằng những thay đổi từ Branch-B của bạn không thể được sáp nhập sử dụng nhanh về phía trước sáp nhập vào master. Trong trường hợp này một three-way-merge được thực hiện:

Thay vì chỉ cần di chuyển con trỏ chi nhánh về phía trước, tạo ra một Git snapshot mới là kết quả của ba chiều kết hợp này và tự động tạo ra một mới cam kết trỏ đến nó. Điều này được gọi là cam kết hợp nhất và đặc biệt ở chỗ nó có nhiều hơn một phụ huynh.

Tôi sẽ luôn xóa bỏ các cam kết của mình trước khi commit chúng vào master để giữ lịch sử tuyến tính.

11

Dường như quá trình hợp nhất đầu tiên là tiến trình tua đi nhanh và phiên bản thứ hai là kết hợp ba chiều.

Giải thích

Git có hai phiên bản hợp nhất: nhanh về phía trước và ba chiều. (Có các phiên bản khác, nhưng đó không phải là những gì đã xảy ra ở đây.) Hành vi mặc định là thực hiện hợp nhất nhanh về phía trước khi có thể, và nếu không, hãy thực hiện hợp nhất ba chiều.

Kết hợp nhanh về phía trước (bạn có thể buộc hành vi này bằng tùy chọn --ff-only, điều này sẽ làm cho quá trình hợp nhất thất bại khi không thể chuyển tiếp nhanh) khi cam kết đang được hợp nhất có vị trí hiện tại của chi nhánh trong lịch sử của nó. Ví dụ:

A - B - C - D <-master 
      \ 
       E - F - G <- branch-a 

Excecuting git merge (với các thiết lập mặc định) sẽ cho kết quả

A - B - C - D - E - F - G <- branch-a <-master 

Bạn cũng sẽ không có cơ hội để chỉnh sửa hợp nhất cam kết vì không ai sánh kịp. Tuy nhiên, khi điều này xảy ra, chi nhánh khác của bạn sẽ bất đồng từ thạc sĩ (không chỉ là phía trước):

A - B - C - D - E - F - G <-master 
        \ 
        E1 - E2 <- branch-b 

Vì vậy, Git không thể chỉ di chuyển con trỏ của thầy G-E2 vì đó sẽ thoát khỏi những thay đổi mà được thực hiện trong FG. Thay vào đó một sự hợp nhất ba chiều xảy ra, tạo ra một cam kết có hai cha mẹ, và cũng có một thông điệp cam kết. Bây giờ, chủ có thể được chuyển đến cam kết này. (Chú ý rằng trong tình huống này, tổng thể và chi nhánh-b KHÔNG trỏ đến cùng cam kết.

A - B - C - D - E - F - G - H <-master 
        \  /
        E1 - E2 <- branch-b 

Nếu bạn muốn có một lịch sử tuyến tính thì bạn cần phải sử dụng rebase, nhưng được cảnh báo trước rằng nếu bất kỳ ai khác có sử dụng rebase sẽ liên quan đến hai bước, rebasing và sau đó nhanh chóng chuyển tiếp hợp nhất.Vì vậy, thay vì sáp nhập bạn đầu tiên thực hiện như sau trong khi trên branch-b Điều này tạo ra các cam kết mới là bản sao của các cam kết cũ, tức là, cùng một tập hợp thay đổi, thông tin tác giả và thông báo, nhưng thông tin về người gửi và lịch sử phụ huynh mới (tôi gọi các cam kết E1 'và E2' trong hình minh họa để chỉ ra rằng chúng chỉ là bản sao.) T ông cam kết cũ sẽ tồn tại cho đến khi họ sẽ trở thành rác, nhưng sẽ không thể truy cập trừ khi bạn nhìn vào reflog.)

A - B - C - D - E - F - G <-master 
        \  \ 
        E1 - E2 \ 
          E1' - E2' <- branch-b 

Thi git checkout master; git merge --ff-only branch-b bây giờ sẽ nhanh về phía trước thay đổi của bạn vào tổng thể, do đó đem lại cho bạn một lịch sử tuyến tính.

A - B - C - D - E - F - G - E1' -E2' <-master <- branch-b 
+0

Tôi cần hợp nhất 'master' thành' branch-b' khi tôi có thay đổi trong cả hai. Làm thế nào tôi có thể viết lại 'branch-b' như nó đã được bắt đầu từ commit' G', không phải 'E'? Nhưng giữ lại lịch sử commit của 'branch-b' và commit các thay đổi thành' branch-b' là xung đột. Giả sử tôi chỉ là người biết về 'branch-b'. – hlcs

+0

Nvm nó chính xác 'git rebase master'. – hlcs

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