Git'te bir dosyanın yalnızca bir bölümünü teslim et


2764

Git'teki bir dosyada değişiklik yaptığımda, değişikliklerin yalnızca bazılarını nasıl yapabilirim?

Örneğin, bir dosyada değiştirilen 30 satırdan yalnızca 15 satırını nasıl işleyebilirim?


3
ilgili stackoverflow.com/q/34609924/52074 : Bir iri parçayı daha küçük iri parçalara bölmeniz gerekiyorsa.
Trevor Boyd Smith

Özet: yetenek açısından: git gui= git add -e> git add -i -p; kolaylık açısından: git gui> git add -i -p> git add -e. Yani: git guiX'e erişiminiz olduğunda seçin git add -i -p. Basit şeyler için seçin ve X git add -eolmadan X olmadan karmaşık evreleme için kullanmak istemediğinizde veya kullanmak istediğinizde seçin .
Penghe Geng

Yanıtlar:


3687

Kullanabilirsiniz git add --patch <filename>(veya -pkısaca) ve git dosyanızı mantıklı "iri parça" (dosyanın bölümleri) olduğunu düşündüğü şekilde parçalamaya başlar. Daha sonra size şu soruyu soracaktır:

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]?

Her seçeneğin açıklaması:

  • y bir sonraki taahhüt için bu iri sahne
  • n bir sonraki taahhüt için bu iri sahne
  • qçıkın; bu iri ya da kalan iri parçalardan herhangi birini sahnelemeyin
  • a bu iri sahne ve daha sonra tüm iri dosya
  • d bu iri veya daha sonraki iri parçaların hiçbirini dosyada yerleştirmeyin
  • g gitmek için bir iri parça seç
  • / verilen normal ifadeyle eşleşen bir iri arama
  • j bu iri kararsız bırak, bir sonraki kararsız iri gör
  • J bu iri kararsız bırak, bir sonraki iri gör
  • k bu iri kararsız bırak, önceki kararsız iri gör
  • K bu iri kararsız bırak, önceki iri gör
  • s mevcut iri parçayı daha küçük iri parçalara böl
  • e geçerli iri parçayı elle düzenle
  • ? hunk yardım yazdır

Dosya henüz depoda değilse, önce bunu yapabilirsiniz git add -N <filename>. Daha sonra devam edebilirsiniz git add -p <filename>.

Daha sonra şunları kullanabilirsiniz:

  • git diff --staged doğru değişiklikleri yaptığınızı kontrol etmek için
  • git reset -p istifsizce yanlışlıkla ekledi yakışıklısı
  • git commit -v taahhüt mesajını düzenlerken taahhüdünüzü görüntülemek için.

Bunun, git format-patchtaahhüt verilerini bir .patchdosyada ayrıştırmak olan komuttan çok farklı olduğuna dikkat edin .

Gelecek için referans: Git Araçları - Etkileşimli Evreleme


83
Faydalı Etkileşimli modu başlatan komutun -p/--patchiçindeki yama eylemine bir kısayol olduğunu belirtmek yararlı olabilir . -i/--interactive
Dajuju

5
> Bu dosya önceden sahnelendiğinde ne olur? Yalnızca işaretlenmemiş değişiklikleri gösterecektir. Aynı git diff.
Eugen Konkov

3
Geçerli iri parçayı manuel olarak nasıl düzenleyebilirim? E yazdıktan sonra ne yapacağımı bilmiyorum.
Hunsu

23
e+-#
Düğmesine

1
bu harika ama şimdi nasıl itebilirim? eğer yaparsam git pushzaten güncel diyor. ve eğer yaparsam söylediğim git diffiri parçalara bakarım n. eğer yaparsam git diff --stagedzorlamak istediğim taahhüdü görürüm. Taahhüdü zorlayabildiğimi varsayarak, söylediğim iri parçalarını nasıl silebilirim no?
chovy

