Phải làm gì với cam kết được thực hiện trong một cái đầu tách ra


279

Sử dụng git tôi đã làm một cái gì đó như thế này

git clone
git checkout {a rev number tree rev before} (here I started to be in a detached head state)
//hacking
git commit
//hacking
git commit
(some commit where made on origin/master)
git pull (which does complete because there was some error due to the fact that I'm no more on master)

Bởi vì nó nói với tôi rằng tôi vẫn có thể cam kết khi ở trạng thái đầu tách ra, tôi đã làm như vậy. Nhưng bây giờ tôi muốn hợp nhất nhánh đầu tách rời và nhánh chính cục bộ của tôi, và sau đó đẩy bó thay đổi của tôi sang gốc / gốc.

Vì vậy, câu hỏi của tôi là làm thế nào tôi có thể hợp nhất nhánh chính với trạng thái thực tế của tôi (đầu tách ra)



Tôi có thể thêm ảnh chụp màn hình của cây cam kết ở trạng thái này (cách cam kết trên đầu tách rời thực sự trông giống như trong gitk hoặc SourceTree), điều đó sẽ khiến câu hỏi này trở nên tốt hơn.
florisla

Thật không may vào lúc này tôi không thể nhưng nếu bạn có thể cung cấp, tôi sẽ rất vui khi thấy nó ở đây. Ngay cả khi đó là một trận hòa, nó sẽ làm cho nó rõ ràng hơn
benzen

Câu trả lời:


476

Tạo một nhánh nơi bạn đang ở, sau đó chuyển sang làm chủ và hợp nhất nó:

git branch my-temporary-work
git checkout master
git merge my-temporary-work

12
Làm thế nào để người ta tránh tách đầu trong tương lai?
ycomp

Tôi đã làm điều này và thấy mình đi trước xuất xứ bằng 5 lần cam kết. Trong trường hợp đó bạn chỉ cần làm git đẩy nguồn gốc?
Winnemucca

5
Thật lạ, tôi nhận được "Đã cập nhật." khi hợp nhất công việc tạm thời của tôi
Robert Sinclair

10
Đừng quên xóa công việc tạm thời của tôi với "chi nhánh git -d công việc tạm thời của tôi"
Thuyền trưởng Lepton

5
@ycomp "tách đầu" xảy ra khi bạn chỉnh sửa các tệp của một cam kết cũ và sau đó cam kết những người không có chi nhánh để tham chiếu cam kết mới này sau đó. Để tránh đầu bị tách ra, đừng kiểm tra các cam kết cũ. Nếu bạn vẫn muốn tất cả các tệp từ đó, nhưng là một cam kết mới, thì bạn có thể kiểm tra thư mục từ cam kết, thay vì chính cam kết đó. Xem câu trả lời này
lucidbrot

96

Bạn có thể làm một cái gì đó như thế này.

# Create temporary branch for your detached head
git branch tmp

# Go to master
git checkout master

# Merge in commits from previously detached head
git merge tmp

# Delete temporary branch
git branch -d tmp

Thậm chí đơn giản hơn

git checkout master
git merge HEAD@{1}

nhưng điều này có một mối nguy hiểm nhỏ là nếu bạn phạm sai lầm, có thể khó hơn một chút để phục hồi các cam kết được thực hiện trên đầu tách ra.


4
Tôi biết đây là năm sau, nhưng cảm ơn vì câu trả lời này. Tôi đã không xem xét bản thân mình khi tìm kiếm với câu trả lời được chấp nhận ở đây vì tôi không muốn rời khỏi một nhánh tạm thời và câu trả lời này có lệnh xóa nó.
Jeremy Pridemore

8
Nếu bạn quyết định sử dụng lệnh, git merge HEAD@{1}có lẽ bạn nên đảm bảo đó là lệnh bạn muốn sử dụng bằng cách sử dụnggit reflog
Michael Stramel

3
Việc có thể hợp nhất HEAD @ {1} đã cứu mạng tôi vì tôi đã kiểm tra chính chủ.
juil

Thật lạ, tôi nhận được "Đã cập nhật." khi hợp nhất tmp (nhưng các tệp khác nhau)
Robert Sinclair

18

Đây là những gì tôi đã làm:

Về cơ bản, hãy nghĩ về detached HEAD một nhánh mới, không có tên. Bạn có thể cam kết vào chi nhánh này giống như bất kỳ chi nhánh nào khác. Khi bạn đã hoàn thành cam kết, bạn muốn đẩy nó vào điều khiển từ xa.

Vì vậy, điều đầu tiên bạn cần làm là detached HEADđặt tên này. Bạn có thể dễ dàng làm điều đó như thế nào, trong khi đang ở trên này detached HEAD:

git checkout -b some-new-branch

Bây giờ bạn có thể đẩy nó vào điều khiển từ xa như bất kỳ chi nhánh nào khác.

Trong trường hợp của tôi, tôi cũng muốn chuyển nhanh chi nhánh này để thành thạo cùng với các cam kết tôi đã thực hiện trong detached HEAD(bây giờ some-new-branch). Tất cả những gì tôi đã làm là

git checkout master

git pull # To make sure my local copy of master is up to date

git checkout some-new-branch

git merge master // This added current state of master to my changes

Tất nhiên, tôi đã hợp nhất nó sau master .

Đó là về nó.


1
Câu trả lời này đã làm việc cho tôi khi những người khác không làm được. git checkout -b new-branchđã làm cho tôi. Các đề xuất khác được yêu cầu git branch new-branch, nhưng điều đó khiến tôi vẫn ở trong tình trạng hỗn loạn và chi nhánh mới không nhận được những thay đổi của tôi.
Jesse Patel

17

Bạn chỉ có thể làm git merge <commit-number>hoặcgit cherry-pick <commit> <commit> ...

Theo đề xuất của Ryan Stewart, bạn cũng có thể tạo một nhánh từ CHÍNH hiện tại:

git branch brand-name

Hoặc chỉ là một thẻ:

git tag tag-name

Bạn có thể tìm thấy số cam kết của mình trên đầu tách ragit rev-parse HEAD
KOGI

6

Trong trường hợp tách ra, các cam kết hoạt động như bình thường, ngoại trừ không có chi nhánh được đặt tên nào được cập nhật. Để nhận được nhánh chính được cập nhật với các thay đổi đã cam kết của bạn, hãy tạo một nhánh tạm thời ở đó (theo cách này, nhánh tạm thời sẽ có tất cả các thay đổi đã cam kết bạn đã thực hiện trong ĐẦU tách rời), sau đó chuyển sang nhánh chính và hợp nhất nhánh tạm thời với bậc thầy.

git branch  temp
git checkout master
git merge temp

3

Một cách khắc phục dễ dàng là chỉ cần tạo một nhánh mới cho cam kết đó và kiểm tra nó : git checkout -b <branch-name> <commit-hash>.

Bằng cách này, tất cả các thay đổi bạn đã thực hiện sẽ được lưu trong nhánh đó. Trong trường hợp bạn cần dọn sạch nhánh chính của mình khỏi các xác nhận còn sót lại, hãy chắc chắn chạygit reset --hard master .

Với điều này, bạn sẽ viết lại các chi nhánh của mình để đảm bảo không làm phiền bất cứ ai với những thay đổi này. Hãy chắc chắn để xem bài viết này để có một minh họa tốt hơn về trạng thái ĐẦU tách ra .


1

Có thể không phải là giải pháp tốt nhất, (sẽ viết lại lịch sử) nhưng bạn cũng có thể làm git reset --hard <hash of detached head commit>.

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.