web-dev-qa-db-fra.com

Pourquoi appeler git branch --unset-upstream pour réparer?

Je suis plus novice en ce qui concerne les opérations avancées dans git. Je maintiens mon blog en utilisant le framework de blogging Octopress . Bien qu'Octopress ne fasse l'objet d'aucun développement depuis 2011, il me convient parfaitement et je n'ai donc pas envisagé de changer quoi que ce soit jusqu'à présent.

Pour votre information, mon blog est hébergé sur des pages Github. 

Aujourd'hui, tout en travaillant sur un nouveau message, git status a affiché le message suivant:

On branch source
Your branch is based on 'Origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

Le même message répété pour toutes les commandes suivantes telles que git add ., git commit -m 'message' et git Push Origin source

  • Que signifie le message? 
  • Quelque chose est cassé? 
  • Si oui quoi? 
  • Dois-je le réparer? 

Si possible, veuillez me diriger vers un article pdf/web où je peux lire et comprendre pour l’avenir.

Plus de détails:

bash-3.2$ git branch -a
* source
  remotes/octopress/2.1
  remotes/octopress/HEAD -> octopress/master
  remotes/octopress/gh-pages
  remotes/octopress/linklog
  remotes/octopress/master
  remotes/octopress/refactor_with_tests
  remotes/octopress/rubygemcli
  remotes/octopress/site
  remotes/Origin/source

S'il vous plaît laissez-moi savoir si plus d'informations sont nécessaires. Merci.

122
Jatin Ganhotra

TL; version DR: la branche de suivi à distance Origin/master existait, mais ne l’est pas maintenant. La branche locale source suit donc quelque chose qui n’existe pas, qui est au mieux suspect: cela signifie qu’une autre fonctionnalité de Git ne peut rien faire pour vous. - et Git vous en avertit. Vous vous entendez très bien sans que la fonction de "suivi en amont" fonctionne comme prévu; vous avez donc la possibilité de changer quelque chose.

Pour une autre prise en compte des paramètres en amont, voir Pourquoi dois-je "git Push --set-up-upstream en amont <branche>"?


Cet avertissement est une nouveauté dans Git, apparaissant d’abord dans Git 1.8.5. Les notes de publication ne contiennent qu'un seul élément de balle à ce sujet:

  • "git branch -v -v" (et "git status") ne fait pas la distinction entre un branche qui ne repose sur aucune autre branche, une branche qui se trouve dans synchroniser avec sa branche amont et une branche configurée avec un branche amont qui n'existe plus.