250

Sen kullanabilirsiniz git add --interactiveveya sonra ve ( değil ); bkz İnteraktif modu içinde git-add man sayfasına veya sadece yönergeleri izleyin.git add -p <file>git commit git commit -a

Modern Git ayrıca git commit --interactive(ve git commit --patchetkileşimli işlemlerde yama seçeneğinin kısayolu).

GUI'den yapmayı tercih ediyorsanız git-gui'yi kullanabilirsiniz . İşleme dahil etmek istediğiniz parçaları basitçe işaretleyebilirsiniz. Kişisel olarak kullanmaktan daha kolay buluyorum git add -i. QGit veya GitX gibi diğer git GUI'leri de bu işlevselliğe sahip olabilir.


1
İlginç bir şekilde, windows.github.com kısmi dosya taahhütleri için destek aldı ama son zamanlarda düşmüş gibi görünüyor ..
Juri

1
@Juri Bence kısmi dosya taahhütleri için destek geri döndü.
Ela782

@Juri Rica ederim. Aslında daha önce orada olduğunu fark ettim - geçen hafta gördüm ve "ah, ne şaşırtıcı yeni bir özellik" düşündüm! :-)
Ela782

1
Günümüzde windows.github.com, Git GUI'den daha iyi olan ve kısmi taahhütleri destekleyen yeniden markalanmış GitHub Desktop'a yönlendiriyor ... ancak taahhüt imzalamayı desteklemiyor. İç çekmek.

147

git gui bu işlevi diff görünümü altında sağlar. İlgilendiğiniz satır (lar) ı sağ tıklayın ve "bu satırı işlemek için hazırlayın" menü öğesini görmelisiniz.


13
karmaşık yamalar için bu genellikle benim için en hızlı yaklaşımdır.
hochl

7
Bu, hazırlama alanına ince taneli bir şekilde değişiklik eklemenin çok etkili ve sezgisel bir yoludur. Ayrıca birden fazla satır seçilebilir ve bu seçimdeki tüm değişiklikler eklenir.
jox

Bunun olmadığını gitk, ancak Windows için Git Bash ile birlikte geldiğini unutmayın ; bunun için bir başlat menüsü girişiniz olmalı veya komutla başlatabilirsiniz git gui. Orada da stage this hunkmuhtemelen daha yararlı olduğu stage this line. Bu yanıt 10 yıl önce oluşturulduğundan beri yeni olabilir.
Chris

82

Bunun git add -e myfileen kolay yol olduğuna inanıyorum (en azından benim tercihim) çünkü bir metin editörü açıyor ve hangi çizgiyi sahne almak istediğinizi ve hangi çizgiyi seçmediğinizi seçmenize izin veriyor. Düzenleme komutları ile ilgili:

eklenen içerik:

Eklenen içerik "+" ile başlayan satırlarla temsil edilir. Herhangi bir ekleme satırını silerek evrelemeyi önleyebilirsiniz.

kaldırılan içerik:

Kaldırılan içerik "-" ile başlayan satırlarla gösterilir. "-" işaretini "" (boşluğa) dönüştürerek kaldırma işlemlerinin aşamasını önleyebilirsiniz.

değiştirilmiş içerik:

Değiştirilen içerik "-" satırlarıyla (eski içeriğin kaldırılması) ardından "+" satırlarıyla (yeni içeriğin eklenmesi ile) temsil edilir. "-" satırlarını "" biçimine dönüştürerek ve "+" satırlarını kaldırarak değişikliğin hazırlanmasını önleyebilirsiniz. Paritenin yalnızca yarısının değiştirilmesinin, endekse kafa karıştırıcı değişiklikler getireceğine dikkat edin.

Hakkında her ayrıntıya şuradan ulaşabilirsiniz git add:git --help add


