Jak wybierać z odległego oddziału?

144

Mam problem z wykonaniem selekcji. Na moim komputerze lokalnym jestem obecnie w gałęzi „master”. Chcę wybrać najlepszy wybór w zatwierdzeniu z innej gałęzi o nazwie „zebra”. Gałąź „zebra” to gałąź zdalna.

Więc status git:

# On branch master
nothing to commit (working directory clean)

Ok, teraz próbuję wybrać najlepsze zatwierdzenie, które chcę:

git cherry-pick xyz
fatal: bad object xyz

gdzie "xyz" to sygnatura interesującego mnie commita, który wydarzył się na gałęzi "zebra".

Więc pierwsze oczywiste pytanie brzmi: dlaczego git nie może znaleźć commita, do którego się odwołuję? Szczerze mówiąc, nie rozumiem, jak to działa. Czy git przechowuje coś w rodzaju bazy danych zmian lokalnie w moim katalogu roboczym dla wszystkich innych gałęzi? Czy podczas wykonywania polecenia cherry-pick przeszukuje lokalną bazę danych, aby znaleźć zatwierdzenie, o którym mówię?

Ponieważ „zebra” to zdalna gałąź, pomyślałem, że nie mam lokalnie jej danych. Więc zmieniłem gałęzie:

git checkout zebra
Switched to branch 'zebra'

Więc teraz na moim komputerze lokalnym widzę, że pliki w katalogu poprawnie odzwierciedlają stan zebry. Przełączam się z powrotem na master, próbuję ponownie wybrać cherry-pick (mając nadzieję, że dane dotyczące zmian są teraz dostępne), ale mam ten sam problem.

Mam fundamentalne niezrozumienie tego, co się tutaj dzieje, każda pomoc byłaby świetna.

user291701
źródło
2
koncepcyjnie wszystko wydaje się w porządku. czy na pewno używasz poprawnego hasha (podpisu, jak go nazywasz) zatwierdzenia? spróbuj „git show <hash>”, aby zweryfikować.
0xc0de
Cześć, tak pozytywnie - obie moje gałęzie są na githubie i mogę ich użyć do znalezienia stron z zatwierdzeniami w ten sposób. Jeśli rozumiem, stan mojej maszyny lokalnie jest taki, że git nie może znaleźć skrótu z „zebry” w kontekście „master”. Czy muszę jakoś powiedzieć, że „zebra” istnieje również lokalnie?
user291701
och, a wykonanie polecenia „git show xyz” daje ten sam błąd „fatal: bad object”. (i zastępuję xyz poprawnym hashem).
user291701
I dla wyjaśnienia, mogę użyć mojego hasha 'xyz', aby bez problemu spojrzeć na zatwierdzenie na github, na przykład: " github.com/me/test/commit/xyz ".
user291701

Odpowiedzi:

209

Ponieważ „zebra” to zdalna gałąź, pomyślałem, że nie mam lokalnie jej danych.

Masz rację, że nie masz odpowiednich danych, ale próbowałeś je rozwiązać w niewłaściwy sposób. Aby zebrać dane lokalnie ze zdalnego źródła, musisz użyć git fetch. Kiedy to zrobiłeś git checkout zebra, przełączyłeś się na stan tej gałęzi przy ostatnim pobieraniu. Więc najpierw pobierz z pilota:

# fetch just the one remote
git fetch <remote>
# or fetch from all remotes
git fetch --all
# make sure you're back on the branch you want to cherry-pick to
git cherry-pick xyz
Peter Lundgren
źródło
1
Link do archiwum
brianpeiris
1
Wypróbowałem to podejście, aby wybrać najlepszą poprawkę na Github i okazało się, że wyrejestrowany hash był inny niż ten na Github. Dlatego musiałem to sprawdzić, zdobyć haszysz i wybrać najlepsze.
DustWolf
1
Naprawdę brakuje tutaj opcji przekazania zdalnego w cherry-pick, takiej jak: git cherry-pick <remote> <hash>
Jared
działał dobrze po pobraniu zdalnego oddziału. Dzięki :)
Adeel
tak działało również po pobraniu dla mnie. Więcej informacji na temat git cherry-pick można znaleźć na stronie atlassian.com/git/tutorials/cherry-pick
Satheesh M
13

Jako dodatek do zaakceptowanej odpowiedzi OP:

Jeśli masz problemy z

fatal: bad object xxxxx

to dlatego, że nie masz dostępu do tego zatwierdzenia. Co oznacza, że ​​nie masz tego repozytorium przechowywanego lokalnie. Następnie:

