Eski bir taahhüdü kontrol etmek ve ana dalda başını sürdürmek mi?


85

Şu anda başka bir git commit'e geçmek için (aynı dalda ... aslında, ana dalda!), Komutu çalıştırıyorum

git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Şimdi, bunu her yaptığımda, bana şu anda kopuk bir kafayla olduğumu söylüyor. Daha eski bir işleme nasıl giderim ve yine de aynı dalda kafa tutabilirim?


1
Bu komutu çalıştırdıktan sonra, HEAD ref bu kaydetmeye göre değişir . HEAD'in başka bir yere işaret etmesini istemek mantıklı değil.
Greg Hewgill

Git'in mesajından anladığım kadarıyla hiçbir yere işaret etmiyor , ki bu istenmeyen bir durum.
yiyip

1
Git mesajı, "HEAD şimdi ea3d5ed'de ..." gibi belirli bir işlemeyi kontrol ettiğinizde gösterir ve size HEAD'in bir yeri işaret ettiğini söyler . Sadece HEAD dışında başka bir adı olmayan bir yere işaret ediyor (şu anda, bir git checkoutbaşka işleme veya dal adından HEAD'i o yeni yere taşıyacağından).
Greg Hewgill

Verilen cevaplar bunu yeterince açıklıyor mu, yoksa üzerinde daha net olabileceğimiz bir şey var mı? Sorunuza cevap vermezse cevabımı sizin için açıklığa kavuşturmaktan memnuniyet duyarım.
Brian Campbell

Buraya HEAD'i tamamen değiştirmeden başka bir kaydı kontrol etmenin bir yolunu ararken geldiyseniz (örneğin daha eski bir işleme geri dönmek için): kontrol etmek istediğiniz commit git revert --no-commit 0766c053..HEADnerede bunu yapacak 0766c053. Bu, stackoverflow.com/a/21718540/525872 adresinden alınmıştır .
Jo Liss

Yanıtlar:


193

Bunu yaptığım zaman çoğu zaman geçici bir şubeye gidiyorum:

git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Sonra işim bittikten sonra şubeyi silerim


79

Bu taahhüdü kontrol ettiğinizde ne yapmak istediğinize bağlıdır. Yaptığınız tek şey, o revizyonu oluşturabilmek veya test edebilmek için onu kontrol etmekse, kopuk bir kafa ile çalışmanın hiçbir sakıncası yoktur. git checkout masterHerhangi bir şubeye dahil olmayan taahhütler oluşturmamak için herhangi bir taahhüt vermeden önce ( örneğin) gerçek bir şubeyi kontrol etmeyi unutmayın .

Ancak, bu noktadan itibaren daha fazla işlem yapmak istiyorsanız, bir şube oluşturmalısınız. Bir şube tarafından referans verilmeyen taahhütler yaparsanız, bunlar kolayca kaybolabilir ve sonunda hiçbir şey onlara atıfta bulunmadığından git'in çöp toplayıcısı tarafından temizlenir. Şunları çalıştırarak yeni bir şube oluşturabilirsiniz:

git checkout -b newbranch ea3d5ed

Görselleştirmeye yardımcı olmak için, ayrı bir kafa üzerinde çalışmanın bir dalda çalışmaktan ne kadar farklı olduğunu gösteren bazı diyagramlar aşağıda verilmiştir.

En 3 kaydedilmesini ile başlar olsun masterA, B, ve C master, bu yüzden, mevcut dalıdır HEADnoktalarına masterC işlemek için olan noktalar,

ABC
* - * - * <- ana <- KAFA

Şimdi, eğer commit yaparsak, git, üst öğesi C olan bir commit yaratacak (çünkü bu, HEADvia ile işaret edilen mevcut commitdir master) ve masterbu yeni commit'i işaret edecek şekilde güncellenecektir . Bizim kaydedilmesini hepsi şimdi masterve HEADyeni işaret yoluyla işlemek master.

ABCD
* - * - * - * <- ana <- KAFA

Şimdi bize bir bağımsız vererek B'yi kontrol edelim HEAD.

ABCD
* - * - * - * <- usta
   ^
    \ - KAFA

Burada her şey yolunda gidiyor; tüm dosyalara bakabilir, programımızı oluşturabilir, test edebilir, vb. Hatta yeni taahhütler de oluşturabiliriz; ama bunu yaparsak, üzerinde olduğumuz bir dal yok, bu yüzden bu yeni işleme herhangi bir dalı işaret edemeyiz. Ona işaret eden tek şey HEAD:

