Git-mv'nin amacı nedir?


287

Anladığım kadarıyla Git'in dosya yeniden adlandırma / taşıma / kopyalama işlemlerini gerçekten izlemesi gerekmiyor , bu yüzden git mv'nin gerçek amacı nedir? Man sayfası özel olarak açıklayıcı değil ...

Eski mi? Normal kullanıcılar tarafından kullanılması amaçlanmayan dahili bir komut mudur?

Yanıtlar:


390
git mv oldname newname

sadece kısaltmasıdır:

mv oldname newname
git add newname
git rm oldname

yani hem eski hem de yeni yollar için dizini otomatik olarak günceller.


38
Ayrıca yerleşik birkaç güvenlik sistemi vardır.
Jakub Narębski

6
Thanks @CharlesBailey - git daha sonra newNameFile ve oldNameFile dosyalarını farklı olarak mı değerlendiriyor? Evetse, birleştirmek istiyorsak ne olur? Diyelim ki A dalında bir karınca projesini dallıyoruz ve B Şubesini oluşturduktan sonra B'de mavenize projeler oluşturuyoruz. Dosya adları aynı ancak proje yapısı değiştikçe farklı yollara koyduk. Her iki dalın da bir süre paralel büyüdüğünü varsayalım. Bir noktada projeleri birleştirmek istiyorsak git, aynı dosyanın yolunu yeniden adlandırdığını nasıl bilecek? ("git mv" == "git add + git rm" ise)
gül

2
@SergeyOrshanskiy Otomatik algılama yanlış giderse mv oldname newname; git add newname; git rm oldname, bunun için de yanlış gidecektir git mv oldname newname( bu cevaba bakınız ).
Ajedi32

5
Not git mvden biraz farklıdır mv oldname newname; git add newname; git rm oldnameönce dosyada değişiklikler eğer ki, git mvbunu ing, bu değişiklikler size kadar sahnelenecek olmayacak git addyeni bir dosya.
Ajedi32

