HEAD'ı önceki bir konuma nasıl geri taşıyabilirim? (Ayrılmış kafa) ve Geri alma taahhütleri


179

Git'te, squash commitbaşka bir dalda bir araya gelerek ve daha sonra HEADşu şekilde bir önceki yere sıfırlayarak yapmaya çalışıyordum :

git reset origin/master

Ama bundan çıkmam gerek. HEAD'ı önceki konuma nasıl geri taşıyabilirim?

Taşımam 23b6772gereken taahhüdün SHA-1 parçasına ( ) sahibim. Bu taahhüde nasıl geri dönebilirim?


12
HEAD, geçerli konumunuza ilişkin bir işarettir (veya kesin olması gereken düzeltmedir). git checkout 23b6772yapmak gerekir.
Yaroslav Admin


1
No @YaroslavAdmin olması gerektiği değil . Bir taahhüdü doğrudan kontrol etmek , bağımsız HEAD durumunun gerçekleşmesinin nedenidir (uzaktan izleme dalları kendilerini kontrol edemez ve OP'nin yaptığı gibi yapmaya çalıştıklarında işaret ettikleri taahhüdü otomatik olarak ertelediğinden) Ayrıca, nekromantik için özür dilerim Yorum :-) Umarım ilk sorun zaten çözülmüş olur ...
RomainValeri

Yanıtlar:


398

Yanıtlamadan önce bunun ne HEADolduğunu açıklayan bir arka plan ekleyelim .

First of all what is HEAD?

HEADyalnızca geçerli daldaki geçerli taahhüde (en son) bir referanstır. Herhangi bir zamanda
yalnızca bir kişi olabilir HEAD(hariç git worktree).

İçeriği HEADdepolanır .git/HEADve mevcut taahhüdün 40 bayt SHA-1'ini içerir.


detached HEAD

En son taahhütte değilseniz - yani HEADtarihte önceki bir taahhüde işaret eden anlamına gelir detached HEAD.

Resim açıklamasını buraya girin

Komut satırında, HEADşu anki dalın ucunu işaret etmediğinden , şube adı yerine SHA-1 şöyle görünecektir :

Resim açıklamasını buraya girin

Resim açıklamasını buraya girin


Müstakil bir KAFADAN kurtarma için birkaç seçenek:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Bu, istenen taahhüde işaret eden yeni şubeyi kontrol edecektir.
Bu komut, verilen bir taahhüde ödeme yapar.
Bu noktada, bir şube oluşturabilir ve bu noktadan itibaren çalışmaya başlayabilirsiniz.

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Her zaman da kullanabilirsiniz reflog.
git reflog güncellenen değişiklikleri görüntüleyecek HEADve istenen reflog girişini kontrol HEADetmek bu işleme geri dönecektir.

HEAD her değiştirilişinde, reflog

git reflog
git checkout HEAD@{...}

Bu sizi istediğiniz taahhüde geri götürür

Resim açıklamasını buraya girin


git reset --hard <commit_id>

HEAD'inizi istenen işleme geri "taşıyın".

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.

git revert <sha-1>

Verilen taahhüt veya taahhüt aralığını "Geri al".
Sıfırlama komutu, verilen işlemde yapılan değişiklikleri "geri alır".
Geri alma yamasıyla yeni bir taahhüt gerçekleştirilecek, orijinal taahhüt de tarihte kalacaktır.

# Add a new commit with the undo of the original one.
# The <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Bu şema hangi komutun ne yaptığını gösterir.
Orada görebileceğiniz gibi, reset && checkoutmodifiye HEAD.

Resim açıklamasını buraya girin


En son taahhütte değilseniz - yani, HEAD tarihte önceki bir taahhüde işaret ediyorsa, tarihteki önceki taahhüt farklı bir dalın ucu değilse, müstakil HEAD olarak adlandırılır . Deneyimlerime göre, HEAD herhangi bir şubenin de işaret ettiği bir taahhüdü işaret etmiyorsa, müstakil olduğunuzu söyleyebilirsiniz. Bu, etiketler için geçerli değildir.
Tim

Müstakil HEAD içinde olabilirsiniz ve aynı zamanda bu şubenin HEAD'iyle aynı taahhütte olan bir şubeniz olabilir.
Yorumunuzu

3
Başlıklar için satır içi kod işaretlemesi kullanımınızla ilgili sorun yaşıyorum :)
jub0bs

Vurgulamak için daha iyi bir yol bulunamadı. düzenlemek için çekinmeyin. hoş geldiniz daha
CodeWizard

22

Yapmak

git reset 23b6772

Doğru pozisyonda olup olmadığınızı görmek için:

git status

Bir şey göreceksin

Şube yöneticisi hakkında Şubeniz 17 taahhütte 'orijin / master' ın arkasındadır ve hızlı bir şekilde iletilebilir.

Ardından, değişikliği yansıtmak için uzaktan kumandanızdaki geçmişi yeniden yazın:

git push --force-with-lease // a useful command @oktober mentions in comments

1
İle son derece temkinli olun git push --force. Birçok durumda bir süre için takımdaki en az popüler olanı yapacak ....
Kay V

Yukarıdaki nota eklemek için, bu alıntıyı about.gitlab.com/blog/2014/11/26/keeping-your-code-protected adresinde buldum ve eklemek zorunda kaldım: "Tek bir git push --force komutu birçok insan için günü kolayca mahvedebilir: [186 Jenkins] depolarının şube başkanları eski taahhütlere işaret etmek için geri sarıldılar ve gerçekte yeni komisyonlar kötü git-push'tan sonra yanlış yerleştirildi. " - çok popüler olmayan geliştirici ....
Kay V

2
@KayV bir göz atın git push --force-with-lease(Thoughtbot makalesi: thoughtbot.com/blog/git-push-force-with-lease )
oktober

