Сделать текущую фиксацию единственной (начальной) фиксацией в репозитории Git?
в настоящее время у меня есть локальный репозиторий Git, который я нажимаю на репозиторий Github.
локальный репозиторий имеет ~10 коммитов, а репозиторий Github является синхронизированным дубликатом этого.
то, что я хотел бы сделать, это удалить всю историю версий из локального репозитория Git, поэтому текущее содержимое репозитория отображается как единственная фиксация (и поэтому более старые версии файлов в репозитории не хранятся).
тогда я хотел бы нажать эти изменения в Github.
Я исследовал git rebase, но это, похоже, больше подходит для удаления конкретных версий.
Другим потенциальным решением является удаление локального РЕПО и создание нового - хотя это, вероятно, создаст много работы!
ETA: есть определенные каталоги / файлы, которые не отслеживаются - если это возможно, я хотел бы сохранить untracking этих файлов.
12 ответов:
вот подход грубой силы. Он также удаляет конфигурацию репозитория.
Примечание: это не работает, если в репозитории есть подмодули! Если вы используете подмодули, вы должны использовать, например,interactive rebase
Шаг 1: удалить всю историю (убедитесь, что у вас есть резервная копия, это не может быть отменена)
rm -rf .gitШаг 2: восстановите РЕПО Git только с текущим содержание
git init git add . git commit -m "Initial commit"Шаг 3: Нажмите на GitHub.
git remote add origin <github-uri> git push -u --force origin master
единственное решение, которое работает для меня (и продолжает подмодулей работает)
git checkout --orphan newBranch git add -A # Add all files and commit them git commit git branch -D master # Deletes the master branch git branch -m master # Rename the current branch to master git push -f origin master # Force push master branch to github git gc --aggressive --prune=all # remove the old filesудаление
.git/всегда вызывает огромные вопросы, когда у меня есть подмодули. Используяgit rebase --rootкаким-то образом вызовет конфликты для меня (и займет много времени, так как у меня было много истории).
Это мой любимый подход:
git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})это создаст новую ветку с одной фиксацией, которая добавляет все в голову. Это ничего не меняет, так что это совершенно безопасно.
другой вариант, который может оказаться большой работой, если у вас много коммитов, - это интерактивная перебаза (при условии, что ваша версия git >=1.7.12):
git rebase --root -iпри представлении списка коммитов в Редакторе:
- измените "pick "на" reword " для первого коммита
- изменить "выбрать", чтобы "исправить" любой другой коммит
сохранить и закрыть. Git начнет перебазирование.
в конце у вас будет новый root commit-это комбинация всех тех, которые появились после него.
преимущество заключается в том, что вам не нужно удалять свой репозиторий, и если у вас есть сомнения, у вас всегда есть запасной вариант.
Если вы действительно хотите уничтожить свою историю, сбросьте master на эту фиксацию и удалите все остальные ветви.
вариант larsmansпредложенный метод:
сохраните список untrackfiles:
git ls-files --others --exclude-standard > /tmp/my_untracked_filesсохраните конфигурацию git:
mv .git/config /tmp/затем выполните первые шаги ларсмана:
rm -rf .git git init git add .восстановить свой config:
mv /tmp/config .git/Untrack you untracked files:
cat /tmp/my_untracked_files | xargs -0 git rm --cachedзатем совершить:
git commit -m "Initial commit"и, наконец, нажмите на свой репозиторий:
git push -u --force origin master
вы могли бы использовать мелкий клоны (git > 1.9):
git clone --depth depth remote-urlдальнейшее чтение:http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
приведенный ниже метод точно воспроизводим, поэтому нет необходимости снова запускать clone, если обе стороны были согласованы, просто запустите скрипт с другой стороны.
git log -n1 --format=%H >.git/info/grafts git filter-branch -f rm .git/info/graftsЕсли вы хотите, чтобы очистить его, попробовать этот скрипт:
http://sam.nipl.net/b/git-gc-all-ferocious
Я написал сценарий, который "убивает историю" для каждой ветви в репозиторий:
http://sam.nipl.net/b/git-kill-history
Смотрите также:http://sam.nipl.net/b/confirm
git for-each-ref --format='git update-ref -d %(refname)' \ refs/{heads,tags} | sh -x current=$(git commit-tree -m 'Initial commit' `git write-tree`) git update-ref -m 'Initial commit' `git symbolic-ref HEAD` $currentэто удалит все локальные ветви и теги, сделает единую фиксацию без истории с состоянием вашей текущей проверки на любой текущей ветке и оставит все остальное о вашем РЕПО нетронутым. Затем вы можете принудительно нажать на пульты дистанционного управления, как вам нравится.
то, что я хотел бы сделать, это удалить всю историю версий из локального репозитория Git, поэтому текущее содержимое репозитория отображается как единственная фиксация (и поэтому более старые версии файлов в репозитории не хранятся).
более концептуальный ответ:
git автоматически собирает старые коммиты, если на них не указывают теги/ветви/ссылки. Поэтому вам просто нужно удалить все теги / ветви и создать новый сиротский коммит, связанный с любой веткой-по соглашению вы бы позволили ветке
masterукажите на эту фиксацию.старые, недостижимые коммиты больше никогда не будут замечены кем-либо, если они не будут копать с низкоуровневыми командами git. Если этого достаточно для вас, я бы просто остановился там и позволил автоматическому GC делать свою работу, когда он захочет. Если вы хотите избавиться от них сразу же, вы можете использовать
git gc(возможно, с--aggressive --prune=all). Для удаленного репозитория git вы не можете заставить это сделать хотя, если у вас нет доступа оболочки к их файловой системе.
чтобы удалить последнюю фиксацию из git, вы можете просто запустить
git reset --hard HEAD^если вы удаляете несколько коммитов сверху, вы можете запустить
git reset --hard HEAD~2чтобы удалить последние два коммита. Вы можно увеличить число, чтобы удалить еще больше коммитов.
Git tutoturial здесь предоставляет справку о том, как очистить репозиторий:
вы действительно хотите удалить файл из истории и добавить его .gitignore чтобы убедиться, что это не случайно повторно совершено. Для наших примеров, мы собираюсь удалить Rakefile из репозитория GitHub gem.
git clone https://github.com/defunkt/github-gem.git cd github-gem git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch Rakefile' \ --prune-empty --tag-name-filter cat -- --allтеперь, когда мы стерли файл из истории, давайте убедимся, что мы не совершайте это случайно снова.
echo "Rakefile" >> .gitignore git add .gitignore git commit -m "Add Rakefile to .gitignore"если вы довольны состоянием репозитория, вам нужно к принудительно-нажмите изменения, чтобы перезаписать удаленный репозиторий.
git push origin master --force
Я решил аналогичную проблему просто удалив
.gitпапка из моего проекта и повторная интеграция с контролем версий через IntelliJ. Примечание:.gitпапка скрыта. Вы можете просмотреть его в терминале с помощьюls -a, а затем удалить его с помощьюrm -rf .git.
для этого используйте команду Shallow Clone git clone --depth 1 URL-он будет клонировать только текущий глава репозитория
Comments