<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Felipe Augusto</title>
    <description>The latest articles on DEV Community by Felipe Augusto (@felipementel).</description>
    <link>https://dev.to/felipementel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F554610%2Fd2525e9a-3af4-4da6-8629-14550121e67c.jpeg</url>
      <title>DEV Community: Felipe Augusto</title>
      <link>https://dev.to/felipementel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/felipementel"/>
    <language>en</language>
    <item>
      <title>Como usar git-filter-repo para remover arquivos e segredos do histórico Git</title>
      <dc:creator>Felipe Augusto</dc:creator>
      <pubDate>Sat, 21 Mar 2026 11:05:59 +0000</pubDate>
      <link>https://dev.to/felipementel/como-usar-git-filter-repo-para-remover-arquivos-e-segredos-do-historico-git-3k1o</link>
      <guid>https://dev.to/felipementel/como-usar-git-filter-repo-para-remover-arquivos-e-segredos-do-historico-git-3k1o</guid>
      <description>&lt;h2&gt;
  
  
  Como usar git-filter-repo para remover arquivos e segredos do histórico Git
&lt;/h2&gt;

&lt;p&gt;Quando um arquivo sensível ou uma chave vaza para o repositório, apagar o arquivo no commit atual não resolve o problema. O conteúdo continua acessível no histórico do Git. Nesses casos, a abordagem correta é reescrever todo o histórico do repositório.&lt;/p&gt;

&lt;p&gt;Hoje, a ferramenta mais recomendada para esse tipo de limpeza é o &lt;code&gt;git-filter-repo&lt;/code&gt;, inclusive apontada como substituta do antigo &lt;code&gt;git filter-branch&lt;/code&gt;. O projeto exige Python 3.6+ e Git &amp;gt;= 2.24.0, e a versão publicada no PyPI no momento é a &lt;code&gt;2.47.0&lt;/code&gt;, liberada em 4 de dezembro de 2024 (o que consideramos ser bastante estável)&lt;/p&gt;

&lt;p&gt;Neste artigo, vou mostrar como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;verificar se o Python está pronto no Windows;&lt;/li&gt;
&lt;li&gt;instalar o &lt;code&gt;git-filter-repo&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;apagar arquivos do histórico;&lt;/li&gt;
&lt;li&gt;substituir segredos no histórico;&lt;/li&gt;
&lt;li&gt;publicar a nova árvore de commits;&lt;/li&gt;
&lt;li&gt;orientar o restante do time após o rewrite;&lt;/li&gt;
&lt;li&gt;conectar isso com um fluxo de prevenção usando Gitleaks no GitHub Actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Também deixo no final um vídeo seu no YouTube que complementa esse processo.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Verificando a versão do Python
&lt;/h2&gt;

&lt;p&gt;No Windows, um jeito simples de listar as versões instaladas é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;git-filter-repo&lt;/code&gt; requer &lt;strong&gt;Python 3.6 ou superior&lt;/strong&gt; como já falamos.&lt;/p&gt;

&lt;p&gt;Se você não tiver uma versão compatível, instale uma versão atual do Python antes de continuar. A própria documentação do projeto observa que usuários Windows às vezes enfrentam problemas com aliases do Python e, nesses casos, pode ser necessário executar o script explicitamente com o interpretador Python.&lt;br&gt;
Entenda esse alias, como as configuração da variável de ambiente para o path de onde o python esta instalado.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Documentando a instalação do git-filter-repo
&lt;/h2&gt;

&lt;p&gt;A página oficial do pacote no PyPI é a referência mais prática para documentar a versão e a instalação do &lt;code&gt;git-filter-repo&lt;/code&gt;. No momento, ela mostra a versão &lt;code&gt;2.47.0&lt;/code&gt; e o comando base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;git-filter-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No entanto, a documentação oficial do projeto destaca instalação via &lt;code&gt;pipx&lt;/code&gt; ou &lt;code&gt;uv tool&lt;/code&gt; como caminhos recomendados para o pacote PyPI. Exemplo com &lt;code&gt;pipx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pipx &lt;span class="nb"&gt;install &lt;/span&gt;git-filter-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você quiser apenas validar a instalação depois, pode testar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git filter-repo &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se no seu ambiente Windows o comando &lt;code&gt;git filter-repo&lt;/code&gt; não funcionar diretamente, a própria documentação sugere chamar o script pelo Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python git-filter-repo &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Antes de mexer no histórico: clone limpo e cuidado com impacto
&lt;/h2&gt;

