2011-06-17 26 views
6

Tôi đang gặp sự cố khi hiểu cách hoạt động của git merge theo các cam kết được tạo bởi quá trình hợp nhất. Tôi đã đọc các phần liên quan trong git pro và sách cộng đồng git, nhưng tôi vẫn còn bối rối.Git xử lý cam kết trong quá trình hợp nhất như thế nào?

Hãy xem xét kịch bản này: Tôi có một "nguồn gốc" git repo:

  master 
      | 
a0--a1--a2--a3 
    \ 
    -b0--b1 
     | 
     branch2 

tôi sao chép repo này cho một repo địa phương và sau đó chỉ làm việc trên các repo địa phương. Trong branch2, tôi đã làm một "git merge master". Bây giờ repo địa phương của tôi trông như thế này:

 master/origin/master 
      | 
a0--a1--a2--a3 
    \   \ 
    -b0--b1-----merge 
     |  | 
    origin/branch2 |  
       branch2 

Vì vậy, hợp nhất đã tạo 1 cam kết, "hợp nhất", sau cam kết "b1". "git log" cho branch2 hiển thị biểu đồ dự kiến:

> git log branch2 --graph --pretty=oneline --decorate 
* a7b69fc6759e1dd5463bab379ce101a6ad026c7b (HEAD, branch2) Merge branch 'master' into branch2 
|\ 
| * 482e4026f05e33395a9fc3c87f50a746f692406a (origin/master, origin/HEAD, master) a3 
| * 8de57bdea2d316073af3b7055f8c28c56004ce94 a2 
| * 1e991047996aad269f2c01b9a0b9a7d8293096a1 a1 
* | 99955f66843df51fb9d40c7797156c32cad57415 (origin/branch2) b1 
* | 30ca9b6363558322f2bb7810d75cda0d9c2ba3e0 b0 
|/ 
* 76a7c6d0eb54a9580841115ff2c3429360ab2ac9 a0 

Ngoài ra, nếu tôi thực hiện một cam kết trước đầu hiện tại, tôi nhận cam kết b1, như mong đợi. (theo dòng branch2 trong biểu đồ và quay lại 1 cam kết)

> git log branch2~ --graph --pretty=oneline --decorate 
* 99955f66843df51fb9d40c7797156c32cad57415 (origin/branch2) b1 
* 30ca9b6363558322f2bb7810d75cda0d9c2ba3e0 b0 
* 76a7c6d0eb54a9580841115ff2c3429360ab2ac9 a0 

Đây là sự nhầm lẫn của tôi. Tôi chưa đẩy các thay đổi của mình về nguồn gốc, nhưng khi tôi thực hiện "trạng thái git", git nói chi nhánh 2 của tôi ở phía trước nguồn gốc/nhánh 2 bằng 4 lần commit. Tôi nghĩ việc hợp nhất chỉ dẫn đến một cam kết "hợp nhất" mới, như được thấy bởi biểu đồ/sơ đồ ở trên? Tại sao 4?

> git status 
# On branch branch2 
# Your branch is ahead of 'origin/branch2' by 4 commits. 
# 
nothing to commit (working directory clean) 

Ngoài ra, thực hiện "cam kết git" từ nguồn gốc/nhánh 2 đến nhánh 2 cho thấy 4 cam kết thay vì 1 tôi mong đợi (chuyển từ "b1" sang "hợp nhất").

> git log origin/branch2..branch2 --graph --pretty=oneline --decorate 
* a7b69fc6759e1dd5463bab379ce101a6ad026c7b (HEAD, branch2) Merge branch 'master' into branch2 
* 482e4026f05e33395a9fc3c87f50a746f692406a (origin/master, origin/HEAD, master) a3 
* 8de57bdea2d316073af3b7055f8c28c56004ce94 a2 
* 1e991047996aad269f2c01b9a0b9a7d8293096a1 a1 

Tôi hiểu 4 cam kết là 3 từ master (a1, a2, a3) mà hợp nhất được cho là sẽ chuyển sang nhánh 2, cộng với cam kết "hợp nhất". Nhưng tại sao biểu đồ không hiển thị theo cách đó? Nếu có, nó sẽ trông giống như:

 master/origin/master 
      | 
a0--a1--a2--a3----------- 
    \      \ 
    -b0--b1--a1'--a2'--a3'--merge 
     |     | 
    origin/branch2   |  
         branch2 

Và branch2 ~ sẽ đưa tôi đến a3 'thay vì b1.

Cảm ơn trước vì đã được trợ giúp.

+0

a1, a2, a3 và hợp nhất đơn giản không phải là một phần của origin/branch2, đó là lý do tại sao nó truyền cho bạn 4 cam kết. –

+0

Nếu bạn muốn có các thay đổi từ hợp nhất dưới dạng một cam kết, bạn có thể sử dụng 'git merge --squash'. – hammar

Trả lời

6

Như đã đề cập trong "How to get the changes on a branch in git":

git log origin/branch2..branch2 

có nghĩa là: tất cả các cam kết trên branch2 (tham khảo tích cực) mà không phải là trên origin/branch2 (tham khảo tiêu cực)
(Trên tài liệu tham khảo tích cực và tiêu cực, xem "Difference in 'git log origin/master' vs 'git log origin/master..'")

Trong trường hợp của bạn, sau khi hợp nhất, bạn có 4 cam kết về branch2 (một trong những địa phương) mà không phải là trên origin/branch2: a1, a2, a3merge.

+0

Cảm ơn bạn đã phản hồi nhanh chóng. Vì vậy, tôi hiểu lầm 2 điều: 1) "Chi nhánh của bạn trước bởi x lần commit". có nghĩa là có x cam kết trong chi nhánh hiện tại của bạn không tồn tại trong .Các cam kết này KHÔNG có nghĩa là có 4 cam kết giữa chi nhánh hiện tại của bạn và trên biểu đồ repo. 2) git log .. KHÔNG hiển thị những cam kết nào tôi sẽ đi qua khi tôi ngang từ đến trong biểu đồ repo. Thay vào đó, nó có thể được suy nghĩ của việc hiển thị một "khác" của các cam kết trong lịch sử của . – digitalsky

+0

@digitalsky: 'git log' nhận phạm vi * của bản sửa đổi và đi về biểu đồ các bản sửa đổi, bắt đầu với tham chiếu tích cực, quay lại lịch sử sửa đổi, dừng lại khi gặp phải các bản sửa đổi có thể truy cập từ tham chiếu phủ định . 'git diff' mất * hai * sửa đổi (không phải là một phạm vi) và là về việc hiển thị sự khác biệt giữa hai. Ngoại trừ 'diff A ... B' hiển thị trong' B' vì nó phân tách từ 'A'. – VonC

+0

@digitalsky: vì vậy bốn của bạn 1), phần "phía trước" là về việc quay trở lại đồ thị sửa đổi, biết rằng cam kết từ một chi nhánh khác, sau khi hợp nhất với chi nhánh địa phương của bạn, bây giờ có thể truy cập từ chi nhánh địa phương cho biết. Đối với 2 của bạn), tôi sẽ tránh thuật ngữ "diff";) – VonC

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