Làm cách nào tôi có thể điều hòa tách rời ĐẦU với chủ / gốc?


1558

Tôi mới biết về sự phức tạp phân nhánh của Git. Tôi luôn làm việc trên một nhánh duy nhất và cam kết thay đổi và sau đó định kỳ đẩy đến nguồn gốc từ xa của mình.

Gần đây, tôi đã thiết lập lại một số tệp để đưa chúng ra khỏi cam kết, và sau đó đã rebase -iloại bỏ một vài cam kết gần đây của địa phương. Bây giờ tôi đang ở trong một trạng thái tôi không hiểu lắm.

Trong khu vực làm việc của tôi, git loghiển thị chính xác những gì tôi mong đợi-- Tôi đang đi đúng chuyến tàu với những cam kết mà tôi không muốn đi, và những người mới ở đó, v.v.

Nhưng tôi chỉ bị đẩy vào kho lưu trữ từ xa, và có gì khác biệt - một vài cam kết tôi đã giết trong cuộc nổi loạn đã bị đẩy, và những cái mới được cam kết tại địa phương không có ở đó.

Tôi nghĩ rằng "master / origin" được tách ra từ HEAD, nhưng tôi không rõ ràng 100% về điều đó có nghĩa là gì, làm thế nào để hình dung nó bằng các công cụ dòng lệnh và cách khắc phục nó.


Bạn đã đẩy các cam kết trước khi rebase?
manojlds

@manojlds: Không chắc ý bạn là gì. Tôi đã đẩy một thời gian trước cuộc nổi loạn, nhưng không phải ngay lập tức trước đó.
Ben Zotto

Như trước đây bạn đã đẩy các cam kết mà bạn đã loại bỏ trong rebase -i .. Từ câu trả lời của bạn tôi nghĩ là không.
manojlds

@manojlds: Đúng. Tôi chỉ giết những cam kết gần đây hơn lần đẩy gần đây nhất. (Mặc dù như tôi đã đề cập, tôi đã bị đẩy, vì tôi nghĩ mọi thứ đều ổn)
Ben Zotto

Bạn có thể giải thích những gì bạn đã làm I did a reset of some files to get them out of commit stagingmột phần? xin lỗi vì những câu hỏi :)
manojlds

Câu trả lời:


2521

Trước tiên, hãy làm rõ CHÍNH là gì và ý nghĩa của nó khi nó bị tách ra.

ĐẦU là tên tượng trưng cho cam kết hiện đang được kiểm tra. Khi không bị tách ra ( tình huống TRỌNG 1 bình thường : bạn có một chi nhánh đã được kiểm tra), thì TRỰC TIẾP thực sự chỉ vào một lượt giới thiệu của Chi nhánh và chi nhánh chỉ vào cam kết. Do đó, ĐẦU TIÊN gắn liền với một chi nhánh. Khi bạn thực hiện một cam kết mới, nhánh mà ĐẦU trỏ tới được cập nhật để trỏ đến cam kết mới. ĐẦU theo sau tự động vì nó chỉ vào nhánh.

  • git symbolic-ref HEADnăng suất refs/heads/master
    Chi nhánh có tên là chủ cấp chủ đề được kiểm tra.
  • git rev-parse refs/heads/masternăng suất 17a02998078923f2d62811326d130de991d1a95a
    Cam kết đó là tiền boa hiện tại hoặc trên đầu của nhánh nhánh.
  • git rev-parse HEADcũng mang lại 17a02998078923f2d62811326d130de991d1a95a
    Đây là ý nghĩa của việc trở thành một ref ref tượng trưng của người Viking. Nó trỏ đến một đối tượng thông qua một số tài liệu tham khảo khác.
    (Các tham chiếu tượng trưng ban đầu được triển khai dưới dạng các liên kết tượng trưng, ​​nhưng sau đó đã thay đổi thành các tệp đơn giản với giải thích thêm để chúng có thể được sử dụng trên các nền tảng không có liên kết tượng trưng.)

Chúng ta có HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