&lt;p&gt;Reescrever histórico não é uma operação trivial. Ela altera hashes de commits, branches e tags reescritas. O &lt;code&gt;git-filter-repo&lt;/code&gt; tem inclusive uma checagem de segurança voltada a uso em clone “fresco”, e o uso de &lt;code&gt;--force&lt;/code&gt; serve justamente para contornar esse bloqueio quando você sabe o que está fazendo.&lt;/p&gt;

&lt;p&gt;Por isso, a boa prática é:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;trabalhar em um clone separado;&lt;/li&gt;
&lt;li&gt;confirmar exatamente o que deve ser removido;&lt;/li&gt;
&lt;li&gt;avisar o time antes do push forçado;&lt;/li&gt;
&lt;li&gt;publicar a limpeza;&lt;/li&gt;
&lt;li&gt;orientar todos a sincronizar novamente o repositório local.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4. Descobrindo em que commit um arquivo entrou
&lt;/h2&gt;

&lt;p&gt;Quando o problema é um arquivo grande, um artefato indevido ou um ZIP versionado por engano, vale primeiro descobrir onde ele apareceu no histórico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--full-history&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"caminho/do/arquivo.zip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando ajuda a localizar os commits relacionados ao arquivo, entender o impacto da limpeza e até documentar o incidente.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Apagando um arquivo de todos os commits
&lt;/h2&gt;

&lt;p&gt;Se a necessidade for remover completamente um arquivo do histórico, o comando é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git filter-repo &lt;span class="nt"&gt;--path&lt;/span&gt; &lt;span class="s2"&gt;"caminho/do/arquivo.zip"&lt;/span&gt; &lt;span class="nt"&gt;--invert-paths&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;As vezes vc pode ter problema no path, colocando um ./ na frente ou não - então por vezes vai precisar fazer mais de uma vez ate vc acertar - mas isso é um erro seu e não do pacote. Alerto sobre isso pq eu que uso muito o PowerShell Core, ao usar o tab para completar os caminhos path, o terminal pode fazer esse erro de colocar um ./ ou inverter uma barra, o que pode prejudicar a execução do comando - portanto tenha atenção nisso.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A lógica é simples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--path&lt;/code&gt; indica o caminho afetado;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--invert-paths&lt;/code&gt; diz para remover esse caminho e manter o restante.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se o problema for uma pasta inteira, o raciocínio é o mesmo. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git filter-repo &lt;span class="nt"&gt;--path&lt;/span&gt; &lt;span class="s2"&gt;"storybook-static/"&lt;/span&gt; &lt;span class="nt"&gt;--invert-paths&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Gerando análise antes ou depois da limpeza
&lt;/h2&gt;

&lt;p&gt;Um comando muito útil para inspeção é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git filter-repo &lt;span class="nt"&gt;--analyze&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele gera relatórios dentro de &lt;code&gt;.git/filter-repo/analysis&lt;/code&gt;, o que ajuda a entender melhor paths, blobs e objetos do repositório.&lt;/p&gt;

&lt;p&gt;Esse comando é especialmente útil quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;você quer descobrir arquivos grandes;&lt;/li&gt;
&lt;li&gt;suspeita de lixo histórico;&lt;/li&gt;
&lt;li&gt;quer investigar quais caminhos mais pesam no repositório;&lt;/li&gt;
&lt;li&gt;precisa de uma visão mais segura antes de sair removendo coisas.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7. Substituindo segredos do histórico com arquivo &lt;code&gt;.gitfilter&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Quando o problema é uma chave, token, senha ou segredo hardcoded, você pode usar &lt;code&gt;--replace-text&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Exemplo de arquivo &lt;code&gt;.gitfilter&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;389123yunfg34iug348r739ht==&amp;gt;**REMOVIDA**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git filter-repo &lt;span class="nt"&gt;--replace-text&lt;/span&gt; .gitfilter &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse processo percorre o histórico reescrevendo o texto encontrado. Para incidentes de segredo exposto, isso é muito útil porque você não precisa necessariamente remover o arquivo inteiro; em alguns cenários, basta substituir o valor comprometido.&lt;/p&gt;

&lt;h3&gt;
  
  
  Um ponto importante sobre arquivos começando com ponto
&lt;/h3&gt;

