Не удалось переименовать файл в удаленном хранилище git - PullRequest
0 голосов
/ 28 сентября 2018

Я немного заблудился с мерзавцем.Моя ситуация такова:

У меня есть удаленный репозиторий, где я push редактировал свой локальный репозиторий.Тогда я заметил, что у меня было 2 файла докера.Один с именем Dockerfile другой с именем Dockerfile (local_model).Я также заметил, что мне нужно только 1 Dockerfile, и это должно быть Dockerfile (local_model).

Другими словами, мне нужно было удалить Dockerfile, а затем переименовать Dockerfile (local_model) в Dockerfile.

Я использовал эти команды для достижения этого:

git rm --cached path/to/Dockerfile
git commit -m "Deleted a file"
git push -u origin master

, который удалил файл в удаленном хранилище (я проверил его в браузере, и он, кажется, сработал).

Затем яиспользуется:

git mv "path/to/Dockerfile (local_model)" "path/to/Dockerfile"

неустранимый: место назначения существует, источник = путь / к / Dockerfile (local_model), место назначения = путь / к / Dockerfile

, что помешало мнепереименование файла, поскольку существует другой файл с тем же именем.Мне удалось переименовать файл, используя:

git mv --force "path/to/Dockerfile (local_model)" "path/to/Dockerfile"

в конце концов (а также применяя commit ... и push.. впоследствии), но я запутался.

Где был файл, который имелтакое же имя, как у моего файла назначения?Я знаю, что эта команда влияет только на удаленный репозиторий, поэтому не должно быть конфликтов с локальным репозиторием, верно?

1 Ответ

0 голосов
/ 28 сентября 2018

Комментарий eftshift0 содержит ответ: файл, о котором Git писал, который был перезаписан git mv --force, был копией рабочего дерева .Здесь происходит то, что Git имеет много копий файлов!

Коммиты являются постоянными (ну, в основном) и доступны только для чтения, и замораживают файлы навсегда

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

  • снимок всех файлов, которые вы сказали Git заморозить в этом коммите;
  • ваше имя (как автора и коммиттера) или имяавтор / коммиттер, если коммит был сделан кем-то другим;
  • ваше (или чужое) сообщение журнала о том, почему вы сделали коммит;и - эта часть крайне важна, но мы не будем ее здесь рассматривать, потому что нас пока не интересует, как работает история Git - хэш-идентификатор родителя или родителей коммита.

Фактическое имя каждого коммита - это большой уродливый хэш-идентификатор, который Git составляет на месте, когда вы (или кто-либо другой) делает коммит.Git гарантирует, что каждый большой уродливый хэш-идентификатор будет уникальным, поэтому каждый коммит будет иметь свой хэш-идентификатор.Однажды сделанный, никто - ни вы, ни Git - не могут изменить коммит: если вы попытаетесь это сделать, и действительно что-то измените и сделаете коммит снова, то вы получите другой коммит, с новым и другим идентификатором хэша.Старый коммит также остается в репозитории.

В некоторых случаях вы можете сказать Git забыть о коммите (на самом деле, целую цепочку коммитов), так что вы никогда не сможете найти ихснова;в конце концов Git очистит их и удалит их.Но в основном то, что мы делаем с репозиторием Git, это добавление новых коммитов , сохраняя при этом все существующие коммиты без изменений.Мы не можем изменить какой-либо существующий коммит вообще, поэтому после его создания у него есть замороженная копия всех файлов, сохраненная навсегда на тот случай, если они понадобятся вам из глубокой заморозки.

Замороженные файлысжатые и только для Git, поэтому у нас должно быть рабочее дерево

Поскольку Git сохраняет, навсегда (в основном), каждую версию каждый файл, который вы (или кто-либо еще)) когда-либо говорили, что для сохранения эти файлы быстро займут все ваше хранилище, если Git сохранит их как есть.Таким образом, замороженные файлы сжимаются, иногда очень сжимаются, в специальном формате Git-only, разделяется среди всех коммитов.Новые заморозки - новые коммиты - просто по возможности повторно используйте старые заморозки из старых коммитов.Все это происходит автоматически и негласно, но имеет серьезные последствия.

