Chciałbym zdefiniować nową gałąź „root” w tym repozytorium git. Przez gałąź "root" rozumiem gałąź, która jest całkowicie niezależna od wszystkich innych gałęzi w repozytorium 1 .
Niestety, nawet zatwierdzenie (nazwijmy to A
) w samej podstawie drzewa zatwierdzeń repozytorium zawiera wiele plików (było to repozytorium zainicjowane w już dość dojrzałym projekcie).
Oznacza to, że nawet gdybym podał A
jako nową gałąź <start-point>
, ta nowa gałąź nie zaczynałby się od „czystej karty”, ale raczej zawierałaby wszystkie zatwierdzone pliki A
.
Czy jest jakiś sposób, żebym mógł stworzyć całkowicie nagą gałąź w tym repozytorium, <start-point>
tak blisko, A
jak to możliwe?
1 BTW, nie jest to równoznaczne z utworzeniem nowego repozytorium. Oddzielne repozytoria byłyby mniej wygodne z wielu powodów.
EDYCJA : OK, oto co zrobiłem na podstawie odpowiedzi vcsjones :
# save rev of the current earliest commit
OLDBASE=$(git rev-list --max-parents=0 HEAD)
# create a new orphan branch and switch to it
git checkout --orphan newbranch
# make sure it's empty
git rm -rf .
# create a new empty commit in the new branch, and
# save its rev in NEWBASE
git commit --allow-empty -m 'base commit (empty)'
NEWBASE=$(git rev-list HEAD)
# specify $NEWBASE as the new parent for $OLDBASE, and
# run filter-branch on the original branch
echo "$OLDBASE $NEWBASE" > .git/info/grafts
git checkout master
git filter-branch
# NOTE: this assumes that the original repo had only one
# branch; if not, a git-filter-branch -f <branch> command
# need to be run for each additional branch.
rm .git/info/grafts
Chociaż ta procedura jest nieco skomplikowana, wynikiem końcowym jest puste zatwierdzenie podstawowe, które może służyć jako <start-point>
nowa gałąź „clean-slate”; wszystko co wtedy musiałbym zrobić to
git checkout -b cleanslate $(git rev-list --max-parents=0 HEAD)
W przyszłości zawsze będę tworzyć nowe repozytoria, takie jak to:
git init
git commit --allow-empty -m 'base commit (empty)'
... tak, że pierwsze zatwierdzenie jest puste i zawsze dostępne do rozpoczęcia nowej niezależnej gałęzi. (Wiem, że byłby to bardzo rzadko potrzebny obiekt, ale łatwo jest go udostępnić).
git rebase --onto
, patrz stackoverflow.com/questions/645450/ ...Odpowiedzi:
Użyj
--orphan
podczas tworzenia oddziału:Spowoduje to utworzenie nowej gałęzi z zerowymi zatwierdzeniami, jednak wszystkie Twoje pliki zostaną umieszczone w poczekalni. W tym momencie możesz je po prostu usunąć.
("usuń je": A
git reset --hard
opróżni indeks, pozostawiając puste drzewo robocze)Spójrz na stronę podręcznika man do kasy, aby uzyskać więcej informacji na temat --orphan.
źródło
Aby dodać do zaakceptowanej odpowiedzi - najlepszą praktyką powrotu do czystego stanu jest utworzenie początkowego pustego zatwierdzenia, aby można było łatwo zmienić bazę podczas konfigurowania gałęzi dla potomności. Poza tym, ponieważ chcesz mieć czysty stan, prawdopodobnie zatwierdziłeś pliki, których nie powinieneś, więc musisz usunąć je z indeksu. Mając to na uwadze, powinieneś:
źródło
Jeśli używasz git 2.23 lub nowszego, możesz być przyzwyczajony do
git switch
igit restore
zamiastgit checkout
. Jeśli tak, flaga jest taka sama, jak wspomniano w tej odpowiedzi .źródło
Rzeczywiste polecenie do użycia (z Git 2.28+) to:
git switch
jest dostępny od Git 2.23 (sierpień 2019) i zastępuje stare, mylącegit checkout
polecenie .Ale poleciłbym Git 2.28 (Q3 2020), ponieważ
git switch --discard-changes --orphan
został zoptymalizowany w tej wersji.Zobacz commit 8d3e33d , commit 8186128 (21 maja 2020) autorstwa briana m. carlson (
bk2204
) .(Scalone przez Junio C Hamano -
gitster
- w zobowiązaniu ded44af , 09 czerwca 2020 r.)Test:
źródło