&lt;p&gt;Aqui vale uma correção conceitual importante: arquivos com &lt;code&gt;.&lt;/code&gt; no nome, como &lt;code&gt;.gitfilter&lt;/code&gt;, &lt;code&gt;.env&lt;/code&gt; ou &lt;code&gt;.gitignore&lt;/code&gt;, &lt;strong&gt;não são “por definição” arquivos que não devem ser versionados&lt;/strong&gt;. No Unix e em vários ambientes, eles são apenas arquivos “ocultos” por convenção. Alguns devem sim ser versionados, como &lt;code&gt;.gitignore&lt;/code&gt;, &lt;code&gt;.editorconfig&lt;/code&gt; e muitos arquivos de configuração do projeto. Outros, como &lt;code&gt;.env&lt;/code&gt;, muitas vezes não devem. Então a regra prática é: &lt;strong&gt;sempre confira o &lt;code&gt;.gitignore&lt;/code&gt; e a política do projeto antes de decidir&lt;/strong&gt;. Isso evita transformar uma convenção em regra absoluta.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Exemplo completo de fluxo
&lt;/h2&gt;

&lt;p&gt;Um fluxo simples para um incidente comum pode ser:&lt;/p&gt;

&lt;h3&gt;
  
  
  Caso A: apagar um arquivo indevido do histórico
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;--full-history&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"caminho/do/arquivo.zip"&lt;/span&gt;
git filter-repo &lt;span class="nt"&gt;--analyze&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt;
git filter-repo &lt;span class="nt"&gt;--path&lt;/span&gt; &lt;span class="s2"&gt;"caminho/do/arquivo.zip"&lt;/span&gt; &lt;span class="nt"&gt;--invert-paths&lt;/span&gt;
git remote set-url https://&amp;lt;URL_DO_REPO&amp;gt;.git
git push origin &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Caso B: substituir um segredo vazado
&lt;/h3&gt;

&lt;p&gt;Crie o arquivo &lt;code&gt;.gitfilter&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chave-antiga==&amp;gt;**REMOVIDA**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois rode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git filter-repo &lt;span class="nt"&gt;--analyze&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt;
git filter-repo &lt;span class="nt"&gt;--replace-text&lt;/span&gt; .gitfilter &lt;span class="nt"&gt;--force&lt;/span&gt;
git remote set-url https://&amp;lt;URL_DO_REPO&amp;gt;.git
git push origin &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. Publicando a nova árvore de commits
&lt;/h2&gt;

&lt;p&gt;Depois da limpeza, é necessário enviar a nova história para o remoto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt;
git push origin &lt;span class="nt"&gt;--force&lt;/span&gt; &lt;span class="nt"&gt;--tags&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esses comandos forçam a atualização das branches e tags reescritas. Isso é esperado, porque os hashes dos commits mudam quando o histórico é alterado.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. O que o restante do time precisa fazer depois
&lt;/h2&gt;

&lt;p&gt;Depois de um rewrite desses, o time precisa sincronizar o ambiente local com a nova história. Um fluxo objetivo para a branch principal é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch origin
git checkout main
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; origin/main
git clean &lt;span class="nt"&gt;-fd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse conjunto de comandos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;busca a nova referência do remoto;&lt;/li&gt;
&lt;li&gt;muda para a branch principal;&lt;/li&gt;
&lt;li&gt;alinha o histórico local exatamente ao remoto;&lt;/li&gt;
&lt;li&gt;remove arquivos e diretórios não rastreados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em alguns times, também vale orientar as pessoas a recriar branches locais derivadas de commits antigos, porque qualquer branch baseada na história anterior pode carregar referências inválidas ou até reintroduzir conteúdo removido.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Relacionando isso com Gitleaks no GitHub Actions
&lt;/h2&gt;

&lt;p&gt;Limpar o passado é importante, mas o ideal é impedir reincidência. É aí que entra o Gitleaks.&lt;/p&gt;

&lt;p&gt;O Gitleaks é uma ferramenta para detectar segredos em repositórios Git, e a ação oficial para GitHub Actions permite rodar varredura em pushes e pull requests.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitleaks&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scan&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitleaks&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Gitleaks&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gitleaks/gitleaks-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A conexão entre as duas ferramentas fica muito clara:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git-filter-repo&lt;/code&gt; corrige o passado;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Gitleaks&lt;/code&gt; ajuda a proteger o futuro.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uma abordagem madura é usar os dois: primeiro saneia o histórico, depois adiciona validação contínua no pipeline para evitar que novos segredos cheguem ao repositório novamente.&lt;/p&gt;

&lt;p&gt;Para conhecer mais sobre o projeto Gitleaks, acesse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/gitleaks/gitleaks" rel="noopener noreferrer"&gt;https://github.com/gitleaks/gitleaks&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Erros comuns e observações práticas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Usar &lt;code&gt;--force&lt;/code&gt; sem entender o impacto
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;--force&lt;/code&gt; existe porque reescrever histórico é destrutivo e o &lt;code&gt;git-filter-repo&lt;/code&gt; tenta evitar acidentes. Use apenas quando estiver operando em um clone seguro e com plano de comunicação ao time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Achar que apagar no commit atual resolve
&lt;/h3&gt;

