Как мне зафиксировать только изменения имени файла в Git?

Я изменил имя файла, сняв с заглавной буквы первую букву, как в Name.jpg в name.jpg, Git не распознает эти изменения, и мне пришлось удалить файлы и загрузить их снова. Есть ли способ, что Git может быть чувствительным к регистру при проверке изменений в именах файлов? Я не вносил никаких изменений в сам файл.

22 ответа

Вы можете использовать git mv:

git mv -f OldFileNameCase newfilenamecase

Git имеет параметр конфигурации, который указывает, нужно ли учитывать регистр или нечувствителен: core.ignorecase, Чтобы Git учитывал регистр, просто установите для этого параметра значение false:

git config core.ignorecase false

Документация

От git config документация:

core.ignorecase

Если true, этот параметр позволяет использовать различные обходные пути, чтобы позволить git лучше работать на файловых системах, которые не чувствительны к регистру, например, FAT. Например, если распечатка каталога находит makefile когда Git ожидает Makefile, git предположит, что это действительно тот же файл, и продолжит запоминать его как Makefile,

По умолчанию используется значение false, за исключением того, что git-clone(1) или git-init(1) будут проверять и устанавливать core.ignorecase Значение true, если необходимо, при создании хранилища.

Нечувствительные к регистру файловые системы

Две самые популярные операционные системы, в которых есть файловые системы без учета регистра, которые я знаю:

  • Windows
  • OS X

Я использовал следующие шаги:

git rm -r --cached .
git add --all .
git commit -a -m "Versioning untracked files"
git push origin master

Для меня это простое решение

Используя SourceTree, я смог сделать все это из пользовательского интерфейса

  • переименовывать FILE.ext в whatever.ext
  • Подготовьте этот файл
  • Теперь переименуйте whatever.ext в file.ext
  • Поместите этот файл снова

Это немного утомительно, но если вам нужно сделать это только с несколькими файлами, это довольно быстро

Это то, что я сделал на OS X:

git mv File file.tmp
git mv file.tmp file

Два шага, потому что в противном случае я получил ошибку "файл существует". Возможно, это можно сделать за один шаг, добавив --cached или такой.

Иногда бывает полезно временно изменить чувствительность к регистру в Git. Два возможных метода:

Способ 1:

git -c core.ignorecase=true checkout mybranch отключить чувствительность к регистру для одного checkout команда. Или в целом: git -c core.ignorecase=<<true or false>><<command>>, (Благодарим VonC за предложение об этом в комментариях.)

Способ 2:

Чтобы изменить настройку на более длительный срок (например, если необходимо выполнить несколько команд, прежде чем снова ее изменить):

  1. git config core.ignorecase (возвращает текущую настройку, например, false).
  2. git config core.ignorecase<<true or false>> - установите желаемую новую настройку.
  3. ... Выполнить несколько других команд...
  4. git config core.ignorecase<<false or true>> - верните значение конфигурации к предыдущему значению.

Мы можем использовать команду git mv. Пример ниже, если мы переименовали файл abcDEF.js в abcdef.js, то мы можем запустить следующую команду из терминала

git mv -f .\abcDEF.js  .\abcdef.js

В OSX, чтобы избежать этой проблемы и избежать других проблем при разработке в файловой системе без учета регистра, вы можете использовать Дисковую утилиту для создания виртуального диска / образа диска с учетом регистра.

Запустите утилиту диска, создайте новый образ диска и используйте следующие параметры (или измените их, как вам угодно, но сохраните их с учетом регистра):

Скриншот Mac Disk Utility

Обязательно сообщите git, что он теперь на регистре чувствительных символов:

git config core.ignorecase false

1) переименовать файл Name.jpg в name1.jpg

2) зафиксировать удаленный файл Name.jpg

3) переименовать файл name1.jpg в name.jpg

4) изменить добавленный файл name.jpg к предыдущему коммиту

git add
git commit --amend

Подобно ответу @Sijmen, это то, что у меня сработало в OSX при переименовании каталога (вдохновлено этим ответом из другого поста):