Khi ĐẦU được tách ra, nó chỉ trực tiếp vào một cam kết thay vì gián tiếp chỉ vào một người thông qua một nhánh. Bạn có thể nghĩ về một ĐẦU tách ra như đang ở trên một nhánh không tên.

  • git symbolic-ref HEAD thất bại với fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEADnăng suất 17a02998078923f2d62811326d130de991d1a95a
    Vì nó không phải là một tham chiếu tượng trưng, ​​nó phải trỏ trực tiếp vào chính cam kết.

Chúng ta có HEAD17a02998078923f2d62811326d130de991d1a95a

Điều quan trọng cần nhớ với một ĐẦU tách rời là nếu cam kết mà nó trỏ đến không được ước tính (không có tham chiếu nào khác có thể đạt được), thì nó sẽ trở thành một trò chơi nguy hiểm khi bạn kiểm tra một số cam kết khác. Cuối cùng, các cam kết lơ lửng như vậy sẽ được cắt xén thông qua quy trình thu gom rác (theo mặc định, chúng được giữ trong ít nhất 2 tuần và có thể được giữ lâu hơn bằng cách được giới thiệu bởi reflog của HEAD).

1 Hoàn toàn ổn khi thực hiện công việc bình thường, với một đầu tách rời, bạn chỉ cần theo dõi những gì bạn đang làm để tránh phải bỏ lịch sử ra khỏi reflog.


Các bước trung gian của một rebase tương tác được thực hiện với một ĐẦU tách rời (một phần để tránh gây ô nhiễm cho reflog của nhánh hoạt động). Nếu bạn hoàn thành thao tác rebase đầy đủ, nó sẽ cập nhật nhánh ban đầu của bạn với kết quả tích lũy của thao tác rebase và gắn lại HEAD vào nhánh ban đầu. Tôi đoán là bạn không bao giờ hoàn thành đầy đủ quá trình rebase; điều này sẽ để lại cho bạn một ĐẦU tách rời chỉ vào cam kết được xử lý gần đây nhất bởi thao tác rebase.

Để phục hồi từ tình huống của bạn, bạn nên tạo một nhánh trỏ đến cam kết hiện được chỉ ra bởi ĐẦU bị tách ra của bạn:

git branch temp
git checkout temp

(hai lệnh này có thể được viết tắt là git checkout -b temp)

Điều này sẽ gắn lại ĐẦU của bạn vào tempchi nhánh mới .

Tiếp theo, bạn nên so sánh cam kết hiện tại (và lịch sử của nó) với nhánh thông thường mà bạn dự kiến ​​sẽ làm việc:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Bạn có thể sẽ muốn thử nghiệm các tùy chọn nhật ký: thêm -p, bỏ đi --pretty=…để xem toàn bộ thông điệp tường trình, v.v.)

Nếu tempchi nhánh mới của bạn có vẻ tốt, bạn có thể muốn cập nhật (ví dụ) masterđể trỏ đến chi nhánh :

git branch -f master temp
git checkout master

(hai lệnh này có thể được viết tắt là git checkout -B master temp)

Sau đó, bạn có thể xóa chi nhánh tạm thời:

git branch -d temp

Cuối cùng, bạn có thể sẽ muốn đẩy lịch sử tái lập:

git push origin master

Bạn có thể cần phải thêm --forcevào cuối lệnh này để đẩy nếu nhánh từ xa không thể chuyển đổi nhanh chóng sang Cam kết mới (nghĩa là bạn đã bỏ hoặc viết lại một số cam kết hiện có hoặc viết lại một chút lịch sử).

Nếu bạn đang ở giữa một hoạt động rebase, có lẽ bạn nên dọn sạch nó. Bạn có thể kiểm tra xem rebase có đang được xử lý hay không bằng cách tìm thư mục .git/rebase-merge/. Bạn có thể tự dọn sạch rebase đang thực hiện bằng cách xóa thư mục đó (ví dụ: nếu bạn không còn nhớ mục đích và bối cảnh của hoạt động rebase đang hoạt động). Thông thường bạn sẽ sử dụng git rebase --abort, nhưng đó là một số thiết lập lại bổ sung mà bạn có thể muốn tránh (nó di chuyển CHÍNH trở lại nhánh ban đầu và đặt lại nó về cam kết ban đầu, sẽ hoàn tác một số công việc chúng tôi đã làm ở trên).


