Git Push: Refs / Heads / My / Subbranch existiert, kann nicht erstellen

87

Ist es nicht möglich, einen Unterordner in einem Repo auf einem Server zu erstellen?

wenn ich mache:

git push origin dev/master 

alles arbeit finden

aber wenn ich es mache

git push origin dev/sub/master

Ich schaff das:

error: 'refs/heads/dev/sub' exists; cannot create 'refs/heads/dev/sub/master'

Ich habe mit "git branch -r" und direkt mit ssh nachgesehen, es ist noch kein dev / sub-Ordner erstellt.

was ist los?

Snyf
quelle
1
Was gibt git ls-remote origin zurück?
Ikke

Antworten:

156

Es ist kein Ordner , der existiert, es ist ein Zweig . (Nun, möglicherweise ist irgendwo ein Ordner / Verzeichnis beteiligt - oder auch nicht, da Referenzen "gepackt" werden und nicht mehr als Dateien in Verzeichnissen vorhanden sind.)

  • Wenn ein Zweig bvorhanden ist, kann kein Zweig mit dem Namen b/anythingerstellt werden.
  • Wenn keine Verzweigung dev/bvorhanden ist, dev/b/ckann diese ebenfalls nicht erstellt werden.

Dies ist eine git-interne Einschränkung. In diesem speziellen Fall hat die Fernbedienung origineinen Zweig mit dem Namen dev/sub(unabhängig davon, ob Sie ihn haben oder nicht, ist es wichtig, ob die Fernbedienung ihn hat). Um auf zu erstellen origin, mit dem Namen ein Zweig dev/sub/master, müssen Sie zuerst den Zweig löschen Namen dev/subauf origin:

git push origin :dev/sub

(Natürlich kann diesen Zweig zu löschen etwas löschen wichtig es über, so sicher sein , wissen Sie , was Sie tun. Im Allgemeinen, könnten Sie wollen git fetch originzuerst, die Erfassung ihrer dev/subals origin/dev/sub. Anschließend können Sie eine lokale Niederlassung machen namens dev/renamed-subzeigt auf die gleiche begehen , dev/renamed-subauf der Fernbedienung erstellen, die Fernbedienung löschen dev/subund dann dev/sub/masterauf der Fernbedienung erstellen .)


Wenn Sie sich auf der Fernbedienung (dem System, auf dem origingehostet wird) anmelden können , können Sie dort in das Repository gehen und einfach den lokalen dev/subZweig umbenennen . (Aufgrund der folgenden Kommentare vermute ich, dass es dort auch ein defektes Skript für die automatische Bereitstellung gibt, das wahrscheinlich behoben werden sollte, um nur "bereitstellbare" Zweige bereitzustellen, anstatt alles, was gepusht wird. Aber ich rate hier nur.)

torek
quelle
1
Ich denke, wir beschäftigen uns hier nur mit der Terminologie. Durch die „innere Begrenzung“ meine ich , es ist etwas , git ohne Änderung , wie jemand überwinden konnte Verwendungen git. Eine uneingeschränkte Einschränkung wäre viel grundlegender, z. B. wenn jemand SHA1 bricht: Während selbst dies überwunden werden könnte (z. B. zu SHA256 übergehen), werden die Details von SHA-1 mit 40 Zeichen in z. B. den meisten Hooks offengelegt. Diese Einschränkung tritt also in externe Bereiche ein.
Torek
2
Das ist eine seltsam irritierende Einschränkung, vorausgesetzt, Sie möchten release/1.1und release/1.2mit release/1.1/hofix/prevent-upload-bork& release/1.1/hotfix/assure-user-of-competenceusw. haben. Und die Fehlermeldung führt hierher (danke), anstatt die Einschränkung anzugeben! Aber danke für die einfache und klare Erklärung.
Benjohn
2
"Dies ist eine interne Einschränkung." -- OK, aber warum? War eine Logik auf diese Weise einfacher zu implementieren? Oder eine Baumdurchquerung? Oder was?
D. Kovács
2
@ D.Kovács: Indem Git diesen Fall verbietet, kann es einfach Referenz-Hashes in Dateien schreiben, deren Name erzeugt wird, indem die Referenz als Pfadname behandelt wird. Wenn Git beides zulässt refs/tags/foound dies refs/tags/foo/2beispielsweise nicht kann, muss es einen eigenen Schlüsselwertspeicher implementieren. Ich denke, Git wird sowieso gezwungen sein, einen eigenen Schlüsselwertspeicher zu implementieren, aber ich weiß nicht, ob sie die Einschränkung dann aufheben werden.
Torek
1
@ ĐinhAnhHuy: Ich kenne keine formale Dokumentation, die diese Einschränkung beschreibt. Submodule befinden sich jedoch in einem völlig separaten Namensraum: Submodulnamen und Zweignamen sollten nicht auf die gleiche Weise kollidieren, wie Zweignamen und Dateinamen nicht kollidieren (dh, aber Sie fügen einen Disambiguator hinzu: git checkout -- masterbedeutet Auschecken die benannte Dateimaster anstelle des Zweignamens).
Torek
60

