Dosyaları teslim almadan Git dalını değiştirin


100

Git'te tüm dosyaları teslim almadan başka bir dala geçmek mümkün mü?

Şubeyi değiştirdikten sonra tüm dosyaları silmem, yeniden oluşturmam, kaydetmem ve geri dönmem gerekiyor. Yani dosyaları kontrol etmek sadece zaman kaybıdır (ve yaklaşık 14.000 dosya vardır - bu uzun bir işlemdir).

Her şeyi netleştirmek için:

Belgeleri GitHub'a yüklemek için tüm bunlara ihtiyacım var .

Gh-pages şubesi olan bir depom var . Dokümantasyonu yerel olarak yeniden oluşturduğumda, onu depo dizinine kopyalıyorum, teslim ediyorum ve GitHub'a gönderiyorum. Ama mutlu değildim çünkü yerel olarak iki nüsha belgem vardı. Ve boş bir dal oluşturmaya karar verdim ve taahhüt ettikten sonra boşa geçip dosyaları sildim. Ancak geri dönmek uzun bir işlem - bu yüzden bu soruyu sordum.

Gh sayfalarının dalından ayrılabileceğimi ve dosyaları silebileceğimi biliyorum, ama kirli ağaçlardan hoşlanmam.


Senin için "uzun" ne kadar? Hangi platformda çalışıyorsun? NFS veya diğer dosya paylaşımları gibi bir ağ üzerinde mi çalışıyorsunuz?
Greg Hewgill

Bu alıştırmanın amacı nedir? Biri ayrıntılı taahhütlere sahip, ikincisi yalnızca büyük değişiklikleri kaydeden (kaba taneli) iki şubeye mi sahip olmak istiyorsunuz?
Jakub Narębski

Belki de çalışma kopyanızın geçici (veya kalıcı?) Bir klonunu oluşturmak daha ucuzdur. İlgili cevabım ve bir yazma , bunun ana deponun bir alt dizini olarak bile nasıl çalıştığını gösteriyor.
krlmlr

Yanıtlar:


106

Evet, bunu yapabilirsiniz.

git symbolic-ref HEAD refs/heads/otherbranch

Bu şubeye taahhüt vermeniz gerekiyorsa, endeksi de sıfırlamak isteyeceksiniz, aksi takdirde son ödünç aldığınız şubeye göre bir şey taahhüt etmiş olursunuz.

git reset

1
Dal yerine bir ref'i göstermek için echo "ebff34ffb665de0694872dceabe0edeaf50ec5a9" > .git/HEADardından gelen tuşunu kullanın git reset.
cadorn

