5 pontos por GN⁺ 2024-02-14 | 1 comentários | Compartilhar no WhatsApp
  • Mesmo usuários que usam Git há muito tempo podem deixar passar muitos recursos menos conhecidos, o que coloca em dúvida a premissa de que conhecimentos avançados de linha de comando se tornaram comuns
  • Diferentemente da geração que migrou de SVN e CVS, desenvolvedores que só usaram Git tiveram menos oportunidades de aprender alguns usos avançados
  • Com o tempo, o Git continuou adicionando recursos pequenos, mas úteis, e essas mudanças podem ter valor prático em situações específicas
  • Para usuários intermediários a avançados, recursos antigos mas úteis, recursos adicionados recentemente e temas de grandes repositórios e monorepos são divididos em uma série curta de 3 partes
  • Ao revisitar recursos que não aparecem apenas com hábitos familiares de uso do Git, é possível lidar com tarefas cotidianas em repositórios de forma mais eficiente

Por que revisitar o Git

  • Em apresentações recentes sobre Git e GitButler, ficou claro que muitos desenvolvedores têm muitas lacunas de conhecimento sobre Git
  • No passado, eram feitas apresentações avançadas sobre Git, mas nos últimos cerca de 10 anos partiu-se do pressuposto de que as pessoas já conheciam recursos avançados de linha de comando
  • A geração de desenvolvedores que só usou Git não teve a experiência de migrar de ferramentas como SVN e CVS para Git, nem de reaprender conceitos anteriores
  • O Git também aprendeu novos recursos ao longo do tempo, e embora a maioria sejam mudanças sutis ou voltadas a usos específicos, elas podem ajudar no trabalho real
  • A série de posts foi estruturada com base na apresentação da FOSDEM 2024 little known Git stuff

Série de dicas de Git em 3 partes

  • O público-alvo são usuários intermediários a avançados de Git, e a série aborda recursos que mesmo quem usa Git há muito tempo pode ter deixado passar
  • Em vez de reunir tudo em um único texto, a série é composta por 3 posts curtos, divididos em alguns temas
  • Temas incluídos:
  • O primeiro post continua em Oldies but Goodies

