Как вы инициализируете текущее содержимое каталога как состояние ветки git?

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

Есть 2 возможности, о которых я знаю в настоящее время:

  1. Оформить заказ A во временный каталог C, удалить все, кроме ".git", скопировать содержимое каталога B в C, а затем добавить /commit/push из каталога C. Наконец, переместить все содержимое C обратно в B.
  2. Клонируйте хранилище без извлечения во временный каталог C, переместите каталог ".git" из C в B. Добавьте /commit/push изнутри B.

Проблемы с обоими этими решениями, помимо того, что они ужасно неуклюжи, заключаются в том, что они требуют дискового пространства для каталогов B и C. Вариант 1 также включает в себя немного больше перетасовки файлов. Поэтому в настоящее время моим лучшим решением является вариант 2, подробные шаги которого приведены ниже.

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

mkdir /tmp/git_output
cd /tmp/git_output
git init
git remote add origin /path_or_url_to/git/repo.git
git fetch
git checkout name_of_branch
mv .git /path/to/new/src/
cd /path/to/new/src/
git commit -a
git push
rm -rf /tmp/git_output

Спасибо за любую помощь.

2 ответа

Я думаю, что должна быть возможность удалить все из вашей рабочей копии (убедитесь, что НЕ удалите .git папка - делать резервные копии!). Затем скопируйте содержимое вашего каталога B, git add -u (в зависимости от версии Git), чтобы удалить отсутствующие файлы из индекса и добавить новые файлы в индекс. Commit. Будь счастлив.


Еще один способ, которым я могу придумать, - это инициализировать свежий Git-репозиторий в вашем каталоге. B, зафиксируйте все файлы, затем нажмите A: cd B; git init; git add .; git commit -m 'complete rewrite'; git push /path/to/A HEAD:rewrite,

Сейчас в AСоздайте прививку, рассказав Git, что верхушка ветви rewrite имеет верхушку ветви master из A как его родитель. Тогда беги git filter-branch сделать этот прививок постоянным.

git checkout A
GIT_WORK_TREE=path/to/B git add -An .   # take out the `n` to actually do it
git commit
git checkout as-you-were

(редактировать: если вы уже находитесь на ветке А, вам нужно сделать git reset --hard после, чтобы обновить ваше настоящее рабочее дерево.)

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

(
  export GIT_INDEX_FILE=.git/sideband-index
  export GIT_WORK_TREE=path/to/B
  cp .git/HEAD{,~}
  git symbolic-ref HEAD refs/heads/A
  git add -A .
  git commit
  mv .git/HEAD{~,}
)

Или даже

(
  export GIT_INDEX_FILE=`mktemp -u`
  export GIT_WORK_TREE=path/to/B
  git add -A .
  git update-ref A $(git commit-tree -m 'hi there!' -p A $(git write-tree))
)
Другие вопросы по тегам