É possível pedir ao git diff que inclua arquivos não rastreados em sua saída diff? Ou é minha melhor aposta para o git adicionar os novos arquivos que eu criei e os arquivos existentes que eu editei e use
git diff --cached
?
É possível pedir ao git diff que inclua arquivos não rastreados em sua saída diff? Ou é minha melhor aposta para o git adicionar os novos arquivos que eu criei e os arquivos existentes que eu editei e use
git diff --cached
?
Respostas:
Nas versões recentes do git, é possível git add -N
o arquivo (ou --intent-to-add
), que adiciona um blob de tamanho zero ao índice nesse local. O resultado é que seu arquivo "não rastreado" agora se torna uma modificação para adicionar todo o conteúdo a esse arquivo de tamanho zero, e isso aparece na saída "git diff".
git diff
echo "this is a new file" > new.txt
git diff
git add -N new.txt
git diff
diff --git a/new.txt b/new.txt
index e69de29..3b2aed8 100644
--- a/new.txt
+++ b/new.txt
@@ -0,0 +1 @@
+this is a new file
Infelizmente, como apontado, você não pode git stash
enquanto tiver um --intent-to-add
arquivo pendente como este. Embora, se você precisar ocultar, adicione os novos arquivos e os oculte. Ou você pode usar a solução alternativa da emulação:
git update-index --add --cacheinfo \
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
(configurar um apelido é seu amigo aqui).
git add -N .
Eu acredito que você pode diferenciar os arquivos no seu índice e nos arquivos não rastreados, simplesmente fornecendo o caminho para os dois arquivos.
git diff --no-index tracked_file untracked_file
git diff --no-index untracked_file_1 untracked_file_2
para obter git diff
cores de sintaxe etc. em diffs ... lindas.
/dev/null
em vez disso: git diff --no-index -- /dev/null <untracked_file>
.
cat untracked_file_1
, ou talvez printf '\e[1;32m%s\e[0m\n' "$(cat untracked_file_1)"
se você realmente precisa de uma saída verde. :) (Embora em uma observação mais séria, observe que a substituição de comandos removerá as novas linhas à direita do seu arquivo.) #
Para as minhas tarefas interativas do dia-a-dia (onde eu difuso a árvore de trabalho em relação ao HEAD o tempo todo e gostaria de incluir arquivos não rastreados incluídos no diff), add -N/--intent-to-add
é inutilizável, porque ele quebra git stash
.
Então aqui está o meu git diff
substituto. Não é uma solução particularmente limpa, mas como eu realmente a uso apenas de maneira interativa, estou bem com um hack:
d() {
if test "$#" = 0; then
(
git diff --color
git ls-files --others --exclude-standard |
while read -r i; do git diff --color -- /dev/null "$i"; done
) | `git config --get core.pager`
else
git diff "$@"
fi
}
Digitar apenas d
incluirá arquivos não rastreados no diff (que é o que mais me interessa no meu fluxo de trabalho) e d args...
se comportará como normal git diff
.
Notas:
git diff
apenas diferenças individuais são concatenadas, portanto não é possível diferenciar a d
saída de uma "diferença real" - exceto pelo fato de que todos os arquivos não rastreados são classificados por último.git diff
. Se alguém descobrir como fazer isso ou se algum recurso for adicionado git
em algum momento no futuro, deixe uma nota aqui!git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 new.txt
solução que eu sugeri para gits mais velhos faz o trabalho com git stash
, supondo que você já tem e69de29bb na sua db, por exemplo, ao tentar usar add -N
anteriormente. Então, aparentemente, não é exatamente equivalente de git add -N
alguma forma: tbh não sei como.
test
comando, a propósito. Não deve afetar nada, mas test "$#" -eq 0
é mais precisamente o que se pretende.
less
para que você não precise pressionar q
para cada arquivo e pareça exatamente como git diff
, removendo a paginação por arquivo ( -P
), adicionando-a novamente depois ( | less
), preservando a cor ( --color=always
) e interpretando-a como cor ( less -r
ou less -R
). Então por completo é:do git -P diff --color=always -- /dev/null "$i"; done | less -r
test -t 1
(por exemplo, if [ -t 1 ]; then color_arg=--color; fi
algo assim), é uma maneira de o shell verificar se sua saída é um terminal, o que é uma maneira útil de decidir sobre a coloração. E xargs
pode dar um jeito de se livrar do loop while. Você ainda precisará -n 1
disso, por isso ainda lançará o git várias vezes e ainda precisará ser pareado dessa maneira, mas ... ele se livra while
e read
, então talvez seja melhor?!? Deixo isso para o leitor.
Não 100% ao ponto, mas se por algum motivo você não quiser adicionar seus arquivos ao índice, conforme sugerido pela resposta aceita, aqui está outra opção:
Se os arquivos não forem rastreados, obviamente o diff é o arquivo inteiro, então você pode visualizá-los com menos:
less $(git ls-files --others --exclude-standard)
Navegue entre eles com :n
e :p
para o próximo e o anterior.
Atualização a partir dos comentários: Se você precisar de um formato de patch, também poderá combiná-lo com git diff
:
git ls-files --others --exclude-standard | xargs -n 1 git --no-pager diff /dev/null | less
Você também pode redirecionar a saída para um arquivo ou usar outro comando diff nesse caso.
git diff /dev/null <untracked_tile>
e obter o patch no formato de remendo, em vez de "apenas" um arquivo
git add -A
git diff HEAD
Gere o patch, se necessário, e depois:
git reset HEAD
git add -p
muita frequência (o que eu geralmente recomendo, a propósito) ... Isso dá uma maneira de fazer a coisa básica, apenas ... deve-se notar que ele tem o potencial para o lado indesejado efeitos
isso funciona para mim:
git add my_file.txt
git diff --cached my_file.txt
git reset my_file.txt
O último passo é opcional, ele deixará o arquivo no estado anterior (não rastreado)
útil se você estiver criando um patch também:
git diff --cached my_file.txt > my_file-patch.patch
As alterações funcionam quando preparadas e não preparadas com este comando. Novos arquivos funcionam quando testados:
$ git diff HEAD
Se eles não forem testados, você verá apenas diferenças de arquivo.
git add
de cada arquivo não monitorado
git add
que é o mais simples , se seu caso de uso é verificar o que você acabou de adicionar / deseja adicionar
Para um arquivo:
git diff --no-index /dev/null new_file
Para todos os novos arquivos:
for next in $( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null $next; done;
Como alias:
alias gdnew="for next in \$( git ls-files --others --exclude-standard ) ; do git --no-pager diff --no-index /dev/null \$next; done;"
Para todos os arquivos modificados e novos combinados como um comando:
{ git --no-pager diff; gdnew }
Normalmente, quando eu trabalho com equipes de localização remota, é importante para mim que eu tenha conhecimento prévio de quais alterações foram feitas por outras equipes no mesmo arquivo, antes de seguir as etapas git untrack -> staged -> commit para isso, escrevi um script bash que ajude-me a evitar conflitos desnecessários de mesclagem com a equipe remota ou criar uma nova filial local e comparar e mesclar na filial principal
#set -x
branchname=`git branch | grep -F '*' | awk '{print $2}'`
echo $branchname
git fetch origin ${branchname}
for file in `git status | grep "modified" | awk "{print $2}" `
do
echo "PLEASE CHECK OUT GIT DIFF FOR "$file
git difftool FETCH_HEAD $file ;
done
no script acima eu busco o branch principal remoto (não é necessário o branch master) para FETCH_HEAD, faça uma lista apenas do meu arquivo modificado e compare os arquivos modificados com o git difftool
aqui muitos difftool suportados pelo git, eu configuro o 'Meld Diff Viewer' para uma boa comparação da GUI.
Supondo que você não tenha confirmações locais,
git diff origin/master
git diff
comando que inclua arquivos não rastreados. Este comando não os inclui. Além disso, a existência ou não de confirmações locais não tem absolutamente nada a ver com a questão.
git merge --squash mybranch
e git diff master
mostrei as alterações nos arquivos não rastreados.
git diff
não mostra diferenças nos arquivos não rastreados: como eles não são rastreados, nunca há diferenças a serem mostradas, por definição. É assim que o Git funciona. :)