7
Bu satırların gerçekte nasıl seçileceğine dair net bir açıklama olsaydı daha faydalı olurdu (yani, girilecek gerçek komutlar). Belgelerde bir tane bulamadım. Referans ekleyebilir misiniz?
Alex

4
Steno seçeneklerini sevmeyenler -eiçin --edit.
Kolyunya

2
@AlexFreedomBanana tarafından eklenen referans alıntıları, YAMA DÜZENLEME bölümünde yer almaktadırgit --help add
Randall

8
sEtkileşimli yama modunda parçaları daha küçük hale getiremediğinizde satır ekleme / çıkarma sorununu çözen tek cevap (sadece git gerektiren) .
cdosborn

3
Bu komutun ( git add -e) * diskteki dosya içeriğini değiştirmediğini anlamak yararlı olabilir . Sadece değişikliklerin bir bölümünü etiketsizden aşamalıya (dizin) taşır.
Penghe Geng

44

Vim kullanıyorsanız, kaçak denilen mükemmel eklentiyi denemek isteyebilirsiniz .

Çalışma kopyası ve dizin ile arasındaki bir dosyanın farkını görebilir :Gdiffve daha sonra gibi klasik vim diff komutlarını kullanarak dizine satır veya öbek ekleyebilirsiniz dp. Değişiklikleri dizine kaydedin ve taahhüt edin :Gcommit, işlem tamam.

Çok iyi tanıtım Screencasts burada (bkz başkasıyla. Parçasını 2 ).


Bu bağlantılar için çok teşekkür ederim. Tam olarak ihtiyacım olanla aynı. Özellikle :diffget/:diffputgörsel modda, sıfırlamak / tamamlamak istediğim belirli satırları seçebileceğim. Tekrar emin olun: vim harika.
goodniceweb

30

Atlassian SourceTree kullanmanızı şiddetle tavsiye ediyorum . (Ücretsiz.) Bunu önemsiz kılıyor. Tek tek kod yığınlarını veya tek tek kod satırlarını hızlı ve kolay bir şekilde düzenleyebilirsiniz.

resim açıklamasını buraya girin


1
SourceTree'nin bu amaç için iyi bir araç olduğunu kabul ediyorum, çünkü size komut satırından mümkün olandan daha hassas bir kontrol sağlıyor.

19
@cupcake, SourceTree muhtemelen bu komut satırı git executables kullandığını görüyorum, aksine, doğal olarak "komut satırı" üzerinden aynı (veya daha fazla) ince taneli eylemleri yapmak her zaman mümkün olacaktır.
tutuDajuju

2
Her ne kadar ince taneli argüman, SourceTree'yi tavsiye ederim, çünkü öyküleri ve bireysel satırları hazırlama çok kolay: i.imgur.com/85bNu4C.png
Mars Robertson

1
@tutuDajuju Bu durumda, bunun doğru olduğundan emin değilim. SourceTree, hangi bölümleri satır satır sahne alacaklarını seçme yeteneğine sahiptir . Tüm bir iri parça sahnelemek zorunda değilsiniz; bir iri parçanın ortasına 2 çizgi yerleştirebilirsiniz. Yine de bunu nasıl başardığı hakkında hiçbir fikrim yok. (Şu anda, SourceTree'nin izlenmeyen bir dosya için belirli satırları sahne alamaması üzerinde çalışıyorum. Buraya, sadece git'in satır satır yeteneği sunmadığını görmek için bir geçici çözüm arayan yere indim. En azından basit bir şekilde değil.)
jpmc26

1
@Sun 50 satırını tıklayıp 100 satırını shift tuşuna basıp ardından sahne alabilirsiniz. Sourcetree'de çizgi 50-100'ü kolayca sahne edebilirsiniz :)
ryan123

26

Yeni bir dosya için kullanabileceğinizi belirtmek git add --patchiçin , önce dizine eklenecek dosyayı eklemeniz gerekir :git add --intent-to-add

git add -N file
git add -p file

23

