Какова цель git-mv?



из того, что я понимаю, Git действительно не нужно отслеживать file переименование/перемещение / копирование операций, так какова реальная цель
из git mv? Справочная страница не является специально описательной...



он устарел? Это внутренняя команда, не предназначенная для использования обычными пользователями?

580   5  
git

5 ответов:

git mv oldname newname

- это просто сокращенная запись:

mv oldname newname
git add newname
git rm oldname

т. е. он автоматически обновляет индекс как для старых, так и для новых путей.

С официальный GitFaq:

Git имеет команду переименовать git mv, но это просто для удобства. Эффект неотличим от удаления файла и добавления другого с разными имя и тот же контент

Git просто пытается угадать для вас, что вы пытаетесь сделать. Она делает все возможное, чтобы сохранить нерушимую историю. Конечно, это не идеально. Так что git mv позволяет вам быть явным с вашим намерением и избежать некоторых ошибок.

рассмотрим такой пример. Начиная с пустого РЕПО,

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

результат:

# 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")

автоопределение не :( Или это сделал?

$ 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

и затем

$ 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

теперь попробуйте вместо этого (не забудьте удалить .git папка при экспериментировании):

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

так:

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


git mv b a
git status

теперь никто не совершенен:

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

в самом деле? Ну конечно же...

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

...и результат тот же, что и выше: только --follow показывает полную историю.


теперь, будьте осторожны с переименованием, как любой вариант может по-прежнему производить странно эффекты. Пример:

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

сравните его с:

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

результат:

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... Теперь история возвращается к начальная a вместо начальная b, что неверно. Поэтому, когда мы делали два хода за раз, Git запутался и не отслеживал изменения должным образом. Кстати, в моих экспериментах то же самое происходило, когда я удалял/создавал файлы вместо использования git mv. Действуйте осторожно; вы были предупрежденный...

Как говорит @ Charles,git mv - Это стенография.

реальный вопрос здесь - "другие системы контроля версий (например. Subversion и Perforce) обрабатывают имена файлов специально. Почему не ГИТ?"

Линус объясняет в http://permalink.gmane.org/gmane.comp.version-control.git/217 с характерным тактом:

пожалуйста, остановите это дерьмо" отслеживать файлы". Треки ГИТ ровно что имеет значение, а именно"коллекции файлов". Ничто другое не имеет значения, и даже мышление что это актуально только ограничивает ваше мировоззрение. Обратите внимание, как понятие CVS "аннотировать" всегда неизбежно заканчивается ограничением того, как люди используют оно. Я думаю, что это совершенно бесполезный кусок дерьма, и я описал что-то, что я думаю в миллион раз полезнее, и все это выпало ровно потому что я не ограничиваю свое мышление неправильная модель мир.

у меня есть еще одно применение git mv не упомянутые выше.

С момента обнаружения git add -p (режим патча git add; см. http://git-scm.com/docs/git-add), я хотел бы использовать его для просмотра изменений, как я добавляю их в индекс. Таким образом, мой рабочий процесс становится (1) работа над кодом, (2) просмотр и добавление в индекс, (3) фиксация.

как git mv подходят? Если переместить файл напрямую, то с помощью git rm и git add, все изменения добавляются в индекс, и с помощью git diff просмотр изменений менее прост (перед фиксацией). Используя git mv, однако, добавляет новый путь к индексу, но не изменения, внесенные в файл, что позволяет git diff и git add -p работать как обычно.

Comments

    Ничего не найдено.