wake-up-neo.com

alte alte Git-Zweige aufräumen

Hier ist mein Git Workflow.

Ich arbeite auf zwei verschiedenen Computern (A und B) und speichere ein gemeinsames git remote im Dropbox-Verzeichnis.

Nehmen wir an, ich habe zwei Zweige, Meister und Entwicklung. Beide verfolgen ihre entfernten Kollegen Origin/master und Origin/devel.

Nun lösche ich auf Computer A die Zweigentwicklung - sowohl lokal als auch remote - wie folgt:

git Push Origin :heads/devel

git branch -d devel

Wenn ich jetzt git branch -a auf Computer A mache, bekomme ich

master
Origin/HEAD
Origin/master

Ich gehe jetzt zu Computer B. Do git fetch. Ich kann den lokalen Entwicklungszweig durch entfernen

git branch -d devel

Ich kann den Remote-Entwicklungszweig jedoch nicht entfernen.

git Push Origin :heads/devel

error: unable to Push to unqualified destination: heads/proxy3d
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.
fatal: The remote end hung up unexpectedly

In git branch -a werden weiterhin Origin/Entwicklung in entfernten Zweigen aufgeführt.

Wie kann ich die entfernte Eingabe von Entwicklung von Maschine B bereinigen?

564
Jayesh

Was ist das Ergebnis von git branch -a auf Maschine B?

Zweitens haben Sie heads/devel bereits auf Origin gelöscht. Aus diesem Grund können Sie es nicht aus Maschine B löschen.

Versuchen

git branch -r -d Origin/devel

oder

git remote Prune Origin

oder

git fetch Origin --Prune

sie können am Ende Ihrer git-Anweisung --dry-run hinzufügen, um das Ergebnis der Ausführung anzuzeigen, ohne es tatsächlich auszuführen. 

1069
Jakub Narębski

Betrachten zu laufen:

git fetch --Prune

In regelmäßigen Abständen werden in jedem Repo lokale Zweige entfernt, die einen entfernten Zweig verfolgt haben, der gelöscht wurde (im Remote-GIT-Repo nicht mehr vorhanden).

Dies kann durch weiter vereinfacht werden

git config remote.Origin.Prune true

dies ist eine per-repo-Einstellung, die jeden zukünftigen git fetch or git pull automatisch in Prune umwandelt.

Um dies für Ihren Benutzer einzurichten, können Sie auch die globale .gitconfig-Datei bearbeiten und hinzufügen

[fetch]
    Prune = true

Es wird jedoch empfohlen, dies mit dem folgenden Befehl auszuführen:

git config --global fetch.Prune true

oder systemweit anwenden (nicht nur für den Benutzer)

git config --system fetch.Prune true
67
Arif

Hier ist ein bash-Skript, das es für Sie tun kann. Es ist eine modifizierte Version von http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git script. Meine Modifikation ermöglicht es, verschiedene entfernte Standorte zu unterstützen.

#!/bin/bash

