web-dev-qa-db-fra.com

Réinitialiser la branche de référentiel local pour qu’elle soit comme un référentiel distant HEAD

Comment réinitialiser ma branche locale pour qu'elle ressemble à la branche du référentiel distant?

J'ai fait:

git reset --hard HEAD

Mais quand je lance un git status,

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
      modified:   Java/com/mycompany/TestContacts.Java
      modified:   Java/com/mycompany/TestParser.Java

Pouvez-vous s'il vous plaît me dire pourquoi j'ai ces "modifiés"? Je n'ai pas touché à ces fichiers? Si je le faisais, je veux les supprimer.

3291
hap497

Régler votre branche pour qu'elle corresponde exactement à la branche distante peut être réalisée en deux étapes:

git fetch Origin
git reset --hard Origin/master

Si vous voulez sauvegarder l'état de votre branche actuelle avant de le faire (au cas où), vous pouvez faire:

git commit -a -m "Saving my work, just in case"
git branch my-saved-work

Maintenant, votre travail est enregistré sur la branche "my-saved-work" au cas où vous décideriez de le récupérer (ou de le regarder plus tard ou de le comparer à votre branche mise à jour).

Notez que le premier exemple suppose que le nom du référentiel distant est "Origine" et que la branche "maître" du référentiel distant correspond à la branche actuellement extraite de votre référentiel local.

BTW, cette situation dans laquelle vous vous trouvez ressemble énormément à un cas classique dans lequel une diffusion a été effectuée dans la branche actuellement extraite d'un référentiel non exposé. Avez-vous récemment accédé à votre dépôt local? Si ce n'est pas le cas, pas d'inquiétude: quelque chose d'autre a dû causer la modification inattendue de ces fichiers. Autrement, vous devez savoir qu'il n'est pas recommandé de placer un fichier dans un référentiel non-nu (et non dans la branche actuellement extraite, en particulier).

5738
Dan Moulding

Je devais faire (la solution dans la réponse acceptée):

git fetch Origin
git reset --hard Origin/master

Suivi par:

git clean -f

pour supprimer les fichiers locaux

Pour voir quels fichiers seront supprimés (sans les supprimer réellement):

git clean -n -f
340
Akavall

Tout d’abord, réinitialisez la HEAD précédemment extraite de la branche en amont correspondante:

git reset --hard @{u}

L'avantage de spécifier @{u} ou sa forme commentée @{upstream} est que le nom du référentiel et de la branche distants ne doit pas être explicitement spécifié.

Ensuite, si nécessaire, supprimez les fichiers non suivis, éventuellement aussi avec -x:

git clean -df

Enfin, si nécessaire, obtenez les dernières modifications:

git pull
221
Acumenus

git reset --hard HEAD ne réinitialise en fait que le dernier état validé. Dans ce cas, HEAD fait référence au HEAD de votre branche.

Si vous avez plusieurs commits, cela ne fonctionnera pas.

Ce que vous voulez probablement faire est de réinitialiser la tête d’origine ou le nom de votre référentiel distant. Je ferais probablement quelque chose comme

git reset --hard Origin/HEAD

Attention cependant. Les réinitialisations dures ne peuvent pas être facilement annulées. Il est préférable de faire ce que suggère Dan et de créer une copie de vos modifications avant de procéder à la réinitialisation.

102
Mikael Ohlson

Toutes les suggestions ci-dessus sont correctes, mais souvent réellement réinitialiser votre projet, vous devez également supprimer les fichiers contenus dans votre .gitignore .

Pour obtenir l'équivalent moral de effacer votre répertoire de projet et ré-cloner de la télécommande, c'est:

git fetch
git reset --hard
git clean -x -d -f

Avertissement: git clean -x -d -f est irréversible et vous risquez de perdre des fichiers et des données (par exemple des choses que vous avez ignorées avec .gitignore).

68
Christopher Smith

La question mélange deux questions ici:

  1. comment réinitialiser une branche locale au point où se trouve la télécommande
  2. comment effacer votre zone de stockage intermédiaire (et éventuellement le répertoire de travail), de sorte que git status dise nothing to commit, working directory clean.

Le guichet unique est:

  1. git fetch --Prune (facultatif) Met à jour l'instantané local du référentiel distant. Les autres commandes sont uniquement locales.
    git reset --hard @{upstream}Place le pointeur de la branche locale sur l'emplacement de la capture instantanée de la télécommande et définit l'index et le répertoire de travail sur les fichiers de cette validation.
  2. git clean -d --force Supprime les fichiers et les répertoires non suivis empêchant git de dire "répertoire de travail propre".
36
Robert Siemer

