Eu tenho um repositório Git com n commits.
Eu tenho um arquivo que eu preciso, e que costumava estar no repositório, e de repente procuro e penso "Oh! Para onde foi esse arquivo?"
Existe algum (s) comando (s) Git que me diz que "o arquivo really_needed.txt foi excluído no commit n-13"?
Em outras palavras, sem olhar para todos os commit individuais, e sabendo que meu repositório Git tem todas as alterações de todos os arquivos, posso encontrar rapidamente o último commit que possui esse arquivo, para recuperá-lo?
Respostas:
git log --full-history -- [file path]
mostra as alterações de um arquivo, funcione mesmo que o arquivo tenha sido excluído.Exemplo:
Se você deseja ver apenas o último commit, que excluiu um arquivo, use -1 além disso, por exemplo,
git log --full-history -1 -- [file path]
Consulte Qual confirmação excluiu um arquivo
fonte
git log -- */<<filename>>.<<file extension>>
não sabendo o caminho completo do arquivo.Resposta curta:
mostrará a você todos os commit no histórico de seu repo, incluindo os commit de mesclagem que foram tocados
your_file
. O último (superior) é o que excluiu o arquivo.Alguma explicação:
A
--full-history
bandeira aqui é importante. Sem ele, o Git executa a "simplificação do histórico" quando você solicita o log de um arquivo. Os documentos são detalhados sobre exatamente como isso funciona e eu não tenho a coragem e a coragem necessárias para tentar descobrir isso a partir do código-fonte, mas os documentos do git-log têm muito a dizer:Isso é obviamente preocupante quando o arquivo cujo histórico queremos é excluído , pois o histórico mais simples que explica o estado final de um arquivo excluído não é histórico . Existe o risco de que,
git log
sem--full-history
, simplesmente afirme que o arquivo nunca foi criado? Infelizmente sim. Aqui está uma demonstração:Observe como
git log -- bar
no despejo terminal acima resultou literalmente em nenhuma saída; O Git está "simplificando" a história em uma ficção ondebar
nunca existiu.git log --full-history -- bar
, por outro lado, nos fornece o commit que crioubar
e o commit que o excluiu.Para ser claro: esta questão não é meramente teórica. Eu só procurei nos documentos e descobri o
--full-history
sinalizador porquegit log -- some_file
estava falhando para mim em um repositório real, onde estava tentando rastrear um arquivo excluído. Às vezes, a simplificação do histórico pode ser útil quando você está tentando entender como um arquivo existente existe no estado atual, mas ao tentar rastrear uma exclusão de arquivo , é mais provável que você estrague tudo ocultando a confirmação com a qual você se preocupa. . Sempre use o--full-history
sinalizador para este caso de uso.fonte
git log
saída em si, não é de todo óbvio que a última confirmação excluiu o arquivo. Eu também tenteigit log --name-status --full-history -- file_name
egit log -p --stat --full-history -- file_name
, mas nenhum indica explicitamente que o arquivo foi removido na confirmação mais recente. Isso parece um bug.mkdir somedir && cd somedir && git init && touch foo && git add foo && git commit -m "Added foo" && git checkout -b newbranch && touch bar && git add bar && git commit -m "Added bar" && git checkout master && git rm foo && git commit -m "Deleted foo" && git checkout newbranch && git rm bar && git commit -m "Deleted bar" && git checkout master && git merge newbranch && git log --name-status --full-history -- bar
incluiD bar
eA bar
para mim na saída de log do Git 2.12.2. Você não vê essas linhas na saída? Que versão você tem?git version 2.15.1
Sim, sua sequência de comandos informaD bar
eA bar
. Talvez meu problema seja específico ao histórico do meu arquivo. Eu estava rastreando o histórico de um.htaccess
arquivo que foi ignorado e removido. Finalmente descobri isso e adicionei o arquivo de volta. Quando incluo--name-status
nogit log
comando, vejo duasA .htaccess
entradas (desde que a adicionei novamente na confirmação mais recente), mas nãoD .htaccess
. Portanto, parece que em alguns casos, mesmo que um arquivo tenha sido removido do repositório,git log
não mostrará umaD file_name
entrada explícita ..htaccess
tenha sido adicionado em um commit X, mas não incluído no commit de mesclagem que trouxe o X ao master? Essa é a única coisa em que consigo pensar que eu poderia argumentar que deveria parecer que um arquivo foi adicionado e nunca excluído e ainda não está presente. Seria interessante tentar descobrir um MCVE, descobrir se é um bug do Git e, se não, se é possível ajustar minha resposta para lidar com o seu caso.Git log, mas você precisa prefixar o caminho com
--
Por exemplo:
fonte
Acabei de adicionar uma solução aqui (existe uma maneira no git de listar todos os arquivos excluídos no repositório?) Para encontrar as confirmações dos arquivos excluídos usando um regexp:
Isso retorna tudo excluído em um diretório chamado
some_dir
(em cascata). Qualquer sed regexp lá onde\/some_dir\/
está vai fazer.OSX (graças a @triplee e @keif)
fonte
sed: 1: "/^commit/h;/\/some_dir\ ...": bad flag in substitute command: '}'
sed
Aparentemente, o nem sempre é bom com ponto e vírgula como separadores de comando. Tente transformá-los em novas linhas ou mude parased -n -e '/^commit/h' -e '\:/some_dir/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
trabalhei para mim no OSX.Você pode encontrar o último commit que excluiu o arquivo da seguinte maneira:
Mais informações estão disponíveis aqui
fonte
Tentar:
fonte