ABCD
* - * - * - * <- usta
    \
     * <- KAFA
     E

Daha sonra mastertekrar kontrol etmeye karar verirsek , E'ye atıfta bulunan hiçbir şey olmayacak.

ABCD
* - * - * - * <- ana <- KAFA
    \
     *
     E

Buna atıfta bulunan hiçbir şey olmadığından, bulmak zor olabilir ve git, hiçbir referansın terk edilmeyeceğini düşünür (bunlar oldukça yaygın olarak, yeniden taban alırsanız, yamaları sıkıştırırsanız veya başka eğlenceli tarih manipülasyonu yaparsanız olur; bunlar genellikle terk edilmiş yamaları temsil eder. artık umursamadığınız). Belirli bir süre sonra git, çöp toplama çalışmasının bir sonraki çalışmasında atılması için bunun çöp olduğunu düşünecektir.

Bu nedenle, çıplak bir revizyonu kontrol etmek ve bağımsız bir başlık almak yerine, daha fazla taahhütte bulunacağınızı düşünüyorsanız, git checkout -b branch Bbir şube oluşturup kontrol etmek için kullanmalısınız. Artık taahhütleriniz, kolayca başvurabileceğiniz ve daha sonra birleştirebileceğiniz bir şubeye dahil edileceği için kaybolmayacak.

ABCD
* - * - * - * <- usta
   ^
    \ - dal <- HEAD

Bunu yapmayı unutursanız ve bir şubeden taahhütler oluşturursanız endişelenmenize gerek yoktur. İle baş revizyonuna atıfta bulunan bir dal oluşturabilirsiniz git checkout -b branch. Zaten masterşubeye geri döndüyseniz ve başıboş bir taahhüdü unuttuğunuzu fark ettiyseniz, bunu kullanarak bulabilirsiniz git reflog, bu da size HEADson birkaç gün içinde taahhütlerin nelere işaret ettiğinin bir geçmişini gösterecektir . Hala reflog'da olan hiçbir şey çöp olarak toplanmayacaktır ve referanslar genellikle en az 30 gün reflog'da tutulur.


Eski bir işlemi kontrol ettiğinizde kafanın neden koptuğunu tam olarak anlamadım . Belki de sorun kopuk bir kafanın ne anlama geldiğidir ? Öte yandan, kopuk kafalı eski bir kaydı kontrol etmek sadece onu kaybedecekse, neden birisi bunu yapsın? Sadece etrafı karıştırmak ve bir şeyler denemek için mi? Git neden ilk etapta buna izin veriyor?
devoured elysium

5
@devoured elysium "ayrık kafa", sırayla bir commit'i HEADişaret eden bir dalı işaret etmek yerine, doğrudan bir commit'in SHA- 1'ine işaret eden bir referansınız olduğu anlamına gelir . Kafanız bir dala başvurmadığından, Git yeni commit'ler eklediğinizde hangi dalı güncelleyeceğini bilmez. Cevabımın başında açıkladığım gibi, sadece kodu oluşturmak veya test etmek için eski bir sürüme geri dönüyorsanız, bağımsız bir kafaya sahip olmak tamamen iyidir; ile git checkout masterveya benzeri bir şubeye her zaman geri dönebilirsiniz . Bu sadece, kopuk bir kafanız varken bağlanırsanız bir problemdir.
Brian Campbell

@BrianCampbell - Dalda taahhütler yaptıktan sonra (şu anda başınızın olduğu yerde), dalı B'ye birleştirip B'yi ustayla birleştirir misiniz? Bundan sonra ne yapmalısınız?
amey1908

Açıklamanız, benim için bir sürü başka şeyi 'tıkladı'. Teşekkür ederim. Sonunda gitmeyi anlamış olabilirim ...
Joe

8

Herhangi bir değişiklik yapmadan oynamak için daha önceki bir işleme geri dönmek istiyorsanız,

git co <previous-commit-id>

bu komuttan sonra "(dal yok)" adlı bir dalda olacaksınız.

Bunu onaylayın

git br

Bu önceden kaydedilmiş kodla oynadıktan sonra, bulunduğunuz şubeye geçebilirsiniz.

git co <the-branch-you-were-on>