Çok fazla değişiklik yaptığımda ve değişikliklerden birkaç taahhüt oluşturduğumda, bir şeyleri sahnelemeden önce başlangıç ​​noktamı geçici olarak kaydetmek istiyorum.

Bunun gibi:

$ git stash -u
Saved working directory and index state WIP on master: 47a1413 ...
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 1st commit"
$ git checkout -p stash
... step through patch hunks
$ git commit -m "message for 2nd commit"
$ git stash pop

Whymarrh'ın cevabı genellikle yaptığım şeydir, ancak bazen çok fazla değişiklik olur ve bir şeyleri sahnelerken hata yapabileceğimi söyleyebilirim ve ikinci bir geçiş için geri alabileceğim kararlı bir devlet istiyorum.


12

Eğer Emacs'ı kullanmak durumunda, bakmak Magit emacs'dan için bir git arayüz sağlar. Bu destekler hunks evreleme oldukça iyi (dosyaların parçaları).


Bir mx kabuk penceresinden çalıştırdığımda, bir editör açmak isteyen bir git komutunu sık sık geziyorum. Magit bu deliliği kesiyor mu ve bunun için yeni bir tampon mu açıyor? (lütfen arka plan-emacs-daemon ipuçları yok; yine de teşekkürler ama hayat çok kısa).
user2066657

Hayır, söyleyebildiğim kadarıyla buna müdahale etmiyor. Ama sadece benim sözüme güvenmeyin çünkü (1) Emacs'ta kabuk penceresini neredeyse hiç kullanmadım ve (2) normalde emacclient kullanıyorum. Emacsclient eğer, söyledikten olan en az açılıyor ve "COMMIT_EDITMSG" tampon Mevcut Emacs penceresinde açıldı gelen emacs'dan ile ek bir pencere engellediğini, sizin için bir seçenek.
Mark van


9

Git Uzantıları'nı kullananlar için :

Teslim Et penceresinde, kısmen işlemek istediğiniz dosyayı seçin, ardından sağ bölmede işlemek istediğiniz metni seçin, ardından seçimi sağ tıklayın ve içerik menüsünden 'Seçili satırları sahne al' seçeneğini seçin.


2
Git Uzantıları'ndaki 'Seçili satırları sahnele' için klavye kısayolu - sdosyaların bir bölümünü işlem için hızlı bir şekilde aşamalandırmada çok kullanışlıdır.
Alchemistmatt

8

Jdsumsion'un cevabına çok benzer şekilde mevcut çalışmanızı saklayabilirsiniz, ancak seçilen değişiklikleri saklamaktan çıkarmak için meld gibi bir difftool kullanabilirsiniz. Bu şekilde, iri parçaları elle çok kolay bir şekilde düzenleyebilirsiniz, bu da şu durumlarda biraz acı çeker git add -p:

$ git stash -u
$ git difftool -d -t meld stash
$ git commit -a -m "some message"
$ git stash pop

Stash yöntemini kullanmak, kodunuzun çalışmaya devam edip etmeden önce test etmenizi sağlar.


bu iyi çalışıyor, ancak kullanırsanız git commit --amend, daha sonra zulayı açamayacağınız anlaşılıyor veya bunu yapmanın bir yolu var mı?
Mark

7

Önceki bir cevaba ekleyerek, komut satırını kullanmayı tercih ederseniz, girmek git add -e myfilesize taahhüt etmek istediğiniz şeyi satır satır seçme seçeneği sunar , çünkü bu komut aşağıdaki gibi farklılıklar içeren bir düzenleyici açacaktır:

resim açıklamasını buraya girin

Bildiğiniz gibi +, satırlar eklentilerdir, ile başlayan satırlar silmedir -. Yani:

  • Bir eklemeyi aşamamak için o satırı silin.
  • Silme işlemini aşamamak için sadece -boşlukla değiştirin .