1
Doğrudan HEAD dosyasına yazmak daha az güvenilirdir. Ya bir alt dizindeyseniz? Ayrılmış kafa için (kafa doğrudan SHA1'i gösterir) şunu deneyin: git update-ref HEAD refs/heads/otherbranch
Alexander Bird

2
Mevcut şubeden yeni bir şubeye göz atmak istiyorsanız, bunu yapmanın başka bir yolu da 1. git stash2. git checkout -b otherBranch3.git stash pop
Winny

@AlexanderBird: git update-refkullanışlıdır, ancak aynı zamanda mevcut dalın ucunu da hareket ettirir.
tomekwi

47

Yalnızca temel git komutlarını kullanarak:

Bu cevap Charles'ın yanıtından biraz daha uzun, ancak yalnızca anlayabildiğim ve dolayısıyla hatırlayabildiğim temel git komutlarından oluşuyor ve aramaya devam etme ihtiyacını ortadan kaldırıyor.

Mevcut konumunuzu işaretleyin (gerekirse önce taahhüt edin):

git checkout -b temp

Çalışma dizinini değiştirmeden işaretçiyi diğer dala sıfırlayın (taşır):

git reset <branch where you want to go>

şimdi temp ve diğer dallar aynı commit'i gösterir ve çalışma dizininize dokunulmaz.

git checkout <branch where you want to go>

HEAD'iniz zaten aynı commit'i gösterdiğinden, çalışma dizine dokunulmaz

git branch -d temp

Bu komutların herhangi bir grafik istemciden de kolayca elde edilebileceğini unutmayın.


7
git reset --soft <branch where you want to go>Dizini güncellemekten kaçınmayı tercih ederim
JoelFan

7
Git sıhhi tesisat komutlarından kaçınma ve porselen olanları tercih etme stratejinize katılıyorum.
user64141

26

V2.24'te git switchkasa gibi bir şey var git checkout.
Dolayısıyla ben için aşağıdaki takma adını git hopiçin
"worktree değiştirmeden dala hop"

Okuyucunun yararı için:

Charles Bailey'nin çözümünün doğru olduğunu düşünmeme rağmen , bu çözüm yerel bir şube olmayan bir şeye geçerken ince ayar gerektiriyor. Ayrıca bunu normal komutlarla yapmanın anlaşılması kolay bir yolu olmalı. İşte bulduğum şey:

git checkout --detach
git reset --soft commitish
git checkout commitish

Açıklandı:

  • git checkout --detachgit checkout HEAD^{}mevcut şubeyi geride bırakıp "ayrılmış kafa durumuna" geçenin aynısıdır . Yani bir sonraki modifikasyon HEADartık herhangi bir dalı etkilemiyor. Ayırma HEADworktree ne de indeksi etkilemez.
  • git reset --soft commitishdaha sonra verilenin HEADSHA'sına geçer commitish. Dizini de güncellemek istiyorsanız, --softuzak durun, ancak bunu yapmanızı önermiyorum. Bu yine çalışma ağacına ve ( --soft) dizine dokunmaz .
  • git checkout commitishdaha sonra HEADverilen commitish(şubeye) tekrar bağlanır . ( commitishSHA ise hiçbir şey olmaz.) Bu da indeksi veya çalışma ağacını etkilemez.

Bu çözüm, kesinleştirme ile ilgili her şeyi kabul eder, bu nedenle bu bazı gittakma adlar için idealdir . rev-parseAşağıdaki yazım hataları yanlışlıkla (yol daha karmaşık olacağını hata kurtarma) müstakil kafa devlet içine geçmiyoruz böyle olduğundan emin olmak için sadece bir test, zincirde bir şey sonları vardır.

Bu, aşağıdaki git hop treeishtakma ada yol açar :

git config --global alias.hop '!f() { git rev-parse --verify "$*" && git checkout "HEAD^{}" && git reset --soft "$*" && git checkout "$*"; }; f'

Bilginize, gittakma adlar listemde bulabilirsiniz .


Kullanmak istediğiniz etmeyin $@ziyade $*? Aradaki fark, içinde boşluklar olan tırnaklı bağımsız değişkenleri genişletmeyen $ @ 'nın olmasıdır.
kyb

1
@kyb Fonksiyon numarası başka bir SO cevabından çalındı . Ve $@kesinlikle burada kastedilmiyor. $*yerine kullanılır $1, öyle ki git switch -f b, aynı hale gelir git switch '-f b'ki bir hata olmalıdır. Bu şekilde,!f() { [ 1 = $# ] || { echo 'WTF!'; return 1; }; ..
Tino

Çok güzel bir çözüm. Özellikle uzak şubeler için kullanılabilmesi!
Nils-o-mat

14

Bir depolu iki çalışma dizini (iki çalışma alanı), hatta iki depoya sahip olmak daha iyi bir çözüm olmaz mıydı?

Orada git-yeni-Workdir aracını contrib/bu konuda size yardımcı olmak için bölüm.


Git-new-workdir, git'in kendi worktree komutuyla aynı mı? Bir dalı farklı bir klasöre almak istediğimde (tüm depoyu klonlamak zorunda kalmadan) çalışma ağacı kullanıyorum.
Ryuu

git-new-worktreeKomut öncedir git worktreealt komutunun; bu komut cevap yazılırken mevcut değildi. Komut dosyası, örneğin sembolik bağlantı desteği gerektirir; IMHO, yerel desteği kullanmak daha iyidir.
Jakub Narębski

8

Sanırım sıhhi tesisat komutanını arıyorsunuz git read-tree. Bu, dizini güncelleyecek ancak çalışma dizininizdeki hiçbir dosyayı güncellemeyecektir. Örneğin, branchokunacak şubenin adı olduğunu varsayarsak :

git okuma ağacı dalı

Daha sonra okuduğunuz şubeye bağlanmak istiyorsanız, şunları da yapmanız gerekir:

git sembolik-ref HEAD refs / kafalar / dal

hayır sadece dalı değiştirmem gerekiyor, başka değişiklik yok - bu yüzden sembolik referans yeterince iyi
tig

read-treehatayı oluşturur: fatal: Not a valid object name brancheğer yoksagit switch branch henüz
Andry


0

Bu kadar çok dosyayla, her dal için bir tane olmak üzere iki depo saklamak en iyisi olabilir. Değişiklikleri gerektiği gibi ileri geri çekebilirsiniz. Bu, git ile iğrenç hileler oynamaya çalışmaktan daha az şaşırtıcı olacak.


Bunun git-new-worktreeyerine (içinde contrib/) kullanabilirsiniz
Jakub Narębski

Sık sık benzer bir şey yaptım, bu da acemi olarak herhangi bir "korkutucu git işi" yapmadan önce yerel dizinimi kopyalamak (dalları değiştirmek gibi). İnsanları git-fu'nuza güvenene kadar bu rotaya gitmeye, ancak mümkün olduğunda ondan uzaklaşmaya teşvik ederim. İki farklı depoyu saklamak sorun değil, ancak bir karmaşıklık katmanı ekler ve git'in birçok yararlı özelliğinden (birleştirme, kiraz toplama, vb.) Yararlanmanıza izin vermez.
David

0

Sadece uzak bir şubenin gösterdiği yeri değiştirmeye çalışıyorsanız, bunu yerel kopyanıza dokunmadan "git push" ile yapabilirsiniz.

http://kernel.org/pub/software/scm/git/docs/git-push.html

Bir <refspec> parametresinin biçimi isteğe bağlı bir artı +, ardından kaynak ref <src>, ardından iki nokta üst üste: ve ardından hedef ref <dst> gelir. Uzak depodaki <dst> ref'in hangi <src> nesnesiyle güncelleneceğini belirtmek için kullanılır.

örneğin, foo'yu c5f7eba'yı gerçekleştirecek şekilde güncellemek için aşağıdakileri yapın:

git push origin c5f7eba:foo

Bunun peşinde olup olmadığından emin değilim.


Sorunun zaten bir cevabı var: stackoverflow.com/questions/1282639/…
tig

0

faydalanabilirsin

      1. git checkout -f <new-branch>
      2. git cherry-pick -x <previous-branch-commit-id>

previous-branch-commit-id, eski verileri kopyalamak istediğiniz kayıttır.


0

Veya diğer şubenizden ustanıza yama yapmak için sadece bir yama dosyası kullanın

git diff otherbranch master > ~/tmp/otherbranch.diff
git checkout master
git apply ~/tmp/otherbranch.diff

-1

A şubesinde olmak istediğinizi söyleyin, ancak B şubesindeki dosyalarla

git log ile A dalının geçerli kaydetme referansını bulun, örneğin "99ce9a2",

git checkout A
git reset --hard B
git reset 99ce9a2

şimdi, aşamalı olmayan değişiklikler olarak görünen B'ye karşılık gelen bir klasör yapısıyla A dalında olmalısınız (A geçmişi değişmedi).

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.