Jakie są różnice pomiędzy git remote prune, Git prune, git fetch --prune, itp

Moja sytuacja jest taka... ktoś pracujący nad tym samym repo usunął gałąź ze swojego lokalnego i zdalnego repo...

Większość osób, które pytały o tego rodzaju problem na Stack Overflow lub innych stronach, ma problem z gałęziami nadal pokazywanymi na liście gałęzi zdalnego śledzenia git branch -a na dole:

* master
  develop
  feature_blah
  remotes/origin/master
  remotes/origin/develop
  remotes/origin/feature_blah
  remotes/origin/random_branch_I_want_deleted

Jednak w mojej sytuacji oddział, którego nie powinno tam być, jest lokalny:

* master
  develop
  feature_blah
  random_branch_I_want_deleted
  remotes/origin/master
  remotes/origin/develop
  remotes/origin/feature_blah

Gdy wykonam którąkolwiek z poniższych czynności, nie zostanie ona usunięta lokalnie:

$ git prune

Ja też próbowałem:

$ git remote prune origin
$ git fetch --prune

Więcej przydatnych informacji: kiedy sprawdzam git remote show origin tak to wygląda:

* remote origin
Fetch URL: utilities:homeconnections_ui.git
Push  URL: utilities:homeconnections_ui.git
HEAD branch: master
Remote branches:
 master                        tracked
 develop                       tracked
 feature_blah                  tracked
 other123                      tracked
 other444                      tracked
 other999                      tracked
Local branches configured for 'git pull':
 develop                      merges with remote develop
 feature_blah                 merges with remote other999
 master                       merges with remote master
 random_branch_I_want_deleted merges with remote random_branch_I_want_deleted
Local refs configured for 'git push':
 develop         pushes to develop     (local out of date)
 master          pushes to master      (up to date)
 feature_blah    pushes to feature_blah(up to date)

Zauważ, że jest tylko w sekcji zatytułowanej Local branches configured for 'git pull':

Dlaczego?
Author: Matthew Rankin, 2013-11-21

4 answers

Nie winię cię za frustrację. Najlepiej patrzeć na to. Istnieją potencjalnie trzy wersje każdej zdalnej gałęzi:]}

  1. rzeczywista gałąź w zdalnym repozytorium
  2. twoja migawka tej gałęzi lokalnie (przechowywana w refs/remotes/...)
  3. I lokalna gałąź, która może śledzić zdalną gałąź]}

Zacznijmy od git prune. Usuwa obiekty , które nie są już odwołane, nie usuwa referencje. W Twoim przypadku masz lokalny oddział. Oznacza to, że istnieje ref random_branch_I_want_deleted, który odnosi się do niektórych obiektów, które reprezentują historię tej gałęzi. Tak więc z definicji git prune nie usunie random_branch_I_want_deleted. Tak naprawdę, git prune jest sposobem na usunięcie danych, które zostały zgromadzone w Git, ale nie są przez nic przywoływane. Ogólnie rzecz biorąc, nie wpływa to na widok jakichkolwiek gałęzi.

git remote prune origin i git fetch --prune oba działają na referencjach pod refs/remotes/... (odwołam się do nich jako do zdalnych referencji). Informatyka nie wpływa na lokalne oddziały. Wersja git remote jest przydatna, jeśli chcesz usunąć zdalne odwołania tylko pod określonym zdalnym. W przeciwnym razie obaj robią dokładnie to samo. W skrócie, git remote prune i git fetch --prune działają na numerze 2 powyżej. Na przykład, jeśli usunąłeś gałąź za pomocą GUI git web i nie chcesz, aby pojawiała się ona na twojej lokalnej liście gałęzi (git branch -r), to jest to polecenie, którego powinieneś użyć.

Aby usunąć lokalną gałąź, należy użyć git branch -d (lub -D, Jeśli nie scalone w dowolnym miejscu). FWIW, nie ma komendy git, która automatycznie usuwa lokalne gałęzie śledzące, jeśli zdalna gałąź znika.

 465
Author: John Szakmeister,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-03 20:11:57

git remote prune i git fetch --prune Zrób to samo: Usuń refy do gałęzi, które nie istnieją na pilocie, tak jak powiedziałeś. Drugie polecenie łączy się z pilotem i pobiera jego obecne gałęzie przed przycinaniem.

Jednak nie dotyka sprawdzonych lokalnych oddziałów, które możesz po prostu usunąć za pomocą

git branch -d  random_branch_I_want_deleted

Zastąp -d przez -D Jeśli gałąź nie zostanie połączona gdzie indziej

git prune robi coś innego, oczyszcza nieosiągalne obiekty, te commity, które nie są dostępne w żadnej gałęzi lub tagu, a zatem nie są już potrzebne.

 43
Author: CharlesB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-27 09:50:35

Zauważ, że jedna różnica między git remote --prune i git fetch --prune jest stała, z commit 10a6cc8, przez Toma Millera (tmiller) (dla git 1.9/2.0, Q1 2014):

Kiedy mamy zdalnie śledzącą gałąź o nazwie "frotz/nitfol "z poprzedniego pobierania, i upstream ma teraz gałąź o nazwie" * * frotz"**, fetch nie usunie "frotz/nitfol " za pomocą "git fetch --prune " z upstream.
git poinformuje użytkownika, aby użył "git remote prune " do rozwiązania problemu.

Więc: kiedy a upstream repo posiada gałąź ("frotz") o tej samej nazwie co hierarchia oddziałów ("frotz / xxx", możliwa konwencja nazewnictwa gałęzi), git remote --prune udało się (w czyszczeniu gałęzi zdalnego śledzenia z repo), ale git fetch --prune nie powiodło się.

Już Nie:

Zmień sposób działania "fetch --prune", przesuwając operację przycinania przed operacją pobierania.
W ten sposób, zamiast ostrzegać użytkownika o konflikcie, automatycznie go naprawia.

 12
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:44

W razie gdyby ktoś był zainteresowany. Oto szybki skrypt powłoki, który usunie wszystkie lokalne gałęzie, które nie są śledzone zdalnie. Ostrzeżenie: dzięki temu pozbędziesz się każdej gałęzi, która nie jest śledzona zdalnie, niezależnie od tego, czy została scalona, czy nie.

Jeśli zauważycie jakieś problemy z tym proszę dać mi znać, a ja to naprawię (itp. itd.)

Zapisz go w pliku o nazwie git-rm-ntb (nazwij to jak chcesz) na PATH i uruchom:

git-rm-ntb <remote1:optional> <remote2:optional> ...

clean()
{
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  RBRANCHES=()
  while read REMOTE; do
    CURRBRANCHES=($(git ls-remote $REMOTE | awk '{print $2}' | grep 'refs/heads/' | sed 's:refs/heads/::'))
    RBRANCHES=("${CURRBRANCHES[@]}" "${RBRANCHES[@]}")
  done < <(echo "$REMOTES" )
  [[ $RBRANCHES ]] || exit
  LBRANCHES=($(git branch | sed 's:\*::' | awk '{print $1}'))
  for i in "${LBRANCHES[@]}"; do
    skip=
    for j in "${RBRANCHES[@]}"; do
      [[ $i == $j ]] && { skip=1; echo -e "\033[32m Keeping $i \033[0m"; break; }
    done
    [[ -n $skip ]] || { echo -e "\033[31m $(git branch -D $i) \033[0m"; }
  done
}

clean $@
 8
Author: D.Mill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-28 00:21:49