Ich befand mich in einem Zustand, in dem ich nicht einmal abrufen konnte, weil mein Repo Informationen über nicht vorhandene Remote-Filialen enthielt, die ich nicht einmal ausgecheckt hatte. Ich habe es gelöst, indem ich eine Kombination (danke @torek) von:

  • git branch -r lokale Kopien von Remote-Zweigen auflisten
  • git ls-remote Remote-Zweige auflisten
  • git fetch --prune originlokale Kopien von Remote-Zweigen aktualisieren ( das hat mir eigentlich nicht geholfen )
  • git remote prune originInformationen über entfernte Remote-Zweige entfernen ( dies tat es )
Meridius
quelle
8
git remote prune originwar der einzige Befehl, den ich ausgeführt habe, um diesen Fehlerstatus zu beheben. In der Tat eine irreführende Nachricht - in meinem Fall habe ich versucht, eine "Version / 2.6.0" zu pushen, und ich hatte das gesamte Verzeichnis "refs / remotes / origin / release *" entfernt -, aber git beschwerte sich error: update_ref failed for ref 'refs/remotes/origin/release/2.6.0': cannot lock ref 'refs/remotes/origin/release/2.6.0': 'refs/remotes/origin/release' exists; cannot create 'refs/remotes/origin/release/2.6.0'immer wieder, wenn ich Push / Pull / Fetch versuchte
Conny
32

Für mich ->

Fehler =

fatal: cannot lock ref 'refs/heads/release/wl/2.3': 'refs/heads/release/wl' 
exists; cannot create 'refs/heads/release/wl/2.3'

Lösung =

$~ git update-ref -d refs/heads/release/wl
$~ git checkout release/wl/2.3
MEZIDI Hamza
quelle
1
git update-ref -d refs / remotes ... hat mein Problem gelöst, dass 'refs / remotes / origin / hotfix' existiert; kann 'refs / remotes / origin / hotfix / ISSUE ...
Eduardo
Es hat auch mein Problem behoben.
Mikhail Morfikov
16

Die aktuell akzeptierte Antwort hat mir nicht geholfen, da ich keinen Ref auf dem Remote-Repo zum Löschen hatte - es war nur auf meinem lokalen! Wenn Sie sich in dieser Situation befinden, gehen Sie wie folgt vor:

Dies ist das Problem, mit dem ich konfrontiert war:

$ git fetch origin
error: cannot lock ref 'refs/remotes/origin/fix/sub-branch': 
'refs/remotes/origin/fix' exists; cannot create 
'refs/remotes/origin/fix/sub-branch'
From <repo URL>
 ! [new branch]      fix/sub-branch          -> origin/fix/sub-branch
 (unable to update local ref)

Ich habe den Vorschlag der akzeptierten Antwort ausprobiert, aber Folgendes erhalten:

$ git push origin :fix
error: unable to delete 'fix': remote ref does not exist
error: failed to push some refs to <repo URL>

Der Schiedsrichter existierte also nicht einmal origin- er hing eindeutig nur irgendwo auf meinem lokalen Repo herum. Also rannte ich $ git remote show me, was produzierte:

Remote branches:
...
refs/remotes/origin/fix             stale (use 'git remote prune' to remove)
...

Was dann die Lösung klar machte:

$ git remote prune origin
Pruning origin
URL: <redacted>
 * [pruned] origin/fix

Damit verschwand das Problem:

$ git fetch origin
remote: Counting objects: 5, done.
remote: Total 5 (delta 2), reused 2 (delta 2), pack-reused 3
Unpacking objects: 100% (5/5), done.
From <repo URL>
 * [new branch]      fix/sub-branch          -> origin/fix/sub-branch
awreccan
quelle
3
Ja, das gleiche Problem, auf das Sie gestoßen sind und das Sie git remote prune originbehoben haben. Vielen Dank!
ToddH
3

Versuchen Sie diesen Befehl, um das Problem zu beheben:

git gc

um eine Reihe von Verwaltungsaufgaben im aktuellen Repository auszuführen und nicht erreichbare Objekte zu entfernen (durch Aufrufen von git pruneund git fsck --unreachable).

