Jak sprawić, by git zawsze pobierał z określonej gałęzi?

485

Nie jestem mistrzem git, ale pracuję z nim już od jakiegoś czasu przy kilku różnych projektach. W każdym projekcie zawsze git clone [repository]i od tego momentu zawsze mogę git pull, o ile oczywiście nie mam wybitnych zmian.

Ostatnio musiałem wrócić do poprzedniej gałęzi i zrobiłem to z git checkout 4f82a29. Kiedy znów byłem gotowy do ciągnięcia, odkryłem, że musiałem przywrócić gałąź do opanowania. Teraz nie mogę ciągnąć za pomocą prostej, git pullale zamiast tego muszę określić git pull origin master, co jest denerwujące i wskazuje mi, że nie do końca rozumiem, co się dzieje.

Co się zmieniło, co nie pozwala mi zrobić strita git pullbez podania wzorca początkowego i jak go zmienić z powrotem?

AKTUALIZACJA:

-bash-3.1$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[branch "master"]
[remote "origin"]
    url = [email protected]:user/project.git
    fetch = refs/heads/*:refs/remotes/origin/*

AKTUALIZACJA 2: Żeby było jasne, rozumiem, że moja oryginalna metoda mogła być niepoprawna, ale muszę naprawić to repozytorium, aby móc git pullponownie użyć . Obecnie git pull powoduje:

-bash-3.1$ git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me either.  Please
name which branch you want to merge on the command line and
try again (e.g. 'git pull  ').
See git-pull(1) for details on the refspec.

If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:

    branch.master.remote = 
    branch.master.merge = 
    remote..url = 
    remote..fetch = 

See git-config(1) for details.

Mogę powiedzieć, git pullktóra gałąź ma zostać scalona i działa poprawnie, ale git pullnie działa tak, jak pierwotnie przed moim git checkout.

David Smith
źródło
Jak wygląda Twój .git / config? Co zrobiłeś po sprawdzeniu tego zatwierdzenia?
Ryan Graham
Czy zrobiłeś commits na podstawie 4f82a29?
Pat Notz
Pat, nie popełniłem żadnych zobowiązań. To jest na serwerze i musieliśmy przywrócić stabilną wersję, aby ukryć błąd, który stworzyliśmy. Ten system nie jest przeznaczony do celów programistycznych, więc po prostu chciałem wycofać, poczekać, aż naprawimy błąd, a następnie cofnąć się do wersji głównej.
David Smith
2
Ryan, zaktualizowałem, aby uwzględnić .git / config. Po kasie nic nie zrobiłem. Ten komputer jest serwerem, a nie do programowania.
David Smith

Odpowiedzi:

730

Poniżej [branch "master"]spróbuj dodać następujące elementy do pliku konfiguracyjnego Git repozytorium ( .git/config):

[branch "master"]
    remote = origin
    merge = refs/heads/master

To mówi Gitowi 2 rzeczy:

  1. Gdy jesteś w gałęzi master, domyślnym pilotem jest origin.
  2. Podczas korzystania git pullz gałęzi głównej, bez określenia zdalnego i gałęzi, użyj domyślnego zdalnego (źródła) i scal zmiany w zdalnej gałęzi głównej.

Nie jestem jednak pewien, dlaczego ta konfiguracja zostałaby usunięta z twojej konfiguracji. Być może będziesz musiał postępować zgodnie z sugestiami opublikowanymi przez inne osoby, ale może to zadziałać (lub przynajmniej pomóc).

Jeśli nie chcesz ręcznie edytować pliku konfiguracyjnego, możesz zamiast tego użyć narzędzia wiersza polecenia:

$ git config branch.master.remote origin
$ git config branch.master.merge refs/heads/master
mipadi
źródło
2
To również zadziałało, sprawdziłem projekt z github. Używam OS X 10.4
Sam Barnum
Dziękuję bardzo - przydarzyło mi się to w jednym projekcie deweloperskim z jednym repozytorium „serwerowym” i dwoma komputerami (których często używałem do wypychania / ciągnięcia bez problemów przed usterką), nie wiem dlaczego, ale poprawka zadziałała w porządku!
chesterbr
1
Co rozumiesz przez Under [oddział „master”]
ianj
3
@ianj: W pliku konfiguracyjnym Git (z katalogu głównego repo .git/config).
mipadi
1
@ianj: W wierszu poleceń zawsze możesz to zrobić $ git config branch.master.remote origin ; git config branch.master.merge refs/heads/master.
mipadi
139

Jeśli wolisz, możesz ustawić te opcje za pomocą wiersza polecenia (zamiast edytować plik konfiguracyjny) w następujący sposób:

  $ git config branch.master.remote origin
  $ git config branch.master.merge refs/heads/master

Lub, jeśli jesteś podobny do mnie i chcesz, aby był domyślny we wszystkich swoich projektach, w tym nad tymi, nad którymi możesz pracować w przyszłości, dodaj go jako globalne ustawienie konfiguracji:

  $ git config --global branch.master.remote origin
  $ git config --global branch.master.merge refs/heads/master
Głowa
źródło
12
+1 za znajomość magicznego słowa „refs / heads / master”. Nie miałem problemy ze zorientowaniem się, jak ustawić zmienną, ale nie miał żadnego pojęcia co ustawić go do , a stron nie były zbyt pomocne. W końcu znalazłem właściwe miejsce w dokumentacji po znalezieniu tej odpowiedzi. Dla ciekawskich: magiczne słowo odnosi się do ścieżki pliku, .gitw której wydaje się, że git zachowuje kod skrótu masterbieżącego zatwierdzenia.
mokus
84
git branch --set-upstream master origin/master

Spowoduje to dodanie następujących informacji do configpliku:

[branch "master"]
    remote = origin
    merge = refs/heads/master

Jeśli tak, branch.autosetuprebase = alwaysto doda również:

    rebase = true
cmcginty
źródło
1
Uważam, że jest to najłatwiejszy sposób, aby git zachowywał się tak, jak pytano, szczególnie jeśli jest więcej gałęzi, nie tylko zdalnych (nawet jeśli musisz to zrobić dla każdej gałęzi, jest to jeden raz na gałąź)
s3v3n
2
Właśnie próbowałem tego i otrzymuję błąd, fatal: Not a valid object name: 'origin/master'.mimo że originjest prawidłowym pilotem i masteristnieje, jak zwykle, w obu repozytoriach.
Ken Williams,
2
Ken, musisz najpierw wykonać „git fetch origin”, aby uzyskać nazwy oddziałów zdalnych.
Eric Lee,
14
Nowszy git chce, żebyś używał git branch --set-upstream-to=origin/master master.
orbeckst
52

Trudno mi zapamiętać dokładne git configlub git branchargumenty jak w odpowiedziach mipadi i Casey, więc używam tych 2 poleceń, aby dodać referencję:

git pull origin master
git push -u origin master

Spowoduje to dodanie tych samych informacji do Twojego .git / config, ale łatwiej mi je zapamiętać.

Luke Sampson
źródło
1
Zgadzam się. To powinna być najprostsza odpowiedź.
linbianxiaocao
2
Twoja odpowiedź powinna zawierać wyjaśnienie, dlaczego to działa, i odnieść się do rozdziału w dokumentacji, który wyjaśnia dlaczego.
vfclists
24

Git pull łączy dwie akcje - pobieranie nowych zatwierdzeń ze zdalnego repozytorium w śledzonych gałęziach, a następnie scalanie ich w bieżącą gałąź .

Po sprawdzeniu konkretnego zatwierdzenia nie masz bieżącej gałęzi, tylko HEAD wskazuje na ostatnie dokonane zatwierdzenie. Nie git pullma więc określonych wszystkich parametrów. Dlatego to nie zadziałało.

Na podstawie zaktualizowanych informacji próbujesz cofnąć zdalne repozytorium. Jeśli znasz zatwierdzenie, które wprowadziło błąd, najłatwiejszym sposobem na poradzenie sobie z tym jest git revertzapisanie nowego zatwierdzenia, które anuluje określony zatwierdzony błąd:

$ git checkout master
$ git reflog            #to find the SHA1 of buggy commit, say  b12345
$ git revert b12345
$ git pull
$ git push

Ponieważ to twój serwer chcesz zmienić, założę, że nie musisz przepisywać historii, aby ukryć zatwierdzone błędy.

Jeśli błąd został wprowadzony w zatwierdzeniu scalania, ta procedura nie będzie działać. Zobacz: Jak przywrócić wadliwe scalenie .

Paweł
źródło
Dajesz mi tutaj świetne wykształcenie, co doceniam, ale być może nie opisuję zbyt dobrze mojej sytuacji, więc nie jest to dokładnie zgodne z moim tokiem pracy. Prawdopodobnie opublikuję kolejne pytanie, aby rozwiązać ten problem. Dzięki, Paul! +1 dla ciebie, Sir.
David Smith
Po prostu źle odczytałem twoją sytuację. Cieszę się, że masz odpowiedź, której potrzebujesz.
Paul
12

Istnieje również sposób skonfigurowania Git, aby zawsze pobierał i wypychał równoważną gałąź zdalną do gałęzi aktualnie pobranej do kopii roboczej. Nazywa się to gałęzią śledzenia, która git ready zaleca ustawienie domyślne .

Dla następnego repozytorium powyżej obecnego katalogu roboczego:

git config branch.autosetupmerge true

Dla wszystkich repozytoriów Git, które nie są skonfigurowane inaczej:

git config --global branch.autosetupmerge true

Niby magia, IMHO, ale może to pomóc w przypadkach, gdy konkretna gałąź jest zawsze bieżącą gałęzią .

Po pierwszym branch.autosetupmergeustawieniu truei sprawdzeniu oddziału Git powie Ci o śledzeniu odpowiedniego oddziału zdalnego:

(master)$ git checkout gh-pages
Branch gh-pages set up to track remote branch gh-pages from origin.
Switched to a new branch 'gh-pages'

Następnie Git automatycznie prześle do odpowiedniej gałęzi:

(gh-pages)$ git push
Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 1003 bytes, done.
Total 6 (delta 2), reused 0 (delta 0)
To [email protected]:bigben87/webbit.git
   1bf578c..268fb60  gh-pages -> gh-pages
Bengt
źródło
10

Nie chcąc edytować mojego pliku konfiguracyjnego git, podążyłem za informacjami w poście @ mipadi i użyłem:

$ git pull origin master

źródło
13
Chodziło o to, aby zrobić to automatycznie, zamiast go określać.
Eric
4

Twoje natychmiastowe pytanie, jak sprawić, by przyciągnęło mistrza, musisz zrobić, co mówi. Określ refspec, z którego chcesz pobierać w konfiguracji oddziału.

[branch "master"]
    merge = refs/heads/master
Ryan Graham
źródło
Czy nie powinno to być „refs / heads / master”? Według git-pull (1) jest to nazwa oddziału w zdalnej witrynie, która jest domyślnie scalona.
Adam Monsen,
Tak, masz rację. Repo, z którego wziąłem swój przykład, jest szczególnym przypadkiem. Poprawione
Ryan Graham
0

Chciałem tylko dodać kilka informacji, które możemy sprawdzić, czy git pullautomatycznie odnosi się do dowolnego oddziału, czy nie.

Jeśli uruchomisz polecenie, git remote show origin(zakładając, że źródłem jest nazwa zdalna), git wyświetli tę informację, niezależnie od tego, czy istnieje jakieś domyślne odniesienie git pull.

Poniżej znajduje się przykładowy wynik (pochodzi z dokumentacji git).

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Zwróć uwagę na część, w której to pokazuje, gałąź lokalna skonfigurowana dla git pull.

W takim przypadku git pullbędzie się odnosić dogit pull origin master

Początkowo, jeśli sklonowałeś repozytorium, używając git clone, te rzeczy są automatycznie załatwiane. Ale jeśli dodałeś zdalnie ręcznie za pomocą zdalnego dodawania git, brakuje ich w konfiguracji git. W takim przypadku brakowałby fragmentu, w którym wyświetla się „Lokalna gałąź skonfigurowana dla„ git pull ”:” git remote show origin.

Kolejne kroki, które należy wykonać, jeśli nie istnieje konfiguracja git pull, zostały już wyjaśnione innymi odpowiedziami.

dr_dev
źródło