6
Thú vị từ man git-symbolic-ref: "Trước đây, .git/HEADlà một liên kết tượng trưng chỉ vào refs/heads/master. Khi chúng tôi muốn chuyển sang một chi nhánh khác, chúng tôi đã làm ln -sf refs/heads/newbranch .git/HEADvà khi chúng tôi muốn tìm hiểu xem chúng tôi đang ở chi nhánh nào, chúng tôi đã làm readlink .git/HEAD. , vì vậy hiện tại chúng không được dùng nữa và các refs tượng trưng (như được mô tả ở trên) được sử dụng theo mặc định. "
Dmitry Minkovsky

10
Tôi đồng ý với @AntonioSesto: đối với hầu hết các dự án (thậm chí là những dự án khá lớn), bạn không cần sự phức tạp khó hiểu đó là Git. Não tôi nổi loạn vật lộn với thứ gì đó quá rõ ràng. Tôi không cần nó, và tôi không muốn nó.
Jasper Sp bôi đen

36
Đây là một câu trả lời tốt, nhưng tôi nghĩ không cần đến nhánh tạm thời (mặc dù tôi thường sử dụng một bản thân mình). git branch -f master HEAD && git checkout masterlà đủ - giả sử mục tiêu của bạn là giữ đầu hiện tại của bạn nhưng chỉ định nó là master. Các mục tiêu khác cũng có ý nghĩa, và kêu gọi các công thức nấu ăn khác.
Adrian Ratnapala 6/11/2015

38
Lol tại bình luận quay về chiều dài. Trong khi đó, phần còn lại của chúng tôi chỉ cần quét qua cho đến khi chúng tôi đạt được dòng chữ "Để phục hồi từ tình huống của bạn [...]", và đi từ đó - trong khi ghi chú tinh thần rằng có một câu chuyện hậu trường được giải thích rõ ràng mà chúng ta có thể đọc được vào một ngày mưa. Các tùy chọn để đọc thêm không làm tổn thương bạn, nhưng nó không đứng để lợi ích người khác.
gạch dưới

5
Đây là lý do tại sao tôi ghét git.
Monica Heddneck

627

Chỉ cần làm điều này:

git checkout master

Hoặc, nếu bạn có những thay đổi mà bạn muốn giữ, hãy làm điều này:

git checkout -b temp
git checkout -B master temp

57
Đây là một phản ứng nguy hiểm. Những người đi đến câu trả lời này có các trạng thái khác nhau và câu trả lời "chỉ cần làm điều này để khắc phục" không trả lời câu hỏi. Điều này có thể dễ dàng phá hủy công việc.
Archonic

15
! "git checkout master" sẽ khiến tất cả các thay đổi bị mất nếu phần đầu tách rời không phải là một phần của master !!
Tony

3
@Blauhirn Có lẽ bạn đã kiểm tra cam kết, không phải chi nhánh. Chi nhánh vẫn trỏ đến cùng một cam kết, nhưng bạn đang ở một 'chế độ' khác.
Daniel Alexiuc

1
git resetsẽ đi kèm với một cảnh báo "Nếu bạn không biết bạn đang làm gì, hãy dừng nó lại". Mới hồi phục sau một giờ khủng bố với suy nghĩ tôi đã mất tuần làm việc cuối cùng. Cảm ơn!
Opus1217

1
Đồng ý với @Archonic Điều quan trọng là phải hiểu cách git hoạt động trước khi bạn mù quáng chạy bất kỳ lệnh nào. Bạn có thể tiết kiệm thời gian bằng cách không đọc câu trả lời lớn, nhưng có thể mất nhiều thời gian hơn nếu công việc của bạn bị mất.
Yusufali2205

132

Tôi gặp vấn đề này và khi tôi đọc câu trả lời được bình chọn hàng đầu:

ĐẦU là tên tượng trưng cho cam kết hiện đang được kiểm tra.

Tôi nghĩ: Ah-ha! Nếu HEADlà tên tượng trưng cho cam kết thanh toán hiện tại, tôi có thể điều hòa lại masterbằng cách chống lại nó master:

git rebase HEAD master

Lệnh này:

  1. kiểm tra ra master
  2. xác định các cam kết cha mẹ HEADquay lại điểm được HEADchuyển hướng từmaster
  3. chơi những cam kết trên đầu trang master