Bu nedir git add -hdosyaları bu şekilde (dosyaları yama) ekleme hakkında diyor ki:

eklenen içerik Eklenen içerik "+" ile başlayan satırlarla gösterilir. Herhangi bir ekleme satırını silerek evrelemeyi önleyebilirsiniz.

kaldırılan içerik: Kaldırılan içerik "-" ile başlayan satırlarla gösterilir. "-" işaretini "" (boşluğa) dönüştürerek kaldırma işlemlerinin aşamasını önleyebilirsiniz.

değiştirilmiş içerik: Değiştirilmiş içerik "-" satırlarıyla (eski içeriği kaldırarak) ve ardından "+" satırlarıyla (yeni içeriğin eklenmesi ile) temsil edilir. "-" satırlarını "" biçimine dönüştürerek ve "+" satırlarını kaldırarak değişikliğin hazırlanmasını önleyebilirsiniz. Paritenin yalnızca yarısının değiştirilmesinin, endekse kafa karıştırıcı değişiklikler getireceğine dikkat edin.

Dikkat: dosyanın içeriğini değiştirmeyin, burası bunu yapmak için iyi bir yer değildir. Sadece silinen veya eklenen satırların operatörlerini değiştirin.


Önceki cevap nedir? Cevaplar sahip oldukları puan sayısına göre saklanır. Yani cevabınız şimdi diğer cevaplara kıyasla yazdığınızdan farklı bir yerde.
KulaGGin

Başvurulan cevabın @FreedomBanana'dan geldiğine inanıyorum
K. Symbol

6

vim-gitgutter eklentisi kullanarak vim editörü terk etmeden iri parçalara sahne olabilir

:GitGutterStageHunk

Bunun yanı sıra, bazı modern IDE'lerde olduğu gibi fark işareti sütunu gibi diğer harika özellikler de sağlar.

İri parçaların sadece bir kısmı vim-kaçak olarak evrelendirilmelidir

:Gdiff

görsel aralık seçimine izin verir :'<,'>diffputveya :'<,'>diffgettek tek çizgi değişikliklerini aşamalı / geri döndürür.



4

TortoiseGit ile:

dosyayı sağ tıklayın ve kullanın Context Menu → Restore after commit. Bu dosyanın olduğu gibi bir kopyasını oluşturur. Ardından, dosyayı TortoiseGitMerge'de düzenleyebilir ve işlemek istemediğiniz tüm değişiklikleri geri alabilirsiniz. Bu değişiklikleri kaydettikten sonra dosyayı teslim edebilirsiniz.


4

Bu sorunun sorulmasından bu yana 10 yıl geçti. Ve umarım bu cevap birisi için faydalı olacaktır. Cevapta belirtildiği üzere burada GUI bir seçenek Andrew Shadura en olmadığı, crecord uzatma biz işlemek için çizgileri seçebileceğiniz bir ncurses'in penceresini getirir.

Uzantıyı aşağıdaki gibi ayarlayın:

git clone https://github.com/andrewshadura/git-crecord
cd git-crecord
./setup.py install
ln -s $PWD/git-crecord ~/.local/bin/git-crecord

git deponuza cd atın ve aşağıdaki gibi çağırın:

git crecord

Bu, aşağıda gösterildiği gibi kullanılabilecek ncurses arayüzünü getirecektir. Ncurses penceresinde aşağıdaki tuşlara basıldığında belirli işlemler yapılır:

f       hunk toggle fold (arrow keys can also be used)
space   toggle hunk selection
a       toggle commit or amend
c       confirm and open commit window

Örnek kullanım gösteren ekran görüntüsüMisal


3

İçin Atom kullanıcıları, paket github tarzında interaktif kademelendirme içerir git gui. Kısayollar için paketin belgelerine bakın .

Atom kullanmak koyu arka plana sahip bir tema ile çalışmaya izin verir (varsayılan olarak git guibeyaz arka plana sahiptir).