"(Şube yok)" otomatik olarak silinecektir. Bu şekilde geçici bir şube oluşturmanıza gerek kalmaz.


5

Git'in HEAD'i, çalışma dizininde ne olduğunu söyleyen bir işaretçi. Bir dalın başı olmayan bir commit'i kontrol etmek istiyorsanız, sadece HEAD'inizi o commit'i gösterecek şekilde yönlendirmeniz gerekir. Etrafında bir yol yok. Bu işlemde geçici bir dal oluşturabilirsiniz, ancak HEAD yine de ana birimden uzağa yönlendirilecektir.

Kısa açıklama bu. Aşağıdaki ayrıntı, umarım HEAD ve ustanın nasıl farklı olduğunu anlamaya yardımcı olacaktır:

Normalde işler şöyle görünür:

C ← refs/heads/master ← HEAD 
↓
B
↓
A

Yani: “C'nin ebeveyni B'dir ve B'nin ebeveyni A'dır. Şube yöneticisi C'yi işaret ediyor ve şu anda ana bilgisayarın içeriğini kontrol ettim. Ayrıca taahhüt ettiğimde usta güncellenecek. "

Taahhüt grafiğinin tam olarak anlaşılması için gerekli olan bazı varsayımlar bunda örtüktür. Yani, taahhütler yalnızca ebeveynlerine atıfta bulunur ve bir şubenin içeriği, ana bağlantıları takip ederek ulaşılabilen taahhütlerdir (ve yalnızca bu işlemlerdir). Çalışma ağacının ve dizinin (değiştirilmemiş) içeriği, dolaylı olarak ("sembolik") veya doğrudan ("ayrılmış"), HEAD tarafından adlandırılan işleme karşılık gelmelidir.

Bu nedenle, eski bir kaydetmeyi kontrol etmek istiyorsanız, HEAD istenen kaydetmeyi işaret edecek şekilde güncellenmelidir. git-checkoutsadece şunu yapar:

C ← refs/heads/master 
↓
B ← HEAD
↓
A

Şimdi, eski bir şeye baktığın için dalını arkanda bıraktın. "Bağımsız kafa" tavsiyesinin size sakince söylediği gibi (vurgu benim):

Etrafınıza bakabilir, deneysel değişiklikler yapabilir ve bunları gerçekleştirebilirsiniz ve bu durumda yaptığınız taahhütleri herhangi bir şubeyi etkilemeden başka bir ödeme yaparak iptal edebilirsiniz .

Öte yandan, şubenizi sıfırlamak aynı zamanda olması gereken yerde HEAD'i alırken, çok farklı bir etkiye sahip olacaktır!

C
↓
B ← refs/heads/master ← HEAD
↓
A

Artık ana dalın bir parçası olmasını istemediğinizi beyan ettiğiniz için, C kesinleştirme çöp haline gelecektir.

Kısacası, tüm yapmanız gereken “HEAD” ile aracı git'e anlamak - bu nerede sen olan, herhangi bir dalıdır değil nerede. Nerede olursa sen olan bir dal olduğu aynı değildir, hiçbir seçim ama müstakil bir HEAD kullanmak.

(HEAD'inizin raydan çıkması sizi rahatsız etmeye devam ederse, commit geçmişine göz atmak için GitHub, gitk veya gitweb'e de bakın.)


1

Soru biraz belirsiz, ancak sadece çalışma ağacınızdaki dosyaları değiştirmek istiyorsanız, bunu kolayca yapabilirsiniz:

git checkout [commit|branch] -- .

Daha sonra değişiklikleri aşamalandırabilir ve dilerseniz yeni bir taahhüt oluşturabilirsiniz. Bu bazen oldukça kullanışlıdır.


0

Sanırım sorularınızı anlıyorum. İşte onu çözmek için bulduğum şey. ve bunun bir GUI çözümü yoktur, bunu çözmek için yalnızca komut kullanabilirsiniz ve bu gerçekten basittir.

1. adım: geri dönmek istediğiniz eski işlemenin bir etiketini oluşturun.

etiket v2.0 gibi

2. adım: git checkout v2.0

işte burada, şimdi HEAD'iniz 'v2.0' commit'i gösteriyor, ancak master hala son commit'i gösteriyor.

C:\Program Files\Git\doc\git\html\git-checkout.html bu belge size yardımcı olabilir

veya git help <checkout> yazın

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.