Kết quả cuối cùng là tất cả các cam kết trong HEADnhưng không phải mastersau đó cũng trong master. mastervẫn được kiểm tra


Về điều khiển từ xa:

một vài cam kết mà tôi đã giết trong cuộc nổi loạn đã bị đẩy mạnh, và những cam kết mới được cam kết tại địa phương không có ở đó.

Lịch sử từ xa không còn có thể được chuyển tiếp nhanh bằng lịch sử địa phương của bạn. Bạn sẽ cần buộc-đẩy ( git push -f) để ghi đè lên lịch sử từ xa. Nếu bạn có bất kỳ cộng tác viên nào, sẽ rất hợp lý khi phối hợp điều này với họ để mọi người đều ở trên cùng một trang.

Sau khi bạn đẩy mastersang điều khiển từ xa origin, nhánh theo dõi từ xa của bạn origin/mastersẽ được cập nhật để trỏ đến cùng một cam kết như master.


3
git: "Đầu tiên, tua lại đầu để phát lại công việc của bạn trên đầu trang ... Master chuyển tiếp nhanh tới ĐẦU." Tôi đẹp!"
Benjamin

81

Nhìn vào đây để giải thích cơ bản của đầu tách ra:

http://git-scm.com/docs/git-checkout

Dòng lệnh để trực quan hóa nó:

git branch

hoặc là

git branch -a

bạn sẽ nhận được đầu ra như dưới đây:

* (no branch)
master
branch1

Các * (no branch)chương trình bạn đang ở trong đầu tách ra.

Bạn có thể đã đến trạng thái này bằng cách thực hiện git checkout somecommitvv và nó sẽ cảnh báo bạn bằng những điều sau:

Bạn đang ở trạng thái 'tách rời'. Bạn có thể nhìn xung quanh, thực hiện các thay đổi thử nghiệm và cam kết chúng và bạn có thể loại bỏ bất kỳ cam kết nào bạn thực hiện trong trạng thái này mà không ảnh hưởng đến bất kỳ chi nhánh nào bằng cách thực hiện thanh toán khác.

Nếu bạn muốn tạo một nhánh mới để giữ lại các cam kết bạn tạo, bạn có thể làm như vậy (bây giờ hoặc sau này) bằng cách sử dụng -b với lệnh thanh toán một lần nữa. Thí dụ:

kiểm tra git -b new_branch_name

Bây giờ, để đưa chúng lên chủ:

Làm một git refloghoặc thậm chí chỉ git logvà ghi chú cam kết của bạn. Bây giờ git checkout mastergit mergecác cam kết.

git merge HEAD@{1}

Biên tập:

Để thêm, sử dụng git rebase -ikhông chỉ để xóa / giết các cam kết mà bạn không cần, mà còn để chỉnh sửa chúng. Chỉ cần đề cập đến "chỉnh sửa" trong danh sách cam kết và bạn sẽ có thể sửa đổi cam kết của mình và sau đó đưa ra quyết git rebase --continueđịnh. Điều này sẽ đảm bảo rằng bạn không bao giờ đi vào một ĐẦU tách ra.


Cảm ơn các chi tiết và con trỏ thông tin tuyệt vời ở đây. Có vẻ như một sự hợp nhất rõ ràng là không cần thiết, nhưng điều này đã hình dung ra một số khái niệm mà tôi sẽ quay trở lại. Cảm ơn.
Ben Zotto

6
"@ {1}" làm gì?
ebi

35

Nhận cam kết tách rời của bạn vào chi nhánh của riêng mình

Đơn giản chỉ cần chạy git checkout -b mynewbranch.

Sau đó chạy git logvà bạn sẽ thấy cam kết đó hiện đang HEADở chi nhánh mới này.


Nếu tôi làm điều này, có mynewbranchgắn liền với bất cứ điều gì?
Stewohn 5/10/2015

1
Vâng, nó gắn vào nơi mà cái đầu tách ra sẽ được gắn vào, đó chính xác là những gì tôi muốn. Cảm ơn!
Stewohn 6/10/2015

22

nếu bạn vừa có nhánh chính và muốn quay lại "phát triển" hoặc một tính năng chỉ cần làm điều này:

git checkout origin/develop

Lưu ý: kiểm tra nguồn gốc / phát triển .