1 comentários

 
GN⁺ 2024-02-14
Comentários do Hacker News
  • Como autor, admito que aprendi uma boa parte disso só bem recentemente. Os recursos para repositórios grandes são coisas que Microsoft e GitHub vêm adicionando aos poucos ao core do Git nos últimos anos, então é difícil encontrar um material que reúna em um só lugar o que eles fizeram
    Também tive conversas interessantes com o pessoal do Mercurial, e eles dizem que recentemente obtiveram melhorias surpreendentes de velocidade ao escrever partes internas do Hg em Rust
    Também estou pensando em uma 3ª edição do Pro Git, então, se houver coisas que vocês aprenderam sobre Git do jeito difícil ou que gostariam de saber, me avisem
    • Você talvez já conheça, mas difftastic é ótimo para usar no lugar do diff do Git: https://difftastic.wilfred.me.uk/
      Como aliases frequentes no gitconfig, uso fza, gone e root. git fza mostra arquivos modificados/novos em uma janela do fzf e passa o arquivo selecionado para git add: https://github.com/junegunn/fzf
      git gone apaga branches locais que não existem no remoto, e git root imprime a raiz do repositório, o que é útil para voltar à raiz a partir de um diretório profundo. Hoje em dia uso menos isso porque uso zoxide: https://github.com/ajeetdsouza/zoxide
    • Na parte sobre diferenças de espaço em branco, seria bom incluir também o ignore-revs-file. Você deixa um arquivo de ignore-revs commitado no repositório, e quem fizer uma grande reformatação adiciona esse SHA para que o git blame não fique quebrado
      https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revltrevgt
    • Uma das coisas que aprendi sobre Git do jeito difícil é que operações como merge, cherry-pick e rebase funcionam com diferenças e patches — mais precisamente, com merge de três vias — e não com snapshots. O Pro Git enfatiza bem o modelo de armazenamento por snapshots do Git, mas, se você pensar só nesse modelo, pode acabar se confundindo, especialmente no rebase
      Por exemplo, eu não entendia por que, durante um rebase, apenas remover um commit fazia todos os commits seguintes mudarem. Só fui entender rebase depois de perceber que o armazenamento é baseado em snapshots, mas as operações são baseadas em diferenças; enfatizar mais isso no ensino também ajudaria
  • Não quero aprender truques de Git; quero usá-lo do jeito mais simples possível. Só quero dar push no código, encerrar a parte do Git e continuar trabalhando
    Respeito quem gosta de Git, mas para mim é só uma ferramenta que preciso usar
    • Parte da complexidade do Git vem do fato de ele ter sido originalmente projetado como um encanamento de baixo nível (plumbing). A expectativa era que uma camada mais amigável para usuários finais (porcelain) fosse construída sobre o modelo de dados do Git, então, se você quer uma UI simples e consistente, talvez esse ainda seja o melhor caminho. Jujutsu e Got (game of trees) podem ser exemplos disso
    • Entendo esse sentimento, mas o Git não é tão difícil assim. Além do básico de checkout/commit/push, aprender algumas coisas — especialmente reescrita de histórico — melhora muito a qualidade do histórico de commits e facilita para os outros engenheiros do projeto entenderem o fluxo
      O Git parece ser quase uma constante duradoura da indústria e é uma das ferramentas com que você mais interage no desenvolvimento diário, então vale a pena olhar um pouco mais a fundo
    • Há detalhes inerentes ao próprio problema e outros que não são. Acho que existe uma tendência a subestimar a dificuldade inerente
      Por isso, acho aceitável que o Git tenha um certo nível de complexidade
    • Parece semelhante a dizer que você não quer aprender programação e quer usar o computador do jeito mais simples possível. Algo como só dizer o que quer fazer e pronto
    • A interface do Git parece uma abstração vazando. Eu não queria aprender truques de Git, mas acabei entendendo bem mais do que queria
  • Acabei de aprender sobre core.fsmonitor. Do ponto de vista de monorepos grandes, eu gostaria que git clone tivesse uma opção de continuar um download interrompido
    Nos anos 2000, tentei clonar o repositório do kernel em uma conexão de baixa largura de banda e tive o mesmo problema; só consegui baixar depois de pedir ajuda na mailing list e alguém colocar o repositório completo em um tar compactado em um site pessoal
    Ainda hoje, se a VPN da empresa cai por um instante, às vezes acontece o mesmo com clones de repositórios grandes. Imagine baixar 95% de um repositório de 300 GB do Windows e o Wi‑Fi cair por um momento
    É estranho que Git e Docker, duas das maiores consumidoras de largura de banda no stack moderno de desenvolvimento, não suportem direito a retomada de downloads
    • O que você quer parece mais próximo de git bundle. Só que isso depende de alguém criar o bundle antes de tudo
      https://git-scm.com/docs/git-bundle
    • Talvez dê para fazer com um clone raso e ir expandindo várias vezes. Ainda assim, o protocolo de fetch/push basicamente assume repositórios menores, ou uma conexão de internet e servidores muito bons
  • Muito interessante. Quero ver quem consegue resolver com uma interface mais simples o problema de várias pessoas contribuírem para diferentes releases, recursos e hotfixes, colocarem tags nas releases e voltarem ao passado para encontrar bugs
    É parecido com querer uma linguagem de baixo nível que esconda a complexidade do sistema; as duas coisas são praticamente excludentes. O Git é satisfatório e não é tão difícil de aprender, então, em parte, as pessoas simplesmente precisam aprender Git
    • É por isso que acabo recomendando fortemente o GitKraken. Falo com cuidado porque é um produto pago, mas já usei várias ferramentas e nada foi tão bom em liberar esse poder quanto o GitKraken
      Ele remove essa sensação de caixa-preta que muitos desenvolvedores têm no terminal e coloca o grafo em destaque, além de mostrar visualmente o trabalho de rebase de um jeito natural, o que torna o Git divertido
      Proficiência em CLI ainda tem valor, mas é frustrante ver desenvolvedores com 10 anos de experiência se enrolando para resolver problemas básicos ou estragando o histórico do projeto por causa daquele clima de que “engenheiros de verdade só usam Git pela CLI”
      Hoje em dia, mesmo quando digo para usar a CLI, também digo para manter o grafo aberto o dia todo em outra janela. Dá para fazer isso de graça no VS Code, JetBrains e até na CLI

