Başka bir şubeden sadece bir dosya nasıl alınır


1264

Git kullanıyorum ve ana dal üzerinde çalışıyorum. Bu dalda bir dosya var app.js.

Bir var experimentben değişim ve kaydedilmesini ton bir demet yapılmış olan dalı. Şimdi sadece yapılan tüm değişiklikleri getirmek istiyorum app.jsden experimentüzere masterşube.

Bunu nasıl yaparım?

Bir kez daha birleşme istemiyorum. Ben sadece tüm değişiklikleri getirmek istiyorum app.jsden experimentdala masterdalı.



1
İstisnai cevap ve bugün itibariyle diğerleri dosyanın içeriğinin nasıl kopyalanacağını cevaplıyor, bunu bulduğumda kendim istediğim buydu. Ancak, tam olarak okunduysa, Nick değişiklikleri tam metin değil, getirmek istedi ve dosyadan mastersapabilir experiment, örneğin dosyada kaybolacak diğer dallardan birleştirilen değişiklikler sadece kopyalanabilir. Öte yandan PS birleştirmek istemiyor, ancak bildiğim kadarıyla git mergeterim sadece şube için, belirli bir dosya için değil, bu yüzden burada herhangi bir çelişki yok.
Alexei Martianov

Yanıtlar:


1602
git checkout master               # first get back to master
git checkout experiment -- app.js # then copy the version of app.js 
                                  # from branch "experiment"

Ayrıca bkz. Git, bir dosyadaki değişiklikleri nasıl geri alabilirim?


Güncelleme Ağustos 2019, Git 2.23

Yeni git switchve git restorekomutlarla bu şöyle olur:

git switch master
git restore -s experiment -- app.js

Varsayılan olarak, yalnızca çalışma ağacı geri yüklenir.
Siz de dizinini güncellemek istiyorsanız (dosya içeriği geri, anlam ve tek komuta dizinine eklemesine):

git restore -s experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -WS -- app.js

As Jakub Narębski yorumlardaki bahisler:

git show experiment:path/to/app.js > path/to/app.js

" Git'te belirli bir revizyondan tek bir dosya nasıl alınır? " sorusunda ayrıntılı olarak açıklandığı gibi , reponun kök dizininden tam yolu kullanmanız gerekir.
Bu nedenle Jakub tarafından kendi örneğinde kullanılan / / app.js yolu.

As Frosty yorumunda bahseder:

yalnızca en son app.js durumunu alırsınız

Ancak, git checkoutveya için git show, aslında " git gui'deki bir dosyanın git checkout revizyonu " SO sorusunda gösterildiği gibi, istediğiniz herhangi bir düzeltmeye başvurabilirsiniz :

$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME

aynı olur $ FILENAME sürüm dosyasının tam yoludur .

$REVISIONgösterildiği gibi olabilir git rev-parse:

experiment@{yesterday}:app.js # app.js as it was yesterday 
experiment^:app.js            # app.js on the first commit parent
experiment@{2}:app.js         # app.js two commits ago

ve bunun gibi.

schmijos yorumlarda şunları ekliyor :

bunu bir saklamaktan da yapabilirsiniz:

git checkout stash -- app.js

İki dal üzerinde çalışıyorsanız ve taahhüt etmek istemiyorsanız bu çok yararlıdır.


13
Bir not: sadece app.js'nin en son durumunu alacaksınız, deneme dalından geçmiş herhangi bir geçmiş elde etmeyeceksiniz.
Soğuk

2
@ThomasReggi, bir dosyayı herhangi bir şubeden geçerli bir şubeye aktarabilmeniz (teslim almanız) gerekir. Yapamıyorsanız, bu, tam hata mesajı ve Git ve OS sürümü gibi belirli ayrıntılarla burada sormak iyi bir soru olabilir.
VonC

2
Bir alt dizinde de kullanabilirsiniz experiment:./app.js. (Tam yolu belirtmek zorunda değilsiniz.) Git bana çok yardımcı olan hata mesajı sayesinde bunu öğrendim: "'mybranch: full / path / to / my / file.xsl' aka 'mybranch mı demek istediniz: ./file.xsl '?" Evet yaptım! Ölümcül bir hata mesajından bu kadar memnun olduğumu düşünmüyorum.
Evan Lenz

1
@TomaszGandor Evet, git show'un dizini değiştirmeyeceği stackoverflow.com/a/21066489/6309'da git checkout'un dizini değiştirdiğinden bahsediyorum .
VonC

1
Cevabımı gör: bu gün, olurdugit restore -s new-feature path/to/app.js
VonC

360

Her şey çok daha basit, bunun için git checkout kullanın.

Diyelim ki you're on masterşube almak için app.js from new-featureşube:

git checkout new-feature path/to/app.js

// note that there is no leading slash in the path!

Bu size istenen dosyanın içeriğini getirir. Her zaman olduğu gibi, dosyayı belirli bir işlemde olduğu gibi almak için yeni özellik şube adı yerine sha1'in bir kısmını kullanabilirsiniz .

Not : Uzak bir şube değil, yerel bir şube new-featureolması gerekir .


77
git checkout origin/source_branch path/to/fileYerel deponuzun kaynak dalını güncellemeyi ihmal ettiyseniz, dosyanın eski bir sürümünü edinebileceğiniz için başlangıç ​​noktasını belirtmeyi yararlı buluyorum ... Bana nasıl bildiğimi sor. ;)
talyric

3
@Mymozaaa soru uzaktan söz vermedi, bu yüzden tamamen yerel bir repo olduğu varsayımı
Dmitry Avtonomov

1
Bu komut dosyanın geçmişini mi yoksa dosyanın yalnızca son sürümünü mü getirir?
user1366265