Если бы у Git не было способа восстановить / повторно гидрировать ваши файлы, высушенные вымораживанием, вы никогда бы не смогли получить любых из них назад!Там не будет git checkout.Одним словом, это было бы плохо.Таким образом, Git предоставляет вам пространство, в котором он извлекает (и размораживает) ваши файлы, превращая их обратно в полезные файлы.Это пространство - ваше рабочее дерево или рабочее дерево .

В общем, вы используете git checkout, чтобы сообщить Git: Мне бы здесь хотелосьКоммит, пожалуйста. Вы используете имя , как master, но вы действительно выбираете коммит по его уникальному хэш-идентификатору.Git восстанавливает файлы и помещает их в ваше рабочее дерево, чтобы вы могли получить к ним доступ и работать с ними.

Git запоминает, какой коммит вы выбрали (и его имя ветки): это ваш текущий коммит.Git делает это, прикрепляя имя HEAD к имени ветви. 1 Он остается вашим текущим коммитом, пока вы не сделаете что-то, чтобы изменить то, что является вашим текущим коммитом - включая git checkout, но также включая создание новый коммит, который затем становится текущим коммитом.В любом случае, очевидно, что на данный момент у нас есть две копии каждого файла.Если у вас есть файл с именем README.txt, мы можем назвать один из них HEAD:README.txt, а другой просто README.txt.Копия HEAD только для Git и заморожена на все времена, а копия рабочего дерева нормальная.

Git coulОстановимся на этом - на нем могут храниться замороженные Git-файлы, сохраненные навсегда в коммитах, плюс одна копия рабочего дерева, с которой вы работаете или с которой работаете.Но Git добавляет третью копию в смесь.


1 Присоединение HEAD к какому-либо имени ветви достаточно, чтобы запомнить как текущую ветку , так и вашутекущий коммит, потому что имя ветки запоминает коммит.Вы можете спросить Git: Как называется ветка для HEAD? , и вы получите ветку;или вы можете спросить Git: Что такое хеш-код коммита для HEAD? , и Git использует имя ветви для поиска коммита.


Индекс

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

Эта третья область - действительно средняя область между commit и work-tree - по-разному называются index , staging area или cache , в зависимости от того, кто / какой бит Git являетсязвонитьПервое, что делает этот индекс, это то, что он делает git commit быстрым .Поскольку файлы в индексе (или промежуточной области) всегда уже находятся в правильной форме , все, что нужно сделать git commit - это заморозить их.Другие системы управления версиями вынуждены изучать все ваше рабочее дерево, тщательно изучая каждый файл, чтобы увидеть, не изменился ли он, что может даже потребовать повторного сжатия файла в замороженном виде.Это занимает много времени.Git не обязан этого делать.

Но это означает, что когда вы работаете, у вас есть третья версия каждого файла.Мало того, что HEAD:README.txt должно идти с вашим рабочим деревом README.txt, есть также index копия README.txt, которую мы можем назвать :README.txt.

Когда вызапустите git add для файла, Git сжимает версию этого файла в рабочем дереве и заменяет ту, которая была в индексе ранее.Или, если раньше его вообще не было в индексе, теперь это так.В любом случае, новая версия файла теперь готова к работе - все, что git commit должен сделать, это заморозить предварительно сжатый файл!

Вот где git rm приходит. Если у вас есть файлэто в вашем рабочем дереве, потому что оно было в коммите, у вас - или Git в любом случае - прямо сейчас у вас есть три копии файла: HEAD:file в текущем коммите, :file виндекс и file в рабочем дереве.Запуск git rm file удаляет две копии: одну в индексе и одну в рабочем дереве.(Он не может коснуться замороженного, потому что, ну, он заморожен!) Теперь, когда файл отсутствует в индексе, он не будет находиться в следующем коммите васmake.

Однако, если вы запускаете git rm --cached, Git удаляет only индексную копию.Теперь у вас есть HEAD:file и file, но нет :file.Это означает, что сделанный вами следующий коммит не будет содержать файл file.Хотя немного трудно понять, что вы сделали, потому что индексная копия каждого файла обычно невидима.Если вы используете свои обычные компьютерные инструменты, чтобы увидеть, какие файлы у вас есть, это покажет вам файлы work-tree .