2
git mv, dosya adı durumundaki değişiklikleri (foo.txt - Foo.txt) işlerken farklı bir şey yapıyor, bu komutlar tek tek çalıştırılıyor (OSX'te)
greg.kindel

66

Gönderen resmi GitFaq :

Git'in bir yeniden adlandırma komutu var git mv, ancak bu sadece bir kolaylık. Efekt, dosyayı kaldırmaktan ve farklı ad ve aynı içerikle başka bir dosya eklemekten ayırt edilemez.


8
Dosya geçmişini kaybediyor musunuz? Yeniden adlandırmanın bu dizinin eski tarihini koruyacağını tahmin ediyorum ...
Will Hancock

17
Evet, hayır. Yeniden adlandırmalar hakkında yukarıdaki resmi GitFaq bağlantısını okuyun ve ardından bir SCM aracı izleme dosyası kavramını neden sevmediğine dair Linus Torvalds uzun e-postasını okuyun: permalink.gmane.org/gmane.comp.version-control.git/ 217
Adam Nofsinger

3
@WillHancock Git'i biraz daha şimdi kullandım ve size daha kesin olarak cevap verebilirim: git istemcinize ve seçeneklerine bağlı olarak, dosya dahili olarak kabul edilebilecek kadar az değiştiğinde, yeniden adlandırma işleminden sonra dosyayı izleyebileceksiniz. Adını değiştirmek. Dosyayı çok fazla değiştirirseniz ve yeniden adlandırırsanız, git dosyayı algılamaz - bir anlamda "hayır, tamamen farklı bir dosya olduğunu da düşünebilirsiniz!"
Adam Nofsinger

7
@AdamNofsinger bu bağlantının öldüğünü. İşte bir ayna: web.archive.org/web/20150209075907/http://…
Carl Walsh

2
git mvEl ile yaklaşım arasındaki denkliği belirten resmi bir referans var mı (yani bir SSS'ye daha fazla itiraz etmeye değer) ? Bu belli değil git help mv.
tvo

40

Git sadece sizin için ne yapmaya çalıştığınızı tahmin etmeye çalışıyor. Kesintisiz tarihi korumak için her türlü çabayı göstermektedir. Tabii ki, mükemmel değil. Böylece git mvniyetinizi açıkça belirtmenize ve bazı hatalardan kaçınmanıza izin verir.

Bu örneği ele alalım. Boş bir repo ile başlayarak,

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
mv a c
mv b a
git status

Sonuç:

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   a
#   deleted:    b
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   c
no changes added to commit (use "git add" and/or "git commit -a")

Otomatik algılama başarısız oldu :( Yoksa mı?

$ git add *
$ git commit -m "change"
$ git log c

commit 0c5425be1121c20cc45df04734398dfbac689c39
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

ve sonra

$ git log --follow c

Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

commit 50c2a4604a27be2a1f4b95399d5e0f96c3dbf70a
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:45 2013 -0400

    initial commit

Şimdi bunun yerine deneyin (denerken .gitklasörü silmeyi unutmayın ):

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
git mv a c
git status

Çok uzak çok iyi:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    a -> c


git mv b a
git status

Şimdi kimse mükemmel değil:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a
#   deleted:    b
#   new file:   c
#

Gerçekten mi? Ama tabii...

git add *
git commit -m "change"
git log c
git log --follow c

... ve sonuç yukarıdakiyle aynıdır: yalnızca --followtam geçmişi gösterir.


Her iki seçenek de tuhaf efektler üretebileceğinden , şimdi yeniden adlandırmaya dikkat edin . Misal:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git commit -m "first move"
git mv b a
git commit -m "second move"

git log --follow a

commit 81b80f5690deec1864ebff294f875980216a059d
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:35:58 2013 -0400

    second move

commit f284fba9dc8455295b1abdaae9cc6ee941b66e7f
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:34:54 2013 -0400

    initial b

Kontrast ile:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git mv b a
git commit -m "both moves at the same time"

git log --follow a

Sonuç:

commit 84bf29b01f32ea6b746857e0d8401654c4413ecd
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:37:13 2013 -0400

    both moves at the same time

commit ec0de3c5358758ffda462913f6e6294731400455
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:36:52 2013 -0400

    initial a

Ups ... Şimdi tarih, ilk b yerine ilk a'ya geri dönüyor , bu yanlış. Bir seferde iki hamle yaptığımızda Git'in kafası karıştı ve değişiklikleri düzgün bir şekilde takip etmedi. Bu arada, deneylerimde aynı şey dosyaları kullanmak yerine sildiğim / oluşturduğumda oldu . Dikkatle ilerleyin; uyarılmıştın...git mv


5
Ayrıntılı açıklama için +1. Dosyalar git'e taşınırsa günlük geçmişinde oluşabilecek sorunları arıyordum, cevabınız gerçekten ilginçti. Teşekkür ederim! Btw, git'te dosyaları taşırken kaçınmamız gereken başka tuzakları biliyor musunuz? (veya işaret edebileceğiniz herhangi bir referans .... bunun için çok şanslı bir googling değil)
pabrantes

1
Örneklerim kötümser. Dosyalar boş olduğunda, değişiklikleri uygun şekilde yorumlamak çok daha zordur. Her yeniden adlandırma dizisinden sonra taahhüt verirseniz iyi olmanız gerektiğini düşünüyorum.
osa

27

@Charles'ın dediği gibi git mv, bir stenografi.

Burada asıl soru "Diğer sürüm kontrol sistemleri (örn. Subversion ve Perforce) dosya adlarını özel olarak ele alıyor. Neden Git yok?"

Linus http://permalink.gmane.org/gmane.comp.version-control.git/217 adresinde karakteristik dokunuşla açıklıyor :

Lütfen bu "dosyaları izle" bok durdurun. Git izler tam olarak yani "koleksiyonları dosyaların", neyin önemli. Başka hiçbir şey alakalı değildir ve bunun alakalı olduğunu düşünmek bile yalnızca dünya görüşünüzü sınırlar. CVS'nin "açıklama" kavramının daima kaçınılmaz olarak insanların nasıl kullandığını sınırlandırdığına dikkat edin. Bunun bok tamamen yararsız parça olduğunu düşünüyorum ve ben bir milyon kat daha yararlı olduğunu düşünüyorum o şey tarif ettik ve hepsi düştü aynen Ben dünyanın yanlış modeline benim düşünce sınırlayıcı değilim çünkü.


9

git mvYukarıda bahsetmediğim başka bir kullanım var .

Keşfetmeden bu yana git add -p(git add'in yama modu; bkz. Http://git-scm.com/docs/git-add ), değişiklikleri dizine eklerken değişiklikleri gözden geçirmek için kullanmak istiyorum. Böylece benim iş akışı (1) kod üzerinde çalışmak, (2) gözden geçirmek ve endekse eklemek, (3) taahhüt olur.

Nasıl git mvsığar? Bir dosyayı doğrudan taşıdıktan sonra git rmve düğmelerini kullanarak git addtüm değişiklikler dizine eklenir ve değişiklikleri görüntülemek için git diff'i kullanmak daha az kolaydır (işleme başlamadan önce). Kullanılması git mvAncak dizine yeni bir yol ekler ancak bu şekilde sağlayan, dosyada yapılan değişiklikleri git diffve git add -pher zamanki gibi işe.


5

git mvÇok kullanışlı olan bir niş vaka var : büyük / küçük harfe duyarlı olmayan bir dosya sisteminde bir dosya adının büyük / küçük harf durumunu değiştirmek istediğinizde. APFS (mac) ve NTFS (windows) varsayılan olarak büyük / küçük harfe duyarlı değildir (ancak büyük / küçük harf korumalıdır).

greg.kindel, CB Bailey'in cevabına yaptığı bir yorumda bundan bahsediyor.

Bir mac üzerinde çalıştığınızı ve Mytest.txtgit tarafından yönetilen bir dosyanız olduğunu varsayalım . Dosya adını olarak değiştirmek istiyorsunuz MyTest.txt.

Deneyebilirsiniz:

$ mv Mytest.txt MyTest.txt
overwrite MyTest.txt? (y/n [n]) y
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Ah hayatım. Git, dosyada herhangi bir değişiklik olduğunu kabul etmez.

Sen olabilir geri adlandırma sonra tamamen dosyayı yeniden adlandırarak bu geçici bir çözüm:

$ mv Mytest.txt temp.txt
$ git rm Mytest.txt
rm 'Mytest.txt'
$ mv temp.txt MyTest.txt
$ git add MyTest.txt 
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt

Yaşa!

Veya aşağıdakileri kullanarak kendinizi tüm bu rahatsızlıktan kurtarabilirsiniz git mv:

$ git mv Mytest.txt MyTest.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt
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.