Zdalne odrzucenie (płytka aktualizacja nie jest dozwolona) po zmianie zdalnego adresu URL Git

164

Mam projekt pod kontrolą wersji Git, nad którym pracowałem zarówno na serwerze, jak i na komputerze lokalnym. Początkowo miałem zdalne źródło ustawione jako mój komputer lokalny, ale teraz chciałbym zmienić to na BitBucket.

Na serwerze użyłem polecenia

git remote set-url origin bitbucket_address

Ale teraz, kiedy próbuję przekazać projekt, pojawia się błąd

 ! [remote rejected] master -> master (shallow update not allowed)

Co jest tego przyczyną i jak to naprawić?

rwolst
źródło
3
Jak sklonowałeś swoją lokalną wersję? git clone --depth?
Sascha Wolf
To było jakiś czas temu i nie pamiętam. Czy jest sposób, aby się tego dowiedzieć?
rwolst
2
Nie powinno być plik o nazwie shalloww ty .gitfolder.
Sascha Wolf
Tak, widzę shallowplik.
rwolst
Zobacz stackoverflow.com/a/50996201, aby znaleźć rozwiązanie, które po prostu odrzuca (lub przepisuje) brakującą historię
caw

Odpowiedzi:

329

Wygląda na to, że git clone --depth <number>klonowałeś swoją lokalną wersję. Powoduje to płytki klon . Jednym z ograniczeń takiego klonu jest to, że nie można go wypchnąć do nowego repozytorium.

Masz teraz dwie możliwości:

  1. jeśli nie obchodzi Cię Twoja aktualna lub brakująca historia, spójrz na to pytanie
  2. jeśli chcesz zachować pełną historię, czytaj dalej:

Więc chcesz zachować swoją historię, co? Oznacza to, że musisz odblokować repozytorium. Aby to zrobić, musisz ponownie dodać starego pilota.

git remote add old <path-to-old-remote>

Następnie używamy git fetchdo pobrania pozostałej historii ze starego pilota (jak zasugerowano w tej odpowiedzi ).

git fetch --unshallow old

A teraz powinieneś być w stanie wypchnąć do nowego zdalnego repozytorium.


Uwaga : po odblokowaniu klona można oczywiście ponownie usunąć starego pilota.

Sascha Wolf
źródło
45
co jeśli sklonowałem projekt kick-start i nie chcę / potrzebuję całej historii? czy jest sposób, aby tego uniknąć?
itamar
9
@itamar To wydaje się być dobrym przykładem na zupełnie poprawne nowe pytanie. Możesz link do tego pytania w celach informacyjnych.
Sascha Wolf
14
Zadane
2
Zauważ, że git fetch --unshallowmoże wymagać refspec, aby odblokować tylko określoną gałąź, a nie całe repozytorium. Np .:git fetch --unshallow origin refs/heads/mydeepbranch:refs/remotes/origin/mydeepbranch
clacke
5
Jeśli pchasz do repozytorium, które jest nieco za repozytorium, z którego sklonowałeś, a nie tworzysz zupełnie nowego repozytorium, wystarczy, że twoje lokalne odniesienie jest wystarczająco głębokie, aby zawierało zdalne odniesienie. Więc jeśli miałeś origin/master20 zatwierdzeń przed twoim, oldrepo/masterkiedy clone --depth 1go edytowałeś, a od tego czasu wykonałeś 17 lokalnych zatwierdzeń, wystarczy, że to zrobisz git fetch --depth 37 origin refs/heads/master:refs/remotes/origin/master(przeprosiny za każdy błąd poza jednym), a wtedy możesz obejść się git push oldrepo masterbez incydentów (może wymagać git 1.9.0 lub nowszej).
clacke
28

Jeśli Twoje repozytorium to origin, a oryginalne repozytorium to upstream:

git fetch --unshallow upstream
dorycki
źródło
to działa dla mnie i całkiem proste, wtedy najlepsza głosowała odpowiedź.
Maosheng Wang
11

Inną opcją, jeśli chcesz zachować repozytorium tak, jak jest z nowymi zatwierdzeniami, które dodałeś od czasu płytkiego, początkowego zatwierdzenia, jest: Zmień to zatwierdzenie za pomocą interaktywnej rebase .

  • Uruchom interaktywną rebase zawierającą pierwsze zatwierdzenie (root) za pomocą

    git rebase --interactive --root
    
  • Zmień pickpoczątkowe zatwierdzenia na, editzapisz i zamknij plik.

    Jeśli sklonowałeś repozytorium z głębią większą niż 1, być może będziesz musiał zrobić to samo dla wszystkich tych zatwierdzeń. Lub, alternatywnie, wykonaj je fixupdla wszystkich podczas interaktywnej rebase.

  • Przekonwertuj to zatwierdzenie na zwykły, nie płytkie zatwierdzenie z

    git commit --amend --no-edit
    

    Spowoduje to również zmianę identyfikatora zatwierdzenia i dodanie Ciebie jako współautora do tego początkowego zatwierdzenia.

  • Nie zapomnij zakończyć rebase

    git rebase --continue
    
Rene Hamburger
źródło
Dziękuję Ci! Działało jak urok, gdy oryginalne repozytorium zostało usunięte i masz tylko płytką kopię.
Vitalii Dmitriev
9

Jeśli chcesz wypchnąć nowe repozytorium bez zmian, możesz spróbować tego:

  • Najpierw usuń old git folderz bieżącego repozytorium,sudo rm -rf .git
  • Następnie ponownie zainicjuj gita git init
  • Następnie dodaj nowe zdalne repozytorium git remote add your-new-repo
  • Następnie naciśnij.
Akhter-uz-zaman
źródło
Uważam, że to lepsze rozwiązanie, ponieważ nie wymaga naciskania na stare. Czasami może się to zdarzyć w przypadku płytek stałych.
rnpd
To jest w zasadzie odpowiedź z powiązanego pytania, które można znaleźć tutaj .
Sascha Wolf,
@NachPD Nie jestem pewien, co masz na myśli, mówiąc, że drugie rozwiązanie wymaga „pchnięcia na stare”. Czy masz na myśli pobieranie zamiast pchania? Ponieważ nie wymaga pchania.
Sascha Wolf,
0

Jeśli pobieranie --unshallow nie działa. W twoim oddziale muszą być jakieś problemy. Napraw to za pomocą następującego polecenia przed pchnięciem.

git filter-branch -- --all

Rób to tylko z opcją --unshallow nie działa, ponieważ istnieje obawa o BEZPIECZEŃSTWO .

Chayapol
źródło