Cách tạo nhánh từ cam kết cụ thể trong nhánh khác nhau


102

Tôi đã thực hiện một số cam kết trong nhánh chính và sau đó hợp nhất chúng vào nhánh dev.

Tôi muốn tạo một nhánh từ một cam kết cụ thể trong nhánh dev, lần đầu tiên được cam kết trong nhánh chính.

Tôi đã sử dụng các lệnh:

git checkout dev
git branch  <branch name> <commit id>

Tuy nhiên, điều này tạo ra nhánh từ nhánh chủ, không phải nhánh nhà phát triển mà tôi mong đợi. Id cam kết giống nhau trong nhánh chính và nhánh nhà phát triển. Vì vậy, làm thế nào tôi có thể phân biệt cùng một id cam kết trong các nhánh khác nhau?

Tái bút: Tôi đã làm một ví dụ trong github tại đây https://github.com/RolandXu/test_for_branch

Tôi đã sử dụng các lệnh:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Điều tôi mong đợi là nhánh thử nghiệm chứa aa.txt bb.txt cc.txt. Tuy nhiên, nhánh kiểm tra chỉ chứa aa.txt và cc.txt. Rất có thể nó đã tạo nhánh từ nhánh chính.

Câu trả lời:


145

Nếu bạn đang sử dụng dạng branchlệnh này (với điểm bắt đầu), không quan trọng bạn HEADđang ở đâu .

Bạn đang làm gì:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Đầu tiên, bạn đặt của bạn HEADvào chi nhánh dev,

  • Thứ hai, bạn bắt đầu một nhánh mới trên cam kết 07aeec98. Không có bb.txt tại cam kết này (theo repo github của bạn).

Nếu bạn muốn bắt đầu một chi nhánh mới tại vị trí bạn vừa kiểm tra, bạn có thể chạy chi nhánh không có điểm bắt đầu:

git branch test

hoặc như người khác đã trả lời, phân nhánh và thanh toán ở đó trong một thao tác:

git checkout -b test

Tôi nghĩ rằng bạn có thể bị nhầm lẫn bởi thực tế đó 07aeec98là một phần của nhánh dev. Đúng là cam kết này là tổ tiên của dev, các thay đổi của nó là cần thiết để đạt được cam kết mới nhất trong dev. Tuy nhiên, chúng là những cam kết khác cần thiết để đạt được điều mới nhất devvà những cam kết này không nhất thiết phải có trong lịch sử của 07aeec98.

8480e8ae(nơi bạn đã thêm bb.txt) chẳng hạn như không có trong lịch sử của 07aeec98. Nếu bạn phân nhánh từ 07aeec98, bạn sẽ không nhận được các thay đổi được giới thiệu bởi 8480e8ae.

Nói cách khác: nếu bạn hợp nhất nhánh A và nhánh B thành nhánh C, sau đó tạo một nhánh mới trên cam kết của A, bạn sẽ không nhận được những thay đổi được giới thiệu trong B.

Tương tự ở đây, bạn có hai nhánh master và dev song song, bạn đã hợp nhất trong dev. Việc phân nhánh từ một cam kết chính (cũ hơn so với hợp nhất) sẽ không cung cấp cho bạn những thay đổi của nhà phát triển.


Nếu bạn muốn tích hợp vĩnh viễn các thay đổi mới từ chính vào các nhánh tính năng của mình, bạn nên hợp nhấtmaster vào chúng và tiếp tục. Tuy nhiên, điều này sẽ tạo ra các cam kết hợp nhất trong các nhánh tính năng của bạn.

Nếu bạn chưa xuất bản các nhánh tính năng của mình, bạn cũng có thể căn cứ lại chúng trên bản chính được cập nhật: git rebase master featureA . Hãy chuẩn bị để giải quyết những xung đột có thể xảy ra.

Nếu bạn muốn một quy trình làm việc trong đó bạn có thể làm việc trên các nhánh tính năng mà không có cam kết hợp nhất và vẫn tích hợp với các thay đổi mới hơn trong tổng thể, tôi khuyên bạn nên làm như sau:

  • dựa trên mọi nhánh tính năng mới dựa trên cam kết chính
  • tạo một dev nhánh trên một cam kết chính
  • khi bạn cần xem nhánh tính năng của mình tích hợp như thế nào với những thay đổi mới trong cái chính, hãy hợp nhất cả nhánh cái và nhánh tính năng vào dev.

Không cam kết devtrực tiếp, chỉ sử dụng nó để hợp nhất các chi nhánh khác.

Ví dụ: nếu bạn đang làm việc trên tính năng A và B:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

Hợp nhất các nhánh thành một devnhánh để kiểm tra xem chúng có hoạt động tốt với cái chính mới hay không:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

Bạn có thể tiếp tục làm việc trên các nhánh tính năng của mình và tiếp tục hợp nhất các thay đổi mới từ cả nhánh chính và nhánh tính năng thành devthường xuyên.

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

Khi đã đến lúc tích hợp các tính năng mới, hãy hợp nhất các nhánh tính năng (không phải dev!) Thành chính.