&lt;p&gt;Não resolve. O arquivo ou segredo continua acessível em commits antigos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Esquecer as tags
&lt;/h3&gt;

&lt;p&gt;Se você só der push forçado nas branches e esquecer as tags, parte do histórico antigo ainda pode permanecer referenciada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Não orientar o time
&lt;/h3&gt;

&lt;p&gt;Esse é um dos pontos mais negligenciados. Sem alinhar o procedimento pós-rewrite, alguém pode fazer push de uma branch antiga e reintroduzir o problema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tratar dotfiles como regra universal
&lt;/h3&gt;

&lt;p&gt;Nem todo arquivo iniciado por &lt;code&gt;.&lt;/code&gt; deve ficar fora do versionamento. Isso depende da função do arquivo e da estratégia do repositório.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Vídeo complementar
&lt;/h2&gt;

&lt;p&gt;Você também pode complementar a leitura com este vídeo no YouTube, que fala justamente sobre detecção de chaves commitadas e limpeza do histórico:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn how to detect committed keys in Git and how to clear the history to solve the problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=HzfK3MZ1UpE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=HzfK3MZ1UpE&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;git-filter-repo&lt;/code&gt; é hoje uma das formas mais seguras e práticas de reescrever histórico Git para remover arquivos indevidos e dados sensíveis. Ele é especialmente útil em dois cenários muito comuns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quando um arquivo grande, ZIP ou pasta de build foi versionado por engano;&lt;/li&gt;
&lt;li&gt;quando uma chave, token ou segredo foi commitado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O fluxo ideal costuma ser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;identificar o problema;&lt;/li&gt;
&lt;li&gt;analisar o histórico;&lt;/li&gt;
&lt;li&gt;remover o path ou substituir o texto;&lt;/li&gt;
&lt;li&gt;forçar push de branches e tags;&lt;/li&gt;
&lt;li&gt;alinhar o time para resetar os clones locais;&lt;/li&gt;
&lt;li&gt;adicionar Gitleaks no GitHub Actions para evitar recorrência.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Isso transforma um incidente pontual em uma melhoria real de governança do repositório.&lt;/p&gt;

</description>
      <category>git</category>
      <category>security</category>
      <category>tooling</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Como Configurar Multiplas Contas do Git na sua Máquina Usando o Arquivo .gitconfig</title>
      <dc:creator>Felipe Augusto</dc:creator>
      <pubDate>Fri, 20 Jun 2025 19:57:49 +0000</pubDate>
      <link>https://dev.to/felipementel/como-configurar-multiplas-contas-do-git-na-sua-maquina-usando-o-arquivo-gitconfig-3joa</link>
      <guid>https://dev.to/felipementel/como-configurar-multiplas-contas-do-git-na-sua-maquina-usando-o-arquivo-gitconfig-3joa</guid>
      <description>&lt;h3&gt;
  
  
  Um Desenvolvedor, Várias Identidades
&lt;/h3&gt;

&lt;p&gt;Imagine um desenvolvedor que atua em diversos projetos em alguns clientes e está fazendo um curso (faculdade, mestrado ou qualquer tipo de curso) e também tem diversos projetos pessoais que sempre versiona no seu GitHub pessoal (se identificou com esse cenário). Cada uma dessas frentes exige uma identidade diferente no Git, certo?&lt;/p&gt;

&lt;p&gt;Em um certo momento, esse desenvolvedor percebe que estava enviando commits do projeto corporativo com o e-mail pessoal, misturando identidades e gerando confusão tanto para ele quanto para seus colegas do trabalho, do curso e em seus projetos pessoais. Foi então que decidiu resolver isso com uma abordagem mais elegante e automatizada: usando o arquivo &lt;em&gt;.gitconfig&lt;/em&gt; para configurar perfis por pasta de projeto.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos explorar como configurar múltiplas identidades no Git de forma eficiente, com base em um cenário real. Se você também vive entre múltiplas contas, continue lendo para entender como o Git pode trabalhar a seu favor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entendendo a Estrutura do &lt;em&gt;.gitconfig&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;O Git permite configurar suas preferências em três níveis:&lt;/p&gt;