1
Faydalı bayrak, @oktober ve iyi bir makale. Buraya eklediğiniz ve bana ping attığınız için teşekkürler.
Kay V

1
teşekkür ederim! bu da kötü bir birleştirme yapmama yardımcı oldu. çünkü birleşmeler reverttaahhütlerle aynı şekilde tepki vermediğinden, kendimi inanılmaz zor bir durumda buldum. force-with-leasebana diğer insanların çalışmalarını etkilemeden şubenin git tarihini yeniden yazma konusunda güven verdi. Bravo!
anon58192932

11

Mümkün olan en hızlı çözüm (sadece 1 adım)

kullanım git checkout -

Göreceksin Switched to branch <branch_name>. İstediğiniz dal olduğunu onaylayın.


Kısa açıklama: Bu komut HEAD'ı son konumuna geri götürecektir. Bu cevabın sonundaki sonuçlar hakkındaki nota bakınız .


Anımsatıcı: Bu yaklaşım, cd -daha önce ziyaret ettiğiniz dizine dönmek için kullanmak gibidir . Sözdizimi ve ilgili durumlar oldukça iyi bir eşleşmedir (örneğin, aslında HEAD'in bulunduğu yere dönmesini istediğinizde kullanışlıdır).


Daha metodik bir çözüm (2 adım, ancak unutulmaz)

Hızlı yaklaşım OP'nin sorusunu çözmektedir. Ama durumunuz biraz farklıysa: Bash'ı yeniden başlattığınızı ve kendinizi HEAD'ın ayrılmış olarak bulduğunu söyleyin. Bu durumda, 2 basit, kolay hatırlanan adım.

1. İhtiyacınız olan dalı seçin

kullanım git branch -v

Mevcut yerel şubelerin bir listesini görürsünüz. İhtiyaçlarınıza uygun şube adını alın.

2. KAFA hareket ettirin

kullanım git checkout <branch_name>

Göreceksin Switched to branch <branch_name>. Başarı!


Çıktıları

Her iki yöntemle de artık çalışmanızı daha önce olduğu gibi eklemeye ve taahhüt etmeye devam edebilirsiniz: sonraki değişiklikleriniz takip edilecektir <branch_name>.

Hem o Not git checkout -ve git checkout <branch_name>BAŞ müstakil iken sen kaydedilmiş değişiklikler varsa ek talimatları verecektir.


Bu Yaparsam (8acc968 BAŞ ~ 2 olduğunu varsayarak) çünkü çalışmıyor git checkout 8acc968sonra git branch -vsahip MyBranchaşağıda ... listede ama sonra git checkout MyBranchyorumlarımı siler.
amuliar

Merhaba @amuliar - git checkout 8acc968bir taahhüt değil, bir taahhüt kontrol edecektir. İstediğiniz MyBranchtaahhütleri varsa deneyin git checkout MyBranch. Taahhüt 8acc968'deki değişiklikleri içermiyorsa, şubeyi kontrol ettikten sonra bu değişiklikleri birleştirmeniz gerekir.
Kay V

Cevap için teşekkürler! git checkoutÖnceki bir taahhüdü gördüm ve en son taahhüdüne geri dönmek istedim. Ama son taahhüt karması olmadan, neredeyse kayboldum. Bu çözüm benim durumum için mükemmel!
zyy

4

Soru şu şekilde okunabilir:

Ben HEADat ile müstakil durumda 23b6772ve git reset origin/masteryazdım (çünkü ezmek istedim). Şimdi nasıl geri gitmek, fikrimi değiştirdim HEADolmak 23b6772?

Basit cevap şudur: git reset 23b6772

Ama bu soruya çarptım çünkü her seferinde referans vermek istediğimde HEADve herhangi bir stenografi olup olmadığını görmek için Googling'di.

Ortaya çıkıyor!

git reset -(veya benim durumumda git cherry-pick -)

Hangi tesadüfen * nix cd -önceki önceki dizine dönmek aynı oldu ! Yaşasın, bir taşla iki şey öğrendim.


0

Komutu çalıştırdığınızda git checkout commit_idHEAD,13ca5593d(say commit-id) ve şube daha uzun süre kullanılabilir olacak.

Komut adımını akıllıca çalıştırarak önceki konuma geri dönün -

  1. git pull origin branch_name (efendi de)
  2. git checkout branch_name
  3. git pull origin branch_name

Uzak depodan güncellenmiş bir taahhütle önceki konuma geri döneceksiniz.


0

Bugün, yanlışlıkla bir taahhüdü kontrol ettim ve üzerinde çalışmaya başladım, HEAD durumunu ayırma konusunda bazı taahhütlerde bulundum. Sonra aşağıdaki komutu kullanarak uzak şubeye ittim:

git push origin HEAD: <My-remote-branch>

Sonra

git checkout <My-remote-branch>

Sonra

git pull

Sonunda şubemde HEAD'ı ayırmak için yaptığım tüm değişiklikleri aldım.


0

Bu teknik bir çözüm olmayabilir, ancak işe yarar. (eğer takım arkadaşınızdan birinin yerel şubesi aynı ise)

Şube adınızı şube-xxx olarak kabul edelim .

Çözülmesi Gereken Adımlar:

  • Güncelleme veya çekme yapma - hiçbir şey
  • Sadece yeni bir şube (oluşturmak dal-yyy ) den dal-xxx Telesekreterine
  • Hepsi bu, mevcut tüm değişiklikleriniz bu yeni dalda ( şube-yyy ) olacak. Bu şubeyle çalışmalarınıza devam edebilirsiniz.

Not: Yine, bu teknik bir çözüm değildir, ancak kesin olarak yardımcı olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.