Очистка старых удаленных ветвей git

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

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

Скажем, у меня есть два ветки: мастер и девелоп. Оба отслеживают их удаленные копии происхождения/ведущего и происхождение/девелоп.

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

git push origin :heads/devel

git branch -d devel

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

master
origin/HEAD
origin/master

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

git branch -d 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 по-прежнему указывает начало/развитие удаленных ветвей.

Как я могу очистить удаленный вход разработчика с машины B?

Ответ 1

Во-первых, каков результат 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, чтобы увидеть результат его выполнения без его фактического запуска.

Документы для git remote prune и git branch.

Ответ 2

Рассмотрим для запуска:

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

Ответ 3

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

#!/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

Ответ 4

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

Ответ 5

Если 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/*    ### don't fetch everything
  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 и выпускаем ветки, не стесняйтесь адаптироваться по мере необходимости.

Ответ 6

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

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

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

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

git push --all --prune

Ответ 7

Вот как это сделать с помощью SourceTree (v2.3.1):
 1. Щелкните Fetch
 2. Установите флажок "Отслеживание черновиков"...  3. Нажмите ОК
 4. 😀

введите описание изображения здесь

Ответ 8

Я должен добавить ответ здесь, потому что другие ответы либо не охватывают мой случай, либо излишне сложны. Я использую 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>.