&lt;p&gt;Global: Aplica-se a todos os repositórios do usuário. Normalmente salvo em &lt;em&gt;~/.gitconfig&lt;/em&gt; no Linux/macOS ou &lt;em&gt;C:/Users//.gitconfig&lt;/em&gt; no Windows.&lt;/p&gt;

&lt;p&gt;Local: Específico de um repositório, salvo no arquivo .git/config dentro do próprio repositório.&lt;/p&gt;

&lt;p&gt;Sistema: Configurações que afetam todos os usuários da máquina.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos focar na configuração global com inclusões condicionais, que é uma forma poderosa de alternar configurações com base no diretório do projeto.&lt;/p&gt;

&lt;h3&gt;
  
  
  O Cenário: Três Contextos, Três Perfis
&lt;/h3&gt;

&lt;p&gt;Os projetos estão organizados da seguinte maneira:&lt;/p&gt;

&lt;p&gt;Projetos da empresa: C:/Proj/EmpresaX/&lt;/p&gt;

&lt;p&gt;Projetos acadêmicos: C:/Proj/Academico/&lt;/p&gt;

&lt;p&gt;Projetos pessoais: qualquer outro diretório da máquina&lt;/p&gt;

&lt;p&gt;Cada contexto precisa de uma identidade Git diferente. Veja abaixo a estrutura de um exemplo de &lt;em&gt;.gitconfig&lt;/em&gt; global e como ele resolve esse desafio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[init]
    defaultBranch = main

[includeIf "gitdir:C:/Proj/canaldeploy/**"]
    path = C:/Users/&amp;lt;usuario&amp;gt;/.gitconfig-canaldeploy

[includeIf "gitdir:C:/Proj/Academico/**"]
    [user]
        name = Nome Exemplo
        email = usuario.academico@email.com

[user]
    name = Nome Exemplo
    email = usuario.pessoal@email.com

[http]
    sslverify = false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explicando o Arquivo Passo a Passo
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Definição do Branch Padrão
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[init]
    defaultBranch = main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define que todos os novos repositórios iniciados terão o branch principal como main.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inclusão Condicional por Caminho
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[includeIf "gitdir:C:/Proj/canaldeploy/**"]
    path = C:/Users/usuario/.gitconfig-canaldeploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sempre que o Git for utilizado em um repositório dentro desse caminho, ele incluirá as configurações do arquivo &lt;em&gt;.gitconfig-canaldeploy&lt;/em&gt;, permitindo isolar nome, e-mail, credenciais e chaves SSH corporativas (mas não vamos abordar chaves ssh nesse artigo)&lt;br&gt;
Abaixo, segue o conteúdo do arquivo &lt;em&gt;.gitconfig-empresax&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[user]
  name = Felipe Augusto
  email = felipe.augusto@canaldeploy.com.br
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Configuração Direta para Projetos Acadêmicos - Caso não queira criar multiplos arquivos, é possível fazer a configuração dentro do próprio &lt;em&gt;.gitconfig&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[includeIf "gitdir:C:/Proj/Academico/**"]
    [user]
        name = Felipe Augusto
        email = felipe.augusto@academico.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse caso, não é usado um arquivo externo, mas sim a configuração embutida diretamente dentro do includeIf.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identidade Padrão
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[user]
    name = Felipe Augusto
    email = felipe.augusto@pessoal.com

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aplica-se a todos os outros diretórios que não se encaixam nas condições anteriores. Representa o perfil pessoal.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SSL e Safe Directory
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[http]
    sslverify = false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desabilita a verificação de SSL, útil em ambientes corporativos com proxies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Como verificar se a configuração está correta
&lt;/h3&gt;

&lt;p&gt;Abra um terminal dentro de cada projeto e execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config user.email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso retornará o e-mail em uso naquele diretório, confirmando se a identificação está correta.&lt;/p&gt;

&lt;p&gt;Se quiser ver todas as configurações que estão sendo aplicadas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --list --show-origin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Considerações Finais
&lt;/h3&gt;

&lt;p&gt;Configurar corretamente os perfis do Git evita confusão de identidade e dor de cabeça para resolver esses problemas, que apesdar de simples, podem demorar algumas horas para serem resolvidos. Além de manter seu histórico de commits limpo e profissional.&lt;/p&gt;

&lt;p&gt;Com poucos blocos de código, você pode tornar seu ambiente Git inteligente, responsivo ao contexto e livre de erros comuns.&lt;/p&gt;

&lt;p&gt;Com essa abordagem, qualquer pessoa pode aproveitar o poder do &lt;em&gt;.gitconfig&lt;/em&gt; para atuar em múltiplos contextos sem dores de cabeça. Basta planejar, configurar e versionar com tranquilidade.&lt;/p&gt;

