Bir git deposunu uzak bir depoya itmek mümkün mü?


206

Git'te, bir zulası oluşturmak, zulayı uzak bir depoya itmek, zulayı başka bir bilgisayarda almak ve zulayı uygulamak mümkün mü?

Yoksa seçeneklerim:

  • Bir yama oluşturun ve yamayı diğer bilgisayara kopyalayın veya
  • Küçük bir şube oluşturun ve eksik olan işi o şubeye teslim edin.

Yanıtlar:


68

Getirme ya da öylesine almak mümkün değil, ayna refspec olduğunu fetch = +refs/*:refs/*ve saklamak olsa bile refs/stashgönderilmez. Bir müstehcen refs/stash:refs/stashde etkisi yoktur!

Zaten kafa karıştırıcı olurdu, çünkü bu tüm zıvanaları değil, en sonuncuyu getirmeyecekti; stashes listesidir reflog ref refs/stashes.


4
En son saklamayı bir git uzaktan kumandasından alabilir, ancak saklamanıza değil, sadece başka bir referansa alabilirsiniz. Gibi bir şey . Ancak eski depoları alamazsınız, çünkü bunlar alınamayan reflogda saklanır. Bkz. Stackoverflow.com/questions/2248680/…git fetch some-remote +refs/stash:refs/remotes/some-remote/stashgit stash apply some-remote/stash
sj26

75

Not: Bu cevabı sadece kemetimin altında 24 saat daha git-fu ile yeniden yazdım :) Kabuk geçmişimde, tüm shebang şimdi üç tek katlı. Ancak, rahatınız için onları yoğunlaştırmadım.

Bu şekilde, umarım bir şeyi körü körüne kopyalamak / yapıştırmak yerine, nasıl yaptığımı görebileceksiniz.


İşte adım adım.

Varsayım ~ / OLDREPO'da saklayıcı içeren bir kaynaktır. Zımba içermeyen bir TEST klonu oluşturun:

cd ~/OLDREPO
git clone . /tmp/TEST

Tüm zulayı geçici dallar olarak itin:

git send-pack /tmp/TEST $(for sha in $(git rev-list -g stash); \
    do echo $sha:refs/heads/stash_$sha; done)

Zımbalara geri dönüş yapmak için alıcı uçtaki halka:

cd /tmp/TEST/
for a in $(git rev-list --no-walk --glob='refs/heads/stash_*'); 
do 
    git checkout $a && 
    git reset HEAD^ && 
    git stash save "$(git log --format='%s' -1 HEAD@{1})"
done

Geçici şubelerinizi temizleyin

git branch -D $(git branch|cut -c3-|grep ^stash_)

Git stash listesi yapın ve şöyle bir şey olacak:

stash@{0}: On (no branch): On testing: openmp import
stash@{1}: On (no branch): On testing: zfsrc
stash@{2}: On (no branch): WIP on sehe: 7006283 fixed wrong path to binary in debianized init script (reported as part of issue
stash@{3}: On (no branch): WIP on debian-collab: c5c8037 zfs_pool_alert should be installed by default
stash@{4}: On (no branch): WIP on xattrs: 3972694 removed braindead leftover -O0 flag
stash@{5}: On (no branch): WIP on testing: 3972694 removed braindead leftover -O0 flag
stash@{6}: On (no branch): WIP on testing: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{7}: On (no branch): WIP on xattrs: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{8}: On (no branch): WIP on testing: 28716d4 fixed implicit declaration of stat64
stash@{9}: On (no branch): WIP on emmanuel: bee6660 avoid unrelated changes

Orijinal depoda, aynı şekilde

stash@{0}: WIP on emmanuel: bee6660 avoid unrelated changes
stash@{1}: WIP on testing: 28716d4 fixed implicit declaration of stat64
stash@{2}: WIP on xattrs: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{3}: WIP on testing: db9f77e fuse_unmount_all could be starved for the mtx lock
stash@{4}: WIP on testing: 3972694 removed braindead leftover -O0 flag
stash@{5}: WIP on xattrs: 3972694 removed braindead leftover -O0 flag
stash@{6}: WIP on debian-collab: c5c8037 zfs_pool_alert should be installed by default
stash@{7}: WIP on sehe: 7006283 fixed wrong path to binary in debianized init script (reported as part of issue #57)
stash@{8}: On testing: zfsrc
stash@{9}: On testing: openmp import

1
Çok kısa sürede çok şey öğreniyorum ve muhtemelen daha önce yapmaya çalışacağım önceki yaklaşımımda çok sayıda komut kullanmam gerektiğini hissediyorum.
2011'de

9
Bu benim için iyi çalıştı, ancak sahnelenmeden yeni dosyaları saklamayı reddettiği için adımdan git add .önce bir ihtiyacım vardı . Ayrıca sonucunu boru yoluyla tersine çevrilir stashes sırası aynı sırayla çıkıp böylece. git stash save ...git stashgit rev-list ...tac
Alan Krueger

1
@sehe Mükemmel script !! İki öneri: 1) - son ref listesini tersine çevirin, böylece yığınlar hedef repoda orijinal ile aynı sırada olur. 2) Son fordöngüyü sonlandırın git branch -D stash_$a(stashler oluşturuldukça temizleyin), böylece bir şeyler ters giderse ve tekrar denersek, zaten başarıyla saklanan taahhütleri yeniden işlemeyiz.
Keith Robertson

1
"Çözümü yayınlamak" yerine ne yaptığınızı açıklamak için zaman ayırdığınız için teşekkür ederiz.
Marjan Venema

1
Solüsyon daha da geliştirilebilir: Eğer değiştirirseniz git stash save "$(git log --format='%s' -1 HEAD@{1})"ile git update-ref --create-reflog -m "$(git show -s --format=%B $rev)" refs/stash $revorijinal zulası mesajı almak size ( update-refne git stash saveperde arkasında).
Sebastian Schrader

31

Partiye biraz geç kaldım, ancak bu konuda benim için çalışan bir şey bulduğuma inanıyorum ve koşullarınız aynı veya benzer ise sizin için de olabilir.

Kendi dalında bir özellik üzerinde çalışıyorum. Şube efendi ile birleşmedi ve bitene kadar itmedi ya da halka rahat gösterebileceğimi taahhüt ettim. Bu nedenle, aşamalı olmayan değişiklikleri başka bir bilgisayara aktarmak istediğinizde yaptığım şey:

  • Aktarılmasını [non-commit] FOR TRANSFER ONLYistediğiniz içeriği içeren " " gibi bir taahhüt mesajıyla bir taahhütte bulunun .
  • Diğer bilgisayara giriş yapın.
  • Sonra şunları yapın:

    git pull ssh+git://<username>@<domain>/path/to/project/ rb:lb

    Deponuza farklı bir şekilde erişirseniz URL sizin için farklı olabilir. Bu, bu URL'deki değişiklikleri "rb" uzak dalından "lb" yerel dalına çeker. Kendi bilgisayarımda çalışan bir ssh sunucum olduğunu ve depoya bu şekilde erişebildiğimi unutmayın.

  • git reset HEAD^(ima eder --mixed)

    Bu, HEAD'ı "[taahhüt edilmemiş]" taahhütten önce devlete işaret edecek şekilde sıfırlar.

Git-reset'ten (1): " --mixed: Dizini sıfırlar, ancak çalışma ağacını sıfırlamaz ( örneğin, değiştirilen dosyalar korunur, ancak kesinleştirme için işaretlenmez) [...]"

Sonuçta dosyalarda değişikliklere sahip olacaksınız, ancak master yapmak için hiçbir taahhüt yapılmaz ve bir saklamaya gerek yoktur.

Ancak bu işlem git reset --hard HEAD^, "[taahhütlü olmayan]" ı yaptığınız depoda bulunmanızı gerektirecektir , çünkü bu taahhüt çöptür.


Bu daha sonra sadece yeni bir özellik dalı oluşturmak sonra silme çok dirtier ....
Taegost

@Taegost sanırım ortamınıza bağlı. Sadece dalları willy nilly yukarı iterek önleyen bazı CI / CD şeyler olabilir. Ancak evet, tercih ettiğiniz şeye bağlı olarak, aynı şeyi gerçekleştirmek için sadece bir şube oluşturmak isteyebilirsiniz.
Victor Zamanian

22

Biraz geç oldu, ama bu cevap birine yardımcı olabilir. Bunu bilmek istedim, çünkü devam eden bir özelliği / bug / neyi itmek ve başka bir bilgisayarda aynı noktadan çalışmak istedim.

Benim için işe yarayan, devam eden kodumu (yalnız üzerinde çalıştığım bir dalda) taahhüt etmektir. Diğer bilgisayarıma geldiğimde, bir çekim yapın, ardından aşağıdakileri taahhüt edin:

git reset --soft HEAD^

Tüm devam eden değişiklikleriniz, taahhüt edilmemiş ve gönderilmemiş olarak, olduğu gibi çalışmaya devam edin.

Umarım yardımcı olur.


Bunu yapmaya çalıştığımda, Origin hala taahhüt edilmemiş olan Taahhüt'ü korur. Kapat ama benim için puro yok.
rezwits

@rezwits Evet, uzaktan kumanda onu tutar, ancak geçici dalı kökünden silmek için yeterince kolaydır.
Sir Robert

Aslında yaptığım şey bu!
rezwits

19

Bunu çözmek için çok düzgün bir hile var gibi görünüyor. Kullanabileceğiniz git diff > file.diffkullanarak değişiklikleri geri sonra, (ve dosyayı işlemek) git apply file.diffaynı sonucu elde etmek (herhangi bir yerden).

Bu da burada açıklandı .


5
izlenmemiş dosyalarınız varsa: 1. git add. 2. git diff HEAD> file.diff
trickpatty

Farkı kendinize iletmek, repoda hiçbir taahhüt / ayak izi bırakmaz! (örneğin: Signal masaüstü uygulamasıyla not-to-self) veya e-posta.
John Mee

9

Her ne kadar usta / özellikli dal için taahhüt edemezsiniz hiçbir fikrim olmasa da ikinci yaklaşım ile gitmek istiyorum. Kiraz toplama yapmak da mümkündür.


27
"Bu gerçek bir taahhüt değil, sadece işimi koruyarak başka bir makineye alabilirim" demek istediğim için, ustalaşmak / öne çıkmamak için teknik bir neden yok.
Andrew Grimm

4

AFAIK, saklamak için tüm fikir, yerel halı altında çok önemli olmayan bir şeyi gizlemektir . Kimse en sevdiğin saçmalık hakkında bilmemeli ;-) Tek "ama" şudur: Ama birkaç iş istasyonunda gelişirsem? O zaman scpçok daha iyi.


9
Bu komik şey bir yorum olmalı. ;-)
Andrew Grimm

2
Toplam git-ssh-newbie burada ama o zaman github ile scp kullanabilirsiniz?
Koen

Hayır, github'ın git-ssh ön ucu programlanmıştır, böylece hiç ssh kabuğuna / konsoluna sahip olmazsınız. Yalnızca sunucu tarafı git işlemini çalıştırabilir.
argent_smith

1
Yani ana dalınız github üzerinde ise scp bu senaryo için gerçekten bir seçenek değil mi? Bu durumda bir saklamak için başka öneriniz var mı?
Koen

1
Stash transferinin hiç mümkün olmadığını vurgulamaya çalıştım AFAIK.
argent_smith

2

Şu anda kabul edilen cevap teknik olarak doğrudur, Git'e tüm saklamaklarınızı doğrudan bir uzaktan kumandaya itmesini ve ardından her şeyi başka bir bilgisayardaki yerel saklamaklarınıza çekmesini doğrudan söyleyemezsiniz.

Ederken şu anda üst upvoted cevap çalışmalıdır geçici dalları bir demet oluşturur ve elle zulası işlemek kontrol ve benzeri sorunlara yol açabilir bir stash, olarak kaydedilmesini gerektiriyorsa o böyle, ben yapmadım Bu yoruma bahsedilen ve bir yinelenen yol açar On (no branch): On testing:. Elbette daha iyi bir yol olmalı!

Bu nedenle, doğrudan zulası itemezsiniz, ancak bir zulası sadece bir taahhüttür (aslında iki taahhüt) ve git pushman sayfası başına taahhütleri itebilirsiniz:

<src>Sıklıkla itmek isteyeyim şube adıdır, ancak herhangi bir keyfi "SHA-1 ifadesi" olabilir ...

Zımbaları itmeyi seçtim, refs/stashes/*böylece uzaktan kumandayı ekstra dallarla karıştırmayacağım. Böylece bunu yapabilirim:

git push origin stash@{0}:refs/stashes/$(git rev-parse --short stash@{0})

( rev-parseKomut, depo için benzersiz olacak olan stash'ın kısa karmasını alır.)

Sonra, diğer bilgisayardan saklamak getirmem gerekiyor. Git sadece dalları varsayılan olarak getirir, bu nedenle özellikle stashes getirmeniz gerekir:

git fetch origin refs/stashes/*:refs/stashes/*

Şimdi saklamak yerine gerçek bir saklamak dönüştürmek. Belirtildiği gibi, her zamanki gibi saklamak, sıfırlamak ve saklamak kontrol ederken, fazladan adımlar gerektirdiğini veya saklamak için dizin durumunu koruyamayacağını sevmiyorum. Çevrimiçi olarak bunu otomatik olarak yapmanın bir yolunu arıyordum, ancak search-fu'm başarısız oldu. Sonunda ben git stashbuldum adam sayfası , baktım :

create
Ref (boş bir taahhüt nesnesi olan) bir stash oluşturun ve ref ad alanında herhangi bir yerde saklamadan nesne adını döndürün. Bunun komut dosyaları için yararlı olması amaçlanmıştır. Muhtemelen kullanmak istediğiniz komut değildir; yukarıdaki "kaydet" bölümüne bakın.

saklamak
Git stash create (sarkan birleştirme taahhüdü) aracılığıyla oluşturulan belirli bir zulayı saklamak için saklayın. Bunun komut dosyaları için yararlı olması amaçlanmıştır. Muhtemelen kullanmak istediğiniz komut değildir; yukarıdaki "kaydet" bölümüne bakın.

Taahhüdüm zaten olduğundan, storeistediğim gibi geliyor. Böylece yapabilirim:

git stash store --message "$(git show --no-patch --format=format:%s <SHA>)" <SHA>

<SHA>Yeni getirilen sakla ile değiştirilmesi .

( git showKomut, saklanma günlüğüne mesaj olarak kullanmak için saklama mesajını saklamak için alır.)

Stash artık yerel repoma normal geldi:

$ git stash list
stash@{0}: On master: temp
...

Uzaktan kumandayı temizlemek için zımbalar uzaktan kumandadan şu şekilde silinebilir:

git push origin :refs/stashes/<SHA>

Bu yöntem aynı zamanda idempotent olma avantajına sahiptir: pushkomutu tekrar çalıştırırsanız rapor verecektir Everything up-to-date. fetchKomut ayrıca güvenle defalarca çalıştırılabilir. stash storeEn son saklananla aynı ise saklamayı atlayacak olsa da , daha eski saklananların kopyalarını engellemez. Bu benim git-rstashsenaryomda yaptığım gibi , aşağıya bakın.


Tamamlamak için, tüm zulayı kolayca itebilirsiniz ( ):

for i in $(seq 0 $(expr $(git rev-list --walk-reflogs --count stash) - 1))
do
  git push origin stash@{$i}:refs/stashes/$(git rev-parse --short stash@{$i})
done

veya getirilen tüm yığınları içe aktarın:

for stash in $(ls .git/refs/stashes)
do
  git stash store --message "$(git show --no-patch --format=format:%s $stash)" $stash
done

Ben yarattım bir alt komut (örneğin git rstash push 0) olarak adlandırılabilir komut dosyası bu yüzden tüm bunları hatırlamak zorunda değilsiniz. git-rstashburada bulabilirsiniz.


1

Aşağıdakiler stash ile çalışmaz, ancak çalışma dizinindeki taahhüt edilmeyen değişikliklerle çalışmaz. Bir şube oluşturur, mevcut tüm değişiklikleri otomatik olarak yapar ve uzaktan kumandaya iter:

commit_and_push_ ( ) {
    # This will:
    #  1. checkout a new branch stash-XXX
    #  2. commit the current changes in that branch
    #  3. push the branch to the remote
    local locbr=${1:-autostash-XXX}
    git checkout -b $locbr
    git add .
    git commit -a -m "Automatically created commit"
    git push origin $locbr
    echo "Autocommitted changes in branch $locbr ..."
}

Gibi kullanın:

commit_and_push_ my-temp-branch
commit_and_push_

0

Ben sadece yeni bir saklamak şube oluşturmak ve bu şube gerekli olmadığında kaldırmak.

git add . // Add work-in-progress job
git checkout -b stash-branch // Create and checkout to stash-branch
git commit -m 'WIP: job description' // Commit message
git push origin stash-branch // Push to remote
git pull origin stash-branch // Pull the stash-branch
git checkout master // Checkout to working branch
git rebase stash-branch // Rebase the stash-branch
git reset --soft // Equivalent to stash!!
git branch -d stash-branch // Delete when not needed from local
git push -d origin stash-branch // Delete when not needed from remote

-9

Dropbox'ı bu adam gibi kullanın. Bu şekilde, tüm kodlarınız yedekleneceğinden yığınları itme konusunda endişelenmenize gerek kalmaz.

http://blog.sapegin.me/all/github-vs-dropbox


2
Herkesin diz sarsıntısı reaksiyonu olmadan önce, Github yerine Dropbox kullanmayı söylemiyorum, ancak Dropbox'ta yerel olarak hala kontrol altında olacak bir taahhüt için hazır olmayan kodu saklamak için söylüyorum.
NYC Teknik Mühendisi

4
tüm projeyi uzak buluta kopyalamak çok zaman alacaktır.
Stav Alfi
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.