cảm ơn. Bạn trả lời câu hỏi của tôi. Tôi đã hiểu sai về chế độ nhánh git. Và bạn có bất kỳ đề nghị cho vấn đề của tôi. Tôi có nhánh chính có nhiều cam kết kịp thời từ những người khác (đồng bộ với perforce). Tôi có nhánh nhà phát triển, tôi làm công việc cá nhân. Tôi muốn một nhánh chứa tất cả các cam kết từ nhánh chủ và nhánh nhà phát triển, sau đó tôi có thể dễ dàng tạo nhánh dựa trên nhánh này, sau đó để bắt đầu làm việc cụ thể.
RolandXu 14/12/11

Tôi không thể trả lời trong một nhận xét, vì vậy tôi cập nhật câu trả lời của mình bằng quy trình công việc được đề xuất.
Gauthier

Này - cảm ơn vì câu trả lời tuyệt vời và thấu đáo! Chỉ tò mò: Cuối cùng, tại sao nên một merge the feature branches (not dev!) into master?
cassi.lup

Không có sự phát triển mới thực sự trong devchi nhánh. Bạn nên giữ đặc điểm chi nhánh của mình cụ thể. devchỉ chứa các cam kết hợp nhất. Sẽ có ý nghĩa hơn khi hợp nhất tất cả các tính năng mới với trực tiếp master, hơn là hợp nhất các tính năng với nhau rồi hợp nhất kết quả vào master.
Gauthier

@Gauthier Bạn đã không giải quyết được câu hỏi tại sao. Đối với tôi, nó giống như hợp nhất một devchỉ với các tính năng A BChợp nhất vào nó thànhmaster giống hệt như hợp nhất A BCvào riêng lẻ master. Nếu không, điều đó thách thức sự hiểu biết của tôi về cách hoạt động của git và tôi sẽ rất tò mò tại sao!
Steven Lu

53

Bạn có các đối số không đúng thứ tự:

git branch <branch-name> <commit>

và đối với điều đó, không quan trọng chi nhánh được kiểm tra; nó sẽ làm những gì bạn nói. (Nếu bạn bỏ qua đối số cam kết, nó sẽ mặc định tạo một nhánh ở cùng vị trí với đối số hiện tại.)

Nếu bạn muốn xem chi nhánh mới khi tạo nó:

git checkout -b <branch> <commit>

với hành vi tương tự nếu bạn bỏ qua đối số cam kết.


22

Bạn có thể làm điều này cục bộ như mọi người đã đề cập bằng cách sử dụng

git checkout -b <branch-name> <sha1-of-commit>

Ngoài ra, bạn có thể thực hiện việc này trong chính github, hãy làm theo các bước:

1- Trong kho, nhấp vào Commits .

2- trên cam kết mà bạn muốn phân nhánh, nhấp vào <>để duyệt qua kho lưu trữ tại thời điểm này trong lịch sử.

cam kết lịch sử

3- Nhấp vào tree: xxxxxxở phía trên bên trái. Chỉ cần nhập tên chi nhánh mới vào đó, nhấp vào Create branch xxxnhư hình bên dưới.

tạo chi nhánh mới

Bây giờ bạn có thể tìm nạp các thay đổi từ nhánh đó cục bộ và tiếp tục từ đó.


Đây là những gì tôi cần .. Làm thế nào để làm điều đó trong các trang web
eharo2

Tôi chưa bao giờ biết điều đó. Đây là nó. GUI thật tuyệt vời và tôi muốn rời xa CLI.
Rohit Gupta

10

Thử

git checkout <commit hash>
git checkout -b new_branch

Cam kết chỉ nên tồn tại một lần trong cây của bạn, không phải ở hai nhánh riêng biệt.

Điều này cho phép bạn kiểm tra cam kết cụ thể đó và đặt tên cho nó những gì bạn sẽ làm.


xin chào, tôi thử dùng git log dev và git log master, tôi thấy id băm cam kết giống với cam kết mà tôi hợp nhất thành nhánh dev từ nhánh chính
RolandXu

nó có thể hữu ích khi sử dụng một cái gì đó như gitkđể trực quan hóa nhật ký của bạn
ZMorek

Tôi mới thêm một ví dụ trong github. Và Gauthier đã trả lời câu hỏi của tôi rằng tôi hiểu sai về chế độ nhánh git. Cảm ơn bạn :)
RolandXu

Tôi nghĩ đây là câu trả lời nhạy bén. Cảm ơn
virusss8

9

Bạn phải làm:

git branch <branch_name> <commit>

(bạn đã thay đổi tên chi nhánh và cam kết)

Hoặc bạn có thể làm:

git checkout -b <branch_name> <commit>

Nếu thay vì bạn sử dụng tên nhánh, bạn sẽ nhận được một nhánh từ đầu nhánh.


Đó không phải HEADlà ý nghĩa. Thay vào đó, bạn có thể nói "đầu của nhánh" hoặc "cam kết nhánh trỏ tới".
Cascabel

@Jefromi - Để trở thành những người theo chủ nghĩa thuần túy, chúng ta có thể nói chỉ nhánh, vì bản thân nhánh là con trỏ trỏ đến, tốt, là đỉnh của nhánh.
manojlds
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.