Сделать текущую фиксацию единственной (начальной) фиксацией в репозитории Git?

в настоящее время у меня есть локальный репозиторий Git, который я нажимаю на репозиторий Github.

локальный репозиторий имеет ~ 10 коммитов,и репозиторий Github является синхронизированным дубликатом этого.

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

тогда я хотел бы нажать эти изменения в Github.

Я исследовал git rebase, но это, похоже, больше подходит для удаления определенных версий. Другим потенциальным решением является удаление локального РЕПО и создание нового - хотя это, вероятно, создаст много работы!

ETA: есть определенные каталоги / файлы, которые не отслеживаются - если это возможно, я хотел бы сохранить untracking этих файлов.

12 ответов


вот подход грубой силы. Он также удаляет конфигурацию репозитория.

Примечание: это не работает, если в репозитории есть подмодули! Если вы используете подмодули, вы должны использовать, например,интерактивные перебазирования

Шаг 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})

Это создаст новую ветку с одной фиксацией, которая добавит все в HEAD. Это ничего не меняет, так что это совершенно безопасно.


другой вариант, который может оказаться большой работой, если у вас много коммитов, - это интерактивная ребаза (при условии, что ваша версия git >=1.7.12):git rebase --root -i

когда представлен список коммитов в Редакторе:

  • измените "pick "на" reword " для первого коммита
  • измените " pick "на" fixup " каждый другой commit

сохранить и закрыть. Git начнет перебазирование.

в конце у вас будет новый root commit-это комбинация всех тех, которые пришли после него.

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

Если вы действительно хотите уничтожить свою историю, сбросьте master на эту фиксацию и удалите все остальные ветви.


вариант larsmansпредлагаемый метод:

сохраните список untrackfiles:

git ls-files --others --exclude-standard > /tmp/my_untracked_files

сохраните конфигурацию git:

mv .git/config /tmp/

затем выполнить первые шаги по larsmans:

rm -rf .git
git init
git add .

восстановить свой config:

mv /tmp/config .git/

Untrack вы не отследили файлы:

cat /tmp/my_untracked_files | xargs -0 git rm --cached

затем commit:

git commit -m "Initial commit"

и, наконец, нажмите на свой репозиторий:

git push -u --force origin master

вы можете использовать shallow клоны (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 нет способа заставить это хотя, если у вас нет доступа shell к их файловой системе.


чтобы удалить последнюю фиксацию из git, вы можете просто запустить

git reset --hard HEAD^ 

если вы удаляете несколько коммитов сверху, вы можете запустить

git reset --hard HEAD~2 

чтобы удалить последние два коммита. Вы может увеличить число, чтобы удалить еще больше коммитов.

подробнее здесь.

Git tutoturial здесь предоставляет справку о том, как очистить репозиторий:

вы действительно хотите удалить файл из истории и добавить его .гитюдного чтобы убедиться, что он случайно не повторится. Для наших примеров, мы собирается удалить 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"

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

git push origin master --force

Я решил аналогичную проблему просто удалив .git папка из моего проекта и реинтеграция с контролем версий через IntelliJ. Примечание:.git папка скрыта. Вы можете просмотреть его в терминале с помощью ls -a, а затем удалите его с помощью rm -rf .git .


для этого используйте команду Shallow Clone git clone --depth 1 URL-он будет клонировать только текущий руководитель репозитория