Yalnızca boşluk olmayan değişiklikler ekle


343

Bir dosyayı kaydettikten sonra sondaki boşlukları otomatik olarak kırpmak için metin düzenleyicim var ve sondaki boşluklarla ilgili ciddi sorunları olan açık kaynaklı bir projeye katkıda bulunuyorum.

Bir yama göndermeye çalıştığımda, yalnızca ilgili bilgileri seçmek için önce yalnızca boşlukla ilgili tüm değişiklikleri el ile göz ardı etmeliyim. Sadece bu da değil, koştuğumda git rebasegenellikle onlar yüzünden birkaç problemle karşılaşıyorum.

Bu nedenle, sadece boşluk olmayan değişiklikleri dizine, benzer bir şekilde git add -p, ancak tüm değişiklikleri kendim seçmek zorunda kalmadan eklemek istiyorum.

Bunu nasıl yapacağını bilen var mı?

DÜZENLEME: edemez proje çalışma şeklini değiştirebilir ve bu görmezden, posta listesinde tartıştıktan sonra, karar verdik.

Yanıtlar:


395

@Frew çözümü tam olarak ihtiyacım olan şey değildi, bu yüzden aynı sorun için yaptığım takma ad:

alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'

Veya şunları yapabilirsiniz:

git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -

Güncelleme

Bu yoruma göre seçenekler -U0ve --unidiff-zerosırasıyla geçici eşleme sorunlarına seçenekler eklendi .

Temelde addboşluk değişikliği olmadan uygulanacak yamayı uygular . Bundan sonra git addnw your/filehala değişmemiş değişiklikler olacağını fark edeceksiniz , boşluklar kaldı.

--No-rengi gerekli değildir, ancak her zaman ayarlanmış renklerim olduğu için kullanmak zorundayım. Neyse, özür dilemekten daha güvenli.


7
Bu benim için iyi çalıştı, ancak git apply --ignore-whitespacebaşka türlü kullanmak zorunda kaldım, aksi takdirde yama belirgin nedenlerle geçerli olmazdı.
jupp0r

106
Git ekleyecek bir seçenek olmalı, bunun gibi git add -w.
Jarl

7
Bu bana patch does not applyve error while searching for... herhangi bir fikir verir?
DTI-Matt

18
benim için çalışmadı. Bir patch does not applyhata var.
Jerry Saravia

13
Eğer alıyoruz @bronson çıkış noktaları olarak bağlamında nedeniyle boşluk için 'yama başarısız oldu', bu revize komut çalışır (Hiçbir içerikle bir yama oluşturur): git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero. Endeks zaten olabildiğince güncel olduğundan riskli değil, bu nedenle yama için güvenilir bir temel.
void.pointer

36

Bu benim için çalışıyor:

Etrafta bir saklamak istiyorsanız, bu işe yarıyor

git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

Zulayı sevmiyorum ama var git + cygwin Öyle şeyler ben aşağıdaki kurmak en azından reflog gitti emin olmak için, değişiklikleri kaybetmek nerede bir hata çıkıyor:

git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

Temel olarak, alan değişikliklerini içermeyen bir fark yaratırız, tüm değişikliklerimizi geri alırız ve farkı uygularız.


1
+1. git stashEn azından test edilinceye kadar değişikliklerinizin yedeğini almak için ödeme yerine bir ödeme yapmak isteyebilirsiniz .
Paŭlo Ebermann

1
Sonunda bir sürü zıvana alırsınız ve temelde tüm bunları yapmanız gerekmez. Çalışıyor ama biraz dağınık olduğunu düşünüyorum
Colin Hebert

3
Colin ile aynı fikirdeyim. Komut dosyası çalışırsa, bir zulası oluşturmaya gerek yoktur. Dikkate alınması iyi bir şey, önce stash, sonra stash pop çalıştırmak olacaktır. Haşhaşlı istifler gerekirse kurtarılabilir, ancak aksi halde çok fazla zıvana ile sonuçlanmazsınız. Bu ayrıca etrafında yatan ekstra bir dosya bırakır
Casebash

İkili dosyaları atlamaya ne dersiniz? Yukarıdaki snippet'i uygulamaya çalışırken, düzeltme ekinin tam dizin satırı olmadan uygulanamayacağı hataları alıyorum! Beni yenen ilk etapta bu dosyalara / ikili dosyalara bile dokunmadım!
tver3305