current_branch=$(git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$current_branch" != "master" ]; then
  echo "WARNING: You are on branch $current_branch, NOT master."
fi
echo -e "Fetching merged branches...\n"

git remote update --Prune
remote_branches=$(git branch -r --merged | grep -v '/master$' | grep -v "/$current_branch$")
local_branches=$(git branch --merged | grep -v 'master$' | grep -v "$current_branch$")
if [ -z "$remote_branches" ] && [ -z "$local_branches" ]; then
  echo "No existing branches have been merged into $current_branch."
else
  echo "This will remove the following branches:"
  if [ -n "$remote_branches" ]; then
echo "$remote_branches"
  fi
  if [ -n "$local_branches" ]; then
echo "$local_branches"
  fi
  read -p "Continue? (y/n): " -n 1 choice
  echo
  if [ "$choice" == "y" ] || [ "$choice" == "Y" ]; then
    remotes=`echo "$remote_branches" | sed 's/\(.*\)\/\(.*\)/\1/g' | sort -u`
# Remove remote branches
for remote in $remotes
do
        branches=`echo "$remote_branches" | grep "$remote/" | sed 's/\(.*\)\/\(.*\)/:\2 /g' | tr -d '\n'`
        git Push $remote $branches 
done

# Remove local branches
git branch -d `git branch --merged | grep -v 'master$' | grep -v "$current_branch$" | sed 's/Origin\///g' | tr -d '\n'`
  else
echo "No branches removed."
  fi
fi
14
Alex Amiryan

Mit diesem Befehl werden alle entfernten (Origin) zusammengeführten Verzweigungen mit Ausnahme von master "trockenlaufen". Sie können das ändern oder nach dem Master zusätzliche Zweige hinzufügen: grep -v for-example-your-branch-here |

git branch -r --merged | 
  grep Origin | 
  grep -v '>' | 
  grep -v master | 
  xargs -L1 | 
  awk '{sub(/Origin\//,"");print}'| 
  xargs git Push Origin --delete --dry-run

Wenn es gut aussieht, entfernen Sie den --dry-run. Außerdem können Sie dies zunächst auf einer Gabel testen.

7
weston

Wenn git branch -r viele Remote-Tracking-Verzweigungen anzeigt, an denen Sie nicht interessiert sind und Sie diese nur aus lokal entfernen möchten, verwenden Sie den folgenden Befehl:

git branch -r | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

Eine sicherere Version wäre, nur die zusammengeführten zu entfernen:

git branch -r --merged | grep -Ev 'HEAD|master|develop'  | xargs -r git branch -rd

Dies kann für große Projekte nützlich sein, bei denen Sie nicht die Funktionszweige anderer Teammitglieder benötigen, sondern beim ersten Klon viele Fernverfolgungszweige abrufen müssen.

Und dieser Schritt allein ist noch nicht abgeschlossen, da diese gelöschten Fernverfolgungszweige beim nächsten git fetch wieder auftauchen würden. 

Um das Abrufen dieser Remote-Tracking-Zweige zu beenden, müssen Sie die zu holenden Refs explizit in .git/config angeben:

[remote "Origin"]
  # fetch = +refs/heads/*:refs/remotes/Origin/*
  fetch = +refs/heads/master:refs/remotes/Origin/master
  fetch = +refs/heads/develop:refs/remotes/Origin/develop
  fetch = +refs/heads/release/*:refs/remotes/Origin/release/*

Im obigen Beispiel holen wir nur master, develop und geben Zweige frei, fühlen uns frei und fügen Ihre hinzu.

3
ryenus

Löschen ist immer eine herausfordernde Aufgabe und kann gefährlich sein !!! Führen Sie daher zuerst den folgenden Befehl aus, um zu sehen, was passieren wird:

git Push --all --Prune --dry-run

Auf diese Weise liefert git eine Liste, was passieren würde, wenn der folgende Befehl ausgeführt wird.

Führen Sie dann den folgenden Befehl aus, um alle Zweige aus dem Remote-Repo zu entfernen, die sich nicht in Ihrem lokalen Repo befinden:

git Push --all --Prune

So geht es mit SourceTree (v2.3.1):
1. Klicken Sie auf Abrufen
2. Aktivieren Sie "Verfolgungszweige bereinigen ...".
3. Drücken Sie OK
4. ???? 

 enter image description here

2
coco

Ich muss hier eine Antwort hinzufügen, da die anderen Antworten entweder meinen Fall nicht abdecken oder unnötig kompliziert sind. Ich benutze github mit anderen Entwicklern und möchte nur alle lokalen Niederlassungen, deren Fernbedienungen (möglicherweise zusammengeführt wurden). aus einem github PR gelöscht, um auf einmal von meinem Rechner gelöscht zu werden. Nein, Dinge wie git branch -r --merged behandeln nicht die Zweige, die nicht lokal zusammengeführt wurden, oder die, die überhaupt nicht zusammengeführt wurden (aufgegeben) usw., daher ist eine andere Lösung erforderlich.

Wie auch immer, der erste Schritt, den ich aus anderen Antworten erhielt:

git fetch --Prune

Ein Testlauf von git remote Prune Origin schien in meinem Fall dasselbe zu tun, also habe ich mich für die kürzeste Version entschieden, um es einfach zu halten.

Nun sollte ein git branch -v die Zweige markieren, deren Fernbedienungen als [gone]..__ gelöscht werden. Daher muss ich nur noch Folgendes tun:

git branch -v|grep \\[gone\\]|awk '{print $1}'|xargs -I{} git branch -D {}

So einfach löscht es alles, was ich für das obige Szenario möchte.

Die weniger übliche xargs-Syntax ist so, dass sie neben Linux auch auf Mac & BSD funktioniert .. Vorsicht: Dieser Befehl ist kein Trockenlauf, daher werden alle als [gone] markierten Zweige zwangsweise gelöscht. Offensichtlich ist dieses Nichts für immer verschwunden. Wenn Sie Zweige gelöscht sehen, an die Sie sich erinnern, dass Sie sie behalten wollten, können Sie sie jederzeit wiederherstellen (der obige Befehl wird beim Löschen einen Hash-Wert anzeigen lassen, also ein einfacher git checkout -b <branch> <hash>.).

1
Ecuador