git mv CSS CSS2
git mv CSS2 css

Просто делаю git mv CSS css дал ошибку неверного аргумента: fatal: renaming '/static/CSS' failed: Invalid argument возможно, потому что файловая система OSX нечувствительна к регистру

PS Кстати, если вы используете Django, collectstatic также не распознает разницу в регистре, и вам придется делать это вручную и в статическом корневом каталоге.

Я попробовал следующие решения из других ответов, и они не сработали:

  • git mv filename
  • git rm -f filename

Если ваш репозиторий размещен на GitHub, как у меня, вы можете переименовать файл в источнике (GitHub.com) и принудительно переименовать файл сверху вниз. Вот что я сделал:

  1. Посетите GitHub.com
  2. Перейдите в свой репозиторий на GitHub.com и выберите ветку, в которой вы работаете
  3. Перейдите к файлу, который вы собираетесь переименовать, используя инструмент навигации по сайту.
  4. Нажмите значок "Редактировать этот файл" (он выглядит как карандаш)
  5. Изменить имя файла в текстовом вводе имени файла
  6. Убедитесь в том, что branchname ветка "переключатель" выбран
  7. Нажмите кнопку "Подтвердить изменения"
  8. Локально оформить / вытащить / получить ветку
  9. Готово

С помощью следующей команды:

      git config --global  core.ignorecase false

Вы можете глобально настроить свою систему git так, чтобы в именах файлов и папок учитывался регистр.

Mac OSX High Sierra 10.13 это несколько исправляет. Просто создайте виртуальный раздел APFS для ваших проектов git, по умолчанию он не имеет ограничения по размеру и не занимает места.

  1. В Дисковой утилите нажмите кнопку +, когда выбран Контейнерный диск
  2. Выберите APFS (с учетом регистра) в формате
  3. Назови это Sensitive
  4. прибыль
  5. Необязательно: Создайте папку в Sensitive с именем git а также ln -s /Volumes/Sensitive/git /Users/johndoe/git

Ваш диск будет в /Volumes/Sensitive/

Как мне зафиксировать только изменения имени файла в Git?

Спустя годы мне нужно вернуться к своему вопросу и предложить еще одно возможное решение! Я столкнулся с этой проблемой в проекте, где нужно было переименовать только один файл. Это то, что я сделал, и это сработало для меня.

      git mv -f src/MyFile.js src/myfile.js

Что я узнал как из этой темы, так и из этого ответа

поэтому существует множество решений этой проблемы развертывания с учетом регистра в зависимости от того, как GitHub ее обрабатывает.

В моем случае я изменил соглашение о регистре имен файлов с прописных на строчные.

Я верю, что git может отслеживать изменения, но эта команда определяет, как git работает за кулисами.

В моем случае я запустил команду, и у git внезапно появилось много файлов для отслеживания, помеченных как неотслеживаемые.

Затем я нажал git add. , затем git commit и еще раз запустил мою сборку на netlify.

Тогда все отображаемые ошибки можно было бы отследить, например Module not found: Can't resolve './Components/ProductRightSide' in '/opt/build/repo/components/productsи исправлено так, что git смог успешно отслеживать и внедрять изменения.

Это довольно обходной путь и ноготь от разочарования, но поверьте мне, это обязательно сработает.

PS: после исправления вашей проблемы вы можете запустить команду git config core.ignorecase trueчтобы восстановить работу git с учетом регистра.

Кроме того, обратите внимание git config core.ignorecase falseимеет проблемы с другими расширениями файлов, поэтому вы можете быть осторожны, делайте это, если вы знаете, что делаете, и уверены в этом.

Вот тема на netlify, которая может помочь, возможно

Я сталкивался с этой проблемой несколько раз на MacOS. Git чувствителен к регистру, но Mac сохраняет только регистр.

Кто-то фиксирует файл: Foobar.java и через несколько дней решает переименовать его в FooBar.java, Когда вы извлекаете последний код, он не работает с The following untracked working tree files would be overwritten by checkout...

