Git stara się odgadnąć, co chcesz zrobić. Podejmuje wszelkie próby zachowania nieprzerwanej historii. Oczywiście nie jest doskonały. Tak więc git mv
pozwala ci jasno wyrazić swoją intencję i uniknąć błędów.
Rozważ ten przykład. Zaczynając od pustego repo,
git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
mv a c
mv b a
git status
Wynik:
# 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")
Autodetekcja udało :( Albo to zrobił?
$ 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
a następnie
$ 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
Teraz spróbuj zamiast (pamiętaj, aby usunąć folder .git
podczas eksperymentów):
git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
git mv a c
git status
tej pory tak dobrze:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: a -> c
git mv b a
git status
teraz , nobo dy jest idealny:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a
# deleted: b
# new file: c
#
Naprawdę? Ale oczywiście ...
git add *
git commit -m "change"
git log c
git log --follow c
... a wynik jest taki sam jak powyżej: tylko --follow
przedstawia pełną historię.
Teraz należy być ostrożnym z zmiana nazwy, jak albo opcja może nadal wywołują skutki dziwne. Przykład:
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 go:
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
Wynik:
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 ... Teraz historia wraca do parafować zamiast początkowy b, co jest złe. Kiedy więc robiliśmy dwa ruchy na raz, Git był zdezorientowany i nie śledzi prawidłowo zmian. Nawiasem mówiąc, w moich eksperymentach to samo stało się, gdy usunąłem/utworzyłem pliki zamiast używać git mv
. Kontynuuj ostrożnie; zostałeś ostrzeżony ...
Ma także kilka wbudowanych zabezpieczeń. –
Dzięki @CharlesBailey - czy git uważa pliki newNameFile i oldNameFile za różne? Jeśli tak, co się stanie, jeśli chcemy je połączyć? Załóżmy, że tworzymy projekt mrówki w oddziale A i tworzymy Oddział B, a następnie tworzymy projekty na B. Nazwy plików są takie same, ale umieszczane na różnych ścieżkach w miarę zmiany struktury projektu. Powiedzmy, że obie gałęzie rosły przez jakiś czas równolegle. W którymś momencie, jeśli chcemy połączyć projekty, to czy dowiemy się, że to ten sam plik, który zmienił nazwę swojej ścieżki?(jeśli "git mv" == "git add + git rm") – Rose
Zgaduję, to jest to samo z prawdopodobieństwem 99,9999%. Oczywiście, automatyczne wykrywanie może pójść źle, jeśli masz np. wiele plików o tej samej nazwie i/lub tej samej treści. – osa