$ git reset -- <file_path>
pode redefinir pelo caminho.
No entanto, $ git reset (--hard|--soft) <file_path>
reportará um erro como abaixo:
Cannot do hard|soft reset with paths.
Porque não faz sentido (outros comandos já fornecem essa funcionalidade) e reduz o potencial de fazer a coisa errada por acidente.
Uma "reinicialização completa" de um caminho é feita git checkout HEAD -- <path>
(verificando a versão existente do arquivo).
Uma reinicialização suave de um caminho não faz sentido.
Uma redefinição mista para um caminho é o que git reset -- <path>
faz.
git checkout -- <path>
deveria ser substituído porgit reset --hard <path>
. Faz muito mais sentido ...git checkout -- <path>
não faz uma reinicialização completa; ele substitui o conteúdo da árvore de trabalho pelo conteúdo preparado.git checkout HEAD -- <path>
faz uma redefinição definitiva para um caminho, substituindo o índice e a árvore de trabalho pela versão do commit HEAD.reset --hard
com um caminho forneceria essa peça que faltava. O Git já é tão poderoso que a desculpa "Não permitimos que você faça isso para sua própria proteção" mantém zero de água: existem muitas maneiras de fazer a coisa errada "por acidente". Nada disso importa quando você temgit reflog
.git reset --hard -- <path>
. Existem casos de uso legítimos para isso.Você pode realizar o que está tentando fazer usando
git checkout HEAD <path>
.Dito isto, a mensagem de erro fornecida não faz sentido para mim (como
git reset
funciona muito bem em subdiretórios) e não vejo razão paragit reset --hard
que não deva fazer exatamente o que você está pedindo.fonte
A pergunta como já está respondida , explicarei a parte do porquê .
Então, o que o git reset faz? Dependendo dos parâmetros especificados, ele pode fazer duas coisas diferentes:
Se você especificar um caminho, ele substituirá os arquivos correspondentes no índice pelos arquivos de uma confirmação (HEAD por padrão). Essa ação não afeta a árvore de trabalho e geralmente é usada como o oposto do git add.
Se você não especificar um caminho, ele moverá o cabeçalho da ramificação atual para uma confirmação especificada e, junto com isso , redefinirá opcionalmente o índice e a árvore de trabalho para o estado dessa confirmação. Esse comportamento adicional é controlado pelo parâmetro mode:
--soft : não toque no índice e na árvore de trabalho.
--mixed (padrão): redefine o índice, mas não a árvore de trabalho.
--hard : redefine o índice e a árvore de trabalho.
Também existem outras opções, consulte a documentação para obter a lista completa e alguns casos de uso.
Quando você não especifica uma confirmação, o padrão é HEAD, portanto
git reset --soft
, nada fará, pois é um comando para mover a cabeça para HEAD (para seu estado atual).git reset --hard
, por outro lado, faz sentido devido a seus efeitos colaterais , diz mover a cabeça para HEAD e redefinir o índice e a árvore de trabalho para HEAD.Eu acho que agora deve estar claro por que essa operação não é para arquivos específicos por natureza - ela pretende mover uma cabeça de ramificação em primeiro lugar, redefinindo a árvore de trabalho e o índice é uma funcionalidade secundária.
fonte
git checkout
comando? E redefinir para fazer a mesma coisa confundiria ainda mais os usuários. Minha resposta foi que a--hard
opção não é aplicável a arquivos específicos porque é um modo de redefinição de ramificação, não de redefinição de índice. E a redefinição da árvore de trabalho é denominada checkout, como você pode ler em outras respostas. Tudo isso é apenas um design ruim da interface do usuário do Git, IMHO.git checkout
:git reset --
define apenas o índice, enquantogit checkout --
define apenas a árvore de trabalho?Certifique-se de colocar uma barra entre a origem ou a montante (origem) e a ramificação real:
ou
fonte
Há uma razão muito importante por trás disso: os princípios de
checkout
ereset
.Em termos do Git, checkout significa "trazer para a árvore de trabalho atual". E com
git checkout
isso podemos preencher a árvore de trabalho com dados de qualquer área, seja de uma confirmação no repositório ou de arquivos individuais de uma confirmação ou da área de preparação (que é o padrão).Por sua vez, o git reset não tem essa função. Como o nome sugere, ele redefinirá a ref atual, mas sempre terá o repositório como fonte, independentemente do "alcance" (--soft, --mixed ou --hard).
Recapitular:
Portanto, o que pode ser um pouco confuso é a existência de,
git reset COMMIT -- files
já que "sobrescrever HEAD" com apenas alguns arquivos não faz sentido!Na ausência de uma explicação oficial, posso apenas especular que os desenvolvedores do git descobriram que
reset
ainda era o melhor nome de um comando para descartar as alterações feitas na área de preparação e, dada a única fonte de dados que era o repositório, " vamos estender o funcionalidade "em vez de criar um novo comando.Então, de alguma forma,
git reset -- <files>
já é um pouco excepcional: não substitui o HEAD. IMHO todas essas variações seriam exceções. Mesmo que possamos conceber uma--hard
versão, outras (por exemplo--soft
) não fazem sentido.fonte
git reset -- <files>
caiu como se fosse adicionado, porque esse é um recurso útil, mas ninguém tinha certeza de qual comando deveria ser colocado. Felizmente agora temos muito mais são,git restore
que têm funcionalidadegit checkout -- <path>
git checkout <commit> -- <path>
egit reset [<commit>] -- <path>
com muitos padrões mais saudáveis e ainda mais recursos que você não poderia fazer antes (ao contrário do que a resposta aceita diz. Agora você pode finalmente restaurar facilmente apenas a árvore de trabalho, sem tocar no índice).Explicação
O
git reset
manual lista três maneiras de invocação:2 são de arquivo: Eles não afetam a árvore de trabalho , mas operam apenas nos arquivos no índice especificado por
<paths>
:git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1 é de confirmação: opera em todos os arquivos no referenciado
<commit>
e pode afetar a árvore de trabalho:git reset [<mode>] [<commit>]
Não há modo de chamada que opera apenas em arquivos especificados e afeta a árvore de trabalho.
Gambiarra
Se você deseja ambos:
Você pode usar esse alias no seu arquivo de configuração do git:
Você pode fazer um dos seguintes:
(Mnenônico para
reco
:re
set &&c
hecko
ut)fonte
O nome do arquivo git reset --soft HEAD ~ 1 desfaz a confirmação, mas as alterações permanecem no local. filename poderia ser - para todos os arquivos confirmados
fonte
Cannot do soft reset with paths.