1
Bence ilk komutun sonunda "git rm foo.patch" sadece "rm foo.patch" olmalıdır. Aksi takdirde çok yardımcı teşekkürler.
Jack Casey

33

Yalnızca gerçek değişiklikleri içeren bir yama dosyası oluşturun (yalnızca boşluk değişikliklerine sahip satırlar hariç), ardından çalışma alanınızı temizleyin ve bu yama dosyasını uygulayın:

git diff> backup
git diff -w> değişiklikler
git reset - hard
patch <değişiklikler

Kalan farklılıkları, daha sonra gözden addve commitnormal.

Mercurial'ın eşdeğeri bunu yapmaktır:

hg diff> backup
hg diff -w> değişiklikler
hg geri döndürme - all
hg import - no-taahhüt değişiklikleri


“Korunan” soru nedir? ve Me Too cevapları. Bunun benim de cevap olarak nitelendirdiğini sanmıyorum çünkü soru ince havadan çekildi gibi görünüyor ...
jww

4
@jww Orijinal posterin sorusunun özü "sadece boşluk kontrolünde değişiklik yapmaktan kaçınmak için kaynak kontrolü". OP Git kullanıyor, ancak bu şimdiye kadar kullandığım her kaynak kontrol sistemi için de geçerli. Bu cevap, birisi Mercurial kullanıyorsa doğru prosedürü gösterir. Başka birinin Sublesion, vb. Kullanan insanlar için de bir çözüme katkıda bulunabileceğini hayal edebiliyorum
Steve Pitchers

1
@jww ve @ pagid: Mercurial için kullandığım çözümle aynı yaklaşımı kullanarak cevabımı özellikle Git'e hitap etmek için düzenledim. Benim görüşüme göre, StackOverflow sadece başka bir Q + A forumundan daha fazlasıdır - aynı zamanda bilgi deposu olarak da rol oynar. Orijinal poster dışındaki kişiler verilen cevaplardan yararlanabilir ve koşulları farklılık gösterir. Bu yüzden genel bir prensibi taşıyan cevapların sadece tek bir spesifik durumu hedeflemek yerine geçerli olduğuna inanıyorum.
Steve Pitchers

@Steve - "Ben ... özellikle adrese Git cevabım düzenlenmiş" - neden civalı bağlamında yeni bir soru sormadı ve ardından yeni soruya kendi cevap ekleyin ???
jww

8
Bu aslında gördüğüm yaklaşımların en temiz, en anlaşılır ve en kırılmaz olanı.
Kzqai

12

En çok oy alan cevap, yorumlardaki kullanıcılara göre yama bağlamındaki boşluk nedeniyle her durumda çalışmaz.

Komutu aşağıdaki gibi revize ettim:

$ git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero

Bu, bağlamı olmayan bir yama oluşturur. Yama kısa ömürlü olduğundan sorun olmamalı.

Karşılık gelen takma ad, yine diğer kullanıcılar tarafından sağlananların bir revizyonu:

addw = !sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero' -

Sadece girinti ı kullanmak zorunda değişiklikleri göz ardı etmek --ignore-space-changeyerine -w. git diff -U0 --ignore-space-change --no-color | git apply --cached --unidiff-zero
Andy

Bu güzel hiçbir bağlam hilesini kullanmamaya dair bir uyarı kelimesi, görmezden gelmek istediğiniz 'beyaz boşluk' değişikliklerinden bazıları boş satır kaldırma / eklemeler ise --ignore-blank-lines, fark ötelemelerinin yanlış ofsetlerde yamalandığını göreceksiniz.
elbeardmorez

12

Aşağıdakileri kendinize ekleyin .gitconfig:

anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"

Sayesinde @Colin Herbert'in ilham için verdiği cevap .

Sözdizimi Açıklaması

Nihai #bunun içinde bir yorum olarak tedavi edilmezse bu yüzden tırnak içinde olmalıdır .gitconfig, ancak bunun yerine geçirilir alır ve kabuğun içinde bir yorum olarak kabul edilir - bu sonu arasında yerleştirilir git applyve kullanıcı tarafından sağlanan argümanlar o gitotomatik yerler komut satırının sonu. Bu argümanlar burada git applyistenmiyor - onları tüketmek istemiyoruz , dolayısıyla önceki yorum karakteri. Bu komutu şu şekilde çalıştırmak isteyebilirsiniz:GIT_TRACE=1 git anw görmek için .

