2013-02-22 18 views
12

Jestem bardzo nowy w git i mam problem z prostą operacją fetch.git fetch, FETCH_HEAD i origin/master

Próbuję pobrać postępy współpracownika z jego repozytorium. Na początku zrobiłem git fetch HEAD, co skłoniło gita do pobrania około 350 MB danych, więc byłem pewien, że coś zrobił. Jednakże, origin/master zakończyło się nadal wskazując na to samo stare zatwierdzenie (aktualnie jest pod nazwą dev, ale ja to nazwieję master - nie ma on master).

Po tym spróbowałem git fetch origin master, ale wydawało się, że nic nie robi, zaktualizowano tylko FETCH_HEAD. Zatwierdziłem zatwierdzenie FETCH_HEAD, aby go nie zgubić, ale nadal chciałbym mieć zaktualizowany oddział zdalny.

Co było nie tak? Nie mam dostępu do zdalnego repozytorium. Czy nadal mogę to naprawić w domu?

+0

jest „pochodzenie” współpracowników repo? –

+1

Uwaga: Od git 1.8.4 (sierpień 2013) nie powinieneś już więcej zaskakiwać: 'git fetch origin master' zaktualizuje' origin/master'! Zobacz [moja odpowiedź poniżej] (http://stackoverflow.com/a/20967347/6309) – VonC

+1

Powiązane: [Co oznacza FETCH_HEAD w Git?] (Http://stackoverflow.com/q/9237348/55075) w SO – kenorb

Odpowiedz

13

Jestem nieco zdezorientowany przez polecenia, których używasz. HEAD jest zwykle git etykiety używa do śledzenia commit, który jest obecnie w katalogu roboczym. Komenda git fetch oczekuje, że zdalna konfiguracja będzie zdalna, aby wiedzieć, co ma zostać pobrane. Zastosowanie git fetch HEAD może oznaczać, że HEAD jest zdalnym w twoim repozytorium. To, że polecenie działało bez błędu, jest ciekawe.

Na przykład: Wyniki git fetch HEAD w repozytorium Obecnie pracuję w następującym błędem

fatal: 'HEAD' does not appear to be a git repository 
fatal: Could not read from remote repository. 

Please make sure you have the correct access rights 
and the repository exists. 

Komenda git remote będzie wymienić wszystkie piloty, natomiast git remote --verbose będzie zawierać adres pilocie. Czy możesz tego użyć, aby sprawdzić, czy zdalny zdefiniowany jako HEAD i jaki zdalny adresuje repozytorium znajomych?

Jednak moje pytania pomijają i pomagają wyjaśnić swoje zamieszanie. Polecenie git fetch ... aktualizuje tylko zdalne odwołania - nie lokalne.

Aby było to jasne, zajrzyj do folderu .git w repozytorium (domyślnie jest on ukryty, więc może być konieczne jego odkrycie).Znajdziesz tu strukturę folderów podobną do poniższej

working directory 
|=>.git 
| |=>objects   <= contains data for each commit 
| |=>refs 
|  |=>heads 
|  |-master  <= file containing current commit of local master branch 
|  |=>remotes 
|  |=>origin 
|   |-master <= file containing current commit of remote origin's master branch 
|-FETCH_HEAD   <= file updated by `git fetch`, contains info of what was fetched 

Say kasy oddziału głównego, git checkout master - git zmieni swój katalog roboczy, aby dopasować dane zobowiązują się w folderze „przedmiotów”, który pasuje do popełnienia wartość w plik ".git/refs/heads/master".

Jeśli następnie git fetch origin master, plik ".git/refs/remote/origin/master" jest aktualizowany do zatwierdzenia gałęzi głównej na zdalnym miejscu pochodzenia - i wszystkie dane zatwierdzenia potrzebne do pobrania są pobierane i umieszczane w folderze "obiekty".

Ważną kwestią jest tutaj git fetch nie aktualizuje twojego katalogu roboczego odzwierciedla lokalnego oddziału wyrejestrowanego i git fetch nigdy nie aktualizuje lokalnego oddziału.

Używanie albo git merge ... lub git rebase ... jest potrzebne do aktualizacji lokalnego oddziału master ze zmianami w origin/master. git pull ... wykonuje zarówno git fetch ..., jak i git merge ... lub git rebase ..., w zależności od opcji i konfiguracji (domyślnie jest to git merge ...).

Po tym wyjaśnieniu, chcesz mieć możliwość sprawdzenia, co - jeśli coś - zostało pobrane z repozytorium znajomych. Polecenie git branch -avv wyświetli wszystkie lokalne i zdalne gałęzie, z numerami zatwierdzeń, aw przypadku oddziałów lokalnych, jaką zdalną gałąź będzie śledzić.

Aby zobaczyć, jak gałęzie są ze sobą powiązane, pomocne jest narzędzie do wykreślania drzewa repozytoriów. Jest kilka do wyboru, ale uważam, że wystarczające jest polecenie git log; takie jak git log --all --graph --oneline --decorate. Uczciwe ostrzeżenie, może być dość długie i skomplikowane dla dużego repozytorium. Krótsze wyjście można uzyskać przez dodanie argumentu --simplify-by-decoration.

Podsumowując: jeśli możesz to naprawić w domu, zależy to od informacji w twoim repozytorium. Powyższe polecenia; git remote --verbose, git branch -avv i git log ... powinny dać ci zrozumienie obecnego stanu twojego repozytorium. Stamtąd możesz ustalić, czy potrzebujesz czegoś więcej, aby uzyskać dane w lokalnych oddziałach, używając git merge lub git rebase.

Jak zawsze, jeśli wpadniesz w kłopoty, opublikuj to, czego się nauczysz.

+0

Masz rację. To, co faktycznie zrobiłem, to GIT przywiezione z HEAD. Zrobiłem to, ponieważ nie wiedziałem, czy aktualizował swoją master branch, więc myślałem, że HEAD będzie odnosił się do jakiejkolwiek gałęzi, nad którą pracował. Nadal nie wyśledziłem problemu, ale dziękuję za pomoc. – DanielF

+1

upomina się o błyskotliwą dbałość o szczegóły. "Git pull ... robi zarówno git fetch ... jak i git merge ... lub git rebase ..., w zależności od opcji i konfiguracji (git merge ... jest domyślnie). " – hAcKnRoCk

3

git fetch tak naprawdę nie dotyka Twojej pracy reż. Pobiera tylko najnowsze zmiany z pilotów. Aby zaktualizować aktualny stan, użyj git merge lub git rebase. Możesz również użyć git pull, który działa jak skrót do git fetch + git merge.

Główna różnica między scalaniem a rebase polega na tym, że w niektórych przypadkach scalenie spowoduje utworzenie nowego zatwierdzenia, z zakumulowanym stanem (bez szybkiego przewijania do przodu). IMHO to jest złe, co przypomina mi czasy, w których używałem SVN. Rebase po prostu odtwarza twoje zmiany u góry określonego zatwierdzenia, więc twoja historia jest zawsze liniowa. Tylko pamiętaj, aby użyć tego samego przepływu, co Twoi współpracownicy.

Proponuję przeczytać kilka rzeczy o git w ogóle, a git przepływu: a must-read book i a good article.

1

Co chcesz zrobić, to:

  • Dodaj pilota dla współpracownika
  • Fetch zmiany z jego repozytorium
  • Tworzenie lokalnego oddziału, który odnosi się do swego odległego oddziału

Prawdopodobnie wykonałeś już krok nr 1. Ale pod względem kompletności, to:

git remote add coworker git://path/to/coworkers/repo.git

gdzie URL może być w dowolnym formacie, który obsługuje URL git.

Teraz, gdy pilot dodaje, chcesz sprowadzić jego zmiany:

git fetch coworker

To daje zdalnych oddziałów dla każdego ze swoich oddziałów. Powiedzmy, że jego oddział nazywa się "chomik". Teraz, w celu wykonania pracy, stworzyć własną lokalną kopię zdalnego oddziału

git checkout -b hamster coworker/hamster

Tworzy i przełączy Cię na oddział zwany chomikiem.

Od tego momentu, można wykonać pracę na chomika i przesunąć go do niego z

git push coworker hamster

po raz pierwszy, a potem po prostu git push po tym.

Anytime chcesz ciągnąć w dół i scalić swoje zmiany, można zrobić:

git pull

8

Od git 1.8.4 (sierpień 2013), git fetch zaktualizuje zdalnego oddział śledzenia! Nie tylko FETCH_HEAD.

Zobacz commit f269048 z Jeff King (peff):

Kiedy prowadzimy regularne „git fetch” bez argumentów, możemy zaktualizować bibl śledzenia według skonfigurowanego refspec.
Jednak, gdy uruchomimy "git fetch origin master" (lub "git pull origin master"), nie patrzymy na skonfigurowane refspecs w ogóle, i po prostu aktualizujemy FETCH_HEAD.

Tęsknimy za możliwością aktualizacji "refs/remotes/origin/master" (lub cokolwiek innego, co skonfigurował użytkownik). Niektórzy uważają to mylące, ponieważ chcą zrobić dalszych porównań w stosunku do starego stanu zdalnego pana, jak:

$ git pull origin master 
$ git log HEAD...origin/master 
+1

Git 1.9/2.0 (Q1 2014): 'git push' ma symetryczne zachowanie: https://github.com/git/git/commit/ca02465b41311fe7634acb9bb5b5c61975ef5f38 – VonC