Копия HEAD каждого файла также обычно невидима, которая имеетта же проблема - но поскольку зафиксированные файлы заморожены, нам, как правило, все равно.Мы просто используем git checkout, чтобы переключиться на другой коммит, если мы хотим увидеть файлы.Это обновляет индекс и рабочее дерево, чтобы соответствовать другому коммиту.Тогда мы можем просто посмотреть на рабочее дерево, потому что все три копии всех файлов совпадают.

git status говорит вам все, в сокращенной и, таким образом, полезной форме

Git makes новые коммиты из индекса.Таким образом, индекс определяет, что вы будете совершать.Вот почему мы можем описать это как , что будет в следующем коммите, который вы сделаете. Но индекс по существу невидим.Как вы узнаете, что будет в следующем коммите, который вы делаете?

Запуск git status - это то, как вы узнаете, что происходит с вашим индексом.

Первое, что делает git status, эторасскажет вам о вашей текущей ветке, т.е. она смотрит, к какому имени ветки добавлено специальное имя HEAD.Это говорит вам, куда пойдет ваш следующий коммит.

Остальные выходные данные git status сообщают вам о файлах, подготовленных для фиксации и файлах, не подготовленных к фиксации ,Вместо перечисления каждого файла в индексе, который в большом проекте будет состоять из целого ряда файлов, git status делает сначала сравнивает индексные копии каждого файлачтобы увидеть, что изменилось в авторе с копий HEAD.Точная разница не нужна, просто быстрое сканирование для - это индексная копия , то же самое или другое ? (Это то, что может сделать Gitочень быстро из-за его внутреннего замороженного формата.)

Если файл в индексе - копия :file - отличается от копии HEAD:file, Git сообщает вам, что этот файл для коммита .Вы знаете, что это будет в следующем коммите, но более полезно, что вы также знаете, что это будет другой в новом снимке.Сравнивая старый (текущий HEAD) и предложенный новый коммит, file будет иметь измененный .

Между тем, git status также сравнивает индексную копию :file с работойкопия дерева, file.Если эти два значения разные, Git сообщает вам, что этот файл не подготовлен для фиксации .Это говорит о том, что вы можете запустить git add прямо сейчас, чтобы скопировать file в :file.

Обратите внимание, что все три версии file могут быть разными!В данном случае это и staged for commit и not staged for commit.И, конечно, у вас могут быть новые файлы - файлы, которые не находятся в HEAD, но находятся в в индексе и рабочем дереве сейчас.Вы можете удалить файлы - файлы, которые имеют в HEAD, но теперь не в индексе и рабочем дереве.

Присутствие в индексе - это то, что делает файл отслеженным

Индекс и копии файла рабочего дерева - это разные вещи.Это означает, что вы можете иметь файл, который находится в рабочем дереве, но не в индексе.Такой файл является неотслеживаемым .Обратите внимание, что не имеет значения, находится ли файл в HEAD коммите!(Если это равно в коммите HEAD, то должно быть так, что было в индексе, и вы удалили его из индекса и просто еще не зафиксировали.) Запуск git status сообщит вам о таких файлах, и будет жаловаться, что они не отслежены.

Вы также можете иметь файл, который находится в индексе, но отсутствует в рабочем дереве.Это несколько странное положение вещей, но происходит, если вы используете не-Git команду для удаления файла.Git не особо заботится о том, что вы сделали это - он все равно будет использовать индексную копию для новых коммитов - но git status скажет вам об этом: файл будет удален при сравнении index-vs-work-tree.

Вы можете заставить Git замолчать насчет неотслеживаемых файлов, перечислив их имена (или шаблоны глобуса , как *.tmp) в ваших .gitignore файлах.Это не делает файл неотслеженным!Это заставляет Гита замолчать из-за них.У него есть и другие эффекты, но главный из них - закрыть Git.Это полезно, потому что делает git status вывод короче .

Когда git status сообщает вам только то, что вам нужно знать - некоторые файлы отличаются, когда Git запускает git diff из HEAD для индексации, а некоторые файлы отличаются, когда Git запускает git diff из индекса врабочее дерево - тогда git status становится настолько полезным, насколько это возможно.Вам не нужно выборочно выбирать выходные данные, чтобы найти полезные вещи, потому что файлы X и Y находятся в стадии подготовки, а Z не находятся в стадии размещения это именно то, что нужно.Два файла будут разными в следующем коммите, если вы сделаете это прямо сейчас;файл Z может также отличаться, если вы git add его.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...