Usando o Git, como encontro alterações entre local e remoto

152

Aqui estão duas perguntas diferentes, mas acho que elas estão relacionadas.

  1. Ao usar o Git, como localizo quais alterações foram confirmadas localmente, mas ainda não foram enviadas para uma ramificação remota? Estou procurando algo semelhante ao comando Mercurial hg outgoing.

  2. Ao usar o Git, como encontro as alterações que uma ramificação remota tem antes de fazer um pull? Estou procurando algo semelhante ao comando Mercurial hg incoming.

Para o segundo: existe uma maneira de ver o que está disponível e depois escolher as mudanças que eu quero fazer?

ejunker
fonte
11
Olhando para as respostas, parece haver alguma confusão sobre o que hg incominge hg outgoingrealmente fazer. O equivalente mais próximo ao Git que encontrei é a --dry-runopção. Apenas git pull --dry-rune você verá uma lista de todas as coisas que precisam acontecer.
Roman Starkov

Respostas:

97

O Git não pode enviar esse tipo de informação pela rede, como o Hg pode. Mas você pode executar git fetch(o que é mais do hg pullque isso hg fetch) para buscar novas confirmações nos seus servidores remotos.

Portanto, se você tiver uma ramificação chamada mastere um remoto chamado origin, após a execução git fetch, também deverá ter uma ramificação chamada origin/master. Você pode obter git logtodos os commits que masterprecisam ser um superconjunto origin/masterfazendo git log master..origin/master. Inverta esses dois para obter o oposto.

Um amigo meu, David Dollar, criou alguns scripts git shell para simular hg incoming/outgoing. Você pode encontrá-los em http://github.com/ddollar/git-utils .

Jordi Bunster
fonte
113

A partir do Git 1.7.0, existe uma sintaxe especial que permite que você consulte genericamente a ramificação upstream: @{u}ou @{upstream}.

Para imitar hg incoming:

git log ..@{u}

Para imitar hg outgoing:

git log @{u}..

Eu uso o seguinte incominge os outgoingaliases para facilitar o uso acima:

git config --global alias.incoming '!git remote update -p; git log ..@{u}'
git config --global alias.outgoing 'log @{u}..'
Richard Hansen
fonte
git log .. @ {u} me fornece esses erros. (Eu tenho origem e um repositório upstream na minha configuração do git). erro: nenhum ramo upstream encontrado para '' erro: nenhum ramo upstream encontrado para '..' erro: nenhum ramo upstream encontrado para '..' fatal: argumento ambíguo '.. @ {u}': revisão desconhecida ou caminho ausente a árvore de trabalho. Use '-' para caminhos separados de revisões
Henrik
6
Você receberá esses erros se sua filial local não estiver configurada com uma fonte. Para corrigir, execute git branch --set-upstream foo origin/foo.
Richard Hansen
git log @{u}..lista todas as alterações no repositório para mim. Não há como eles ainda não existirem.
Roman Starkov
@romkyns: é possível que sua filial local tenha a filial remota errada configurada como upstream. Verifique se git rev-parse --symbolic-full-name @{u}imprime a referência remota apropriada. Além disso, git log @{u}..mostra as confirmações que não são acessíveis pela ramificação upstream, que podem incluir confirmações que já estão no repositório remoto (se elas puderem ser acessadas por uma referência diferente). Isso acontecerá logo após a mesclagem em uma ramificação já enviada.
Richard Hansen
@RichardHansen Acho que sou noob demais para saber o que seria apropriado para uma referência remota, no entanto, esse foi um repo recém-clonado no qual eu fiz apenas um checkout <somebranch>e merge <otherbranch>. Neste ponto, eu fiz log @{u}..e vi todas as alterações listadas.
Roman Starkov
42

Não é uma resposta completa, mas o git fetch puxará o repositório remoto e não fará uma mesclagem. Você pode então fazer uma

origem / mestre do mestre do diff do git

Martin Redmond
fonte
1
Trabalhou para mim (mas outra em torno de modo) -git diff origin/master master
Nick Grealy
34
  1. Use "origem do log git .. HEAD"

  2. Use "git fetch" seguido de "git log HEAD..origin". Você pode escolher confirmações individuais usando os IDs de confirmação listados.

O exposto acima pressupõe, é claro, que "origem" é o nome da sua ramificação de rastreamento remoto (que é se você usou o clone com opções padrão).

Greg Hewgill
fonte
3
(E se você não está acompanhando a filial remota, é “origem git log / master..HEAD”.)
PLindberg
4
"origem" não é o nome do ramo de rastreamento remoto, é o nome do controle remoto. E apenas especificar o nome remoto não funciona, você deve especificar a ramificação de rastreamento remoto, que seria origem / mestre.
robinst
22

Há também isso, para comparar todos os ramos:

git log --branches --not --remotes=origin

Isto é o que a página de manual do git log diz sobre isso:

Mostra todas as confirmações que estão em qualquer uma das ramificações locais, mas não em nenhuma das ramificações de rastreamento remoto de origem (o que você tem nessa origem não).

O acima é para outgoing. Para incoming, apenas troque:

git log --remotes=origin --not --branches
robinst
fonte
8

eu faria

$ git fetch --dry-run

para hg incominge

$ git push --dry-run

para hg outgoing.

chris
fonte
Desculpe, eu esqueci que isso já foi dito como um comentário ao OP.
21414 chris
1

O git-out é um script que simula com hg outgoingbastante precisão. Ele analisa a saída "push-n" e, portanto, produz uma saída precisa se você precisar especificar argumentos adicionais a serem enviados.

stepancheg
fonte
0

git de entrada

$ git fetch && git log ..origin/master --stat
OR
$ git fetch && git log ..origin/master --patch

git de saída

$ git fetch && git log origin/master.. --stat
OR
$ git fetch && git log origin/master.. --patch
prayagupd
fonte
0

Quando as respostas "git log" e @ {u} inicialmente me deram erros de "revisão desconhecida", experimentei a sugestão de Chris / romkyns de git push --dry-run .

Você obterá uma saída como "5905..4878 master-> master". 5905 é a confirmação mais recente que o controle remoto tem e confirma através (e incluindo) 4878 será aplicada ao controle remoto.

Você pode usar 5905..4878 como argumentos para vários outros comandos git para obter mais detalhes:

git diff 5905..4878 # Gives full code changes in diff style

git log --online 5905..4878 # Displays each commit's comment
pierce.jason
fonte
-1

Quando você faz o git fetch, todo o conteúdo, incluindo branches, tags (refs), é armazenado temporariamente em .git / FETCH_HEAD, cujo conteúdo pode ser visualizado com o comando: git log FETCH_HEAD Se você não usar o sufixo -a com o git fetch, por padrão , O conteúdo de FETCH_HEAD será substituído por novos conteúdos. A partir desses conteúdos, é possível visualizar e decidir em qual ramificação você deseja mesclá-los, se desejar, ou você pode escolher facilmente se deseja apenas algumas confirmações do que foi trazido pela busca.

AMIT PRAKASH PANDEY
fonte