Como você faz com que o git sempre puxe de um ramo específico?

485

Eu não sou um mestre do git, mas trabalho com ele há algum tempo, com vários projetos diferentes. Em cada projeto, eu sempre git clone [repository]e a partir desse ponto, sempre posso git pull, desde que não tenha mudanças marcantes, é claro.

Recentemente, tive que reverter para uma ramificação anterior e fiz isso com git checkout 4f82a29. Quando eu estava novamente pronto para puxar, descobri que tinha que voltar a dominar meu ramo. Agora, não posso puxar usando um straight, git pullmas, em vez disso, tenho que especificar git pull origin master, o que é chato, e indica para mim que não entendo completamente o que está acontecendo.

O que mudou que não me permite fazer uma sequência git pullsem especificar o mestre de origem e como alterá-la novamente?

ATUALIZAR:

-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/*

ATUALIZAÇÃO 2: Para ser claro, entendo que meu método original pode estar incorreto, mas preciso corrigir esse repositório para que possa simplesmente usá-lo git pullnovamente. Atualmente, o git pull resulta em:

-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.

Eu posso dizer git pullqual ramificação mesclar e funciona corretamente, mas git pullnão funciona como antes do meu git checkout.

David Smith
fonte
Como é o seu .git / config? O que você fez depois de verificar o commit?
21713 Ryan Graham
Você fez commits em cima de 4f82a29?
Pat Notz 18/03/09
Pat, eu não fiz nenhum commit em cima disso. Isso está em um servidor e precisamos reverter para uma versão estável para ocultar um bug que criamos. Esse sistema não é para fins de desenvolvimento, então eu simplesmente queria reverter, esperar enquanto consertamos o bug e voltar à versão principal.
David Smith
2
Ryan, atualizei para incluir o .git / config. Após o checkout, não fiz nada. Este computador é um servidor, não para desenvolvimento.
David Smith

Respostas:

731

Abaixo [branch "master"], tente adicionar o seguinte ao arquivo de configuração Git do repositório ( .git/config):

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

Isso diz ao Git 2 coisas:

  1. Quando você está no ramo principal, o controle remoto padrão é a origem.
  2. Ao usar git pullna ramificação principal, sem controle remoto e ramificação especificados, use o controle remoto padrão (origem) e mescle as alterações na ramificação mestre remota.

Mas não sei por que essa configuração foi removida da sua configuração. Você pode ter que seguir as sugestões que outras pessoas postaram também, mas isso pode funcionar (ou ajudar pelo menos).

Se você não quiser editar o arquivo de configuração manualmente, poderá usar a ferramenta de linha de comando:

$ git config branch.master.remote origin
$ git config branch.master.merge refs/heads/master
mipadi
fonte
2
Isso funcionou para mim também, eu havia verificado um projeto no github. Estou executando o OS X 10.4
Sam Barnum
Obrigado muito muito - isso aconteceu comigo em um único projeto desenvolvedor com um repositório de "servidor" e dois computadores (que eu usei para empurrar / puxar frequentemente sem problemas antes da falha), não sei por que, mas a correção trabalhou bem!
Chesterbr #
1
O que você quer dizer com Under [branch "master"]
ianj
3
@ianj: No arquivo de configuração do Git (a partir da raiz do repositório .git/config).
Mipadi
1
@ianj: Na linha de comando, você sempre pode fazer isso $ git config branch.master.remote origin ; git config branch.master.merge refs/heads/master.
Mipadi
139

Se preferir, você pode definir essas opções através da linha de comando (em vez de editar o arquivo de configuração) da seguinte maneira:

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

Ou, se você é como eu, e deseja que esse seja o padrão em todos os seus projetos, incluindo aqueles em que você poderá trabalhar no futuro, adicione-o como uma configuração global:

  $ git config --global branch.master.remote origin
  $ git config --global branch.master.merge refs/heads/master
Cabeça
fonte
12
+1 por conhecer a palavra mágica "refs / heads / master". Eu não tive nenhuma dificuldade para descobrir como definir a variável, mas não tinha absolutamente nenhuma idéia do que configurá-lo para , e as páginas do manual não foram de muita ajuda. Acabei encontrando o lugar certo nos documentos depois de encontrar esta resposta. Para os curiosos: a palavra mágica refere-se a um caminho de arquivo .gitno qual o git parece manter o código hash do mastercommit atual de s.
Mokus
84
git branch --set-upstream master origin/master

Isso adicionará as seguintes informações ao seu configarquivo:

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

Se você tiver branch.autosetuprebase = always, ele também adicionará:

    rebase = true
cmcginty
fonte
1
Acho isso a maneira mais fácil de fazer se comportam git como pediu, especialmente se houver mais ramos, e não apenas à distância (mesmo se você tiver que fazer isso para cada ramo, é uma vez por ramo)
s3v3n
2
Acabei de tentar isso e recebo o erro fatal: Not a valid object name: 'origin/master'.mesmo sendo originum controle remoto válido e masterexistindo, como de costume, nos dois repositórios.
Ken Williams
2
Ken, você precisa fazer "git fetch origin" primeiro para obter os nomes das filiais remotas.
Eric Lee
14
O git mais recente quer que você use git branch --set-upstream-to=origin/master master.
orbeckst
52

Acho que é difícil lembrar o exato git configou git branchargumentos como em mipadi de e Casey de respostas, então eu uso estes 2 comandos para adicionar a referência a montante:

git pull origin master
git push -u origin master

Isso adicionará as mesmas informações ao seu .git / config, mas acho mais fácil lembrar.

Luke Sampson
fonte
1
Concordo. Essa deve ser a melhor resposta mais simples.
Linuxxiaocao 22/09/2015
2
Sua resposta deve incluir o motivo de funcionar e consultar a seção nos documentos que explica o porquê.
vfclists
24

O Git pull combina duas ações - buscar novas confirmações do repositório remoto nas ramificações rastreadas e depois mesclá-las na ramificação atual .

Quando você efetuou o check-out de um commit específico, não possui uma ramificação atual, apenas o HEAD aponta para o último commit que você fez. Portanto git pull, não possui todos os seus parâmetros especificados. Por isso não funcionou.

Com base nas informações atualizadas, o que você está tentando fazer é reverter seu repositório remoto. Se você conhece o commit que introduziu o bug, a maneira mais fácil de lidar com isso é com o git revertqual registra um novo commit que desfaz o commit especificado do buggy:

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

Como é seu servidor que você deseja alterar, assumirei que você não precisa reescrever o histórico para ocultar a confirmação do buggy.

Se o bug foi introduzido em uma consolidação de mesclagem, esse procedimento não funcionará. Consulte Como reverter uma fusão com defeito .

Paulo
fonte
Você está me dando uma ótima educação aqui, o que eu aprecio, mas talvez eu não esteja descrevendo minha situação muito bem, então essa não é uma correspondência exata para o meu fluxo de trabalho. Provavelmente vou postar outra pergunta para resolver isso. Obrigado, Paul! +1 para você, senhor.
David Smith
Acabei de interpretar mal sua situação. Estou feliz que você tenha a resposta que você precisava.
Paul Paul
12

Há também uma maneira de configurar o Git, para que ele sempre puxe e empurre a filial remota equivalente para a filial atualmente com check-out na cópia de trabalho. É chamado de ramo de rastreamento, que o git ready recomenda a configuração por padrão .

Para o próximo repositório acima do diretório de trabalho atual:

git config branch.autosetupmerge true

Para todos os repositórios Git, que não estão configurados de outra forma:

git config --global branch.autosetupmerge true

Tipo de mágica, IMHO, mas isso pode ajudar nos casos em que o ramo específico é sempre o ramo atual .

Quando você branch.autosetupmergedefine truee faz check-out de uma ramificação pela primeira vez, o Git informa sobre o rastreamento da ramificação remota correspondente:

(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'

O Git irá empurrar automaticamente para o ramo correspondente automaticamente:

(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
fonte
10

Não querendo editar meu arquivo de configuração do git, segui as informações no post do @ mipadi e usei:

$ git pull origin master

fonte
13
O objetivo era fazer isso automaticamente, em vez de especificá-lo.
Eric
4

Sua pergunta imediata sobre como fazê-lo funcionar, você precisa fazer o que diz. Especifique o refspec para obter na sua configuração de filial.

[branch "master"]
    merge = refs/heads/master
Ryan Graham
fonte
Isso não deveria ser "refs / heads / master"? De acordo com git-pull (1), este é o nome da ramificação no site remoto que é mesclada por padrão.
Adam Monsen
Sim, você está correto. O repo do qual tirei meu exemplo é um caso especial. Corrigido.
Ryan Graham
0

Só queria adicionar algumas informações que, podemos verificar essas informações se git pullreferem automaticamente a qualquer ramo ou não.

Se você executar o comando, git remote show origin(assumindo a origem como o nome abreviado para remoto), o git mostra essas informações, se existe git pullou não uma referência padrão .

Abaixo está um exemplo de saída. (Extraído da documentação do 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)

Observe a parte em que mostra, Filial local configurada para git pull.

Nesse caso, git pullse referirá agit pull origin master

Inicialmente, se você clonou o repositório, usando o git clone, essas coisas serão resolvidas automaticamente. Mas se você adicionou um controle remoto manualmente usando o git remote add, eles estão ausentes na configuração do git. Se for esse o caso, a parte em que mostra "Ramificação local configurada para 'git pull':" estaria ausente na saída de git remote show origin.

As próximas etapas a seguir, se não houver configuração git pull, já foram explicadas por outras respostas.

dr_dev
fonte