&lt;p&gt;Gostou dessa dica?&lt;/p&gt;

&lt;p&gt;Temos outras muitas no &lt;a href="//youtube.com/@D.E.P.L.O.Y"&gt;canal DEPLOY&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Retorno de validações semânticas em API Rest</title>
      <dc:creator>Felipe Augusto</dc:creator>
      <pubDate>Tue, 26 Mar 2024 19:36:47 +0000</pubDate>
      <link>https://dev.to/felipementel/retorno-de-validacoes-semanticas-em-api-rest-pd</link>
      <guid>https://dev.to/felipementel/retorno-de-validacoes-semanticas-em-api-rest-pd</guid>
      <description>&lt;p&gt;Em um mundo cada vez mais conectado, as APIs desempenham um papel crucial na troca de informações entre sistemas e na construção de aplicativos robustos e interconectados. No entanto, à medida que a complexidade das aplicações e das interações entre sistemas aumenta, surgem desafios relacionados à integridade e à consistência dos dados transmitidos por meio dessas interfaces.&lt;/p&gt;

&lt;p&gt;Um aspecto fundamental para garantir a qualidade e a confiabilidade das APIs é a capacidade de lidar com erros semânticos nos dados fornecidos pelas requisições. Estes erros, muitas vezes negligenciados, podem comprometer a integridade dos dados e afetar a funcionalidade geral do sistema. Neste artigo, exploraremos o que são os erros semânticos dos dados em APIs, como eles podem surgir e como podem ser mitigados.&lt;/p&gt;

&lt;p&gt;O que são erros semânticos?&lt;/p&gt;

&lt;p&gt;Erros semânticos nos dados fornecidos referem-se a problemas relacionados ao significado ou à interpretação dos dados enviados em uma requisição para a API. Enquanto erros de sintaxe são detectados facilmente através de verificações formais, erros semânticos exigem uma compreensão mais profunda do contexto e das regras de negócio envolvidas.&lt;/p&gt;

&lt;p&gt;Exemplos de erros semânticos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Em uma API de gerenciamento de usuários, tentar cadastrar um usuário com um endereço de e-mail já existente no sistema.&lt;/li&gt;
&lt;li&gt;Em uma API de reservas de hotel, tentar fazer uma reserva para uma data que já passou.&lt;/li&gt;
&lt;li&gt;Em uma API de e-commerce, tentar adicionar um produto ao carrinho com uma quantidade maior do que a disponível em estoque.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Detectando e tratando erros semânticos:&lt;/p&gt;

&lt;p&gt;A detecção de erros semânticos nos dados fornecidos é essencial para garantir a integridade e a consistência dos sistemas. Isso geralmente é feito por meio de validações em código implementadas na API, que verificam se os dados fornecidos estão em conformidade com as regras de negócio estabelecidas.&lt;/p&gt;

&lt;p&gt;Quando um erro semântico é detectado, a API deve retornar uma resposta adequada, geralmente utilizando códigos de status HTTP como o 422 "Unprocessable Entity". Além disso, é importante fornecer informações claras sobre o erro ocorrido, para que o cliente possa corrigir os dados e reenviar a requisição.&lt;/p&gt;

&lt;p&gt;Na imagem abaixo, podemos analisar que, ao tentar inserir um registro (linha 74) é retornado dentro do DTO uma lista de possíveis erros (variável item).&lt;br&gt;
Caso a operação de InsertAsync retorne algo, sera retornado o Http Status Code 422 (linha 79) com todas as msgs de validação de negócio (validação semântica)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5lxutvvn8y1e3p9991x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5lxutvvn8y1e3p9991x.png" alt="Image description" width="800" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja a execução e o retorno:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6a5ryid0erbum1kwctp0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6a5ryid0erbum1kwctp0.png" alt="Image description" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então ao enviar um request com:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nome em branco&lt;/li&gt;
&lt;li&gt;Peso igual a zero.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos obter o resultado da validação de semântica e o Http Status Code 422.&lt;/p&gt;

&lt;p&gt;Plus sobre o artigo ...&lt;/p&gt;

&lt;p&gt;Neste artigo não vou explicar como estamos construindo as validações, mas vou deixar um print aos curiosos.&lt;br&gt;
Quem quiser, pode entrar em contato que posso explicar com mais profundidade:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8knqco05dhh7iceus9qv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8knqco05dhh7iceus9qv.png" alt="Image description" width="722" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwx3oxi3dj8y616s8dm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwx3oxi3dj8y616s8dm9.png" alt="Image description" width="800" height="754"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusão:&lt;/p&gt;

