Como verifico se o repositório remoto foi alterado e preciso extrair?
Agora eu uso este script simples:
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
Mas é bastante pesado.
Existe uma maneira melhor? A solução ideal verificaria todas as ramificações remotas e retornaria os nomes das ramificações alteradas e o número de novas confirmações em cada uma.
git fetch -v --dry-run
é o que você precisa.Respostas:
Primeiro uso
git remote update
, para atualizar seus árbitros remotos. Então você pode fazer uma de várias coisas, como:git status -uno
dirá se o ramo que você está rastreando está à frente, atrás ou divergiu. Se não diz nada, o local e o remoto são os mesmos.git show-branch *master
mostrará os commits em todos os ramos cujos nomes terminam em 'master' (por exemplo, master e origin / master ).Se você usar
-v
comgit remote update
(git remote -v update
), poderá ver quais ramificações foram atualizadas, para que você realmente não precise de mais comandos.No entanto, parece que você deseja fazer isso em um script ou programa e acabar com um valor verdadeiro / falso. Nesse caso, existem maneiras de verificar o relacionamento entre o commit HEAD atual e o chefe do ramo que você está rastreando, embora como haja quatro resultados possíveis, você não possa reduzi-lo a uma resposta sim / não. No entanto, se você estiver preparado para fazer um
pull --rebase
procedimento, poderá tratar "o local está atrasado" e "o local está diferente" como "precisa puxar", e os outros dois como "não precisam puxar".Você pode obter o ID de confirmação de qualquer ref usando
git rev-parse <ref>
, para fazer isso para mestre e origem / mestre e compará-los. Se são iguais, os galhos são os mesmos. Se eles são desiguais, você quer saber o que está à frente do outro. Usargit merge-base master origin/master
indica o ancestral comum de ambos os ramos, e se eles não divergiram, será o mesmo que um ou outro. Se você obtiver três IDs diferentes, os ramos divergirão.Para fazer isso corretamente, por exemplo, em um script, você deve poder se referir à ramificação atual e à ramificação remota que está rastreando. A função de configuração do prompt do bash
/etc/bash_completion.d
possui algum código útil para obter nomes de ramificações. No entanto, você provavelmente não precisa obter os nomes. O Git possui algumas regras simples para se referir a ramificações e confirmações (conforme documentado emgit rev-parse --help
). Em particular, você pode usar@
a ramificação atual (supondo que você não esteja em um estado de cabeça desanexada) e@{u}
a ramificação upstream (por exemploorigin/master
). Assim,git merge-base @ @{u}
irá retornar o (hash do) cometer pelo qual o ramo atual e seu divergem montante egit rev-parse @
egit rev-parse @{u}
lhe dará os hashes das duas pontas. Isso pode ser resumido no seguinte script:Nota: as versões mais antigas do git não eram permitidas
@
por si só, então você pode ter que usá-lo@{0}
.A linha
UPSTREAM=${1:-'@{u}'}
permite que você passe opcionalmente uma ramificação upstream explicitamente, caso deseje verificar uma ramificação remota diferente daquela configurada para a ramificação atual. Isso normalmente seria no formato remotename / branchname . Se nenhum parâmetro for fornecido, o valor será padronizado como@{u}
.O script pressupõe que você tenha feito um
git fetch
ougit remote update
primeiro, para atualizar as ramificações de rastreamento. Não criei isso no script porque é mais flexível poder fazer a busca e a comparação como operações separadas, por exemplo, se você deseja comparar sem buscar porque já buscou recentemente.fonte
git status -s -u no
, o que fornece uma saída menor quegit status -u no
.git remote -v update
,. Veja a saída degit remote --help
para uma explicação mais completa.@{u}
funciona com o git 1.8.3.2, mas@
não funciona. No entanto,@
funciona com1.8.5.4
. Moral da história: o git continua melhorando e vale a pena ter a versão mais recente possível.Se você tem um ramo upstream
Se você não tem um ramo upstream
Compare os dois ramos:
Por exemplo:
(Presumo que
origin/master
seja seu ramo de rastreamento remoto)Se algum commit estiver listado na saída acima, você terá as alterações recebidas - você precisará mesclar. Se nenhum commit estiver listado até
git log
lá, não há nada para mesclar.Observe que isso funcionará mesmo se você estiver em um ramo de recurso - que não possui um controle remoto de rastreamento, pois se refere explicitamente ao
origin/master
invés de usar implicitamente o ramo upstream lembrado pelo Git.fonte
git fetch; git log HEAD.. --oneline
pode ser usada se houver uma ramificação remota padrão para a local.git rev-list HEAD...origin/master --count
fornecerá o número total de confirmações "diferentes" entre as duas.Se for para um script, você pode usar:
(Observação: o benefício dessas respostas vs. respostas anteriores é que você não precisa de um comando separado para obter o nome da filial atual. "HEAD" e "@ {u}" (upstream da filial atual) cuidam disso. "git rev-parse --help" para mais detalhes.)
fonte
git rev-parse @{u}
realmente mostrar o mais recente comprometer sem umgit fetch
?==
que significa "se NÃO houver alterações no upstream". Eu costumava!=
verificar "se há alterações do upstream" para o meu aplicativo. Não se esqueça degit fetch
primeiro!@
é curto paraHEAD
btw.@{u}
exgit rev-parse '@{u}'
O comando
listará o cabeçalho atual no controle remoto - você pode compará-lo com um valor anterior ou verificar se possui o SHA no seu repositório local.
fonte
git rev-list HEAD...origin/master --count
fornecerá o número total de confirmações "diferentes" entre as duas.git fetch
ou agit remote update
primeira.git status
também mostra uma contagem, btw...
é "confirma na origem / mestre, subtraindo HEAD" (ou seja, número de confirmações atrasadas). Considerando que,...
é a diferença simétrica (ie frente e para trás)fetch
.Aqui está uma Bash one-liner que compara HEAD do ramo atual comprometer de hash contra a sua filial a montante remoto, não pesada
git fetch
ougit pull --dry-run
operações exigidas:Veja como essa linha um tanto densa é dividida:
$(x)
Bash sintaxe de .git rev-parse --abbrev-ref @{u}
retorna um ref upstream abreviado (por exemploorigin/master
), que é então convertido em campos separados por espaço pelosed
comando canalizado , por exemploorigin master
.git ls-remote
qual retorna a confirmação principal da ramificação remota. Este comando se comunicará com o repositório remoto. O canalizadocut
comando extrai apenas o primeiro campo (o hash de confirmação), removendo a cadeia de referência separada por tabulação.git rev-parse HEAD
retorna o hash de confirmação local.[ a = b ] && x || y
conclui a linha única: esta é uma comparação de string do Bash=
em uma construção de teste[ test ]
, seguida pelas construções and-list e ou list&& true || false
.fonte
Eu sugiro que você vá ver o script https://github.com/badele/gitcheck . Eu codifiquei esse script para fazer check-in em uma passagem em todos os seus repositórios Git e mostra quem não fez o commit e quem não fez push / pull.
Aqui está um exemplo de resultado:
fonte
git mrepo -c
isso exibirá todas as confirmações pendentes.Baseei esta solução nos comentários do @jberger.
fonte
...
parece ser uma parte válida da sua solução.Já existem muitas respostas muito ricas e engenhosas. Para fornecer algum contraste, eu poderia me contentar com uma linha muito simples.
fonte
Eu acho que a melhor maneira de fazer isso seria:
Supondo que você tenha este refspec registrado. Se você clonou o repositório, caso contrário (ou seja, se o repositório foi criado de novo localmente e enviado para o controle remoto), é necessário adicionar o refspec explicitamente.
fonte
O script abaixo funciona perfeitamente.
fonte
Eu faria o caminho sugerido pelo brool. O script de uma linha a seguir pega o SHA1 da sua última versão confirmada e o compara com o da origem remota e extrai as alterações somente se elas diferirem. E é ainda mais leve das soluções baseadas em
git pull
ougit fetch
.fonte
git rev-parse --verify HEAD
git log --pretty=%H ...refs/heads/master^
o SHA1 da sua última versão confirmada e, em seguida, executegit ls-remote origin -h refs/heads/master |cut -f1
o SHA1 da origem remota. Esses dois são comandos git e não têm nada a ver com o bash. O que o bash faz dentro dos colchetes é comparar a saída do primeiro comando com o segundo e, se forem iguais, retornará true e será executadogit pull
.git pull
". Eu sei que estou sendo meticuloso, mas apenas para salvar a confusão de alguém, isso deve ser "e se não for igual". Além disso, por qualquer motivo, o primeiro comando git não funciona para mim. (Estou no git2.4.1
.) Então, estou apenas usandogit log --pretty=%H master | head -n1
. Mas não tenho certeza se é exatamente o mesmo.Se você executar esse script, ele testará se a ramificação atual precisa de
git pull
:É muito conveniente colocá-lo como um pré-commit de gancho do Git para evitar
quando você
commit
antespulling
.Para usar esse código como um gancho, basta copiar / colar o script em
e
fonte
Eu só quero postar isso como um post real, pois é fácil perder isso nos comentários.
A resposta correta e melhor para esta pergunta foi dada por @Jake Berger, Muito obrigado cara, todo mundo precisa disso e todo mundo sente falta disso nos comentários. Portanto, para todos que lutam com isso aqui é a resposta correta, basta usar a saída deste comando para saber se você precisa executar um git pull. se a saída for 0, obviamente não há nada a atualizar.
@stackoverflow, dê a esse cara um sinal. Obrigado @ Jake Berger
fonte
Execute
git fetch (remote)
para atualizar suas referências remotas; ele mostrará as novidades. Então, quando você fizer o checkout de sua filial local, ele mostrará se está atrasado.fonte
git status
isso também será mostrado.git pull --dry-run
, mas acho que é muito pesado para um script cron ser executado a cada minuto.fetch
, não haverá muito mais do que verificar o status. Se você precisar de uma reação muito rápida e leve em atualizações remotas, convém conectar algum tipo de notificação ao repositório remoto.Todas essas sugestões complexas, enquanto a solução é tão curta e fácil:
fonte
git remote update
executado antes de seu código, para receber as últimas origem comprometer informaçõesgit remote update
Não deve acrescentar antes dosgit show
comandos?Aqui está minha versão de um script Bash que verifica todos os repositórios em uma pasta predefinida:
https://gist.github.com/henryiii/5841984
Ele pode diferenciar situações comuns, como puxar necessário e empurrar necessário, e é multithread, para que a busca ocorra ao mesmo tempo. Possui vários comandos, como pull e status.
Coloque um link simbólico (ou o script) em uma pasta no seu caminho e funcione como
git all status
(, etc.). Ele suporta apenas origem / mestre, mas pode ser editado ou combinado com outro método.fonte
listará tudo o que for mencionado em qualquer controle remoto que não esteja no seu repositório. Para capturar alterações remotas de ref nas coisas que você já tinha (por exemplo, redefine para confirmações anteriores), é necessário um pouco mais:
fonte
Talvez isso, se você deseja adicionar uma tarefa como crontab:
fonte
Usando regexp simples:
fonte
Eu uso uma versão de um script com base na resposta de Stephen Haberman:
Supondo que esse script seja chamado
git-fetch-and-rebase
, ele pode ser chamado com um argumento opcionaldirectory name
do repositório Git local para executar a operação. Se o script for chamado sem argumentos, ele assumirá que o diretório atual faça parte do repositório Git.Exemplos:
Está disponível aqui também.
fonte
Depois de ler muitas respostas e várias postagens, e passar meio dia tentando várias permutações, é isso que eu criei.
Se você estiver no Windows, poderá executar este script no Windows usando o Git Bash fornecido pelo Git for Windows (instalação ou portátil).
Este script requer argumentos
O script irá
Se houver uma alteração impressa pelo script, você poderá buscar ou puxar. O script pode não ser eficiente, mas faz o trabalho por mim.
Atualização - 30/10/2015: stderr to dev null para impedir a impressão do URL com a senha no console.
fonte
Para os usuários do Windows que acabam com essa pergunta procurando, modifiquei algumas das respostas em um script do PowerShell. Ajuste conforme necessário, salve em um
.ps1
arquivo e execute sob demanda ou agendado, se desejar.fonte
Como a resposta de Neils me ajudou muito, aqui está uma tradução em Python sem dependências:
hth
fonte
Você também pode encontrar um script Phing que faz isso agora.
Eu precisava de uma solução para atualizar meus ambientes de produção automaticamente e estamos muito felizes graças a este script que estou compartilhando.
O script é escrito em XML e precisa de Phing .
fonte