Pour décrire ce que cela signifie, vous devez d’abord connaître les «télécommandes», les «branches de suivi à distance» et la manière dont Git gère le «suivi d’une route en amont». (Branches de suivi à distance est un terme terriblement défectueux. J'ai plutôt commencé à utiliser noms de suivi à distance, ce qui, à mon avis, constitue une légère amélioration. Ci-dessous, je vais utiliser "branche de suivi à distance" pour la cohérence avec la documentation Git.)

Chaque "distant" est simplement un nom, comme Origin ou octopress dans ce cas. Leur but est d’enregistrer des choses comme l’URL complète des lieux à partir desquels vous mettez à jour git fetch ou git pull. Lorsque vous utilisez git fetch remote,1 Git va à cette télécommande (en utilisant l'URL enregistrée) et apporte le jeu de mises à jour approprié. Il utilise également enregistrements les mises à jour, en utilisant des "branches de suivi à distance". 

Une "branche de suivi à distance" (ou nom de suivi à distance) est simplement l'enregistrement d'un nom de branche tel que vu pour la dernière fois sur une "distance". Chaque télécommande est elle-même un référentiel Git, elle a donc des branches. Les branches de "Origin" distantes sont enregistrées dans votre référentiel local sous remotes/Origin/. Le texte que vous avez affiché indique qu'il existe une branche nommée source sur Origin et des branches nommées 2.1, linklog et ainsi de suite le octopress.

(Une branche "normale" ou "locale", bien sûr, est juste un nom de branche que vous avez créé dans votre propre référentiel.)

Enfin, vous pouvez configurer une branche (locale) pour "suivre" une "branche de suivi à distance". Une fois que la branche locale L est configurée pour suivre la branche de suivi à distance R, Git appellera R son "amont" et vous dira si vous êtes "en avance". et/ou "derrière" l'amont (en termes de commits). Il est normal (même recommandé) que la branche locale et les branches suivies à distance utilisent le même nom (à l'exception du préfixe distant), comme source et Origin/source, mais ce n'est pas réellement nécessaire.

Et dans ce cas, cela ne se produit pas. Vous avez une branche locale source effectuant le suivi d'une branche à distance Origin/master.

Vous n'êtes pas censé avoir besoin de connaître les mécanismes exacts de comment Git met en place une branche locale pour suivre une branche distante, mais ils sont pertinents ci-dessous, je vais donc montrer comment cela fonctionne. Nous commençons par le nom de votre agence locale, source. Deux entrées de configuration utilisent ce nom, orthographiées branch.source.remote et branch.source.merge. D'après le résultat que vous avez montré, il est clair que ces deux éléments sont définis, afin que vous puissiez voir ce qui suit si vous exécutez les commandes données:

$ git config --get branch.source.remote
Origin
$ git config --get branch.source.merge
refs/heads/master

Les assembler,2 cela indique à Git que votre branche source suit votre "branche de suivi à distance", Origin/master.

Mais regardons maintenant la sortie de git branch -a, qui montre tous les noms de branches locales et de suivi à distance dans votre référentiel. Les noms de suivi à distance sont répertoriés sous remotes/ ... et il n'y a pas de remotes/Origin/master. On peut supposer qu'il y en a eu un à un moment donné, mais il est parti maintenant.

Git vous dit que vous pouvez supprimer les informations de suivi avec --unset-upstream. Cela effacera branch.source.Origin et branch.source.merge et arrêtera l'avertissement.

Il semble assez probable que ce que vous souhaitiez, cependant, consiste à changer de suivre Origin/master, à suivre quelque chose d'autre: probablement Origin/source, mais peut-être l'un des noms octopress/.

Vous pouvez le faire avec git branch --set-upstream-to,3 par exemple.:

$ git branch --set-upstream-to=Origin/source

(en supposant que vous soyez toujours sur la branche "source", et que Origin/source est celui que vous voulez en amont - je n'ai aucun moyen de dire lequel, le cas échéant, vous voulez réellement).(Voir aussi Comment faire en sorte qu'une branche Git existante suive une branche distante? ).

Je pense que la façon dont vous êtes arrivé ici est que lorsque vous avez créé un git clone, la chose à partir de laquelle vous avez cloné avait une branche master. Vous aviez également une branche master, qui était configurée pour suivre Origin/master (ceci est une configuration standard normale pour git). Cela signifiait que vous aviez branch.master.remote et branch.master.merge définis, à Origin et refs/heads/master. Mais alors votre télécommande Origin a changé son nom de master à source. Pour correspondre, je pense que vous avez également changé votre nom local de master à source. Cela a changé le noms de vos paramètres, de branch.master.remote à branch.source.remote et de branch.master.merge à branch.source.merge ... mais il laissait l'ancien valeurs _, branch.source.merge était donc erroné.

C'est à ce stade que la liaison "en amont" s'est rompue, mais dans les versions de Git antérieures à la 1.8.5, Git n'avait jamais remarqué le paramètre cassé. Maintenant que vous avez la 1.8.5, cela est indiqué.

.


Cela couvre la plupart des questions, mais pas la question "dois-je résoudre ce problème". Il est probable que vous travailliez avec le problème depuis des années en utilisant git pull remote branch (par exemple, git pull Origin source). Si vous continuez à le faire, le problème continuera à être résolu - donc, non, vous n'avez pas besoin pour le résoudre. Si vous le souhaitez, vous pouvez utiliser --unset-upstream pour supprimer l'amont et arrêter les réclamations, sans que la branche locale source ne soit marquée comme ayant (aucun) en amont.

L'intérêt d'avoir un amont est de rendre diverses opérations plus pratiques. Par exemple, git fetch suivi de git merge "agira généralement comme il convient" si l'amont est correctement défini, et git status après git fetch vous dira si votre référentiel correspond à celui en amont de cette branche.

Si vous voulez la commodité, ré-initialisez l'amont.

.


git pull utilise git fetch, et à partir de Git 1.8.4, ceci (enfin!) met également à jour les informations de "branche de suivi à distance". Dans les anciennes versions de Git, les mises à jour n'étaient pas enregistrées dans les branches de suivi à distance avec git pull, mais uniquement avec git fetch. Comme votre Git doit être au moins de la version 1.8.5, ce n'est pas un problème pour vous..

Eh bien, cela, plus une ligne de configuration que j'ignore délibérément, se trouve sous remote.Origin.fetch. Git doit mapper le nom de "fusion" pour déterminer que le nom local complet de la branche distante est refs/remotes/Origin/master. Le mappage fonctionne presque toujours comme cela, cependant, il est donc prévisible que master passe à Origin/master..

Ou, avec git config. Si vous souhaitez simplement définir le code amont sur Origin/source, la seule partie à modifier est branch.source.merge, et git config branch.source.merge refs/heads/source.__ le fera. Mais --set-upstream-to indique quoi que vous voulez faire, plutôt que de vous obliger à le faire vous-même manuellement, ce qui en fait un "meilleur moyen".

165
torek

la réponse de torek est probablement parfaite, mais je voulais simplement que le dossier mentionne un autre cas différent de celui décrit dans la question initiale, mais la même erreur peut apparaître (car cela pourrait aider d'autres personnes ayant un problème similaire):

J'ai créé un nouveau référentiel vide en utilisant git init --bare sur l'un de mes serveurs. Ensuite, je l'ai git cloned dans un espace de travail local sur mon PC.

Après avoir validé une seule version sur le dépôt local, j'ai eu cette erreur après avoir appelé git status

Suite à la réponse de torek, je comprends que ce qui s’est passé est que la première validation sur le référentiel de répertoire de travail local a créé la branche "maître". Mais sur le référentiel distant (sur le serveur), il n'y a jamais rien eu, donc il n'y avait même pas de branche "maître" (télécommandes/origine/maître). 

Après avoir exécuté git Push Origin master à partir du référentiel local, le référentiel distant avait enfin une branche principale. Cela a arrêté l'erreur d'apparaître.

Donc, pour conclure - on peut avoir une telle erreur pour un nouveau repo distant avec zéro commits puisqu'il n'a pas de branche, y compris "maître".

138
ElazarR

Cela pourrait résoudre votre problème.

après avoir apporté des modifications, vous pouvez le commettre, puis 

git remote add Origin https://(address of your repo) it can be https or ssh
then
git Push -u Origin master

j'espère que ça marche pour toi.

merci

7
Ajay Kotnala

Pour moi, .git/refs/Origin/master avait été corrompu.

J'ai fait ce qui suit, ce qui a résolu le problème pour moi.

rm .git/refs/remotes/Origin/master
git fetch
git branch --set-upstream-to=Origin/master
7
smremde

supprimer votre branche locale en suivant la commande

git branch -d branch_name

tu pourrais aussi faire

git branch -D branch_name 

ce qui force fondamentalement une suppression (même si local n'est pas fusionné avec la source)

0
Pravin

J'avais cette question deux fois et cela a toujours été causé par la corruption du fichier de cache git dans ma branche locale. Je l'ai corrigé en écrivant le hachage de commit manquant dans ce fichier. J'ai reçu le bon hachage de validation du serveur et j'ai exécuté la commande suivante localement:

cat .git/refs/remotes/Origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/Origin/feature/mybranch
0
user1106400

En fait, torek vous a déjà expliqué comment utiliser les outils beaucoup mieux que je ne saurais le faire. Cependant, dans ce cas, je pense qu’il est important de signaler quelque chose de particulier si vous suivez les instructions à http://octopress.org/docs/deploying/github/ . Vous aurez notamment plusieurs référentiels github dans votre configuration. Tout d’abord, celui avec tout le code source de votre site Web dans le répertoire $WEBSITE, puis celui contenant uniquement les fichiers statiques résidant dans $WEBSITE/_deploy. La chose amusante de l’installation est qu’il existe un fichier .gitignore dans le répertoire $WEBSITE pour que cette installation fonctionne réellement.

Assez introduction. Dans ce cas, l'erreur peut également provenir du référentiel dans _deploy.

cd _deploy

git branch -a
* master
remotes/Origin/master
remotes/Origin/source

Dans .git/config, vous devrez normalement trouver quelque chose comme ceci:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "Origin"]
    url = [email protected]:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/Origin/*
[branch "master"]
    remote = Origin
    merge = refs/heads/master

Mais dans votre cas, le responsable de la succursale n’a pas de télécommande.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "Origin"]
    url = [email protected]:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/Origin/*

Que vous pouvez résoudre par:

cd _deploy
git branch --set-upstream-to=Origin/master

Donc, tout est comme torek vous l’a dit, mais il peut être important de souligner que cela pourrait très bien concerner le répertoire _deploy plutôt que la racine de votre site Web.

PS: Il pourrait être intéressant d’utiliser un shell tel que zsh avec un plugin git pour ne pas être piqué par cette chose à l’avenir. Il montrera immédiatement que _deploy concerne un référentiel différent.

0
Anne van Rossum