Я переместил файл вручную, а затем изменил его. Согласно Git, это новый файл и удаленный файл. Есть ли способ заставить Git рассматривать его как перемещение файла?
Как сделать git пометить удаленный и новый файл в качестве перемещения файла?
Ответ 1
Git автоматически обнаружит перемещение/переименование, если ваша модификация не слишком серьезная. Просто git add
новый файл и git rm
старый файл. git status
затем покажет, обнаружил ли он переименование.
Кроме того, для перемещения по каталогам вам может потребоваться:
- cd в начало этой структуры каталогов.
- Запустить
git add -A .
- Запустите
git status
, чтобы убедиться, что "новый файл" теперь является "переименованным" файлом
Если статус git по-прежнему показывает "новый файл", а не "переименован", вы должны следовать рекомендациям Hank Gays и выполнять переход и изменять в двух отдельных фиксациях.
Ответ 2
Сделайте перемещение и изменение в отдельных фиксациях.
Ответ 3
Все это воспринимается. Git обычно хорош при распознавании ходов, потому что GIT является трекером контента
Все, что на самом деле зависит от того, как отображается ваш "stat". Единственное различие здесь - флаг -M.
git log -stat -M
commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date: Fri Jan 9 22:13:51 2009 +1300
Category Restructure
lib/Gentoo/Repository.pm | 10 +++++-----
lib/Gentoo/{ => Repository}/Base.pm | 2 +-
lib/Gentoo/{ => Repository}/Category.pm | 12 ++++++------
lib/Gentoo/{ => Repository}/Package.pm | 10 +++++-----
lib/Gentoo/{ => Repository}/Types.pm | 10 +++++-----
5 files changed, 22 insertions(+), 22 deletions(-)
git log --stat
commit 9c034a76d394352134ee2f4ede8a209ebec96288
Author: Kent Fredric
Date: Fri Jan 9 22:13:51 2009 +1300
Category Restructure
lib/Gentoo/Base.pm | 36 ------------------------
lib/Gentoo/Category.pm | 51 ----------------------------------
lib/Gentoo/Package.pm | 41 ---------------------------
lib/Gentoo/Repository.pm | 10 +++---
lib/Gentoo/Repository/Base.pm | 36 ++++++++++++++++++++++++
lib/Gentoo/Repository/Category.pm | 51 ++++++++++++++++++++++++++++++++++
lib/Gentoo/Repository/Package.pm | 41 +++++++++++++++++++++++++++
lib/Gentoo/Repository/Types.pm | 55 +++++++++++++++++++++++++++++++++++++
lib/Gentoo/Types.pm | 55 -------------------------------------
9 files changed, 188 insertions(+), 188 deletions(-)
git журнал справки
-M
Detect renames.
-C
Detect copies as well as renames. See also --find-copies-harder.
Ответ 4
git diff -M
или git log -M
должны автоматически определять такие изменения, как переименование с незначительными изменениями, если они действительно есть.
Если ваши незначительные изменения не являются незначительными, вы можете уменьшить сходство threashold, например.
$ git log -M20 -p --stat
чтобы уменьшить его по умолчанию от 50% до 20%.
Ответ 5
Здесь быстрое и грязное решение для одного или нескольких переименованных и измененных файлов, которые не зарегистрированы.
Скажем, файл был назван foo
, и теперь он называется bar
:
-
Переименуйте
bar
во временное имя:mv bar side
-
Оформить заказ
foo
:git checkout HEAD foo
-
Переименуйте
foo
вbar
с помощью Git:git mv foo bar
-
Теперь переименуйте свой временный файл обратно в
bar
.mv side bar
Этот последний шаг - это то, что возвращает ваш измененный контент в файл.
Хотя это может сработать, если перемещенный файл слишком отличается по содержанию от оригинала git, он будет более эффективным, чтобы решить, что это новый объект. Позвольте мне продемонстрировать:
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ git add README.md work.js # why are the changes unstaged, let add them.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ git stash # what? let go back a bit
Saved working directory and index state WIP on dir: f7a8685 update
HEAD is now at f7a8685 update
$ git status
On branch workit
Untracked files:
(use "git add <file>..." to include in what will be committed)
.idea/
nothing added to commit but untracked files present (use "git add" to track)
$ git stash pop
Removing README
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
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)
deleted: README
modified: work.js
Dropped refs/[email protected]{0} (1ebca3b02e454a400b9fb834ed473c912a00cd2f)
$ git add work.js
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
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)
deleted: README
$ git add README # hang on, I want it removed
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
deleted: README
new file: README.md
modified: work.js
$ mv README.md Rmd # Still? Try the answer I found.
$ git checkout README
error: pathspec 'README' did not match any file(s) known to git.
$ git checkout HEAD README # Ok the answer needed fixing.
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
new file: README.md
modified: work.js
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)
deleted: README.md
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ git mv README README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: work.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
Rmd
$ mv Rmd README.md
$ git status
On branch workit
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: .gitignore
renamed: README -> README.md
modified: work.js
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: README.md
modified: work.js
$ # actually that half of what I wanted; \
# and the js being modified twice? Git prefers it in this case.
Ответ 6
Если вы говорите о git status
, не показывающем переименования, попробуйте git commit --dry-run -a
вместо
Ответ 7
Если вы используете TortoiseGit, важно отметить, что автоматическое обнаружение переименования Git происходит во время фиксации, но тот факт, что это произойдет, не всегда отображается программным обеспечением заранее. Я переместил два файла в другой каталог и выполнил некоторые небольшие изменения. Я использую TortoiseGit как инструмент фиксации, а в списке "Изменения" показаны файлы, которые удаляются и добавляются, а не перемещаются. Выполнение статуса Git из командной строки показало аналогичную ситуацию. Однако после фиксации файлов они отображались как переименованные в журнал. Поэтому ответ на ваш вопрос заключается в том, что если вы не сделали ничего слишком резкого, Git должен автоматически переименовать.
Изменить: Очевидно, если вы добавляете новые файлы, а затем выполняете статус Git из командной строки, переименование должно появляться до совершения.
Изменить 2: Кроме того, в TortoiseGit добавьте новые файлы в диалог фиксации, но не делайте их. Затем, если вы войдете в команду "Показать журнал" и посмотрите на рабочий каталог, вы увидите, было ли Git обнаружено переименование перед фиксацией.
Здесь был задан один и тот же вопрос: https://tortoisegit.org/issue/1389 и был зарегистрирован как ошибка для исправления здесь: https://tortoisegit.org/issue/1440 Оказывается, это проблема отображения с диалогом фиксации TortoiseGit, а также вид существует в состоянии Git, если вы не добавили новые файлы.
Ответ 8
Используйте команду git mv
для перемещения файлов вместо команд перемещения ОС:
https://git-scm.com/docs/git-mv
Обратите внимание, что команда git mv
существует только в Git версий 1.8.5 и выше. Поэтому вам, возможно, придется обновить ваш Git, чтобы использовать эту команду.
Ответ 9
Или вы можете попробовать ответить на этот вопрос здесь от Амбер! Чтобы процитировать это снова:
Сначала отмените поэтапное добавление для перемещенного вручную файла:
$ git reset path/to/newfile
$ mv path/to/newfile path/to/oldfile
Затем используйте Git для перемещения файла:
$ git mv path/to/oldfile path/to/newfile
Конечно, если вы уже совершили перемещение вручную, вы можете вместо этого сбросить ревизию до перемещения, а затем просто выполнить git mv.
Ответ 10
У меня была эта проблема в последнее время при перемещении (но не изменении) некоторых файлов.
Проблема заключается в том, что Git изменил некоторые окончания строк, когда я переместил файлы, а затем не смог сказать, что файлы были одинаковыми.
Использование git mv
устраняет проблему, но работает только на отдельных файлах/каталогах, и у меня было много файлов в корне репозитория.
Один из способов исправить это будет с помощью bash/batch magic.
Другим способом является следующее
- Переместите файлы и
git commit
. Это обновляет окончание строки. - Переместите файлы обратно в исходное местоположение, теперь, когда у них есть новые окончания строк, и
git commit --amend
- Переместите файлы еще раз и
git commit --amend
. На этот раз изменений в окончаниях линии нет, поэтому Git счастлив
Ответ 11
Для меня это сработало, чтобы сохранить все изменения перед фиксацией и вывести их снова. Это заставило git проанализировать добавленные/удаленные файлы и правильно пометить их как перемещенные.
Ответ 12
Вероятно, есть лучший способ командной строки, и я знаю, что это взломать, но Ive так и не смог найти хорошее решение.
Использование TortoiseGIT: если у вас есть фиксация GIT, где некоторые операции перемещения файла отображаются как загрузка добавлений/удалений, а не переименований, даже если файлы имеют небольшие изменения, сделайте следующее:
- Проверьте, что вы сделали локально.
- Проверьте мини-однострочное изменение во 2-й фиксации
- Перейти к GIT войти в черепаху git
- Выберите два коммита, щелкните правой кнопкой мыши и выберите "слить в один коммит"
Новая команда теперь корректно покажет переименования файлов..., что поможет поддерживать правильную историю файлов.
Ответ 13
Когда я редактирую, переименую и перемещаю файл одновременно, ни одно из этих решений не работает. Решение состоит в том, чтобы сделать это в двух коммитах (отредактировать и переименовать/переместить отдельно), а затем fixup
второй фиксатор через git rebase -i
, чтобы иметь его в одном коммите.
Ответ 14
Как я понимаю этот вопрос: "Как заставить git распознавать удаление старого файла и создание нового файла при перемещении файла".
Да, в рабочем каталоге, когда вы удалите старый файл и вставите старый файл, git status
скажет "deleted: old_file
" и "Untracked files: ... new_file
"
Но в промежуточном индексе/уровне, когда вы добавляете и удаляете файл с помощью git, он будет распознаваться как перемещение файла. Для этого, если вы выполнили удаление и создание с помощью своей операционной системы, введите следующие команды:
git add new_file
git rm old_file
Если содержимое файла примерно на 50% или более, команда git status
выдаст вам:
renamed: old_file -> new_file