Zmienić bieżący commit jako jedyny (początkowy) commit w repozytorium Git?

Obecnie mam lokalne repozytorium Gita, które przesyłam do repozytorium Github.

Lokalne repozytorium ma ~10 commitów, a repozytorium Github jest zsynchronizowanym duplikatem tego.

To, co chciałbym zrobić, to usunąć całą historię wersji z lokalnego repozytorium Git, aby bieżąca zawartość repozytorium pojawiła się jako jedyny commit (i dlatego starsze wersje plików w repozytorium nie są przechowywane).

Chciałbym więc przesunąć te zmiany do Github.

Zbadałem Git rebase, ale wydaje się, że bardziej nadaje się to do usuwania konkretnych wersji. Innym potencjalnym rozwiązaniem jest usunięcie lokalnego repo i utworzenie nowego-choć prawdopodobnie stworzyłoby to dużo pracy!

ETA: istnieją konkretne katalogi / pliki, które nie są śledzone - jeśli to możliwe, chciałbym zachować Nie śledzące tych plików.

Author: jsroyal, 2012-03-13

12 answers

Oto podejście brute-force. Usuwa również konfigurację repozytorium.

Uwaga: to nie działa, jeśli repozytorium ma podmoduły! Jeśli używasz podmodułów, powinieneś użyć np. interactive rebase

Krok 1: Usuń całą historię (Upewnij się, że masz kopię zapasową, nie można jej przywrócić )

rm -rf .git

Krok 2: zrekonstruuj repo Git tylko z bieżącą zawartością

git init
git add .
git commit -m "Initial commit"

Krok 3: push to GitHub.

git remote add origin <github-uri>
git push -u --force origin master
 832
Author: Fred Foo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 09:13:54

Jedynym rozwiązaniem, które działa dla mnie (i utrzymuje działanie podmodułów) jest

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

Usuwanie .git/ zawsze powoduje ogromne problemy, gdy mam podmoduły. Używanie git rebase --root w jakiś sposób spowodowałoby dla mnie konflikty (i trwało długo, odkąd miałem dużo historii).

 473
Author: Zeelot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-29 14:46:39

To moje ulubione podejście:

git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})

Spowoduje utworzenie nowej gałęzi z jednym commitem, który doda wszystko w HEAD. To nie zmienia niczego innego, więc jest całkowicie bezpieczne.

 70
Author: dan_waterworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-22 13:53:36

Inną opcją, która może okazać się dużo pracy, jeśli masz dużo commitów, jest interaktywna rebase (zakładając, że Twoja wersja git jest >=1.7.12):git rebase --root -i

Po przedstawieniu listy commitów w edytorze:

  • Zmień "pick" na "reword" dla pierwszego commita
  • Zmień "pick " na" fixup " co drugi commit
Zapisz i zamknij. Git rozpocznie rebasing.

Na końcu będziesz miał nowy commit root, który jest kombinacją wszystkich tych, którzy przyszli po niego.

Zaletą jest to, że nie musisz usuwać swojego repozytorium i jeśli masz wątpliwości, zawsze masz alternatywę.

Jeśli naprawdę chcesz nukeować swoją historię, zresetuj master do tego commita i usuń wszystkie inne gałęzie.

 29
Author: Carl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 21:59:49

Wariant zaproponowanej metody larsmanów :

Zapisz listę untrackfiles:

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

Zapisz konfigurację git:

mv .git/config /tmp/

Następnie wykonaj pierwsze kroki larsmanów:

rm -rf .git
git init
git add .

Przywróć konfigurację:

mv /tmp/config .git/

Untrack you untracked files:

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

Następnie commit:

git commit -m "Initial commit"

I na koniec wrzuć do repozytorium:

git push -u --force origin master
 16
Author: lalebarde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-30 22:47:05

Możesz użyć płytkich klonów (git > 1.9):

git clone --depth depth remote-url

Czytaj dalej: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/

 5
Author: Matthias M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 11:12:30