Bạn đang ở trạng thái ĐẦU tách ra . Bạn có thể nhìn xung quanh, thực hiện các thay đổi thử nghiệm và cam kết chúng, và bạn có thể loại bỏ bất kỳ cam kết nào bạn thực hiện trong trạng thái này mà không ảnh hưởng đến bất kỳ chi nhánh nào bằng cách thực hiện thanh toán khác ...

sau đó

git checkout -b develop

Nó hoạt động :)


7
Những gì đã làm việc cho tôi không phải là "nguồn gốc thanh toán git / phát triển" mà là "phát triển thanh toán git". Việc sử dụng 'nguồn gốc / phát triển' luôn dẫn đến không có thay đổi, do đó vẫn còn trong "ĐẦU tách ra tại điểm gốc / phát triển". Bỏ qua phần 'gốc' đã sửa mọi thứ.
DrStrangepork

18

Nếu bạn muốn đẩy ĐẦU tách rời hiện tại của mình (kiểm tra git logtrước), hãy thử:

git push origin HEAD:master

để gửi ĐẦU tách rời của bạn vào nhánh chính tại điểm gốc. Nếu cú ​​đẩy của bạn bị từ chối, git pull origin mastertrước tiên hãy thử thay đổi từ nguồn gốc. Nếu bạn không quan tâm đến những thay đổi từ nguồn gốc và nó bị từ chối, bởi vì bạn đã thực hiện một số phản ứng có chủ ý và bạn muốn thay thế nguồn gốc / chủ bằng nhánh hiện tại của mình - thì bạn có thể buộc nó ( -f). Trong trường hợp bạn mất một số quyền truy cập vào các cam kết trước đó, bạn luôn có thể chạy git reflogđể xem lịch sử từ tất cả các chi nhánh.


Để quay lại nhánh chính, trong khi vẫn giữ các thay đổi, hãy thử các lệnh sau:

git rebase HEAD master
git checkout master

Xem: Git: "Hiện tại không có trên bất kỳ chi nhánh nào." Có một cách dễ dàng để lấy lại chi nhánh, trong khi vẫn giữ các thay đổi?


2
Điều này thực sự gửi các cam kết tách rời đến nguồn gốc / chủ. Để gắn đầu vào chi nhánh địa phương, hãy làm điều này: stackoverflow.com/a/17667057/776345
Paschalis

Khi tôi làm điều này, tôi nhận được Kho lưu trữ này được định cấu hình cho Git LFS nhưng không tìm thấy 'git-lfs' trên đường dẫn của bạn. Nếu bạn không còn muốn sử dụng Git LFS, hãy xóa hook này bằng cách xóa .git / hook / post-checkout.
dùng2568374

16

Tôi tìm thấy câu hỏi này khi tìm kiếm You are in 'detached HEAD' state.

Sau khi phân tích những gì tôi đã làm để đến đây, so với những gì tôi đã làm trong quá khứ, tôi phát hiện ra rằng tôi đã phạm sai lầm.

Dòng chảy bình thường của tôi là:

git checkout master
git fetch
git checkout my-cool-branch
git pull

Lần này tôi đã làm:

git checkout master
git fetch
git checkout origin/my-cool-branch
# You are in 'detached HEAD' state.

Vấn đề là tôi đã vô tình làm:

git checkout origin/my-cool-branch

Thay vì:

git checkout my-cool-branch

Cách khắc phục (trong tình huống của tôi) chỉ đơn giản là chạy lệnh trên và sau đó tiếp tục luồng:

git checkout my-cool-branch
git pull

11

Sau đây làm việc cho tôi (chỉ sử dụng chi nhánh chủ):

git push origin HEAD:master
git checkout master        
git pull

Cái đầu tiên đẩy ĐẦU tách ra đến nguồn gốc từ xa.

Cái thứ hai chuyển sang nhánh chủ.

Cái thứ ba phục hồi ĐẦU được gắn vào nhánh chính.

Các vấn đề có thể phát sinh ở lệnh đầu tiên nếu việc đẩy bị từ chối. Nhưng điều này sẽ không còn là vấn đề của đầu tách ra nữa, mà là về thực tế rằng ĐẦU tách ra không nhận thức được một số thay đổi từ xa.


