Сделать текущую фиксацию единственной (начальной) фиксацией в репозитории Git?
В настоящее время у меня есть локальный репозиторий Git, который я нажимаю на репозиторий Github.
Локальный репозиторий имеет ~ 10 коммитов, а репозиторий Github является синхронизированным дубликатом этого.
Что бы я хотел сделать, это удалить ВСЕ историю версий из локального репозитория Git, так что текущее содержимое репозитория будет отображаться как единственное коммита (и, следовательно, более старые версии файлов в репозитории не сохраняются),
Я хотел бы нажать эти изменения в Github.
Я исследовал Git rebase, но это, похоже, больше подходит для удаления определенных версий.
Еще одно потенциальное решение - удалить локальное репо и создать новый, хотя это, вероятно, создало бы много работы!
ETA: Существуют определенные каталоги/файлы, которые не отслеживаются - если возможно, я хотел бы поддерживать отключение этих файлов.
Ответы
Ответ 1
Здесь подход грубой силы. Также удаляет конфигурацию хранилища.
Примечание: это НЕ работает, если в хранилище есть субмодули! Если вы используете субмодули, вы должны использовать, например, интерактивная перебазировка
Шаг 1. удалите всю историю (Убедитесь, что у вас есть резервная копия, ее нельзя восстановить)
cat .git/config # note <github-uri>
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
Ответ 2
Единственное решение, которое работает для меня (и работает подмодулей) -
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
каким-то образом вызовет для меня конфликты (и у меня много истории).
Ответ 3
Это мой благоприятный подход:
git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})
Это создаст новую ветку с одной фиксацией, которая добавит все в HEAD. Он ничего не меняет, поэтому он полностью безопасен.
Ответ 4
Другим вариантом, который может оказаться большой работой, если у вас много коммитов, является интерактивная rebase (если ваша версия git равнa > 1,7.12): git rebase --root -i
При представлении списка коммитов в вашем редакторе:
- Измените "pick" на "reword" для первого фиксации
- Измените "pick" на "fixup" каждый другой commit
Сохранить и закрыть. git начнет перезагружаться.
В конце у вас будет новый корневой фиксатор, который является комбинацией всех тех, которые пришли после него.
Преимущество в том, что вам не нужно удалять ваш репозиторий, и если у вас есть другие мысли, у вас всегда есть резерв.
Если вы действительно хотите уничтожить свою историю, reset master для этого фиксации и удалить все остальные ветки.
Ответ 5
Удалить папку .git может привести к проблемам в репозитории git.
Если вы хотите удалить всю свою историю фиксации.
выполните следующие действия:
шаг-1 (checkout)
git checkout --orphan latest_branch
step-2 (добавьте все файлы)
git add -A
Шаг 3 (Зафиксируйте изменения)
git commit -am "commit message"
step-4 (Удалить ветвь)
git branch -D master
step-5 (переименуйте текущую ветвь на мастер)
git branch -m master
Шаг 6 (окончательный шаг, сила для обновления вашего репозитория)
git push -f origin master
!! Теперь наслаждайтесь историей фиксации!
Ответ 6
Вариант предложенного метода larsmans:
Сохраните список непечатных файлов:
git ls-files --others --exclude-standard > /tmp/my_untracked_files
Сохраните конфигурацию git:
mv .git/config /tmp/
Затем выполните первые шаги larsmans:
rm -rf .git
git init
git add .
Восстановите конфигурацию:
mv /tmp/config .git/
Откажитесь от непроверенных файлов:
cat /tmp/my_untracked_files | xargs -0 git rm --cached
Затем зафиксируйте:
git commit -m "Initial commit"
И, наконец, нажмите на свой репозиторий:
git push -u --force origin master
Ответ 7
Вы можете использовать неглубокие клоны (git > 1.9):
git clone --depth depth remote-url
Дополнительная литература: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
Ответ 8
Создайте ветвь, скопируйте все содержимое в нее, скопируйте ее и затем удалите главную ветвь:
git checkout --orphan newBranch; git add -A ;git commit -am 'first commit' ;git branch -D master;git branch -m master; git push -f origin master; git gc --aggressive --prune=all
Ответ 9
git filter-branch
является инструментом основной хирургии.
git filter-branch --parent-filter true -- @^!
--parent-filter
выводит родителей на стандартный ввод и должен печатать переписанные родители на стандартный вывод; unix true
успешно завершает работу и ничего не печатает, а значит: нет родителей. @^!
- это Git сокращение от "главный коммит, но не его родители". Затем удалите все другие ссылки и нажмите на досуге.
Ответ 10
Ниже приведен скрипт, адаптированный из ответа @Zeelot. Следует удалить историю из всех ветвей, а не только из основной ветки:
for BR in $(git branch); do
git checkout $BR
git checkout --orphan ${BR}_temp
git commit -m "Initial commit"
git branch -D $BR
git branch -m $BR
done;
git gc --aggressive --prune=all
Это сработало для моих целей (я не использую подмодули).
Ответ 11
Метод ниже воспроизводимый, поэтому нет необходимости запускать клон снова, если обе стороны согласованы, просто запустите script с другой стороны.
git log -n1 --format=%H >.git/info/grafts
git filter-branch -f
rm .git/info/grafts
Если вы хотите его очистить, попробуйте script:
http://sam.nipl.net/b/git-gc-all-ferocious
Я написал script, который "убивает историю" для каждой ветки в репозитории:
http://sam.nipl.net/b/git-kill-history
см. также: http://sam.nipl.net/b/confirm
Ответ 12
Что бы я хотел сделать, это удалить ВСЕ историю версий из локального репозитория Git, так что текущее содержимое репозитория будет отображаться как единственное коммита (и, следовательно, более старые версии файлов в репозитории не сохраняются),
Более концептуальный ответ:
git автоматически мусор собирает старые коммиты, если теги/ветки/ссылки не указывают на них. Таким образом, вам просто нужно удалить все теги/ветки и создать новую сиротскую фиксацию, связанную с какой-либо веткой - по соглашению вы позволите ветке master
указать на это commit.
Старые, недоступные коммиты никогда больше не будут замечены кем-либо, если они не будут копаться с низкоуровневыми командами Git. Если этого достаточно для вас, я просто остановлюсь на этом, и пусть автоматический GC сделает это, когда захочет. Если вы хотите избавиться от них сразу, вы можете использовать git gc
(возможно, с --aggressive --prune=all
). Для удаленного репозитория Git вам не удастся это сделать, если только у вас нет доступа к файловой системе.
Ответ 13
Просто удалите репозиторий Github и создайте новый. Безусловно, самый быстрый, самый простой и безопасный подход. В конце концов, что вы должны получить, выполняя все эти команды в принятом решении, когда все, что вам нужно, - это основная ветка с одним коммитом?
Ответ 14
Вот, пожалуйста:
#!/bin/bash
#
# By Zibri (2019)
#
# Usage: gitclean username password giturl
#
gitclean ()
{
odir=$PWD;
if [ "$#" -ne 3 ]; then
echo "Usage: gitclean username password giturl";
return 1;
fi;
temp=$(mktemp -d 2>/dev/null /dev/shm/git.XXX || mktemp -d 2>/dev/null /tmp/git.XXX);
cd "$temp";
url=$(echo "$3" |sed -e "s/[^/]*\/\/\([^@]*@\)\?\.*/\1/");
git clone "https://$1:[email protected]$url" && {
cd *;
for BR in "$(git branch|tr " " "\n"|grep -v '*')";
do
echo working on branch $BR;
git checkout $BR;
git checkout --orphan $(basename "$temp"|tr -d .);
git add -A;
git commit -m "Initial Commit" && {
git branch -D $BR;
git branch -m $BR;
git push -f origin $BR;
git gc --aggressive --prune=all
};
done
};
cd $odir;
rm -rf "$temp"
}
Также размещено здесь: https://gist.github.com/Zibri/76614988478a076bbe105545a16ee743
Ответ 15
Я решил аналогичную проблему, просто удалив папку .git
из моего проекта и реинтегрировав с помощью контроля версий через IntelliJ.
Примечание. Папка .git
скрыта. Вы можете просмотреть его в терминале с помощью ls -a
, а затем удалить его с помощью rm -rf .git
.
Ответ 16
Для этого используйте команду Shallow Clone
git clone --depth 1 URL - он будет клонировать только текущий HEAD репозитория
Ответ 17
Чтобы удалить последнюю фиксацию из 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