Réinitialiser la branche dépôt local pour être exactement comme la tête du dépôt distant
Comment réinitialiser ma branche locale pour qu'elle ressemble à la branche du dépôt distant?
j'ai fait:
git reset --hard HEAD
mais quand je cours 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é'? Je n'ai pas touché ces fichiers? Si je l'ai fait, je veux les enlever.
19 réponses
configurer votre branche pour qu'elle corresponde exactement à la branche distante peut être fait en deux étapes:
git fetch origin
git reset --hard origin/master
si vous voulez sauvegarder l'état de votre branche actuelle avant de faire ceci (juste au cas), vous pouvez faire:
git commit -a -m "Saving my work, just in case"
git branch my-saved-work
maintenant votre travail est sauvegardé sur la branche "my-saved-work" au cas où vous décidez de le récupérer (ou de le regarder plus tard ou de le comparer à votre branche mise à jour).
noter que le premier exemple suppose que le nom du repo distant est "origin" et que la branche nommée "master" dans le repo distant correspond à la branche actuellement cochée dans votre repo local.
BTW, cette situation dans laquelle vous êtes ressemble terriblement à un cas courant où une poussée a été faite dans la branche actuellement vérifiée d'un dépôt non-nu. Avez-vous récemment poussé dans votre repo local? Si ce n'est pas le cas, alors pas de soucis -- quelque chose d'autre a dû faire que ces fichiers ont été modifiés de manière inattendue. Sinon, vous devez savoir qu'il n'est pas recommandé de pousser dans un dépôt non-nu (et pas dans la branche actuellement cochée, en particulier).
j'avais besoin de faire (la solution dans la réponse acceptée):
git fetch origin
git reset --hard origin/master
suivi de:
git clean -f
pour supprimer les fichiers locaux
Pour voir quels fichiers seront supprimés (sans les supprimer):
git clean -n -f
d'abord, réinitialiser à la HEAD
précédemment récupérée de la branche en amont correspondante:
git reset --hard @{u}
l'avantage de spécifier @{u}
ou sa forme verbeuse @{upstream}
est que le nom de la branche et du repo distants ne doit pas être spécifié explicitement.
ensuite, si nécessaire, supprimer les fichiers non tracés, éventuellement aussi avec -x
:
git clean -df
enfin, comme nécessaire, obtenir les dernières modifications:
git pull
git reset --hard HEAD
ne se réinitialise en fait que dans le dernier état commis. Dans ce cas, HEAD se réfère au responsable de votre succursale.
si vous avez plusieurs commits, cela ne marchera pas..
ce que vous voulez probablement faire, est réinitialisé à la tête d'origine ou peu importe le nom que vous donnez au dépôt distant. Je ferais probablement quelque chose comme
git reset --hard origin/HEAD
faites attention. Les réinitialisations dures ne peuvent pas être défaites facilement. Il est préférable de le faire en Dan suggère, et biffe une copie de vos changements avant de les réinitialiser.
tout ce qui précède suggère sont justes, mais souvent à vraiment réinitialiser votre projet, vous avez également besoin de supprimer même les fichiers qui sont dans votre .gitignore
.
pour obtenir l'équivalent moral de effacer votre répertoire de projet et re-Clonage de la télécommande 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 données (par exemple, choses que vous avez ignorées en utilisant .gitignore
).
la question mélange deux questions ici:
- comment réinitialiser une branche locale au point où la distance est
- comment nettoyer votre zone de transit (et peut-être le répertoire de travail), de sorte que
git status
ditnothing to commit, working directory clean.
one-stop-réponse est:
-
git fetch --prune
(optionnel) met à jour le snapshot local du repo distant. Les autres commandes sont uniquement locales.
git reset --hard @{upstream}
met le pointeur de la branche locale à l'endroit où se trouve le snapshot de la télécommande, ainsi que Place l'index et le répertoire de travail dans les fichiers de cette propagation. -
git clean -d --force
supprime les fichiers et répertoires introuvables qui empêchent git de dire "répertoire de travail propre".
C'est quelque chose que je fais face régulièrement, et j'ai généralisé le script Wolfgang fourni ci-dessus pour travailler avec n'importe quelle branche
j'ai aussi ajouté un "êtes-vous sûr de l'invite", et de la rétroaction de la sortie
#!/bin/bash
# reset the current repository
# WF 2012-10-15
# AT 2012-11-09
# see /q/reset-local-repository-branch-to-be-just-like-remote-repository-head-25365/"+%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
à condition que le dépôt distant soit origin
, et que vous soyez intéressé par branch_name
:
git fetch origin
git reset --hard origin/<branch_name>
Aussi, vous allez pour réinitialiser la branche courante de origin
à HEAD
.
git fetch origin
git reset --hard origin/HEAD
Comment cela fonctionne:
git fetch origin
télécharge la dernière version à distance sans essayer de fusionner ou de reformater quoi que ce soit.
puis le git reset
réinitialisez la branche <branch_name>
à ce que vous venez de récupérer. L'option --hard
modifie tous les fichiers de votre arborescence de travail pour faire correspondre les fichiers de origin/branch_name
.
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 supporte les branches
#!/bin/bash
# reset the current repository
# WF 2012-10-15
# see /q/reset-local-repository-branch-to-be-just-like-remote-repository-head-25365/"+%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
j'ai fait:
git branch -D master
git checkout master
pour réinitialiser totalement la branche
note, vous devez quitter une autre branche pour pouvoir supprimer la branche requise
Si vous aviez un problème que moi, que vous avez déjà commis quelques changements, mais maintenant, pour une raison quelconque vous souhaitez vous en débarrasser, le moyen le plus rapide est d'utiliser des git reset
comme ceci:
git reset --hard HEAD~2
j'ai eu 2 ne sont pas nécessaires s'engage, par conséquent, le nombre 2. Vous pouvez le changer en votre propre nombre de commits à réinitialiser.
donc, pour répondre à votre question - si vous êtes 5 commits avant la tête du dépôt distant, vous devez exécuter cette commande:
git reset --hard HEAD~5
notez que vous perdrez les changements que vous avez faits, alors faites attention!
si vous voulez revenir à l'état HEAD
pour le répertoire de travail et l'index, alors vous devez git reset --hard HEAD
, plutôt que HEAD^
. (Cela peut avoir été une faute de frappe, tout comme le simple versus double tiret pour --hard
.)
en ce qui concerne votre question spécifique sur la raison pour laquelle ces fichiers apparaissent dans le statut tel que modifié, il semble que vous avez peut-être fait une réinitialisation douce au lieu d'une réinitialisation dure. Cela provoquera les fichiers qui ont été changés dans HEAD
s'engagent à apparaître comme si elles étaient mises en scène, ce qui est probablement ce que vous voyez ici.
les réponses précédentes supposent que la branche à réinitialiser est la branche courante (cochée). Dans ses commentaires, L'OP hap497 a précisé que la succursale était bel et bien cochée, mais que la question initiale ne l'exigeait pas explicitement. Puisqu'il y a au moins une question "dupliquer", réinitialiser complètement la branche à l'état de dépôt , qui ne suppose pas que la branche est cochée, voici une alternative:
si branche "mybranch" est pas en cours d'extraction, de le réinitialiser à distance de la branche "myremote/mybranch"'s la tête, vous pouvez utiliser ce de bas niveau "151960920 de la commande":
git update-ref refs/heads/mybranch myremote/mybranch
cette méthode laisse la branche cochée telle qu'elle est, et l'arbre qui travaille intact. Il déplace simplement la tête de mybranch à un autre commit, peu importe ce qui est donné comme deuxième argument. Ceci est particulièrement utile si plusieurs branches doivent être mises à jour vers de nouvelles têtes distantes.
faites attention en faisant cela, cependant, et utilisez gitk
ou un outil similaire pour vérifier la source et la destination. Si vous faites accidentellement cela sur la branche courante (et git ne vous empêchera pas de le faire), vous pouvez devenir confus, parce que le contenu de la nouvelle branche ne correspond pas à l'arbre de travail, qui n'a pas changé (pour corriger, mettre à jour la branche de nouveau, à l'endroit où elle était avant).
aucune quantité de réinitialisation et de nettoyage ne semblait avoir d'effet sur les fichiers non tracés et modifiés dans mon repo git local (j'ai essayé toutes les options ci-dessus). Ma seule solution était de rm locales repo et re-cloner à partir de la télécommande.
heureusement, je n'avais pas d'autres branches dont je me souciais.
la seule solution qui fonctionne dans tous les cas que j'ai vu est de supprimer et reclone. Peut-être qu'il y a un autre moyen, mais évidemment, ce moyen ne laisse aucune chance à l'ancien état d'être laissé là, donc je le préfère. Bash one-liner que vous pouvez définir comme une macro si vous gâchez 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 votre .les fichiers git ne sont pas corrompus
si vous voulez réinitialiser votre branche locale à la dernière propagation dans la branche amont, ce qui fonctionne pour moi jusqu'à présent est:
Vérifiez vos télécommandes, assurez-vous que votre amont et votre origine sont ce que vous attendez, si ce n'est pas comme prévu , utilisez git remote add upstream <insert URL>
, par exemple de l'original GitHub repo que vous avez bifurqué, 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;
ou:
git fetch upstream master;
git reset --hard upstream/master;
git clean -d --force;
sur GitHub, vous pouvez également vérifier la branche avec le même nom que le local, afin de sauvegarder le travail là, bien que cela ne soit pas nécessaire si origin develop a les mêmes changements que la branche locale saved-work. J'utilise la branche develop comme exemple, mais cela peut être n'importe quel nom de branche existant.
git add .
git commit -m "Reset to upstream/develop"
git push --force origin develop
alors si vous avez besoin de fusionner ces changements avec une autre branche alors qu'il y a des conflits, en préservant les changements en développement, utilisez:
git merge -s recursive -X theirs develop
en cours d'utilisation
git merge -s recursive -X ours develop
pour préserver les modifications conflictuelles de branch_name. Sinon, utilisez 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 de upstream/develop vous pouvez utiliser un hachage de propagation, un autre nom de branche, etc. Utilisez un outil CLI tel que Oh My Zsh pour vérifier que votre branche est verte en indiquant qu'il n'y a rien à propager et que le répertoire de travail est propre (ce qui est confirmé ou aussi vérifiable par git status
). Notez que ceci peut en fait ajouter des propagations par rapport au développement amont s'il y a quelque chose automatiquement ajouté par une propagation, par exemple des diagrammes UML, des en-têtes de licence, etc., donc dans ce cas , vous pourriez alors tirer les changements sur origin develop
à upstream develop
, si nécessaire.
utiliser reset -- soft origin/ ce sera réinitialisé à l'origine de la tête, et vous donnent la possibilité de travailler avec les changements. ceux-ci peuvent être éliminés ou
si cela ne vous dérange pas de sauvegarder vos modifications locales, mais que vous voulez tout de même mettre à jour votre dépôt pour qu'il corresponde à l'origine / à la tête, vous pouvez simplement cacher vos modifications locales et ensuite tirer:
git stash
git pull
si vous voulez que les modifications actuelles soient utilisées plus tard, alors gardez les modifications sinon vous pouvez utiliser ces deux commandes,
git fetch origin
git reset --hard origin/master