Как сделать 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