Poniższa metoda jest dokładnie powtarzalna, więc nie ma potrzeby ponownego uruchamiania clone, jeśli obie strony były spójne, po prostu uruchom skrypt również po drugiej stronie.

git log -n1 --format=%H >.git/info/grafts
git filter-branch -f
rm .git/info/grafts

Jeśli chcesz to wyczyścić, wypróbuj ten skrypt:

Http://sam.nipl.net/b/git-gc-all-ferocious

Napisałem skrypt, który "zabija historię" dla każdej gałęzi w repozytorium:

Http://sam.nipl.net/b/git-kill-history

Zobacz: http://sam.nipl.net/b/confirm

 2
Author: Sam Watkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-29 03:48:05
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

Spowoduje to usunięcie wszystkich lokalnych gałęzi i tagów, utworzenie jednego commita bez historii ze stanem bieżącej kasy na dowolnej gałęzi i pozostawienie całej reszty transakcji nietkniętej. Następnie możesz naciskać na piloty, jak chcesz.

 1
Author: jthill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-05 01:42:16

To, co chciałbym zrobić, to usunąć całą historię wersji z lokalnego repozytorium Git, aby bieżąca zawartość repozytorium była widoczna jako jedyny commit(i dlatego starsze wersje plików w repozytorium nie są przechowywane).

Odpowiedź bardziej pojęciowa:

Git automatycznie garbage pobiera stare commity, jeśli żadne znaczniki/gałęzie/refs na nie nie wskazują. Musisz więc po prostu usunąć wszystkie tagi/gałęzie i utworzyć nowy commit sierocy, powiązany z dowolną gałęzią - przez convention pozwoliłbyś gałęzi master wskazać na ten commit.

Stare, nieosiągalne commity nigdy więcej nie będą widziane przez nikogo, chyba że będą kopać za pomocą niskopoziomowych komend git. Jeśli to ci wystarczy, zatrzymałbym się tam i pozwoliłbym automatycznemu GC wykonywać swoją pracę, kiedy tylko zechce. Jeśli chcesz się ich pozbyć od razu, możesz użyć git gc (ewentualnie z --aggressive --prune=all). Dla zdalnego repozytorium git, nie ma sposobu, aby to wymusić, chyba że masz dostęp do powłoki ich system plików.

 0
Author: AnoE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 11:27:13

Aby usunąć ostatni commit z Gita, możesz po prostu uruchomić

git reset --hard HEAD^ 

Jeśli usuwasz wiele commitów z góry, możesz uruchomić

git reset --hard HEAD~2 

Aby usunąć dwa ostatnie commity. Ty może zwiększyć liczbę, aby usunąć jeszcze więcej commitów.

Więcej informacji tutaj.

Git tutoturial tutaj zapewnia pomoc jak wyczyścić repozytorium:

Chcesz usunąć plik z historii i dodać go do .gitignore aby upewnić się, że nie zostanie przypadkowo popełniony ponownie. Na nasze przykłady jesteśmy zamierzam usunąć Rakefile z repozytorium Gem GitHub.

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

Teraz, gdy usunęliśmy Plik z historii, upewnijmy się, że nie popełnij tego ponownie przypadkowo.

echo "Rakefile" >> .gitignore

git add .gitignore

git commit -m "Add Rakefile to .gitignore"

Jeśli jesteś zadowolony ze stanu repozytorium, musisz Wymuś-wypchnij zmiany, aby nadpisać zdalne repozytorium.

git push origin master --force
 -1
Author: octoback,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 05:48:38

Rozwiązałem podobny problem, usuwając folder .git z mojego projektu i ponownie integrując się z kontrolą wersji za pomocą IntelliJ. Uwaga: folder .git jest ukryty. Możesz go wyświetlić w terminalu za pomocą ls -a , a następnie usunąć za pomocą rm -rf .git .

 -1
Author: JB Lovell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-11 18:54:18

Do tego użyj polecenia Shallow Clone git clone --depth 1 URL-spowoduje klonowanie tylko bieżącej głowicy repozytorium

 -1
Author: kkarki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-23 15:55:38