C’est quelque chose que je rencontre régulièrement et j’ai généralisé le script fourni par Wolfgang ci-dessus pour fonctionner avec n’importe quelle branche.

J'ai également ajouté un message "êtes-vous sûr" et quelques commentaires

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# AT 2012-11-09
# see http://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
branchname=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`
read -p "Reset branch $branchname to Origin (y/n)? "
[ "$REPLY" != "y" ] || 
echo "about to auto-commit any changes"
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  echo "Creating backup auto-save branch: auto-save-$branchname-at-$timestamp"
  git branch "auto-save-$branchname-at-$timestamp" 
fi
echo "now resetting to Origin/$branchname"
git fetch Origin
git reset --hard Origin/$branchname
21
Andrew Tulloch

Si le référentiel distant est Origin et que vous êtes intéressé par branch_name:

git fetch Origin
git reset --hard Origin/<branch_name>

Aussi, vous allez pour réinitialiser la branche actuelle de Origin à HEAD.

git fetch Origin
git reset --hard Origin/HEAD

Comment ça marche:

git fetch Origin télécharge le dernier en date à partir de la télécommande sans essayer de fusionner ou de rebaser quoi que ce soit.

Ensuite, le git reset réinitialise la branche <branch_name> à ce que vous venez d'extraire. L'option --hard modifie tous les fichiers de votre arbre de travail pour qu'ils correspondent à ceux de Origin/branch_name.

13
eigenharsha

Utilisez les commandes ci-dessous. Ces commandes vont aussi supprimer tous les fichiers non suivis de git local

git fetch Origin
git reset --hard Origin/master
git clean -d -f
13
Jamsheer

Voici un script qui automatise ce que la réponse la plus populaire suggère ... Voir https://stackoverflow.com/a/13308579/1497139 pour une version améliorée qui prend en charge les branches

#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see https://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head
timestamp=`date "+%Y-%m-%d-%H_%M_%S"`
git commit -a -m "auto commit at $timestamp"
if [ $? -eq 0 ]
then
  git branch "auto-save-at-$timestamp" 
fi
git fetch Origin
git reset --hard Origin/master
13
Wolfgang Fahl

J'ai fait:

git branch -D master
git checkout master

réinitialiser totalement la branche


notez que vous devriez passer à une autre branche pour pouvoir supprimer la branche requise.

12
user2846569

Si vous aviez un problème comme moi, que vous aviez déjà commis des modifications, mais que, pour une raison quelconque, vous voulez vous en débarrasser, le moyen le plus rapide consiste à utiliser git reset comme ceci:

git reset --hard HEAD~2

J'avais 2 commits non nécessaires, d'où le nombre 2. Vous pouvez le changer pour votre propre nombre de commits à réinitialiser.

Donc, pour répondre à votre question - si vous êtes 5 commissions avant le référentiel distant HEAD, vous devez exécuter cette commande:

git reset --hard HEAD~5

Notez que vous allez perdre les modifications que vous avez apportées, alors faites attention!

8
Karol

C'est ce que j'utilise souvent:

git fetch upstream master;
git reset --hard upstream/master;
git clean -d --force;

Notez qu'il est judicieux de ne pas modifier votre maître local, mais de passer à une autre branche pour toute modification, le nom de la branche étant précédé du nom du type de modification, par exemple. feat/, chore/, fix/, etc. Ainsi, il vous suffit d'extraire les modifications et non de les transmettre au maître. Même chose pour les autres branches auxquelles d’autres contribuent. Donc, ce qui précède ne devrait être utilisé que si vous avez validé des modifications dans une branche que d'autres ont validée et que vous devez réinitialiser. Sinon, à l'avenir, évitez de pousser vers une branche que d'autres Push to, au lieu de checkout et Push vers ladite branche via la branche extraite.

Si vous souhaitez réinitialiser votre branche locale sur la dernière validation dans la branche en amont, ce qui fonctionne pour moi jusqu'à présent est la suivante:

Vérifiez vos télécommandes, assurez-vous que votre amont et votre origine correspondent à ce que vous attendez. Sinon, utilisez git remote add upstream <insert URL>, par exemple. du repo GitHub original que vous avez créé et/ou git remote add Origin <insert URL of the forked GitHub repo>.

git remote --verbose

git checkout develop;
git commit -m "Saving work.";
git branch saved-work;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force

Sur GitHub, vous pouvez également extraire la branche avec le même nom que la branche locale, afin de sauvegarder le travail là-bas, bien que cela ne soit pas nécessaire si Origin develop a les mêmes modifications que la branche locale. J'utilise la branche develop comme exemple, mais il peut s'agir de n'importe quel nom de branche existant.

git add .
git commit -m "Reset to upstream/develop"
git Push --force Origin develop

Ensuite, si vous devez fusionner ces modifications avec une autre branche en cas de conflit, tout en préservant les modifications dans develop, utilisez:

git merge -s recursive -X theirs develop

Tout en utilisant

git merge -s recursive -X ours develop

pour préserver les modifications conflictuelles du nom de branche. Sinon, utilisez un outil mergetool avec git mergetool.

Avec tous les changements ensemble:

git commit -m "Saving work.";
git branch saved-work;
git checkout develop;
git fetch upstream develop;
git reset --hard upstream/develop;
git clean -d --force;
git add .;
git commit -m "Reset to upstream/develop";
git Push --force Origin develop;
git checkout branch_name;
git merge develop;

Notez qu’au lieu d’amont/développement, vous pouvez utiliser un hachage de validation, un autre nom de branche, etc. Utilisez un outil de la CLI tel que Oh My Zsh pour vérifier que votre branche est verte, ce qui indique qu’il n’ya rien à valider et que le répertoire de travail est propre ( qui est confirmé ou également vérifiable par git status). Notez que cela peut en fait ajouter des commits par rapport au développement en amont s’il ya quelque chose qui est ajouté automatiquement par un commit, par exemple. Diagrammes UML, en-têtes de licence, etc., vous pouvez alors extraire les modifications de Origin develop en upstream develop, si nécessaire.

6
James Ray

Les réponses précédentes supposent que la branche à réinitialiser est la branche actuelle (extraite). Dans les commentaires, OP hap497 a expliqué que la branche est bien extraite, mais cela n’est pas explicitement requis par la question initiale. Puisqu'il existe au moins une question "dupliquée", réinitialisation complète de la branche sur l'état du référentiel , ce qui ne suppose pas que la branche est extraite, voici une alternative:

Si la branche "mybranch" est pas actuellement extraite, pour la réinitialiser à la tête de la branche distante "myremote/mybranch", vous pouvez l'utiliser - bas nivea commande:

git update-ref refs/heads/mybranch myremote/mybranch

Cette méthode laisse la branche extraite en l'état et l'arborescence de travail intacte. Cela déplace simplement la tête de ma branche vers un autre commit, quel que soit le deuxième argument. Ceci est particulièrement utile si plusieurs branches doivent être mises à jour vers de nouvelles têtes distantes.

Soyez prudent lorsque vous procédez ainsi et utilisez gitk ou un outil similaire pour vérifier deux fois la source et la destination. Si vous faites ceci accidentellement sur la branche courante (et que git ne vous en empêchera pas), vous risquez de vous perdre, car le contenu de la nouvelle branche ne correspond pas à l’arbre de travail qui n’a pas changé (pour réparer, mettez à jour la branche à nouveau, à où il était avant).

5
Rainer Blome

Si vous souhaitez revenir à l'état HEAD pour le répertoire de travail et l'index, vous devez alors git reset --hard HEAD, plutôt que de HEAD^. (C’était peut-être une faute de frappe, tout comme le tiret simple contre le tiret double pour --hard.)

En ce qui concerne votre question spécifique sur la raison pour laquelle ces fichiers apparaissent dans le statut modifié, il semble que vous ayez peut-être effectué une réinitialisation logicielle au lieu d'une réinitialisation matérielle. Ainsi, les fichiers modifiés dans le HEAD commit apparaîtront comme s'ils avaient été mis en scène, ce qui correspond probablement à ce que vous voyez ici.

5
Emil Sit

Aucune réinitialisation ni nettoyage ne semblent avoir d'effet sur les fichiers non suivis et modifiés dans mon dépôt local git (j'ai essayé toutes les options ci-dessus). Ma seule solution à ce problème consistait à rechercher le référentiel local et à le cloner de nouveau à partir de la télécommande.

Heureusement, je ne m'occupais pas d'autres branches.

xkcd: Git

3
Martin

La seule solution qui fonctionne dans tous les cas que j'ai vus consiste à supprimer et à refermer. Peut-être y a-t-il un autre moyen, mais de toute évidence, ce moyen ne laisse aucune chance de laisser l'ancien État là-bas, alors je le préfère. Bash one-liner vous pouvez définir comme une macro si vous gâtez souvent les choses en git:

REPO_PATH=$(pwd) && GIT_URL=$(git config --get remote.Origin.url) && cd .. && rm -rf $REPO_PATH && git clone --recursive $GIT_URL $REPO_PATH && cd $REPO_PATH

* suppose que vos fichiers .git ne sont pas corrompus

0
sudo