Единственный надежный способ, который я видел, это исправляет:

  1. git rm Foobar.java
  2. Передайте это с сообщением, которое вы не можете пропустить git commit -m 'TEMP COMMIT!!'
  3. Тянуть
  4. Это вызовет конфликт, заставляющий вас объединить конфликт - потому что ваше изменение удалило его, а другое изменение переименовало (отсюда и проблема)
    1. Примите ваше изменение, которое является "удаление"
    2. git rebase --continue
  5. Теперь бросьте свой обходной путь git rebase -i HEAD~2 а также drop TEMP COMMIT!!
  6. Убедитесь, что файл теперь называется FooBar.java

Когда вы сделали много переименований файлов, и некоторые из них - просто смена регистра, трудно вспомнить, что есть что. Вручную "перемещать" файл может быть довольно трудоемким. Итак, что бы я сделал во время моих задач по изменению имени файла:

  1. удалите все не git файлы и папки в другую папку / репозиторий.
  2. зафиксировать текущую пустую папку git (это покажет, как все файлы удалены)
  3. добавьте все файлы обратно в исходную папку / репозиторий git.
  4. зафиксировать текущую непустую папку git.

Это решит все проблемы с делом, не пытаясь выяснить, какие файлы или папки вы переименовали.

Я взял ответ Chris Barr и написал скрипт Python 3, чтобы сделать это со списком файлов:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import os
import shlex
import subprocess

def run_command(absolute_path, command_name):
    print( "Running", command_name, absolute_path )

    command = shlex.split( command_name )
    command_line_interface = subprocess.Popen( 
          command, stdout=subprocess.PIPE, cwd=absolute_path )

    output = command_line_interface.communicate()[0]
    print( output )

    if command_line_interface.returncode != 0:
        raise RuntimeError( "A process exited with the error '%s'..." % ( 
              command_line_interface.returncode ) )

def main():
    FILENAMES_MAPPING = \
    [
        (r"F:\\SublimeText\\Data", r"README.MD", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\Alignment", r"readme.md", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\AmxxEditor", r"README.MD", r"README.md"),
    ]

    for absolute_path, oldname, newname in FILENAMES_MAPPING:
        run_command( absolute_path, "git mv '%s' '%s1'" % ( oldname, newname ) )
        run_command( absolute_path, "git add '%s1'" % ( newname ) )
        run_command( absolute_path, 
             "git commit -m 'Normalized the \'%s\' with case-sensitive name'" % (
              newname ) )

        run_command( absolute_path, "git mv '%s1' '%s'" % ( newname, newname ) )
        run_command( absolute_path, "git add '%s'" % ( newname ) )
        run_command( absolute_path, "git commit --amend --no-edit" )

if __name__ == "__main__":
    main()

Или просто переименуйте нужный файл через веб-интерфейс репозитория git и зафиксируйте :)

Если ничего не работает, используйте git rm filename, чтобы удалить файл с диска и добавить его обратно.

Я сделал bash-скрипт для имен файлов репозитория в нижнем регистре:

      function git-lowercase-file {
  tmp="tmp-$RANDOM-$1"
  new=$(echo "$1" | tr '[:upper:]' '[:lower:]') 
  git mv -f $1 $tmp
  git mv -f $tmp $new
}

то вы можете использовать его следующим образом:

      git-lowercase-file Name.jpg

Если вы делаете более сложные изменения, такие как изменение регистра имени каталога, вы можете сделать это изменение с компьютера с Linux, потому что сама Linux (а также git в Linux) обрабатывает файлы/каталоги с одинаковыми именами, но с другим регистром, как совершенно разные файлы /каталоги.

Итак, если вы работаете в Windows, вы можете установить Ubuntu с помощью WSL, клонировать туда свой репозиторий, открыть каталог клонированного репо с помощью VSCode (используйте удаленное расширение WSL для доступа к WSL Ubuntu из Windows), после чего вы сможете переименовывать через VSCode и зафиксируйте/отправьте их с помощью интеграции VSCode с git.

Другие вопросы по тегам