Lesen Sie mehr: git help gcundgit help prune

Kenorb
quelle
2

Wenn alles andere fehlschlägt, überprüfen Sie, ob Ihr Repo-System keine Einschränkungen für Filialnamen aufweist. In meinem Fall konnten Sie nur Zweige erstellen, die mit beginnen SD-<number>. Jede andere Benennung würde Ihnen nur eine generische geben:

remote: error: cannot lock ref 'refs/heads/mybranch': 'refs/heads/mybranch/environment-variables' exists; cannot create 'refs/heads/mybranch'
To git.example.com:project/repository.git
 ! [remote rejected] mybranch -> mybranch (failed to update ref)
error: failed to push some refs to '[email protected]:project/repository.git'
Juha Untinen
quelle
1
#!/usr/bin/env bash
echo "update-ref delete refs/tags"
log="git-update-ref-errors.log"
script="./git-update-ref-exist-tags-delete.sh"
git_command="git update-ref -d refs/tags"

echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors to ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}

echo fetch
log="git-fetch-errors.log"
script="./git-fetch-exist-tags-delete.sh"
git_command="git fetch"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git fetch

echo pull
log="git-pull-errors.log"
script="./git-pull-exist-tags-delete.sh"
git_command="git pull"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git pull

echo push
log="git-push-errors.log"
script="./git-push-exist-tags-delete.sh"
git_command="git push"
echo "log errors from ${git_command} to ${log}"
${git_command} 2>&1 | > ${log}
echo "show errors from ${log}"
cat ${log}
echo create ${script}
touch ${script}
echo "add execute (+x) permissions to ${script}"
chmod +x ${script}
echo "generate ${script} from errors log ${log}"
${git_command} 2>&1 | grep 'exists' | sed -n "s:.*\: 'refs/tags/\(.*\)' exists;.*:git tag -d '\1':p" >> ${script}
echo "execute ${script}"
${script}
git push

Das obige Skript protokolliert Fehler in XXX-Errors.log und behebt sie, indem eine XXX-exist-tags-delete.sh automatisch aus dem XXX-Errors.log mit den folgenden Befehlen generiert und ausgeführt wird:

  1. git update-ref -d refs / tags
  2. Git holen
  3. Git Pull
  4. Git Push
Tomer Bar-Shlomo
quelle
1

git remote prune origin Das Problem wurde für mich behoben

Andrea Gherardi
quelle
1

Als Windows-Benutzer hat keine der bisherigen Lösungen das Problem für mich gelöst. Der Grund, warum ich diesen Fehler sah, war, dass ich (unter Verwendung der Zweigstellennamen des OP) versuchte, einen Zweig zu erstellen, dev/subaber jemand anderes einen Zweig namens erstellt hatte Devund wie wir alle wissen, hat Windows ein Dateisystem, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird.

Als Windows versuchte dev/sub, den Ordner herunterzuziehen , versuchte es zunächst, den Ordner zu erstellen dev, konnte dies jedoch nicht, da er Devbereits vorhanden war.

Die Lösung bestand darin, den DevZweig lokal und remote mit zu löschen git branch -d Dev && git push origin :Dev. A git pulldanach lief gut.

Eine weitere Lektion für die Zukunft: Zweignamen sollten immer in Kleinbuchstaben geschrieben werden, um diese Art von Fallstricken zu vermeiden.

alexkb
quelle
1

Ich verstehe, dass dies bereits beantwortet wurde, aber es hat bei mir nicht funktioniert. Ich habe mich nicht um lokale Änderungen gekümmert, da diese bereits hochgeschoben wurden, aber Probleme beim Zurückziehen hatten. In meinem Fall haben wir auf halbem Weg zwischen "Hotfix" als Verzweigung und Ordnersystem mit übergeordnetem Ordner als "Hotfix" gewechselt.

- hotfix ---- hotfix / 1234_bug ---- hotfix / 3456_bug

Also bekam ich folgenden Fehler:

Fetching from origin Error: cannot lock ref 'refs/remotes/origin/hotfix/1234_bug': 'refs/remotes/origin/hotfix' exists; cannot create 'refs/remotes/origin/hotfix'

Nach der Suche nach ähnlichen Fehlern schließlich fand ich Lösung auf einen Diskussionsthread hier .

git remote prune origin
Sanjay Zalke
quelle
0
git checkout -b hotfix/my-new-branch

ga
gm "my commit"

gp --set-upstream origin hotfix/subscribers-function
Blenden
quelle
0

Umbenennen dev/subin dev/sub/something, dann können Sie einen Zweig erstellen dev/sub/master.

Catanore
quelle