Git: Изменения, вносимые непосредственно в рабочий каталог (связанный с пустым хранилищем) - PullRequest
0 голосов
/ 03 июня 2018

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

Мне пришлось редактировать некоторые файлы непосредственно в рабочем каталоге на сервере.Таким образом, эти изменения не фиксируются в пустом хранилище, и я не могу вытащить их на свой локальный компьютер.

Вот что я попробовал (а что нет)

  1. Насколько мне известно, фиксация не будет работать в рабочем репо, поскольку в нем нет каталога .git (это означает, что, поскольку он не git init-ialized - поэтому я не могу этого сделать
  2. Выполнение)команда commit на голом репо не будет работать и в IMO, потому что я хорошо помню, что читал что-то на SO, что голые репозитории не предназначены для фиксации напрямую. Вместо этого вы просто передаете им код. Вы не можете коммитить, потому что у них неткод для фиксации в них.
  3. Я не могу представить какой-либо другой способ, чтобы эти изменения в рабочем каталоге могли быть определены как фиксация в голом репо.

Я пыталсяЯ ищу это в StackOverflow, но не могу получить ответ. Возможно, не использую правильную терминологию GIT, так как я только изучаю GIT.

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

Ответ DileepNimantha в основном правильный (он пропускает шаг, по крайней мере, в то время, когда я пишу это), но есть несколько потенциально более простых способов.Мы вернемся к самому простому позже;давайте начнем с того, что мы действительно делаем.Я добавлю, что отсутствующим шагом является запуск git fetch и git read-tree (см. Ниже) после git remote add ....Есть также предположение, что текущая ветвь master правильная.

Фундаментальная проблема - это та, которую вы определили: у вас есть пустое хранилище (с core.bare = true, git init --bare и т. Д.), Котороеследовательно, у него нет рабочего дерева.

Чтобы сделать новый коммит в любом Git-репозитории, вам технически не нужно рабочее дерево вообще.Вам нужно, чтобы index (также известный как staging-area или иногда cache ), связанный с этим хранилищем, имел правильное содержимое файла.Однако стандартный способ сделать это - использовать git add <em>file1</em> <em>file2</em> ..., который копирует указанные файлы из вашего рабочего дерева в ваш индекс, перезаписывая старые версии этих файлов в индексе.Это, конечно, требует рабочего дерева.

Пустой репозиторий, несмотря на отсутствие рабочего дерева, все еще имеет индекс.Вот как мы можем обойти отсутствие рабочего дерева.

Вы можете заполнить индекс из определенного коммита, такого как подсказка master, используя git read-tree:

$ git read-tree master

Затем можно заменить одну из записей индекса из файла в файловой системе.В этом случае я обновил sig.py, распаковав его в файл в файловой системе, который сейчас находится в / tmp, а затем отредактировал его там:

$ git hash-object -w -t blob /tmp/sig.py
b6a42a1dd3fff08aa4bed6b054b310f69ed518c1

Теперь необходимо создать git ls-filesэтап записи для этого файла.Старый:

$ git ls-files --stage sig.py
100644 7e49ad4f1042b14e088571a091a7b9f7d1010b4c 0       sig.py

Нам не нужно использовать номер этапа, так как git update-index позволяет нам его пропустить, поэтому мы можем напечатать новый хэш вместе с остальной соответствующей информацией:

$ printf '%s %s %s\t%s\n' 100644 blob \
    b6a42a1dd3fff08aa4bed6b054b310f69ed518c1 sig.py | \
    git update-index --index-info

Я разделил это на три строки, две с обратной косой чертой-новой строкой, для публикации длины.На самом деле это все одна команда, но когда она выражается таким образом, как ввод оболочки, она будет работать так же хорошо.Обратите внимание, что новый хэш blob - это тот, который мы получили, записав новый обновленный файл в хранилище.(Примечание: у нас есть около 14 дней, чтобы закончить нашу работу после того, как мы начнем этот процесс, прежде чем git gc объявит, что наш вновь созданный объект BLOB-объекта не используется, и, следовательно, удалит его.)

