web-dev-qa-db-fra.com

Pourquoi git ne peut pas faire de réinitialisations dures/douces par chemin?

$ git reset -- <file_path> peut être réinitialisé par chemin.

Cependant, $ git reset (--hard|--soft) <file_path> signalera une erreur comme ci-dessous:

Cannot do hard|soft reset with paths.
105
yao

Parce que cela ne sert à rien (d’autres commandes fournissent déjà cette fonctionnalité) et que cela réduit le risque de faire la mauvaise chose par accident.

Une "réinitialisation matérielle" d'un chemin est simplement effectuée avec git checkout HEAD -- <path> (vérification de la version existante du fichier).

Une réinitialisation logicielle pour un chemin n'a pas de sens.

Une réinitialisation mixte pour un chemin correspond à ce que git reset -- <path> fait.

114
Amber

Vous pouvez accomplir ce que vous essayez de faire en utilisant git checkout HEAD <path>.

Cela dit, le message d'erreur fourni n'a aucun sens pour moi (car git reset fonctionne parfaitement dans les sous-répertoires) et je ne vois aucune raison pour que git reset --hard ne fasse pas exactement ce que vous lui demandez. 

17
Aaron Kent

La question comment est déjà a répondu , je vais expliquer la partie pourquoi.

Alors, qu'est-ce que git réinitialise fait? Selon les paramètres spécifiés, il peut faire deux choses différentes:

  • Si vous spécifiez un chemin, il remplace les fichiers correspondants dans l'index par les fichiers d'un commit (HEAD par défaut). Cette action n’affecte en rien l’arbre de travail et est généralement utilisée à l’opposé de git add.

  • Si vous ne spécifiez pas de chemin d'accès, la tête de la branche actuelle est déplacée vers une validation spécifiée et, ainsi que celle-ci, réinitialise éventuellement l'index et l'arbre de travail sur l'état de cette validation. Ce comportement supplémentaire est contrôlé par le paramètre mode:
    --soft: ne touchez pas l'index ni l'arbre de travail.
    --mixed (par défaut): réinitialise l'index mais pas l'arbre de travail.
    --hard: réinitialise l'index et l'arbre de travail.
    Il existe également d’autres options, voir la documentation pour la liste complète et quelques cas d’utilisation.

    Lorsque vous ne spécifiez pas de validation, la valeur par défaut est HEAD. Donc, git reset --soft ne fera rien, car il s’agit d’une commande permettant de déplacer la tête vers HEAD (à son état actuel). git reset --hard, d’autre part, est logique du fait de ses effets secondaires, il est dit de déplacer la tête sur HEAD et réinitialise l’index et l’arbre de travail sur HEAD.

    Je pense que les raisons pour lesquelles cette opération ne s'applique pas à des fichiers spécifiques par nature doivent être clairement définies: il s'agit en premier lieu de déplacer une tête de branche, en réinitialisant l'arbre de travail et l'index étant une fonctionnalité secondaire.

7
user

Assurez-vous de mettre une barre oblique entre Origin ou amont (source) et la branche réelle:

git reset --hard Origin/branch

ou

git reset --hard upstream/branch`
2
Pascal Nitcheu

Il y a une raison très importante derrière cela: les principes de checkout et reset

En termes Git, checkout signifie "importer dans l’arbre de travail actuel". Et avec git checkout, nous pouvons remplir l’arbre de travail avec les données de la zone any, qu’il s’agisse d’une validation du référentiel ou de fichiers individuels d’une validation ou de la zone intermédiaire ( qui est le même par défaut).

À son tour, git reset n'a pas ce rôle. Comme son nom l'indique, il va réinitialiser la référence actuelle, mais toujours ayant le référentiel comme source, indépendamment de la "portée" (--soft, --mixed ou --hard).

Résumer:

  • checkout: de n'importe où (validation d'index/repo) -> arbre de travail
  • reset: Validation par dépôt -> Ecraser HEAD (et éventuellement index et arbre de travail)

Donc ce qui peut être un peu déroutant est l’existence de git reset COMMIT -- files puisque "écraser HEAD" avec seulement quelques fichiers n’a pas de sens! 

En l'absence d'une explication officielle, je ne peux que supposer que les développeurs git ont découvert que reset était toujours le meilleur nom d'une commande permettant d'annuler les modifications apportées à la zone de transfert et que, étant donné que la seule source de données était le référentiel, "étendons la fonctionnalité "au lieu de créer une nouvelle commande.

Donc git reset -- <files> est déjà un peu exceptionnel: il ne remplacera pas le HEAD. IMHO toutes ces variations seraient des exceptions. Même si nous pouvons concevoir une version --hard, d'autres (par exemple --soft) n'auraient aucun sens.

0
F Pereira