không hoạt động, tôi đã nhận: Kho lưu trữ này được định cấu hình cho Git LFS nhưng 'git-lfs' không được tìm thấy trên đường dẫn của bạn. Nếu bạn không còn muốn sử dụng Git LFS, hãy xóa hook này bằng cách xóa .git / hook / pre-push. VÀ Bạn hiện không ở trên một chi nhánh. Vui lòng chỉ định chi nhánh bạn muốn hợp nhất với.
dùng2568374

11

Tôi mới gặp vấn đề này ngày hôm nay và tôi khá chắc chắn rằng tôi đã giải quyết nó bằng cách thực hiện:

git branch temp
git checkout master
git merge temp

Tôi đang ở trên máy tính làm việc của mình khi tôi tìm ra cách để làm điều này và bây giờ tôi đang gặp vấn đề tương tự trên máy tính cá nhân của mình. Vì vậy, tôi sẽ phải đợi đến thứ Hai khi tôi quay lại máy tính làm việc để xem chính xác tôi đã làm như thế nào.


@StarShine Kenorb đã sửa nó. Bây giờ, nó lưu các cam kết tách rời của bạn vào một nhánh mới, tạm thời, chuyển sang chủ và hợp nhất temp thành chủ.
Cees Timmerman

Tôi không biết tại sao ppl lại hạ thấp điều này, nó đã khắc phục vấn đề của tôi nhưng bạn có thể muốn bao gồm lệnh xóa chi nhánh tạm thời.
GlassGhost

8

Nếu bạn hoàn toàn chắc chắn rằng CHÍNH là trạng thái tốt:

git branch -f master HEAD
git checkout master

Bạn có thể không thể đẩy về nguồn gốc, vì chủ của bạn đã chuyển hướng từ nguồn gốc. Nếu bạn chắc chắn không có ai khác đang sử dụng repo, bạn có thể buộc-đẩy:

git push -f

Hữu ích nhất nếu bạn ở trên một nhánh tính năng không có ai khác đang sử dụng.


6

Tất cả những gì bạn phải làm là 'kiểm tra git [tên chi nhánh]' trong đó [tên chi nhánh] là tên của chi nhánh ban đầu mà bạn đã ở trong trạng thái đầu tách ra. (Tách từ asdfasdf) sẽ biến mất.

Vì vậy, ví dụ, trong nhánh 'dev', bạn hãy kiểm tra cam kết asdfasd14314 ->

'git checkout asdfasd14314'

bây giờ bạn đang ở trong một trạng thái tách rời

'chi nhánh git' sẽ liệt kê một cái gì đó như ->

* (detached from asdfasdf)
  dev
  prod
  stage

nhưng để thoát khỏi trạng thái đầu tách ra và quay lại dev ->

'git checkout dev'

và sau đó 'chi nhánh git' sẽ liệt kê ->

* dev
  prod
  stage

nhưng đó là điều tất nhiên nếu bạn không có ý định giữ bất kỳ thay đổi nào từ trạng thái đầu tách rời nhưng tôi thấy mình làm điều này rất nhiều không có ý định thực hiện bất kỳ thay đổi nào mà chỉ để xem xét một cam kết trước đó


6

Như được chỉ ra bởi Chris, tôi đã có tình huống sau đây

git symbolic-ref HEAD thất bại với fatal: ref HEAD is not a symbolic ref