1
@ user1366265 bu komut dosyayı belirttiğiniz belirli bir taahhütte veya belirttiğiniz dalın başlığında olduğu gibi koyacaktır. "Bir dosyanın geçmişi" diye bir şey yoktur, tüm geçmiş bilgileri sadece şubelerde saklanır.
Dmitry Avtonomov

3
Bu, teslim alınan dosyayı otomatik olarak hazırlar. Aynı şeyi sahnelemeden yapmak mümkün müdür?
bluenote10

44
git checkout branch_name file_name

Misal:

git checkout master App.java

Şube adınızın içinde bir nokta varsa bu çalışmaz.

git checkout "fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git.

@PhilipRego Bu cevap doğru. Sanırım şubenizde farklı büyük harf veya noktalama işaretleri var ya da yerel bir şubeniz değil, yalnızca uzak bir şubeniz var. Git ödeme belgesine
Bret

@Bret Şube adının bir dönemi olduğunda işe yaramadığını gördüm. Bir düzenleme
Philip Rego

Bu en iyi cevap. Bu cevabın en yüksek puan almasını diliyorum. Şu anki en yüksek olan çok kafa karıştırıcı ve basit değil
Russell Lego

41

VonC ve chhh cevaplarına ek.

git show experiment:path/to/relative/app.js > app.js
# If your current working directory is relative than just use
git show experiment:app.js > app.js

veya

git checkout experiment -- app.js

2
Güzel! Uzun yollar belirlemekten nefret ediyorum. --Şube adı ile yollar arasındaki çift ​​çizgi ( ) isteğe bağlı mı? Yalnızca kısa çizgiyle başlayan yolların seçenek / anahtar olarak ele alınmasını engellemek mi?
Tomasz Gandor

Dürüst olmak gerekirse bilmiyorum. Bunu işaret edene kadar çift tireyi unuttuğumu fark etmedim bile.
AlexLordThorsen

6
@TomaszGandor Bu --isteğe bağlıdır, ancak şube adlarıyla çakışmayı önlemek daha kullanışlıdır. Örneğin, git checkout -- fooaraçlar (yani. Üzerine yazma yerel değişiklikler "HEAD foo dosyasını kontrol" foo . Bir alt kümesini, yani git reset --hard), ancak git checkout fooanlamına gelebilir veya "let şube gidin foo ".
Alois Mahdal

8

Veya başka bir şubedeki tüm dosyaları istiyorsanız:

git checkout <branch name> -- .

24
İlk queston "sadece bir dosya" içerir.
greatvovan

1
bu birleştirme yerine mevcut dosyaların yerine geçer
Amare

3
Bu .çok büyük bir fark yaratır: başka bir şubeye geçmek yerine o andaki dosyaları bırakırken oradan tüm dosyaları kopyalar. İçeriği başka bir şubeye girmeden alırsınız.
Xeverous

4

Github'daki dosyayı inceleyin ve oradan çekin

Bu, doğrudan OP'ye cevap vermeyen pragmatik bir yaklaşımdır, ancak bazıları yararlı bulmuştur:

Söz konusu dal GitHub üzerindeyse, GitHub'ın sunduğu birçok araçtan birini kullanarak istediğiniz dal ve dosyaya gidebilir, ardından düz metni görüntülemek için 'Ham'i tıklayabilir ve (isteğe bağlı olarak) metni kopyalayıp yapıştırabilirsiniz. İstenen.

Bu yaklaşımı seviyorum, çünkü yerel makinenize çekmeden önce uzak dosyaya bütünüyle bakmanıza izin verir.


2
Ancak ham dosyayı kopyalayıp yapıştırmak git farkınızda istenmeyen karakter değişikliklerine neden olabilir. Değişiklik yapılmasını önlemek için dosyayı doğrudan projenize kaydetmek daha güvenlidir.
Philip Rego

0

Dosyayı belirli bir işlemden (herhangi bir daldan) istiyorsanız, 06f8251f deyin

git checkout 06f8251f Instagram Hesabındaki Resim ve Videoları path_to_file

örneğin, pencerelerde:

git checkout 06f8251f C: \ A \ B \ C \ D \ dosya.h


1
Cevaplamak için zaman ayırdığınız için teşekkür ederiz! Ancak bu soruya cevap vermiyor ve çok ayrıntılı olan iyi bir cevap 9 yıl önce gönderildi. Soruyu çarpmaya gerek yok.
Nathan

Bu geçerli bir pratik senaryodur. Cevap şube ile doğru bir şekilde ilgileniyor, ancak şubenin belirli bir taahhüdüne bakmaya ne dersiniz.
arupjbasu

0

Başka bir yol, farklılıklar içeren bir yama oluşturmak ve örneğin ana dalda uygulamaktır. Diyelim ki app.js üzerinde çalışmaya başlamadan önceki son işlem 00000aaaaa ve istediğiniz sürümü içeren işlem 00000bbbbb

Bunu deneme dalında çalıştırırsınız:

git diff 00000aaaaa 00000bbbbb app.js > ~/app_changes.git

Bu, app.js için bu iki işlem arasındaki tüm farklılıkları istediğiniz yere uygulayabileceğiniz bir dosya oluşturur. Bu dosyayı proje dışında herhangi bir yerde saklayabilirsiniz

Sonra, ustada sadece koşarsınız:

git apply ~/app_changes.git

şimdi projedeki değişiklikleri sanki manuel olarak yapmışsınız gibi göreceksiniz.


-3
git checkout master               -go to the master branch first
git checkout <your-branch> -- <your-file> --copy your file data from your branch.

git show <your-branch>:path/to/<your-file> 

Umarım bu size yardımcı olacaktır. Herhangi bir sorunuz varsa lütfen bize bildirin.

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.