--Sinyaller argümanların bitirmek ve bir dosya adı var bu durumda sağlar-w veya bir anahtar gibi görünecektir şey git diff.

$@Kullanıcı tarafından sağlanan alıntılanmış bağımsız değişkenleri korumak için, kaçan çift tırnak işareti gerekir. Eğer "karakter kaçan edilmez, tükettiği edilecek .gitconfigayrıştırıcı ve kabuk ulaşamaz.

Not: .gitconfigtakma ayrıştırma şey special gibi tek tırnak tanımıyor - onun sadece özel karakterler ", \, \n, ve ;(a dışına "-quoted dize). Bu nedenle a ", tek tırnaklı bir dizenin içinde görünse bile her zaman kaçmalıdır (git tamamen agnostiktir).

Bu önemlidir, örn. bashçalışma ağacının kökünde bir komut yürütmek için kullanışlı bir takma adınız varsa . Yanlış formülasyon:

sh = !bash -c '"$@"' -

Doğru olan:

sh = !bash -c '\"$@\"' -

Mükemmel. Bu, her seferinde bir dosya eklememe izin verdi. Bir argüman için bir kök dizin eklemek dışında, bu çalışmayı 'git add -A' gibi yapmanın bir yolu var mı?
Chucky

7

Aşağıdakiler nasıl olur:

git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`

Geri tırnak içindeki komut, boşluk olmayan değişikliklere sahip dosyaların adlarını alır.


2
veya sadece git add `git diff -w |grep '^+++' |cut -c7-`alt modüller kullanılmazsa
karmakaze

-1

İlk olarak, sondaki boşlukun kasıtlı olup olmadığını düşünmelisiniz. Linux çekirdeği, Mozilla, Drupal ve Kerberos da dahil olmak üzere birçok proje (Vikipedi sayfasından stilden birkaçını belirtmek için) sondaki boşlukları yasaklar. Linux çekirdek belgelerinden:

İyi bir editör edinin ve satırların sonunda boşluk bırakmayın.

Sizin durumunuzda, sorun tam tersidir: önceki taahhütler (ve belki de güncel olanlar) bu yönergeye uymamıştır.

Bahse girerim ki, hiç kimse gerçekten izleyen boşluk istemez ve sorunu düzeltmek hoş bir değişiklik olabilir. Diğer kullanıcılar da aynı sorunu yaşıyor olabilirler. Ayrıca, sondaki boşluk ekleyen katkıda bulunan (lar) ın bunu yaptıklarından habersiz olmaları da muhtemeldir.

Git'i sorunu yok saymak için yeniden yapılandırmaya çalışmak ya da düzenleyicinizde aksi halde istenen işlevselliği devre dışı bırakmak yerine, sorunu açıklayan proje posta listesine bir gönderiyle başlıyorum. Birçok editör (ve git'in kendisi) sondaki boşlukla başa çıkmak üzere yapılandırılabilir.


16
Bu kasıtlı değil, ancak projeye katkıda bulunan 100'den fazla insanın düşünme şeklini değiştiremem. Bunu umursamıyorlar ve sadece sondaki boşlukla ilgilenen 1000+ değişiklik içeren yamaları kabul etmiyorlar. Sorunu biliyorlar ve görmezden gelmeye karar verdiler. Bu tartışma listede zaten oldu ve kapatıldı. Bu durumda, onlara adapte olması gereken benim.
Edu Felipe

19
Ardından düzenleyicinizi, bu projenin kodu üzerinde çalışırken sondaki boşluğu kırpmayacak şekilde yapılandırın.
jamessan

-2

Sondaki boşlukları kaldıran bir git ön işleme kancası buldum . Ancak, başkalarının bunu kullanmasını sağlayamazsanız, geçerli bir çözüm olmayabilir.

  #!/bin/sh

  if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
     against=HEAD
  else
     # Initial commit: diff against an empty tree object
     against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
  fi
  # Find files with trailing whitespace
  for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
     # Fix them!
     sed -i 's/[[:space:]]*$//' "$FILE"
  done
  exit

4
Bu soru, sondaki boşlukların nasıl korunacağını soruyor.
Douglas

@Douglas: Muhtemelen bu yanıtı geçici bir dalda bir taahhüt oluşturmak, gerçek yamayı orada işlemek ve farkı bir şekilde sadece çalışan şubeye almak için kullanabilirsiniz ...
Tobias Kienzler
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.