Как мне зафиксировать только изменения имени файла в 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:
Чтобы изменить настройку на более длительный срок (например, если необходимо выполнить несколько команд, прежде чем снова ее изменить):
git config core.ignorecase
(возвращает текущую настройку, например,false
).git config core.ignorecase
<<true or false>>
- установите желаемую новую настройку.- ... Выполнить несколько других команд...
git config core.ignorecase
<<false or true>>
- верните значение конфигурации к предыдущему значению.
Мы можем использовать команду git mv. Пример ниже, если мы переименовали файл abcDEF.js в abcdef.js, то мы можем запустить следующую команду из терминала
git mv -f .\abcDEF.js .\abcdef.js
В OSX, чтобы избежать этой проблемы и избежать других проблем при разработке в файловой системе без учета регистра, вы можете использовать Дисковую утилиту для создания виртуального диска / образа диска с учетом регистра.
Запустите утилиту диска, создайте новый образ диска и используйте следующие параметры (или измените их, как вам угодно, но сохраните их с учетом регистра):
Обязательно сообщите 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) и принудительно переименовать файл сверху вниз. Вот что я сделал:
- Посетите GitHub.com
- Перейдите в свой репозиторий на GitHub.com и выберите ветку, в которой вы работаете
- Перейдите к файлу, который вы собираетесь переименовать, используя инструмент навигации по сайту.
- Нажмите значок "Редактировать этот файл" (он выглядит как карандаш)
- Изменить имя файла в текстовом вводе имени файла
- Убедитесь в том, что
branchname
ветка "переключатель" выбран - Нажмите кнопку "Подтвердить изменения"
- Локально оформить / вытащить / получить ветку
- Готово
С помощью следующей команды:
git config --global core.ignorecase false
Вы можете глобально настроить свою систему git так, чтобы в именах файлов и папок учитывался регистр.
Mac OSX High Sierra 10.13 это несколько исправляет. Просто создайте виртуальный раздел APFS для ваших проектов git, по умолчанию он не имеет ограничения по размеру и не занимает места.
- В Дисковой утилите нажмите кнопку +, когда выбран Контейнерный диск
- Выберите APFS (с учетом регистра) в формате
- Назови это
Sensitive
- прибыль
- Необязательно: Создайте папку в Sensitive с именем
git
а такжеln -s /Volumes/Sensitive/git /Users/johndoe/git
Ваш диск будет в /Volumes/Sensitive/
Спустя годы мне нужно вернуться к своему вопросу и предложить еще одно возможное решение! Я столкнулся с этой проблемой в проекте, где нужно было переименовать только один файл. Это то, что я сделал, и это сработало для меня.
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...
Единственный надежный способ, который я видел, это исправляет:
git rm Foobar.java
- Передайте это с сообщением, которое вы не можете пропустить
git commit -m 'TEMP COMMIT!!'
- Тянуть
- Это вызовет конфликт, заставляющий вас объединить конфликт - потому что ваше изменение удалило его, а другое изменение переименовало (отсюда и проблема)
- Примите ваше изменение, которое является "удаление"
git rebase --continue
- Теперь бросьте свой обходной путь
git rebase -i HEAD~2
а такжеdrop
TEMP COMMIT!!
- Убедитесь, что файл теперь называется
FooBar.java
Когда вы сделали много переименований файлов, и некоторые из них - просто смена регистра, трудно вспомнить, что есть что. Вручную "перемещать" файл может быть довольно трудоемким. Итак, что бы я сделал во время моих задач по изменению имени файла:
- удалите все не git файлы и папки в другую папку / репозиторий.
- зафиксировать текущую пустую папку git (это покажет, как все файлы удалены)
- добавьте все файлы обратно в исходную папку / репозиторий git.
- зафиксировать текущую непустую папку 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.