Quando alguém da equipe faz merge de um PR, eu vejo na hora e faço rebase da minha branch, então ela fica sempre atualizada com base na main, evitando inferno de merges ou commits horríveis de “fix conflicts”

  • Enquanto eu procurava os 10 arquivos mais modificados desde ontem, encontrei https://github.com/tj/git-extras/blob/main/Commands.md
    Tem muitos comandos extras do Git úteis

  • Clientes modernos com UI como o GitKraken são bons o bastante e ajudam, então não entendo bem por que a maioria dos desenvolvedores insiste tanto no Git CLI: https://www.gitkraken.com/

    • Conhecimento de CLI leva à escrita de scripts, e o conhecimento de Git aprendido em scripts volta para o uso do dia a dia. Não quero ficar impotente só porque preciso usar CLI ao entrar por SSH num Raspberry Pi que uso como servidor
      Não sou totalmente contra GUI, mas hoje a CLI é mais eficiente e não quero gastar tempo procurando uma GUI que atenda às seguintes condições
      Ser bonita, ser um app nativo em vez de um navegador web velho embutido, não ter telemetria ou vir com ela desativada por padrão, ser totalmente open source e dar para esperar que não desapareça daqui a 5 anos
      Além disso, não pode deixar tudo mais confuso. Numa empresa antiga eu era obrigado a usar Visual Studio, e havia um botão com o sinistro rótulo “Accept merge” que na prática queria dizer “marcar como conflito resolvido”
      Não se deve confundir pessoas que já esperam que certas palavras tenham certo significado, e também é difícil confiar em comportamentos como um botão “Commit changes” que, supostamente para ajudar, ainda faz push remoto
    • A CLI também é boa o bastante. Eu uso plugins do editor, mas se já estou na linha de comando resolvo por ali mesmo
      Se eu tiver que mudar para outro programa só para fazer um commit, minha vontade de commitar com frequência diminui
    • A menos que haja um problema muito específico, eu minimizo o que faço com Git. No meu caso, na prática é só push, pull e checkout, então usar GUI parece exagero
    • Parece elegante, mas interfaces gráficas se tornam distrações com muita facilidade. No fim, parece questão de preferência pessoal, e a CLI é rápida, mas tem uma curva de aprendizado alta
      Mesmo usando Git pela CLI, na maior parte do tempo não há nada de especial, só alguns comandos, e eu anoto dicas ou truques menos frequentes num arquivo de texto
  • Eu conhecia -committerdate, mas não sabia que dava para definir isso como ordenação padrão, e é muito útil. Algumas observações
    git columns fica bem confuso se não cabe tudo na tela e você precisa rolar, então seria bom ter numeração
    git maintenance parece bom, mas faço muito rebase e isso me preocupa. Fico pensando se ele perde objetos soltos mais rápido que gc. Dá para ver que gc está desativado, mas não está muito claro
    Em relação ao git blame, há um script pouco conhecido mas útil em https://github.com/gnddev/git-blameall. Era tão pouco conhecido que tive de portar eu mesmo para Python 3, e eu nem sou desenvolvedor Python

    • Na manutenção agendada, o gc fica desativado. Ao executar maintenance run explicitamente, ele é ativado como tarefa
      Ele não coleta objetos soltos mais rápido que gc. No fim, ele simplesmente executa o gc
    • Fico curioso se dá para ordenar em ordem inversa. Uma solução simples para o problema de branches saindo da tela parece ser deixar as branches mais novas por último. Eu faço isso com um script de usuário
    • Não perde mais rápido. Só busca dados do remoto com mais frequência e reempacota os dados. Se o GC estiver desativado, os dados não são apagados
      git-blameall parece interessante, vou testar qualquer hora
  • Simplifiquei bastante meu fluxo de Git com alguns aliases que funcionam em vários ambientes
    git synced sincroniza a branch atual com o upstream, se houver, ou com a origin se não houver, usando rebase. Usa master ou main, com preferência por main
    git pub publica as mudanças na origin remota usando force push com lease
    git pr abre a URL correta de PR no GitHub, sem precisar do cliente GH. Se houver upstream definido, envia o PR para lá
    git hub abre a página GitHub do repositório
    https://softwaredoug.com/blog/2022/11/09/idiot-proof-git-aliases.html

    • Fico curioso por que escolheram aquela seta estranha e peluda como separador
  • Parei de fingir que sei o que estou fazendo e uso ferramentas visuais de Git. Coisas como SmartGit ou as ferramentas embutidas no IntelliJ. Vejo os “heróis da linha de comando” do Git mais como exibicionismo
    A camada de comandos voltada ao usuário pode ser irritantemente confusa. Por exemplo, Yours e Theirs podem significar exatamente o oposto dependendo do contexto
    Como não existe um estilo ou tema comum em toda a interface do usuário, é preciso uma nova camada visual para não enlouquecer as pessoas

    • Também sou assim. É bom sempre poder ver as diferenças e conferir visualmente, de relance, o que vai acontecer. Nem é preciso executar vários comandos extras
      Conheço o app e o Git em geral só na medida do necessário para o trabalho, e quando raramente preciso de mais, procuro. Em vários anos de uso, isso só aconteceu uma ou duas vezes
    • Para o trabalho do dia a dia, sempre uso uma ferramenta visual de Git, especialmente o Tortoise Git
      Mesmo para tarefas complexas de corrigir erros meus ou de outras pessoas, primeiro examino no visual o histórico, os commits, o reflog e as diferenças, para entender o que deu errado e se ainda há algo que possa ser salvo
      Se só preciso voltar para um commit, faço reset --hard; se preciso juntar coisas de vários commits, normalmente uso a linha de comando
  • Os dois não são mutuamente exclusivos. Para coisas como diferenças ou conflitos, uso apenas ferramentas visuais, mas aprendi muito ao estudar objetos de commit, o que o reflog faz, o que o rebase faz por trás, rebase interativo, hard/soft reset etc.