Теперь нам нужнозапишите индекс в виде дерева объекта:

$ git write-tree
e92275076a62ca850b0bda3f6c3603632b4a6cce

и затем сохраните это дерево как объект фиксации.Давайте сделаем этот новый коммит, который мы добавим после текущей подсказки master:

$ git commit-tree -p master \
    -m 'make signal handler work in py2k and py3k' \
    e92275076a62ca850b0bda3f6c3603632b4a6cce

Выполнение этого произвело для меня хеш коммита:

e068bdfce2fd992dc396cb4969327ef5c4d39a43

МыТеперь нужно сделать какое-нибудь имя ветки, возможно, новое, сослаться на этот хеш коммита.Я буду использовать новый вместо того, чтобы обновлять master вместо:

$ git branch fix-signal e068bdfce2fd992dc396cb4969327ef5c4d39a43

Теперь мы можем видеть, сработало ли это, запустив git log в этом голом хранилище:

$ git log --oneline --decorate -n 2 fix-signal
e068bdf (fix-signal) make signal handler work in py2k and py3k
11ae6ca (HEAD -> master) add run-checks script

Давайте рассмотрим изменение как патч:

$ git show fix-signal
[snip]
index 7e49ad4..b6a42a1 100644
--- a/sig.py
+++ b/sig.py
@@ -5,7 +5,10 @@ import sys
 import time

 def signal_handler(signum, frame):
-    os.write(1, bytes('caught sig %d\n' % signum, 'iso8859-1'))
+    if str is not bytes:
+        os.write(1, bytes('caught sig %d\n' % signum, 'iso8859-1'))
+    else:
+        os.write(1, 'caught sig %d\n' % signum)

 def catch_by_sig():
     old_int = signal.signal(signal.SIGINT, signal_handler)

Но это действительно --bare репозиторий:

$ git status
fatal: This operation must be run in a work tree

Упрощение

gitкоманда front-end принимает много опций, которые появляются перед глаголом.Например, если ваше извлеченное рабочее дерево на сервере находится в /tmp/work, вы можете на сервере cd в свой репозиторий Git:

$ cd ...

и затем запустить:

$ git --work-tree=/tmp/work status

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

При необходимости вы можете использовать операцию git read-tree, как мы делали в более длинной форме выше, чтобы заполнить индекс из некоторого конкретного коммита.Вы можете назвать коммит по его имени ветки, как я делал выше, или по его хэш-идентификатору: ключ заключается в заполнении индекса из коммита, который в данный момент развернут в области развертывания.

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

git --work-tree=/tmp/work add file1.ext file2.ext

, например, чтобы добавить эти файлы из рабочейдерево (вы будете делать это, когда "cd" -ed в Git-репозиторий).Затем вы можете запустить:

git --work-tree=/tmp/work commit

как обычно. Обратите внимание, что это будет зафиксировано в текущей ветви, , т. Е. Той, к которой HEAD присоединен в хранилище.Это, вероятно, правильно из-за любого сценария развертывания, который вы используете.

По сути, каждый раз, когда вы запускаете команду Git, вы говорите: игнорируйте настройку core.bare, рабочее дерево поверхв этом другом пути. На самом деле, вероятно, именно так работает ваш хук развертывания во время push-операции.

Я не рекомендую делать это как обычную практику - вы получаете все расходыПозволяет отправлять в не-пустое хранилище, без каких-либо преимуществ, так что вы могли бы просто настроить не-пустое хранилище, вместо того, чтобы заниматься этим.Но как быстрое решение проблемы чрезвычайной ситуации, оно работает.

0 голосов
/ 03 июня 2018

Конечно, вы можете зафиксировать свой код из вашего рабочего каталога.Вы должны просто инициировать это как репозиторий git.Попробуйте следующее:

  1. git init
  2. git remote add origin <your git url>
  3. git add внесите изменения и зафиксируйте их в своем хранилище.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...