&lt;p&gt;Erros semânticos nos dados fornecidos são uma parte inevitável do desenvolvimento de APIs, mas são cruciais para garantir a integridade e a consistência dos sistemas. Ao compreender e tratar adequadamente esses erros, os desenvolvedores podem construir APIs mais robustas e confiáveis, proporcionando uma melhor experiência para os usuários e garantindo o funcionamento correto das aplicações.&lt;/p&gt;

&lt;p&gt;Link úteis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc4918" rel="noopener noreferrer"&gt;https://www.rfc-editor.org/rfc/rfc4918&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Como instalar o componente buildx no docker</title>
      <dc:creator>Felipe Augusto</dc:creator>
      <pubDate>Fri, 29 Dec 2023 13:31:01 +0000</pubDate>
      <link>https://dev.to/felipementel/como-instalar-o-componente-buildx-no-docker-ka9</link>
      <guid>https://dev.to/felipementel/como-instalar-o-componente-buildx-no-docker-ka9</guid>
      <description>&lt;p&gt;Nos últimos meses o docker começou a alertar sobre a descontinuação do processo de build utilizando o comando &lt;strong&gt;docker build&lt;/strong&gt; e a mesagem abaixo sempre é exibida ao utilizar o comando.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8s8x2f6mzt2nmnudo8o8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8s8x2f6mzt2nmnudo8o8.png" alt="Image description" width="800" height="84"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse post quero apresentar como instalar o plugin buildx para que seu docker fique mais aderente ao novo modelo de build, isso inclui a atualização da sua linha de comando para construir suas imagens.&lt;/p&gt;

&lt;p&gt;Vale ressaltar que o meu comando para gerar minhas imagens é:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -f ./src/DEPLOY.Cachorro.Api/Dockerfile -t felipementel/cachorro.api:local ./src
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz4xkcolaojz26i8xp2t6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz4xkcolaojz26i8xp2t6.png" alt="Image description" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora vamos aos comandos para poder começar a fazer nossa instalação&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atualize a versão do Ubuntu/WSL-2 (Para outras distros os comandos para atualização podem ser diferentes pois o gestor de paotes talvez não seja o apt)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt-get update -y &amp;amp;&amp;amp; apt-get upgrade -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para o exemplo, estamos utilizando a versão 0.12.0. Caso queira utilizar outra versão, verifique a lista no site &lt;strong&gt;&lt;a href="https://github.com/docker/buildx/releases" rel="noopener noreferrer"&gt;https://github.com/docker/buildx/releases&lt;/a&gt;&lt;/strong&gt; e adapte os comandos abaixo para a sua versão&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faça o download do pacote utilizando o cURL
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --silent -L https://github.com/docker/buildx/releases/download/v0.12.0/buildx-v0.12.0.linux-amd64 -o buildx-v0.12.0.linux-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Conceda as devidas permissões para o arquivo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod a+x buildx-v0.12.0.linux-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;e pasta de destino
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod +x ~/.docker/cli-plugins/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Movimente o arquivo da pasta do destino do download que acabou de fazer para pasta onde o plugin deverá ser instalado
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mv buildx-v0.12.0.linux-amd64 ~/.docker/cli-plugins/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Vá para o diretório de destino
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/.docker/cli-plugins/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Instale o componente
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apt install docker-buildx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto!&lt;/p&gt;

&lt;p&gt;Repare na imagem abaixo, onde agora temos o comando &lt;strong&gt;docker buildx build ...&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93wdd7i3zn9k0bjuoeas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93wdd7i3zn9k0bjuoeas.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora já pode contar pros seus vizinhos que estamos gerando imagens docker utilizando o buildx &lt;br&gt;
\o&lt;/p&gt;

&lt;p&gt;Espero que esse post tenha ajudado vcs, até breve.&lt;/p&gt;

&lt;p&gt;O projeto utilizado no exemplo, com dockerfile e tudo mais: &lt;a href="https://github.com/felipementel/DEPLOY.Cachorro.Api" rel="noopener noreferrer"&gt;https://github.com/felipementel/DEPLOY.Cachorro.Api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;referências:&lt;br&gt;
&lt;a href="https://docs.docker.com/engine/reference/commandline/buildx_build/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/reference/commandline/buildx_build/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/docker/buildx/releases" rel="noopener noreferrer"&gt;https://github.com/docker/buildx/releases&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Como sair de organizações no Azure usando AzureCLI</title>
      <dc:creator>Felipe Augusto</dc:creator>
      <pubDate>Tue, 06 Jun 2023 14:34:17 +0000</pubDate>
      <link>https://dev.to/felipementel/como-sair-de-organizacoes-no-azure-usando-azurecli-2a79</link>
      <guid>https://dev.to/felipementel/como-sair-de-organizacoes-no-azure-usando-azurecli-2a79</guid>
      <description>&lt;p&gt;Aloha my friend,&lt;/p&gt;