Tuy nhiên, git rev-parse refs/heads/masterđã chỉ ra một cam kết tốt từ nơi tôi có thể phục hồi (Trong trường hợp của tôi, lần cam kết cuối cùng và bạn có thể thấy cam kết đó bằng cách sử dụnggit show [SHA]

Tôi đã làm rất nhiều thứ lộn xộn sau đó, nhưng những gì dường như đã sửa chữa chỉ là,

git symbolic-ref HEAD refs/heads/master

Và đầu được gắn lại!


1
Cảm ơn! Đầu tôi đã bị tách ra. Tôi có thể bắt kịp chủ nhân nhưng họ tình cờ chỉ vào cùng một cam kết chứ không phải chỉ vào chủ chỉ vào cam kết. Mẹo hay = D
RagingRoosevelt 22/03/18

4

Thay vì làm git checkout origin/master

cứ làm đi git checkout master

sau đó git branchsẽ xác nhận chi nhánh của bạn.


4

Tôi đã có vấn đề này ngày hôm nay, nơi tôi đã cập nhật một mô hình con, nhưng không có trên bất kỳ chi nhánh nào. Tôi đã cam kết, vì vậy việc cất giấu, kiểm tra, không làm việc sẽ không hiệu quả. Tôi đã kết thúc việc chọn anh đào của người đứng đầu. Vì vậy, ngay sau khi tôi cam kết (khi việc đẩy không thành công), tôi đã làm:

git checkout master
git cherry-pick 99fe23ab

Suy nghĩ của tôi đã đi: Tôi đang ở trên một cái đầu tách ra, nhưng tôi muốn làm chủ. Giả sử trạng thái tách rời của tôi không khác lắm so với chủ, nếu tôi có thể áp dụng cam kết của mình với chủ, tôi sẽ được thiết lập. Đây chính xác là những gì cherry-pick làm.


3

Nếu bạn đã thực hiện một số cam kết trên đỉnh chính và chỉ muốn "hợp nhất ngược" masterở đó (tức là bạn muốn mastertrỏ đến HEAD), thì một lớp lót sẽ là:

git checkout -B master HEAD
  1. Điều đó tạo ra một nhánh mới có tên master, ngay cả khi nó đã tồn tại (giống như di chuyển mastervà đó là những gì chúng ta muốn).
  2. Nhánh mới được tạo được đặt để trỏ đến HEAD, đó là nơi bạn đang ở.
  3. Chi nhánh mới được kiểm tra, vì vậy bạn sẽ vào mastersau đó.

Tôi thấy điều này đặc biệt hữu ích trong trường hợp các kho lưu trữ phụ, cũng thường xảy ra ở trạng thái tách rời.


3

Tôi đã có cùng một vấn đề và tôi đã giải quyết nó bằng cách thực hiện các bước sau.

Nếu bạn cần giữ những thay đổi của bạn

  1. Trước tiên, bạn cần chạy git checkout masterlệnh để đưa bạn trở lại nhánh chính.
  2. Nếu bạn cần giữ cho các thay đổi của bạn chỉ cần chạy git checkout -b changesgit checkout -B master changes

Nếu bạn không cần thay đổi của bạn

  1. Để xóa tất cả các tệp không bị theo dõi khỏi nhánh của bạn chạy git clean -df.

  2. Sau đó, bạn cần xóa tất cả các thay đổi chưa được sắp xếp trong kho lưu trữ của bạn. Để làm được điều đó bạn phải chạygit checkout --

  3. Cuối cùng, bạn phải đưa nhánh của mình trở lại nhánh chính bằng cách sử dụng git checkout masterlệnh.


3

Đối với tôi nó dễ dàng như xóa chi nhánh địa phương một lần nữa, vì tôi không có bất kỳ cam kết địa phương nào mà tôi muốn thúc đẩy:

Tôi cũng vậy:

git branch -d branchname

Và sau đó kiểm tra chi nhánh một lần nữa:

git checkout branchname

1

Khi cá nhân tôi thấy mình trong một tình huống thì hóa ra tôi đã thực hiện một số thay đổi trong khi tôi không ở master(nghĩa HEADlà tách ra ngay phía trên mastervà không có cam kết nào ở giữa) stashing có thể giúp ích:

git stash # HEAD has same content as master, but we are still not in master
git checkout master  # switch to master, okay because no changes and master
git stash apply  # apply changes we had between HEAD and master in the first place

1

Nói một cách đơn giản, trạng thái CHÍNH tách rời có nghĩa là bạn không được kiểm tra tới ĐẦU (hoặc mẹo) của bất kỳ chi nhánh nào .

Hiểu với một ví dụ

Một nhánh trong hầu hết các trường hợp là chuỗi nhiều lần xác nhận như:

Cam kết 1: chủ -> chi nhánh_HEAD (123be6a76168aca712aea16076e971c23835f8ca)

Cam kết 2: chủ -> 123be6a76168aca712aea16076e971c23835f8ca -> chi nhánh_HEAD (100644a76168aca712aea16076e971c23835f8ca)

Như bạn có thể thấy ở trên trong trường hợp chuỗi cam kết, chi nhánh của bạn trỏ đến cam kết mới nhất của bạn. Vì vậy, trong trường hợp đó nếu bạn thanh toán để cam kết 123be6a76168aca712aea16076e971c23835f8ca sau đó bạn sẽ được ở trạng thái đầu tách ra từ HEAD của điểm chi nhánh của bạn để 100644a76168aca712aea16076e971c23835f8ca và về mặt kỹ thuật bạn đang kiểm tra ra tại HEAD của không có chi nhánh. Do đó, bạn đang ở trạng thái ĐẦU tách ra.

Giải thích lý thuyết

Trong Blog này, rõ ràng kho lưu trữ Git là một cây cam kết, với mỗi cam kết trỏ đến tổ tiên của nó với mỗi con trỏ cam kết được cập nhật và các con trỏ tới mỗi nhánh được lưu trữ trong các thư mục con .git / refs. Các thẻ được lưu trữ trong .git / refs / tags và các nhánh được lưu trữ trong .git / refs / Heads. Nếu bạn xem bất kỳ tệp nào, bạn sẽ thấy mỗi thẻ tương ứng với một tệp, với hàm băm cam kết 40 ký tự và như được giải thích ở trên bởi @Chris Johnsen và @Yaroslav Nikitenko, bạn có thể kiểm tra các tài liệu tham khảo này.


0

Tôi đã rơi vào trạng thái thực sự ngớ ngẩn, tôi nghi ngờ bất kỳ ai khác sẽ thấy điều này hữu ích .... nhưng chỉ trong trường hợp

git ls-remote origin
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        HEAD
6f96ad0f97ee832ee16007d865aac9af847c1ef6        refs/heads/HEAD
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        refs/heads/master

mà cuối cùng tôi đã sửa

git push origin :HEAD

0

Điều này làm việc cho tôi hoàn hảo:

1. git stashđể lưu các sửa đổi cục bộ của bạn

Nếu bạn muốn loại bỏ các thay đổi,
git clean -df
git checkout -- .
git clean sẽ xóa tất cả các tệp không bị theo dõi (cảnh báo: trong khi nó sẽ không xóa các tệp bị bỏ qua được đề cập trực tiếp trong .gitignore, nó có thể xóa các tệp bị bỏ qua trong các thư mục) và kiểm tra git sẽ xóa tất cả các thay đổi chưa được xử lý.

2. git checkout masterđể chuyển sang nhánh chính (Giả sử bạn muốn sử dụng master)
3. git pullđể kéo cam kết cuối cùng từ nhánh chính
4. git statusđể kiểm tra mọi thứ trông thật tuyệt

On branch master
Your branch is up-to-date with 'origin/master'.

0

Trong trường hợp của tôi, tôi đã chạy git statusvà tôi thấy rằng tôi có một vài tệp không bị theo dõi trong thư mục làm việc của tôi.

Để làm cho rebase hoạt động, tôi chỉ cần làm sạch chúng (vì tôi không cần chúng).


0

Nếu bạn đang sử dụng EGit trong Eclipse: giả sử chủ của bạn là nhánh phát triển chính của bạn

  • cam kết bạn thay đổi thành một chi nhánh, thông thường là một chi nhánh mới
  • sau đó kéo từ xa
  • sau đó nhấp chuột phải vào nút dự án, chọn nhóm rồi chọn hiển thị lịch sử
  • sau đó nhấp chuột phải vào tổng thể, chọn kiểm tra
  • Nếu Eclipse cho bạn biết, có hai chủ một điều khiển cục bộ, hãy chọn điều khiển từ xa

Sau này, bạn sẽ có thể gắn lại cho chủ bản gốc.


-1

Tôi đã từng gặp vấn đề tương tự. Tôi thực hiện các thay đổi của mình với git stashvà cứng thiết lập lại chi nhánh tại địa phương thành một cam kết trước đó (tôi nghĩ rằng nó đã gây ra điều đó) sau đó đã làm git pullvà tôi không nhận được cái đầu đó ngay bây giờ. Đừng quên git stash applyđể có những thay đổi của bạn một lần nữa.


-2
git checkout checksum  # You could use this to peek previous checkpoints
git status # You will see HEAD detached at checksum
git checkout master # This moves HEAD to master branch
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.