git remote add LABEL_FOR_THE_REPO REPO_YOU_WANT_THE_COMMIT_FROM
git fetch LABEL_FOR_THE_REPO
git cherry-pick xxxxxxx

Gdzie xxxxxxx to skrót zatwierdzenia, który chcesz.

Cezar Augusto
źródło
hmm, kiedy już dodałem repozytorium bez flagi upstream?
Gobliins
12

Dodanie zdalnego repozytorium (jako „foo”), z którego chcemy wybierać

$ git remote add foo git://github.com/foo/bar.git

Przynieś ich gałęzie

$ git fetch foo

Wymień ich zatwierdzenia (powinno to zawierać listę wszystkich zatwierdzeń w pobranym foo)

$ git log foo/master

Wybierz zobowiązanie, którego potrzebujesz

$ git cherry-pick 97fedac
Muhammad Soliman
źródło
5

Po scaleniu gałęzi programistycznej do mastera zwykle usuwam gałąź programistyczną. Jeśli jednak chcę wybrać zmiany w gałęzi programistycznej, muszę użyć skrótu zatwierdzenia scalającego, aby uniknąć błędu „złego obiektu”.

Juuso Ohtonen
źródło
3

Najpierw musisz pobrać dane obu gałęzi z dysku lokalnego.

To, co się dzieje, to próba wybrania z gałęzi-a do gałęzi-b, gdzie obecnie znajdujesz się na gałęzi-b, ale lokalna kopia gałęzi-a nie jest jeszcze aktualizowana (musisz wykonać git pull on najpierw obie gałęzie).

kroki:
- git checkout branch-a
- git pull origin branch-a
- git checkout branch-b
- git pull origin branch-b
- git cherry-pick <hash>

dane wyjściowe:
[gałąź-b <hash>] dane dziennika
Autor: Autor <Autor
1 plik zmieniony, 1 wstawienie (+), 3 usunięcia (-)

temyong
źródło
2

Ten błąd został zwrócony po użyciu identyfikatora zatwierdzenia z karty identyfikatora zatwierdzenia żądania ściągnięcia. To zatwierdzenie zostało następnie zgniecione i scalone. W żądaniu ściągnięcia github poszukaj tego tekstu: "scalone zatwierdzenie xxxxxxx w ..." zamiast próbować użyć identyfikatorów zatwierdzeń z zakładki zatwierdzeń.

Mary
źródło
2

Zatwierdzenie powinno być obecne w twoim lokalnym, sprawdź używając git log.

Jeśli nie ma zatwierdzenia, spróbuj git fetchzaktualizować lokalny najnowszym pilotem.

Kuldeep Saxena
źródło
0

Można to również łatwo osiągnąć za pomocą SourceTree:

  • sprawdź swoją główną gałąź
  • otwórz zakładkę „Dziennik / Historia”
  • zlokalizuj zatwierdzenie xyz i kliknij je prawym przyciskiem myszy
  • kliknij „Scal ...”

Gotowe :)

Giona
źródło
To jest niepoprawne. Ponieważ teraz scalasz HEAD mastera w zebrę zamiast tylko wybranych zatwierdzeń.
Chef Pharaoh
0

Jeśli pobrałeś, ale nadal tak się dzieje, przyczyną może być następujący powód.

Może się zdarzyć, że commit, który próbujesz wybrać, nie należy już do żadnej gałęzi. Może się to zdarzyć podczas zmiany bazy.

W takim przypadku w zdalnym repozytorium:

  1. git checkout xxxxx
  2. git checkout -b temp-branch

Następnie w repozytorium ponownie pobierz. Nowa gałąź zostanie pobrana, łącznie z tym zatwierdzeniem.

lulalala
źródło
0

Rozwiązałem ten problem, przechodząc do gałęzi z zatwierdzeniem, które chcę wybrać.

git checkout <branch With Commit To Cherry-Pick>

użyj dziennika, aby znaleźć skrót zatwierdzenia

git log

po znalezieniu skrótu wycinania i wklejania na notatniku. jeśli używasz polecenia, po prostu przewiń w górę, aby uzyskać hash, a następnie pobierz gałąź, w której chcesz umieścić zatwierdzenie.

git checkout < branch I Want To Place My Cherry-Picked-Hash In>

na koniec wywołanie cherry-pick z git (note) -x polega na dołączeniu wiadomości cherry-pick do oryginału. „Podczas nagrywania zatwierdzenia, dołącz wiersz z napisem„ (wybrana wiśnia z zatwierdzenia…) ”do pierwotnego komunikatu o zatwierdzeniu, aby wskazać, z którego zatwierdzenia została wybrana ta zmiana.”

git cherry-pick -x <your hash commit to add to the current branch>
RVscript
źródło