&lt;p&gt;Essa semana fui organizar meus ambientes de desenvolvimento para começar a postar meus vídeos no canal do youtube que vou começar com dois amigos. E já fica a dica, se vc não esta seguindo, já pode correr no yt e se inscrever: &lt;a href="https://www.youtube.com/@D.E.P.L.O.Y" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então vamos para o problema:&lt;br&gt;
Abrindo o meu WSL2 no Windows (ainda vou escrever e gravar um vídeo de como subir o WSL2 e instalar algumas coisas legais nele, como Docker, para poder rodar na sua máquina), fiz o comando para poder fazer login no Azure Cloud&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;feito isso, abriu uma pagina web, eu confirmei minha identidade&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdiovuzxdfytx8aaoe5s8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdiovuzxdfytx8aaoe5s8.png" alt="Image description" width="570" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;e dai foram listadas as contas que eu tenho acesso:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft01he272xdzd64ottb1n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft01he272xdzd64ottb1n.png" alt="Image description" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hummmm, dai apareceram alguns tenants que eu não tenho mais acesso e na real nem queria ter. Gosto de ter minha conta bem exuta. (detalhe que eu já havia removido outras contas e dai então decidi escrever esse artigo para ajudar outras pessoas, pq eu mesmo já tentei fazer isso outras vezes)&lt;/p&gt;

&lt;p&gt;Então catando nas documentações do Azure AD, encontrei o link abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://learn.microsoft.com/en-us/azure/active-directory/external-identities/leave-the-organization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E tinha uma forma de sair do Tenant - visto que pelo Azure Cloud Portal, eu não estava conseguindo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9rp5u8ed91x3ql5v7q1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9rp5u8ed91x3ql5v7q1.png" alt="Image description" width="613" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então basicamente a gente precisa copiar o tenant id e montar uma URL na mão (recomendo usar um bloco de notas para isso)&lt;/p&gt;

&lt;p&gt;Dai teremos a URL abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://myaccount.microsoft.com?tenantId=wingtiptoys.onmicrosoft.com or https://myaccount.microsoft.com?tenantId=123ABCD456
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lembre de trocar o 123ABCD456 pelo ID do Tenant da primeira imagem&lt;/p&gt;

&lt;p&gt;Feito isso, só jogar no seu navegador (eu curto usar o Edge da Microsoft).&lt;/p&gt;

&lt;p&gt;Veja como ficou a minha URL&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcucn5qinv6f2pcmizsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcucn5qinv6f2pcmizsw.png" alt="Image description" width="712" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dai é solicitado que eu faça login na minha conta pessoal&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno3mg5ah3kxt48jlb9wj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno3mg5ah3kxt48jlb9wj.png" alt="Image description" width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ao escolher a opção de menu "Organizations" podemos ver exatamente o nome da organização que queremos sair.&lt;/p&gt;

&lt;p&gt;Então precisamos clicar na opção "leave" (o meu esta em inglês então talvez o seu apareça escrito "sair" ou "deixar")&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff48dgqazv1v8dtqaf6nb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff48dgqazv1v8dtqaf6nb.png" alt="Image description" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Será apresentado a tela abaixo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmp0xp8h8xu1qntf5bogv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmp0xp8h8xu1qntf5bogv.png" alt="Image description" width="706" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;e logo na sequencia, uma confirmação:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9mj91ol3cmm50127a1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9mj91ol3cmm50127a1z.png" alt="Image description" width="592" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;onde, precisamos clicar no botão azul, no meu caso que esta em Inglês, "Leave"&lt;/p&gt;

&lt;p&gt;Voltamos para o terminal e ao realizar o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;az login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ver que realmente um tenant não existe mais.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9d27ol2k0v7y7glfgcwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9d27ol2k0v7y7glfgcwc.png" alt="Image description" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Espero que tenha conseguido ajudar vcs&lt;br&gt;
[]´s&lt;/p&gt;

</description>
      <category>azure</category>
      <category>azuread</category>
      <category>activedirectory</category>
      <category>azurecli</category>
    </item>
  </channel>
</rss>