2

git-meld-index - web sitesinden alıntı:

git-meld-index, git dizinine (git aşamalandırma alanı olarak da bilinir) değişiklikleri etkileşimli olarak yerleştirmenizi sağlamak için meld - veya başka bir git difftool (kdiff3, diffuse vb.) çalıştırır.

Bu, git add -p ve git add --interactive işlevlerine benzer. Bazı durumlarda meld kullanımı git add -p'ye göre daha kolay / hızlıdır. Çünkü meld örneğin şunları yapmanızı sağlar:

  • daha fazla bağlam gör
  • hat içi farklara bakın
  • elle düzenleyin ve 'canlı' fark güncellemelerini görün (her tuşa basıldıktan sonra güncellenir)
  • atlamak istediğiniz her değişikliğe 'n' demeden bir değişikliğe gidin

kullanım

Git deposunda şunu çalıştırın:

git meld-index

Meld (veya yapılandırılmış git difftool) ile aşağıdakilerin açıldığını göreceksiniz:

SOL : çalışma ağacınızdan kopyalanan geçici dizin devam eden dosyalar

SAĞ : dizinin içeriğiyle birlikte geçici dizin. Bu, henüz dizinde bulunmayan ancak çalışan kopyada değiştirilen veya izlenmeyen dosyaları da içerir - bu durumda HEAD'den dosya içeriğini görürsünüz.

Dizini (sağ taraf) mutlu olana kadar düzenleyin. Gerektiğinde kaydetmeyi unutmayın.

İşiniz bittiğinde, meld'i kapatın ve git-meld-index, dizini, düzenlediğiniz meld'in sağ tarafındaki geçici dizinin içeriğiyle eşleşecek şekilde günceller.


2

Açıksa Windowsplatformu, bence git guiolduğu için çok iyi bir araç stage/ commitdan birkaç satırunstaged dosyası

1. iri parça bilge:

  • Dosyayı seçin unstagged Changesbölümünde
  • Hazırlanması gereken kod yığınına sağ tıklayın
  • seçmek Stage Hunk for commit

2. Bilge çizgi:

  • Dosyayı seçin unstagged Changesbölümünde
  • Hazırlanacak satırı / satırları seçin
  • Sağ tıklayın ve seçin Stage Lines for commit

3. Dosyayı birkaç satır dışında tamamlamak istiyorsanız:

  • Dosyayı seçin unstagged Changesbölümünde
  • Basın Ctrl+T (Stage file to commit)
  • Seçilen dosya artık Staged ChangesBölüm'e taşınıyor
  • Hazırlanacak satırı / satırları seçin
  • Sağ tıklayın ve seçin UnStage Lines for commit

1

Yukarıdaki bir cevabın gösterdiği gibi, git add --patch filename.txt

ya da kısa biçim git add -p filename.txt

... ancak zaten deponuzda bulunan dosyalar için, s komutunda doğrudan --patch bayrağını kullanmaktan çok daha iyidir (git'in yakın bir sürümünü kullanıyorsanız): git commit --patch filename.txt

... ya da yine kısa biçim git commit -p filename.txt

... ve sonra, taahhütte yer alacak satırları seçmek için belirtilen anahtarları (y / n vb.) kullanarak.


git add -p filename.txtHata için daha az alanın yanı sıra size " " üzerinden ne veriyor ? Kısmi dosya değişikliğini bozarsanız, bir eki geri almak bir taahhüdü geri almaktan daha iyidir.
CTMacUser

Neden bilmiyorum, ama 'n' dediğimde satır dahil edilir .... ve 2. iri parçada 'y' dediğimde, o da dahil olur.
chovy

1

git-cola harika bir GUI'dir ve ayrıca bu özelliğe sahiptir. Sadece sahne alacak hatları seçin ve tuşuna basın S. Seçim yapılmazsa, iri parça hazırlanı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.