очистка старых удаленных веток git - PullRequest
606 голосов
/ 06 июля 2010

Вот мой рабочий процесс git.

Я работаю с двух разных компьютеров (A и B) и храню общий удаленный git в каталоге dropbox.

Допустим, у меня есть две ветви master иDevel.Оба отслеживают свои удаленные аналоги origin / master и origin / devel.

Теперь, находясь на компьютере A, я удаляю ветку devel - локальную и удаленную - следующим образом:

git push origin :heads/devel

git branch -d devel

Теперь, еслиЯ делаю git branch -a на компьютере A, я получаю

master
origin/HEAD
origin/master

Теперь я иду на компьютер B. Сделайте git fetch.Я могу удалить локальную ветку devel с помощью

git branch -d devel

Но я не могу удалить удаленную ветку devel.

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

В git branch -a все еще перечисляются origin / devel в удаленных ветвях.

Как очистить удаленный вход devel с машины B?

Ответы [ 8 ]

1121 голосов
/ 06 июля 2010

Во-первых, каков результат git branch -a на компьютере B?

Во-вторых, вы уже удалили heads/devel на origin, поэтому вы не можете удалить его с компьютера B.

Попробуйте

git branch -r -d origin/devel

или

git remote prune origin

или

git fetch origin --prune

и не стесняйтесь добавлять --dry-run в конец вашего git оператор, чтобы увидеть результат его запуска без фактического запуска.

78 голосов
/ 23 мая 2017

Рекомендуется выполнить:

git fetch --prune

Регулярно в каждом репо удалять локальные ветви, которые отслеживали удаленную ветку, которая удалена (больше не существует в удаленном репозитории GIT).

Это может быть еще более упрощено с помощью

git config remote.origin.prune true

. Это настройка per-repo, которая автоматически применит любое будущее git fetch or git pull обрезка .

настроить это для своего пользователя, вы также можете отредактировать глобальный .gitconfig и добавить

[fetch]
    prune = true

Однако рекомендуется сделать это с помощью следующей команды:

git config --global fetch.prune true

илиприменять его в масштабе всей системы (не только для пользователя)

git config --system fetch.prune true
14 голосов
/ 16 марта 2012

Вот скрипт bash, который может сделать это за вас. Это модифицированная версия скрипта http://snippets.freerobby.com/post/491644841/remove-merged-branches-in-git. Моя модификация позволяет ему поддерживать различные удаленные местоположения.

#!/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
9 голосов
/ 24 октября 2016

Эта команда "пробный запуск" удалит все удаленные (origin) объединенные ветви, кроме master.Вы можете изменить это или добавить дополнительные ветви после мастера: 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

Если все выглядит хорошо, удалите --dry-run.Кроме того, вы можете сначала проверить это на вилке.

4 голосов
/ 07 ноября 2017

Если git branch -r показывает множество веток удаленного отслеживания, которые вас не интересуют, и вы хотите удалить их только из локальной, используйте следующую команду:

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

Более безопасной версией будет удаление только слитых:

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

Это может быть полезно для больших проектов, где вам не нужны ветви функций других товарищей по команде, но есть много веток удаленного отслеживания, извлеченных из исходного клона.

И этот один шаг не завершен, потому что эти удаленные ветви удаленного отслеживания снова появятся при следующем git fetch.

Чтобы прекратить извлекать эти ветви удаленного отслеживания, вам нужно явно указать ссылки для извлечения в .git / config :

[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/*

В приведенном выше примере мы только выбираем master, develop и выпускаем ветки, не стесняйтесь и добавляйте свои.

3 голосов
/ 03 сентября 2016

Удаление всегда является сложной задачей и может быть опасным !!!Поэтому сначала выполните следующую команду, чтобы увидеть, что произойдет:

git push --all --prune --dry-run

Сделав так, как описано выше, git предоставит вам список того, что произойдет, если будет выполнена следующая команда.1007 *

Затем выполните следующую команду, чтобы удалить все ветви из удаленного репо, которых нет в вашем локальном репо:

git push --all --prune
2 голосов
/ 06 июня 2016

Вот как это сделать с SourceTree (v2.3.1):
1. Нажмите Fetch
2. Установите флажок «Обрезать ветви отслеживания ...»
3. Нажмите OK
4.100

enter image description here

1 голос
/ 07 февраля 2019

Мне придется добавить ответ здесь, потому что другие ответы либо не охватывают мой случай, либо излишне сложны. Я использую github с другими разработчиками, и я просто хочу, чтобы все локальные ветки, удаленные из которых (возможно, были объединены и) удалены из github PR, были удалены за один раз с моей машины. Нет, такие вещи, как git branch -r --merged, не охватывают ветви, которые не были объединены локально, или ветви, которые вообще не были объединены (оставлены) и т. Д., Поэтому необходимо другое решение.

Во всяком случае, первый шаг, который я получил из других ответов:

git fetch --prune

Пробный прогон git remote prune origin выглядел так, как будто он сделал бы то же самое в моем случае, поэтому я остановился на самой короткой версии, чтобы сделать ее простой.

Теперь git branch -v должен пометить ветви, удаленные из которых удалены, как [gone]. Поэтому все, что мне нужно сделать, это:

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

Так просто, он удаляет все, что я хочу для вышеуказанного сценария.

Менее распространенный синтаксис xargs таков, что он также работает на Mac и BSD в дополнение к Linux. Осторожно, эта команда не является пробной, поэтому она принудительно удалит все ветви, помеченные как [gone]. Очевидно, что это git - ничто не исчезнет навсегда, если вы видите удаленные ветви, которые, как вы помните, хотели сохранить, вы всегда можете восстановить их (приведенная выше команда перечислит их хэш при удалении, поэтому просто git checkout -b <branch> <hash>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...